Annotation of gcc/combine.c, revision 1.1.1.1

1.1       root        1: /* Optimize by combining instructions for GNU compiler.
                      2:    Copyright (C) 1987 Free Software Foundation, Inc.
                      3: 
                      4: This file is part of GNU CC.
                      5: 
                      6: GNU CC is distributed in the hope that it will be useful,
                      7: but WITHOUT ANY WARRANTY.  No author or distributor
                      8: accepts responsibility to anyone for the consequences of using it
                      9: or for whether it serves any particular purpose or works at all,
                     10: unless he says so in writing.  Refer to the GNU CC General Public
                     11: License for full details.
                     12: 
                     13: Everyone is granted permission to copy, modify and redistribute
                     14: GNU CC, but only under the conditions described in the
                     15: GNU CC General Public License.   A copy of this license is
                     16: supposed to have been given to you along with GNU CC so you
                     17: can know your rights and responsibilities.  It should be in a
                     18: file named COPYING.  Among other things, the copyright notice
                     19: and this notice must be preserved on all copies.  */
                     20: 
                     21: 
                     22: /* This module is essentially the "combiner" phase of the U. of Arizona
                     23:    Portable Optimizer, but redone to work on our list-structured
                     24:    representation for RTL instead of their string representation.
                     25: 
                     26:    The LOG_LINKS of each insn identify the most recent assignment
                     27:    to each REG used in the insn.  It is a list of previous insns,
                     28:    each of which contains a SET for a REG that is used in this insn
                     29:    and not used or set in between.  LOG_LINKs never cross basic blocks.
                     30:    They were set up by the preceding pass (lifetime analysis).
                     31: 
                     32:    We try to combine each pair of insns joined by a logical link.
                     33:    We also try to combine triples of insns A, B and C when
                     34:    C has a link back to B and B has a link back to A.
                     35: 
                     36:    LOG_LINKS does not have links for use of the CC0.  They don't
                     37:    need to, because the insn that sets the CC0 is always immediately
                     38:    before the insn that tests it.  So we always regard a branch
                     39:    insn as having a logical link to the preceding insn.
                     40: 
                     41:    We check (with use_crosses_set_p) to avoid combining in such a way
                     42:    as to move a computation to a place where its value would be different.
                     43: 
                     44:    Combination is done by mathematically substituting the previous
                     45:    insn(s) values for the regs they set into the expressions in
                     46:    the later insns that refer to these regs.  If the result is a valid insn
                     47:    for our target machine, according to the machine description,
                     48:    we install it, delete the earlier insns, and update the data flow
                     49:    information (LOG_LINKS and REG_NOTES) for what we did.
                     50: 
                     51:    To simplify substitution, we combine only when the earlier insn(s)
                     52:    consist of only a single assignment.  To simplify updating afterward,
                     53:    we never combine when a subroutine call appears in the middle.
                     54: 
                     55:    Since we do not represent assignments to CC0 explicitly except when that
                     56:    is all an insn does, there is no LOG_LINKS entry in an insn that uses
                     57:    the condition code for the insn that set the condition code.
                     58:    Fortunately, these two insns must be consecutive.
                     59:    Therefore, every JUMP_INSN is taken to have an implicit logical link
                     60:    to the preceding insn.  This is not quite right, since non-jumps can
                     61:    also use the condition code; but in practice such insns would not
                     62:    combine anyway.  */
                     63: 
                     64: #include "config.h"
                     65: #include "rtl.h"
                     66: #include "regs.h"
                     67: #include "basic-block.h"
                     68: #include "insn-config.h"
                     69: #include "recog.h"
                     70: 
                     71: #define max(A,B) ((A) > (B) ? (A) : (B))
                     72: #define min(A,B) ((A) < (B) ? (A) : (B))
                     73: 
                     74: /* Number of attempts to combine instructions in this function.  */
                     75: 
                     76: static int combine_attempts;
                     77: 
                     78: /* Number of attempts that got as far as substitution in this function.  */
                     79: 
                     80: static int combine_merges;
                     81: 
                     82: /* Number of instructions combined with added SETs in this function.  */
                     83: 
                     84: static int combine_extras;
                     85: 
                     86: /* Number of instructions combined in this function.  */
                     87: 
                     88: static int combine_successes;
                     89: 
                     90: /* Totals over entire compilation.  */
                     91: 
                     92: static int total_attempts, total_merges, total_extras, total_successes;
                     93: 
                     94: 
                     95: /* Vector mapping INSN_UIDs to cuids.
                     96:    The cuids are like uids but increase monononically always.
                     97:    Combine always uses cuids so that it can compare them.
                     98:    But actually renumbering the uids, which we used to do,
                     99:    proves to be a bad idea because it makes it hard to compare
                    100:    the dumps produced by earlier passes with those from later passes.  */
                    101: 
                    102: static short *uid_cuid;
                    103: 
                    104: /* Get the cuid of an insn.  */
                    105: 
                    106: #define INSN_CUID(INSN) (uid_cuid[INSN_UID (INSN)])
                    107: 
                    108: 
                    109: /* Record last point of death of (hard or pseudo) register n.  */
                    110: 
                    111: static rtx *reg_last_death;
                    112: 
                    113: /* Record last point of modification of (hard or pseudo) register n.  */
                    114: 
                    115: static rtx *reg_last_set;
                    116: 
                    117: /* Record the cuid of the last insn that invalidated memory
                    118:    (anything that writes memory, and subroutine calls).  */
                    119: 
                    120: static int mem_last_set;
                    121: 
                    122: /* Record the cuid of the last CALL_INSN
                    123:    so we can tell whether a potential combination crosses any calls.  */
                    124: 
                    125: static int last_call_cuid;
                    126: 
                    127: /* When `subst' is called, this is the insn that is being modified
                    128:    (by combining in a previous insn).  The PATTERN of this insn
                    129:    is still the old pattern partially modified and it should not be
                    130:    looked at, but this may be used to examine the successors of the insn
                    131:    to judge whether a simplification is valid.  */
                    132: 
                    133: static rtx subst_insn;
                    134: 
                    135: /* Record one modification to rtl structure
                    136:    to be undone by storing old_contents into *where.  */
                    137: 
                    138: struct undo
                    139: {
                    140:   rtx *where;
                    141:   rtx old_contents;
                    142: };
                    143: 
                    144: /* Record a bunch of changes to be undone, up to MAX_UNDO of them.
                    145:    num_undo says how many are currently recorded.
                    146:    storage is nonzero if we must undo the allocation of new storage.
                    147:    The value of storage is what to pass to obfree.  */
                    148: 
                    149: #define MAX_UNDO 10
                    150: 
                    151: struct undobuf
                    152: {
                    153:   int num_undo;
                    154:   char *storage;
                    155:   struct undo undo[MAX_UNDO];
                    156: };
                    157: 
                    158: static struct undobuf undobuf;
                    159: 
                    160: static void move_deaths ();
                    161: static void remove_death ();
                    162: static void record_dead_and_set_regs ();
                    163: int regno_dead_p ();
                    164: static int reg_set_in_range_p ();
                    165: static int use_crosses_set_p ();
                    166: static rtx subst ();
                    167: static void undo_all ();
                    168: static void add_links ();
                    169: static void add_incs ();
                    170: static int adjacent_insns_p ();
                    171: static rtx simplify_and_const_int ();
                    172: static rtx gen_lowpart_for_combine ();
                    173: static void simplify_set_cc0_and ();
                    174: 
                    175: /* Main entry point for combiner.  F is the first insn of the function.
                    176:    NREGS is the first unused pseudo-reg number.  */
                    177: 
                    178: void
                    179: combine_instructions (f, nregs)
                    180:      rtx f;
                    181:      int nregs;
                    182: {
                    183:   register rtx insn;
                    184:   register int i;
                    185:   register rtx links, nextlinks;
                    186:   rtx prev;
                    187: 
                    188:   combine_attempts = 0;
                    189:   combine_merges = 0;
                    190:   combine_extras = 0;
                    191:   combine_successes = 0;
                    192: 
                    193:   reg_last_death = (rtx *) alloca (nregs * sizeof (rtx));
                    194:   reg_last_set = (rtx *) alloca (nregs * sizeof (rtx));
                    195:   bzero (reg_last_death, nregs * sizeof (rtx));
                    196:   bzero (reg_last_set, nregs * sizeof (rtx));
                    197: 
                    198:   init_recog ();
                    199: 
                    200:   /* Compute maximum uid value so uid_cuid can be allocated.  */
                    201: 
                    202:   for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
                    203:     if (INSN_UID (insn) > i)
                    204:       i = INSN_UID (insn);
                    205: 
                    206:   uid_cuid = (short *) alloca ((i + 1) * sizeof (short));
                    207: 
                    208:   /* Compute the mapping from uids to cuids.
                    209:      Cuids are numbers assigned to insns, like uids,
                    210:      except that cuids increase monotonically through the code.  */
                    211: 
                    212:   for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
                    213:     INSN_CUID (insn) = ++i;
                    214: 
                    215:   /* Now scan all the insns in forward order.  */
                    216: 
                    217:   last_call_cuid = 0;
                    218:   mem_last_set = 0;
                    219:   prev = 0;
                    220: 
                    221:   for (insn = f; insn; insn = NEXT_INSN (insn))
                    222:     {
                    223:       if (GET_CODE (insn) == INSN
                    224:          || GET_CODE (insn) == CALL_INSN
                    225:          || GET_CODE (insn) == JUMP_INSN)
                    226:        {
                    227:        retry:
                    228:          /* Try this insn with each insn it links back to.  */
                    229: 
                    230:          for (links = LOG_LINKS (insn); links; links = XEXP (links, 1))
                    231:            if (try_combine (insn, XEXP (links, 0), 0))
                    232:              goto retry;
                    233: 
                    234:          /* Try each sequence of three linked insns ending with this one.  */
                    235: 
                    236:          for (links = LOG_LINKS (insn); links; links = XEXP (links, 1))
                    237:            if (GET_CODE (XEXP (links, 0)) != NOTE)
                    238:              for (nextlinks = LOG_LINKS (XEXP (links, 0)); nextlinks;
                    239:                   nextlinks = XEXP (nextlinks, 1))
                    240:                if (try_combine (insn, XEXP (links, 0), XEXP (nextlinks, 0)))
                    241:                  goto retry;
                    242: 
                    243:          /* Try to combine a jump insn that uses CC0
                    244:             with a preceding insn that sets CC0, and maybe with its
                    245:             logical predecessor as well.
                    246:             This is how we make decrement-and-branch insns.
                    247:             We need this special code because data flow connections
                    248:             via CC0 do not get entered in LOG_LINKS.  */
                    249: 
                    250:          if (GET_CODE (insn) == JUMP_INSN
                    251:              && prev != 0
                    252:              && GET_CODE (prev) == INSN
                    253:              && GET_CODE (PATTERN (prev)) == SET
                    254:              && GET_CODE (SET_DEST (PATTERN (prev))) == CC0)
                    255:            {
                    256:              if (try_combine (insn, prev, 0))
                    257:                  goto retry;
                    258: 
                    259:              if (GET_CODE (prev) != NOTE)
                    260:                for (nextlinks = LOG_LINKS (prev); nextlinks;
                    261:                     nextlinks = XEXP (nextlinks, 1))
                    262:                  if (try_combine (insn, prev, XEXP (nextlinks, 0)))
                    263:                    goto retry;
                    264:            }
                    265: #if 0
                    266: /* Turned off because on 68020 it takes four insns to make
                    267:    something like (a[b / 32] & (1 << (31 - (b % 32)))) != 0
                    268:    that could actually be optimized, and that's an unlikely piece of code.  */
                    269:          /* If an insn gets or sets a bit field, try combining it
                    270:             with two different insns whose results it uses.  */
                    271:          if (GET_CODE (insn) == INSN
                    272:              && GET_CODE (PATTERN (insn)) == SET
                    273:              && (GET_CODE (SET_DEST (PATTERN (insn))) == ZERO_EXTRACT
                    274:                  || GET_CODE (SET_DEST (PATTERN (insn))) == SIGN_EXTRACT
                    275:                  || GET_CODE (SET_SRC (PATTERN (insn))) == ZERO_EXTRACT
                    276:                  || GET_CODE (SET_SRC (PATTERN (insn))) == SIGN_EXTRACT))
                    277:            {
                    278:              for (links = LOG_LINKS (insn); links; links = XEXP (links, 1))
                    279:                if (GET_CODE (XEXP (links, 0)) != NOTE)
                    280:                  for (nextlinks = XEXP (links, 1); nextlinks;
                    281:                       nextlinks = XEXP (nextlinks, 1))
                    282:                    if (try_combine (insn, XEXP (links, 0), XEXP (nextlinks, 0)))
                    283:                      goto retry;
                    284:            }
                    285: #endif
                    286:          record_dead_and_set_regs (insn);
                    287:          prev = insn;
                    288:        }
                    289:       else if (GET_CODE (insn) != NOTE)
                    290:        prev = 0;
                    291:     }
                    292:   total_attempts += combine_attempts;
                    293:   total_merges += combine_merges;
                    294:   total_extras += combine_extras;
                    295:   total_successes += combine_successes;
                    296: }
                    297: 
                    298: /* Try to combine the insns I1 and I2 into I3.
                    299:    Here I1 appears earlier than I2, which is earlier than I3.
                    300:    I1 can be zero; then we combine just I2 into I3.
                    301:  
                    302:    Return 1 if successful; if that happens, I1 and I2 are pseudo-deleted
                    303:    by turning them into NOTEs, and I3 is modified.
                    304:    Return 0 if the combination does not work.  Then nothing is changed.  */
                    305: 
                    306: static int
                    307: try_combine (i3, i2, i1)
                    308:      register rtx i3, i2, i1;
                    309: {
                    310:   register rtx newpat;
                    311:   int added_sets_1 = 0;
                    312:   int added_sets_2 = 0;
                    313:   int total_sets;
                    314:   int i2_is_used;
                    315:   register rtx link;
                    316:   int insn_code_number;
                    317:   int recog_flags = 0;
                    318:   rtx i2dest, i2src;
                    319:   rtx i1dest, i1src;
                    320: 
                    321:   combine_attempts++;
                    322: 
                    323:   /* Don't combine with something already used up by combination.  */
                    324: 
                    325:   if (GET_CODE (i2) == NOTE
                    326:       || (i1 && GET_CODE (i1) == NOTE))
                    327:     return 0;
                    328: 
                    329:   /* Don't combine across a CALL_INSN, because that would possibly
                    330:      change whether the life span of some REGs crosses calls or not,
                    331:      and it is a pain to update that information.  */
                    332: 
                    333:   if (INSN_CUID (i2) < last_call_cuid
                    334:       || (i1 && INSN_CUID (i1) < last_call_cuid))
                    335:     return 0;
                    336: 
                    337:   /* Can combine only if previous insn is a SET of a REG, a SUBREG or CC0.
                    338:      That REG must be either set or dead by the final instruction
                    339:      (so that we can safely forget about setting it).
                    340:      Also test use_crosses_set_p to make sure that the value
                    341:      that is to be substituted for the register
                    342:      does not use any registers whose values alter in between.
                    343:      Do not try combining with moves from one register to another
                    344:      since it is better to let them be tied by register allocation.
                    345: 
                    346:      A set of a SUBREG is considered as if it were a set from
                    347:      SUBREG.  Thus, (SET (SUBREG:X (REG:Y...)) (something:X...))
                    348:      is handled by substituting (SUBREG:Y (something:X...)) for (REG:Y...).  */
                    349: 
                    350:   if (GET_CODE (PATTERN (i2)) != SET)
                    351:     return 0;
                    352:   i2dest = SET_DEST (PATTERN (i2));
                    353:   i2src = SET_SRC (PATTERN (i2));
                    354:   if (GET_CODE (i2dest) == SUBREG)
                    355:     {
                    356:       i2dest = SUBREG_REG (i2dest);
                    357:       i2src = gen_rtx (SUBREG, GET_MODE (i2dest), i2src, 0);
                    358:     }
                    359:   if (GET_CODE (i2dest) != CC0
                    360:       && (GET_CODE (i2dest) != REG
                    361:          || GET_CODE (i2src) == REG
                    362:          || use_crosses_set_p (i2src, INSN_CUID (i2))))
                    363:     return 0;
                    364: 
                    365:   if (i1 != 0)
                    366:     {
                    367:       if (GET_CODE (PATTERN (i1)) != SET)
                    368:        return 0;
                    369:       i1dest = SET_DEST (PATTERN (i1));
                    370:       i1src = SET_SRC (PATTERN (i1));
                    371:       if (GET_CODE (i1dest) == SUBREG)
                    372:        {
                    373:          i1dest = SUBREG_REG (i1dest);
                    374:          i1src = gen_rtx (SUBREG, GET_MODE (i1dest), i1src, 0);
                    375:        }
                    376:       if (GET_CODE (i1dest) != CC0
                    377:          && (GET_CODE (i1dest) != REG
                    378:              || GET_CODE (i1src) == REG
                    379:              || use_crosses_set_p (i1src, INSN_CUID (i1))))
                    380:        return 0;
                    381:     }
                    382: 
                    383:   /* If I1 or I2 contains an autoincrement or autodecrement,
                    384:      make sure that register is not used between there and I3.
                    385:      Also insist that I3 not be a jump; if it were one
                    386:      and the incremented register were spilled, we would lose.  */
                    387:   for (link = REG_NOTES (i2); link; link = XEXP (link, 1))
                    388:     if ((enum reg_note) GET_MODE (link) == REG_INC)
                    389:       if (GET_CODE (i3) == JUMP_INSN
                    390:          || reg_used_between_p (XEXP (link, 0), i2, i3))
                    391:        return 0;
                    392: 
                    393:   if (i1)
                    394:     for (link = REG_NOTES (i1); link; link = XEXP (link, 1))
                    395:       if ((enum reg_note) GET_MODE (link) == REG_INC)
                    396:        if (GET_CODE (i3) == JUMP_INSN
                    397:            || reg_used_between_p (XEXP (link, 0), i1, i3))
                    398:          return 0;
                    399: 
                    400:   /* See if the SETs in i1 or i2 need to be kept around in the merged
                    401:      instruction: whenever the value set there is still needed past i3.  */
                    402:   added_sets_2 = (GET_CODE (i2dest) != CC0
                    403:                  && ! dead_or_set_p (i3, i2dest));
                    404:   if (i1)
                    405:     added_sets_1 = ! (dead_or_set_p (i3, i1dest)
                    406:                      || dead_or_set_p (i2, i1dest));
                    407: 
                    408:   combine_merges++;
                    409: 
                    410:   undobuf.num_undo = 0;
                    411:   undobuf.storage = 0;
                    412: 
                    413:   /* Substitute in the latest insn for the regs set by the earlier ones.  */
                    414: 
                    415:   subst_insn = i3;
                    416:   newpat = subst (PATTERN (i3), i2dest, i2src);
                    417:   /* Record whether i2's body now appears within i3's body.  */
                    418:   i2_is_used = undobuf.num_undo;
                    419: 
                    420:   if (i1)
                    421:     newpat = subst (newpat, i1dest, i1src);
                    422: 
                    423:   if (GET_CODE (PATTERN (i3)) == SET
                    424:       && SET_DEST (PATTERN (i3)) == cc0_rtx
                    425:       && GET_CODE (SET_SRC (PATTERN (i3))) == AND
                    426:       && next_insn_tests_no_inequality (i3))
                    427:     simplify_set_cc0_and (i3);
                    428: 
                    429:   /* If the actions of the earler insns must be kept
                    430:      in addition to substituting them into the latest one,
                    431:      we must make a new PARALLEL for the latest insn
                    432:      to hold additional the SETs.  */
                    433: 
                    434:   if (added_sets_1 || added_sets_2)
                    435:     {
                    436:       combine_extras++;
                    437: 
                    438:       /* Arrange to free later what we allocate now
                    439:         if we don't accept this combination.  */
                    440:       if (!undobuf.storage)
                    441:        undobuf.storage = (char *) oballoc (0);
                    442: 
                    443:       if (GET_CODE (newpat) == PARALLEL)
                    444:        {
                    445:          total_sets = XVECLEN (newpat, 0) + added_sets_1 + added_sets_2;
                    446:          newpat = gen_rtx (PARALLEL, VOIDmode,
                    447:                            gen_rtvec_v (total_sets,
                    448:                                         &XVECEXP (newpat, 0, 0)));
                    449:        }
                    450:       else
                    451:        {
                    452:          total_sets = 1 + added_sets_1 + added_sets_2;
                    453:          newpat = gen_rtx (PARALLEL, VOIDmode,
                    454:                            gen_rtvec (total_sets, newpat));
                    455:        }
                    456:      if (added_sets_1)
                    457:        {
                    458:          XVECEXP (newpat, 0, --total_sets) = PATTERN (i1);
                    459:        }
                    460:      if (added_sets_2)
                    461:        {
                    462:          /* If there is no I1, use I2's body as is.  */
                    463:          if (i1 == 0
                    464:          /* If I2 was stuck into I3, then anything within it has
                    465:             already had I1 substituted into it when that was done to I3.  */
                    466:              || i2_is_used)
                    467:            {
                    468:              XVECEXP (newpat, 0, --total_sets) = PATTERN (i2);
                    469:            }
                    470:          else
                    471:            XVECEXP (newpat, 0, --total_sets)
                    472:              = subst (PATTERN (i2), i1dest, i1src);
                    473:        }
                    474:     }
                    475: 
                    476:   /* Is the result of combination a valid instruction?  */
                    477:   insn_code_number = recog (newpat, i3);
                    478: 
                    479:   if (insn_code_number >= 0)
                    480:     {
                    481:       /* Yes.  Install it.  */
                    482:       register int regno;
                    483:       INSN_CODE (i3) = insn_code_number;
                    484:       PATTERN (i3) = newpat;
                    485:       /* Most REGs that previously died in I2 now die in I3.  */ 
                    486:       move_deaths (i2src, INSN_CUID (i2), i3);
                    487:       if (GET_CODE (i2dest) == REG)
                    488:        {
                    489:          /* If the reg formerly set in I2 died only once and that was in I3,
                    490:             zero its use count so it won't make `reload' do any work.  */
                    491:          regno = REGNO (i2dest);
                    492:          if (! added_sets_2)
                    493:            reg_n_sets[regno]--;
                    494:          if (reg_n_sets[regno] == 0 && regno_dead_p (regno, i3))
                    495:            reg_n_refs[regno] = 0;
                    496:          /* If a ref to REGNO was substituted into I3 from I2,
                    497:             then it still dies there if it previously did.
                    498:             Otherwise either REGNO never did die in I3 so remove_death is safe
                    499:             or this entire life of REGNO is gone so remove its death.  */
                    500:          if (!added_sets_2
                    501:              && ! reg_mentioned_p (i2dest, PATTERN (i3)))
                    502:            remove_death (regno, i3);
                    503:        }
                    504:       /* The data flowing into I2 now flows into I3.
                    505:         But we cannot always move I2's LOG_LINKS into I3,
                    506:         since they must go to a setting of a REG from the
                    507:         first use following.  If I2 was the first use following a set,
                    508:         I3 is now a use, but it is not the first use
                    509:         if some instruction between I2 and I3 is also a use.
                    510:         Here, for simplicity, we move the links only if
                    511:         there are no real insns between I2 and I3.  */
                    512:       if (adjacent_insns_p (i2, i3))
                    513:        add_links (i3, LOG_LINKS (i2));
                    514:       /* Any registers previously autoincremented in I2
                    515:         are now incremented in I3.  */
                    516:       add_incs (i3, REG_NOTES (i2));
                    517:       /* Get rid of I2.  */
                    518:       LOG_LINKS (i2) = 0;
                    519:       PUT_CODE (i2, NOTE);
                    520:       NOTE_LINE_NUMBER (i2) = NOTE_INSN_DELETED;
                    521:       NOTE_SOURCE_FILE (i2) = 0;
                    522:       if (i1)
                    523:        {
                    524:          /* Likewise, merge the info from I1 and get rid of it.  */
                    525:          move_deaths (i1src, INSN_CUID (i1), i3);
                    526:          if (GET_CODE (i1dest) == REG)
                    527:            {
                    528:              regno = REGNO (i1dest);
                    529:              if (! added_sets_1)
                    530:                reg_n_sets[regno]--;
                    531:              if (reg_n_sets[regno] == 0 && regno_dead_p (regno, i3))
                    532:                reg_n_refs[regno] = 0;
                    533:              /* If a ref to REGNO was substituted into I3 from I1,
                    534:                 then it still dies there if it previously did.
                    535:                 Else either REGNO never did die in I3 so remove_death is safe
                    536:                 or this entire life of REGNO is gone so remove its death.  */
                    537:              if (! added_sets_1
                    538:                  && ! reg_mentioned_p (i1dest, PATTERN (i3)))
                    539:                remove_death (regno, i3);
                    540:            }
                    541:          if (adjacent_insns_p (i2, i3))
                    542:            add_links (i3, LOG_LINKS (i1));
                    543:          add_incs (i3, REG_NOTES (i1));
                    544:          LOG_LINKS (i1) = 0;
                    545:          PUT_CODE (i1, NOTE);
                    546:          NOTE_LINE_NUMBER (i1) = NOTE_INSN_DELETED;
                    547:          NOTE_SOURCE_FILE (i1) = 0;
                    548:        }
                    549: 
                    550:       combine_successes++;
                    551:       return 1;
                    552:     }
                    553: 
                    554:   /* Failure: change I3 back the way it was.  */
                    555:   undo_all ();
                    556: 
                    557:   return 0;
                    558: }
                    559: 
                    560: /* Undo all the modifications recorded in undobuf.  */
                    561: 
                    562: static void
                    563: undo_all ()
                    564: {
                    565:   register int i;
                    566:   if (undobuf.num_undo > MAX_UNDO)
                    567:     undobuf.num_undo = MAX_UNDO;
                    568:   for (i = undobuf.num_undo - 1; i >= 0; i--)
                    569:     *undobuf.undo[i].where = undobuf.undo[i].old_contents;
                    570:   if (undobuf.storage)
                    571:     obfree (undobuf.storage);
                    572:   undobuf.num_undo = 0;
                    573:   undobuf.storage = 0;
                    574: }
                    575: 
                    576: /* Throughout X, replace FROM with TO, and return the result.
                    577:    The result is TO if X is FROM;
                    578:    otherwise the result is X, but its contents may have been modified.
                    579:    If they were modified, a record was made in undobuf so that
                    580:    undo_all will (among other things) return X to its original state.
                    581: 
                    582:    If the number of changes necessary is too much to record to undo,
                    583:    the excess changes are not made, so the result is invalid.
                    584:    The changes already made can still be undone.
                    585:    undobuf.num_undo is incremented for such changes, so by testing that
                    586:    the caller can tell whether the result is valid.  */
                    587: 
                    588: static rtx
                    589: subst (x, from, to)
                    590:      register rtx x, from, to;
                    591: {
                    592:   register char *fmt;
                    593:   register int len, i;
                    594:   register enum rtx_code code;
                    595: 
                    596:   /* THIS_TO is used to replace FROM if it appears exactly one
                    597:      level down in X.  Simplifications often work by changing
                    598:      THIS_TO after observing that FROM appears in a specific way
                    599:      one level down in X.  Since only THIS_TO is changed, and TO
                    600:      is left alone, further occurrences of FROM within the operands
                    601:      of X are replaced normally.  */
                    602:   rtx this_to;
                    603: 
                    604:   if (x == from)
                    605:     return to;
                    606: 
                    607:   code = GET_CODE (x);
                    608:   this_to = to;
                    609: 
                    610:   /* A little bit of algebraic simplification here.  */
                    611:   switch (code)
                    612:     {
                    613:       /* This case has no effect except to speed things up.  */
                    614:     case REG:
                    615:     case CONST_INT:
                    616:     case CONST:
                    617:     case SYMBOL_REF:
                    618:     case LABEL_REF:
                    619:     case PC:
                    620:     case CC0:
                    621:       return x;
                    622: 
                    623:     case NOT:
                    624:     case NEG:
                    625:       /* Don't let substitution introduce double-negatives.  */
                    626:       if (XEXP (x, 0) == from
                    627:          && GET_CODE (to) == code)
                    628:        return XEXP (to, 0);
                    629:       break;
                    630: 
                    631:     case PLUS:
                    632:       /* In (plus <foo> (ashift <bar> <n>))
                    633:         change the shift to a multiply so we can recognize
                    634:         scaled indexed addresses.  */
                    635:       if ((XEXP (x, 0) == from
                    636:           || XEXP (x, 1) == from)
                    637:          && GET_CODE (to) == ASHIFT
                    638:          && GET_CODE (XEXP (to, 1)) == CONST_INT)
                    639:        {
                    640:          if (!undobuf.storage)
                    641:            undobuf.storage = (char *) oballoc (0);
                    642:          this_to = gen_rtx (MULT, GET_MODE (to),
                    643:                             XEXP (to, 0),
                    644:                             gen_rtx (CONST_INT, VOIDmode,
                    645:                                      1 << INTVAL (XEXP (to, 1))));
                    646:        }
                    647:       /* If we have something (putative index) being added to a sum,
                    648:         associate it so that any constant term is outermost.
                    649:         That's because that's the way indexed addresses are
                    650:         now supposed to appear.  */
                    651:       if (((XEXP (x, 0) == from && GET_CODE (XEXP (x, 1)) == PLUS)
                    652:           || (XEXP (x, 1) == from && GET_CODE (XEXP (x, 0)) == PLUS))
                    653:          ||
                    654:          ((XEXP (x, 0) == from || XEXP (x, 1) == from)
                    655:           && GET_CODE (this_to) == PLUS))
                    656:        {
                    657:          rtx offset = 0, base, index;
                    658:          if (GET_CODE (this_to) != PLUS)
                    659:            {
                    660:              index = this_to;
                    661:              base = XEXP (x, 0) == from ? XEXP (x, 1) : XEXP (x, 0);
                    662:            }
                    663:          else
                    664:            {
                    665:              index = XEXP (x, 0) == from ? XEXP (x, 1) : XEXP (x, 0);
                    666:              base = this_to;
                    667:            }
                    668:          if (CONSTANT_ADDRESS_P (XEXP (base, 0)))
                    669:            {
                    670:              offset = XEXP (base, 0);
                    671:              base = XEXP (base, 1);
                    672:            }
                    673:          else if (CONSTANT_ADDRESS_P (XEXP (base, 1)))
                    674:            {
                    675:              offset = XEXP (base, 1);
                    676:              base = XEXP (base, 0);
                    677:            }
                    678:          if (offset != 0)
                    679:            {
                    680:              if (!undobuf.storage)
                    681:                undobuf.storage = (char *) oballoc (0);
                    682:              return gen_rtx (PLUS, GET_MODE (index), offset,
                    683:                              gen_rtx (PLUS, GET_MODE (index),
                    684:                                       index, base));
                    685:            }
                    686:        }
                    687:       break;
                    688: 
                    689:     case MINUS:
                    690:       /* Can simplify (minus:VOIDmode (zero/sign_extend FOO) CONST)
                    691:         (which is a compare instruction, not a subtract instruction)
                    692:         to (minus FOO CONST) if CONST fits in FOO's mode
                    693:         and we are only testing equality.
                    694:         In fact, this is valid for zero_extend if what follows is an
                    695:         unsigned comparison, and for sign_extend with a signed comparison.  */
                    696:       if (GET_MODE (x) == VOIDmode
                    697:          && XEXP (x, 0) == from
                    698:          && (GET_CODE (to) == ZERO_EXTEND || GET_CODE (to) == SIGN_EXTEND)
                    699:          && next_insn_tests_no_inequality (subst_insn)
                    700:          && GET_CODE (XEXP (x, 1)) == CONST_INT
                    701:          && ((unsigned) INTVAL (XEXP (x, 1))
                    702:              < (1 << (BITS_PER_UNIT * GET_MODE_SIZE (GET_MODE (XEXP (to, 0)))))))
                    703:        this_to = XEXP (to, 0);
                    704:       break;
                    705: 
                    706:     case EQ:
                    707:     case NE:
                    708:       /* If comparing a subreg against zero, discard the subreg.  */
                    709:       if (XEXP (x, 0) == from
                    710:          && GET_CODE (to) == SUBREG
                    711:          && SUBREG_WORD (to) == 0
                    712:          && XEXP (x, 1) == const0_rtx)
                    713:        this_to = SUBREG_REG (to);
                    714: 
                    715:       /* If comparing a ZERO_EXTRACT against zero,
                    716:         canonicalize to a SIGN_EXTRACT,
                    717:         since the two are equivalent here.  */
                    718:       if (XEXP (x, 0) == from
                    719:          && GET_CODE (this_to) == ZERO_EXTRACT
                    720:          && XEXP (x, 1) == const0_rtx)
                    721:        {
                    722:          if (!undobuf.storage)
                    723:            undobuf.storage = (char *) oballoc (0);
                    724:          this_to = gen_rtx (SIGN_EXTRACT, GET_MODE (this_to),
                    725:                             XEXP (this_to, 0), XEXP (this_to, 1),
                    726:                             XEXP (this_to, 2));
                    727:        }
                    728:       /* If we are putting (ASHIFT 1 x) into (EQ (AND ... y) 0),
                    729:         arrange to return (EQ (SIGN_EXTRACT y 1 x) 0),
                    730:         which is what jump-on-bit instructions are written with.  */
                    731:       else if (XEXP (x, 1) == const0_rtx
                    732:               && GET_CODE (XEXP (x, 0)) == AND
                    733:               && (XEXP (XEXP (x, 0), 0) == from
                    734:                   || XEXP (XEXP (x, 0), 1) == from)
                    735:               && GET_CODE (this_to) == ASHIFT
                    736:               && XEXP (this_to, 0) == const1_rtx)
                    737:        {
                    738:          register rtx y = XEXP (XEXP (x, 0),
                    739:                                 XEXP (XEXP (x, 0), 0) == from);
                    740:          if (!undobuf.storage)
                    741:            undobuf.storage = (char *) oballoc (0);
                    742:          this_to = gen_rtx (SIGN_EXTRACT, GET_MODE (this_to),
                    743:                             y,
                    744:                             const1_rtx, XEXP (this_to, 1));
                    745:          from = XEXP (x, 0);
                    746:        }
                    747: 
                    748:       break;
                    749: 
                    750:     case ZERO_EXTEND:
                    751:       if (XEXP (x, 0) == from
                    752:          && GET_CODE (to) == ZERO_EXTEND)
                    753:        this_to = XEXP (to, 0);
                    754:       /* Zero-extending the result of an and with a constant can be done
                    755:         with a wider and.  */
                    756:       if (XEXP (x, 0) == from
                    757:          && GET_CODE (to) == AND
                    758:          && GET_CODE (XEXP (to, 1)) == CONST_INT
                    759:          && (GET_CODE (XEXP (to, 0)) == REG
                    760:              || offsetable_address_p (XEXP (to, 0)))
                    761:          /* Avoid getting wrong result if the constant has high bits set
                    762:             that are irrelevant in the narrow mode where it is being used.  */
                    763:          && ((INTVAL (XEXP (to, 1))
                    764:               & (-1 << (GET_MODE_SIZE (GET_MODE (to)) * BITS_PER_UNIT)))
                    765:              == 0))
                    766:        {
                    767:          if (!undobuf.storage)
                    768:            undobuf.storage = (char *) oballoc (0);
                    769:          return gen_rtx (AND, GET_MODE (x),
                    770:                          gen_lowpart (GET_MODE (x), XEXP (to, 0)),
                    771:                          XEXP (to, 1));
                    772:         } 
                    773:       break;
                    774: 
                    775:     case SIGN_EXTEND:
                    776:       if (XEXP (x, 0) == from
                    777:          && GET_CODE (to) == SIGN_EXTEND)
                    778:        this_to = XEXP (to, 0);
                    779:       /* Sign-extending the result of an and with a constant can be done
                    780:         with a wider and, provided the high bit of the constant is 0.  */
                    781:       if (XEXP (x, 0) == from
                    782:          && GET_CODE (to) == AND
                    783:          && GET_CODE (XEXP (to, 1)) == CONST_INT
                    784:          && (GET_CODE (XEXP (to, 0)) == REG
                    785:              || offsetable_address_p (XEXP (to, 0)))
                    786:          && ((INTVAL (XEXP (to, 1))
                    787:               & (-1 << (GET_MODE_SIZE (GET_MODE (to)) * BITS_PER_UNIT - 1)))
                    788:              == 0))
                    789:        {
                    790:          if (!undobuf.storage)
                    791:            undobuf.storage = (char *) oballoc (0);
                    792:          return gen_rtx (AND, GET_MODE (x),
                    793:                          gen_lowpart (GET_MODE (x), XEXP (to, 0)),
                    794:                          XEXP (to, 1));
                    795:         } 
                    796:       break;
                    797: 
                    798:     case SET:
                    799:       /* In (set (zero-extract <x> <1> <y>) (and <foo> <1>))
                    800:         the `and' can be deleted.  This can happen when storing a bit
                    801:         that came from a set-flag insn followed by masking to one bit.
                    802:         There is probably no need to optimize other field widths similarly
                    803:         because on machines with bit-field insns `and' is not needed
                    804:         to extract the fields.  */
                    805:       if (GET_CODE (XEXP (x, 0)) == ZERO_EXTRACT
                    806:          && XEXP (XEXP (x, 0), 1) == const1_rtx
                    807:          && XEXP (x, 1) == from
                    808:          && GET_CODE (to) == AND
                    809:          && XEXP (to, 1) == const1_rtx)
                    810:        {
                    811:          this_to = XEXP (to, 0);
                    812:         } 
                    813:       break;
                    814: 
                    815:     case AND:
                    816:       if (GET_CODE (XEXP (x, 1)) == CONST_INT)
                    817:        {
                    818:          rtx tem = simplify_and_const_int (x, from, to);
                    819:          if (tem)
                    820:            return tem;
                    821:        }
                    822:       break;
                    823: 
                    824:     case FLOAT:
                    825:       /* (float (sign_extend <X>)) = (float <X>).  */
                    826:       if (XEXP (x, 0) == from
                    827:          && GET_CODE (to) == SIGN_EXTEND)
                    828:        this_to = XEXP (to, 0);
                    829:       break;
                    830: 
                    831:     case ZERO_EXTRACT:
                    832:       /* Extracting a single bit from the result of a shift:
                    833:         see which bit it was before the shift and extract that directly.  */
                    834:       if (XEXP (x, 0) == from
                    835:          && (GET_CODE (to) == ASHIFTRT || GET_CODE (to) == LSHIFTRT
                    836:              || GET_CODE (to) == ASHIFT || GET_CODE (to) == LSHIFT)
                    837:          && GET_CODE (XEXP (to, 1)) == CONST_INT
                    838:          && XEXP (x, 1) == const1_rtx
                    839:          && GET_CODE (XEXP (x, 2)) == CONST_INT)
                    840:        {
                    841:          int shift = INTVAL (XEXP (to, 1));
                    842:          int newpos;
                    843:          if (GET_CODE (to) == ASHIFT || GET_CODE (to) == LSHIFT)
                    844:            shift = - shift;
                    845: #ifdef BITS_BIG_ENDIAN
                    846:          shift = - shift;
                    847: #endif
                    848:          newpos = INTVAL (XEXP (x, 2)) + shift;
                    849:          if (newpos >= 0 &&
                    850:              newpos < BITS_PER_UNIT * GET_MODE_SIZE (GET_MODE (from)))
                    851:            {
                    852:              if (!undobuf.storage)
                    853:                undobuf.storage = (char *) oballoc (0);
                    854:              return gen_rtx (ZERO_EXTRACT, GET_MODE (x),
                    855:                              XEXP (to, 0), const1_rtx,
                    856:                              gen_rtx (CONST_INT, VOIDmode, newpos));
                    857:            }
                    858:        }
                    859:       break;
                    860: 
                    861:     case LSHIFTRT:
                    862:     case ASHIFTRT:
                    863:     case ROTATE:
                    864:     case ROTATERT:
                    865: #ifdef SHIFT_COUNT_TRUNCATED
                    866:       /* (lshift <X> (sign_extend <Y>)) = (lshift <X> <Y>) (most machines).
                    867:         True for all kinds of shifts and also for zero_extend.  */
                    868:       if (XEXP (x, 1) == from
                    869:          && (GET_CODE (to) == SIGN_EXTEND
                    870:              || GET_CODE (to) == ZERO_EXTEND))
                    871:        {
                    872:          if (!undobuf.storage)
                    873:            undobuf.storage = (char *) oballoc (0);
                    874:          this_to = gen_rtx (SUBREG, GET_MODE (to), XEXP (to, 0), 0);
                    875:        }
                    876: #endif
                    877:       /* Two shifts in a row of same kind
                    878:         in same direction with constant counts
                    879:         may be combined.  */
                    880:       if (XEXP (x, 0) == from
                    881:          && GET_CODE (to) == GET_CODE (x)
                    882:          && GET_CODE (XEXP (x, 1)) == CONST_INT
                    883:          && GET_CODE (XEXP (to, 1)) == CONST_INT
                    884:          && INTVAL (XEXP (to, 1)) > 0
                    885:          && INTVAL (XEXP (x, 1)) > 0
                    886:          && (INTVAL (XEXP (x, 1)) + INTVAL (XEXP (to, 1))
                    887:              < BITS_PER_UNIT * GET_MODE_SIZE (GET_MODE (x))))
                    888:        {
                    889:          if (!undobuf.storage)
                    890:            undobuf.storage = (char *) oballoc (0);
                    891:          return gen_rtx (GET_CODE (x), GET_MODE (x),
                    892:                          XEXP (to, 0),
                    893:                          gen_rtx (CONST_INT, VOIDmode,
                    894:                                   INTVAL (XEXP (x, 1))
                    895:                                   + INTVAL (XEXP (to, 1))));
                    896:        }
                    897:       break;
                    898: 
                    899:     case LSHIFT:
                    900:     case ASHIFT:
                    901: #ifdef SHIFT_COUNT_TRUNCATED
                    902:       /* (lshift <X> (sign_extend <Y>)) = (lshift <X> <Y>) (most machines).
                    903:         True for all kinds of shifts and also for zero_extend.  */
                    904:       if (XEXP (x, 1) == from
                    905:          && (GET_CODE (to) == SIGN_EXTEND
                    906:              || GET_CODE (to) == ZERO_EXTEND))
                    907:        {
                    908:          if (!undobuf.storage)
                    909:            undobuf.storage = (char *) oballoc (0);
                    910:          this_to = gen_rtx (SUBREG, GET_MODE (to), XEXP (to, 0), 0);
                    911:        }
                    912: #endif
                    913:       /* (lshift (and (lshiftrt <foo> <X>) <Y>) <X>)
                    914:         happens copying between bit fields in similar structures.
                    915:         It can be replaced by one and instruction.
                    916:         It does not matter whether the shifts are logical or arithmetic.  */
                    917:       if (GET_CODE (XEXP (x, 0)) == AND
                    918:          && GET_CODE (XEXP (x, 1)) == CONST_INT
                    919:          && INTVAL (XEXP (x, 1)) > 0
                    920:          && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
                    921:          && XEXP (XEXP (x, 0), 0) == from
                    922:          && (GET_CODE (to) == LSHIFTRT
                    923:              || GET_CODE (to) == ASHIFTRT)
                    924: #if 0
                    925: /* I now believe this restriction is unnecessary.
                    926:    The outer shift will discard those bits in any case, right?  */
                    927: 
                    928:              /* If inner shift is arithmetic, either it shifts left or
                    929:                 the bits it shifts the sign into are zeroed by the and.  */
                    930:                  && (INTVAL (XEXP (x, 1)) < 0
                    931:                      || ((unsigned) INTVAL (XEXP (XEXP (x, 0), 1))
                    932:                          < 1 << (GET_MODE_BITSIZE (GET_MODE (x))
                    933:                                  - INTVAL (XEXP (x, 0)))))
                    934: #endif
                    935:          && GET_CODE (XEXP (to, 1)) == CONST_INT
                    936:          && INTVAL (XEXP (x, 1)) == INTVAL (XEXP (to, 1)))
                    937:        {
                    938:          if (!undobuf.storage)
                    939:            undobuf.storage = (char *) oballoc (0);
                    940:          /* The constant in the new `and' is <Y> << <X>
                    941:             but clear out all bits that don't belong in our mode.  */
                    942:          return gen_rtx (AND, GET_MODE (x), XEXP (to, 0),
                    943:                          gen_rtx (CONST_INT, VOIDmode,
                    944:                                   (GET_MODE_MASK (GET_MODE (x))
                    945:                                    & ((GET_MODE_MASK (GET_MODE (x))
                    946:                                        & INTVAL (XEXP (XEXP (x, 0), 1)))
                    947:                                       << INTVAL (XEXP (x, 1))))));
                    948:        } 
                    949:       /* Two shifts in a row in same direction with constant counts
                    950:         may be combined.  */
                    951:       if (XEXP (x, 0) == from
                    952:          && (GET_CODE (to) == ASHIFT || GET_CODE (to) == LSHIFT)
                    953:          && GET_CODE (XEXP (x, 1)) == CONST_INT
                    954:          && GET_CODE (XEXP (to, 1)) == CONST_INT
                    955:          && INTVAL (XEXP (to, 1)) > 0
                    956:          && INTVAL (XEXP (x, 1)) > 0
                    957:          && (INTVAL (XEXP (x, 1)) + INTVAL (XEXP (to, 1))
                    958:              < BITS_PER_UNIT * GET_MODE_SIZE (GET_MODE (x))))
                    959:        {
                    960:          if (!undobuf.storage)
                    961:            undobuf.storage = (char *) oballoc (0);
                    962:          return gen_rtx (GET_CODE (x), GET_MODE (x),
                    963:                          XEXP (to, 0),
                    964:                          gen_rtx (CONST_INT, VOIDmode,
                    965:                                   INTVAL (XEXP (x, 1))
                    966:                                   + INTVAL (XEXP (to, 1))));
                    967:        }
                    968:       /* (ashift (ashiftrt <foo> <X>) <X>)
                    969:         (or, on some machines, (ashift (ashift <foo> <-X>) <X>) instead)
                    970:         happens if you divide by 2**N and then multiply by 2**N.
                    971:         It can be replaced by one `and' instruction.
                    972:         It does not matter whether the shifts are logical or arithmetic.  */
                    973:       if (GET_CODE (XEXP (x, 1)) == CONST_INT
                    974:          && INTVAL (XEXP (x, 1)) > 0
                    975:          && XEXP (x, 0) == from
                    976:          && (((GET_CODE (to) == LSHIFTRT || GET_CODE (to) == ASHIFTRT)
                    977:               && GET_CODE (XEXP (to, 1)) == CONST_INT
                    978:               && INTVAL (XEXP (x, 1)) == INTVAL (XEXP (to, 1)))
                    979:              ||
                    980:              ((GET_CODE (to) == LSHIFT || GET_CODE (to) == ASHIFT)
                    981:               && GET_CODE (XEXP (to, 1)) == CONST_INT
                    982:               && INTVAL (XEXP (x, 1)) == - INTVAL (XEXP (to, 1)))))
                    983:        {
                    984:          if (!undobuf.storage)
                    985:            undobuf.storage = (char *) oballoc (0);
                    986:          /* The constant in the new `and' is <Y> << <X>
                    987:             but clear out all bits that don't belong in our mode.  */
                    988:          return gen_rtx (AND, GET_MODE (x), XEXP (to, 0),
                    989:                          gen_rtx (CONST_INT, VOIDmode,
                    990:                                   (GET_MODE_MASK (GET_MODE (x))
                    991:                                    & (GET_MODE_MASK (GET_MODE (x))
                    992:                                       << INTVAL (XEXP (x, 1))))));
                    993:        } 
                    994: 
                    995:     }
                    996: 
                    997:   len = GET_RTX_LENGTH (code);
                    998:   fmt = GET_RTX_FORMAT (code);
                    999: 
                   1000:   /* Don't replace FROM where it is being stored in rather than used.  */
                   1001:   if (code == SET && SET_DEST (x) == from)
                   1002:     fmt = "ie";
                   1003: 
                   1004:   for (i = 0; i < len; i++)
                   1005:     {
                   1006:       if (fmt[i] == 'E')
                   1007:        {
                   1008:          register int j;
                   1009:          for (j = XVECLEN (x, i) - 1; j >= 0; j--)
                   1010:            {
                   1011:              register rtx new;
                   1012:              if (XVECEXP (x, i, j) == from)
                   1013:                new = this_to;
                   1014:              else
                   1015:                new = subst (XVECEXP (x, i, j), from, to);
                   1016:              if (new != XVECEXP (x, i, j))
                   1017:                {
                   1018:                  if (undobuf.num_undo < MAX_UNDO)
                   1019:                    {
                   1020:                      undobuf.undo[undobuf.num_undo].where = &XVECEXP (x, i, j);
                   1021:                      undobuf.undo[undobuf.num_undo].old_contents = XVECEXP (x, i, j);
                   1022:                      XVECEXP (x, i, j) = new;
                   1023:                    }
                   1024:                  undobuf.num_undo++;
                   1025:                }
                   1026:            }
                   1027:        }
                   1028:       else if (fmt[i] == 'e')
                   1029:        {
                   1030:          register rtx new;
                   1031: 
                   1032:          if (XEXP (x, i) == from)
                   1033:            new = this_to;
                   1034:          else
                   1035:            new = subst (XEXP (x, i), from, to);
                   1036: 
                   1037:          if (new != XEXP (x, i))
                   1038:            {
                   1039:              if (undobuf.num_undo < MAX_UNDO)
                   1040:                {
                   1041:                  undobuf.undo[undobuf.num_undo].where = &XEXP (x, i);
                   1042:                  undobuf.undo[undobuf.num_undo].old_contents = XEXP (x, i);
                   1043:                  XEXP (x, i) = new;
                   1044:                }
                   1045:              undobuf.num_undo++;
                   1046:            }
                   1047:        }
                   1048:     }
                   1049:   return x;
                   1050: }
                   1051: 
                   1052: /* This is the AND case of the function subst.  */
                   1053: 
                   1054: static rtx
                   1055: simplify_and_const_int (x, from, to)
                   1056:      rtx x, from, to;
                   1057: {
                   1058:   register rtx varop = XEXP (x, 0);
                   1059:   register int constop = INTVAL (XEXP (x, 1));
                   1060: 
                   1061:   /* (and (subreg (and <foo> <constant>) 0) <constant>)
                   1062:      results from an andsi followed by an andqi,
                   1063:      which happens frequently when storing bit-fields
                   1064:      on something whose result comes from an andsi.  */
                   1065:   if (GET_CODE (varop) == SUBREG
                   1066:       && XEXP (varop, 0) == from
                   1067:       && subreg_lowpart_p (varop)
                   1068:       && GET_CODE (to) == AND
                   1069:       && GET_CODE (XEXP (to, 1)) == CONST_INT
                   1070:       /* Verify that the result of the outer `and'
                   1071:         is not affected by any bits not defined in the inner `and'.
                   1072:         True if the outer mode is narrower, or if the outer constant
                   1073:         masks to zero all the bits that the inner mode doesn't have.  */
                   1074:       && (GET_MODE_SIZE (GET_MODE (x)) < GET_MODE_SIZE (GET_MODE (from))
                   1075:          || constop & (-1 << (BITS_PER_UNIT * GET_MODE_SIZE (GET_MODE (from)))) == 0))
                   1076:     {
                   1077:       if (!undobuf.storage)
                   1078:        undobuf.storage = (char *) oballoc (0);
                   1079:       return gen_rtx (AND, GET_MODE (x),
                   1080:                      gen_lowpart (GET_MODE (x), XEXP (to, 0)),
                   1081:                      gen_rtx (CONST_INT, VOIDmode,
                   1082:                               constop
                   1083:                               /* Remember that the bits outside that mode
                   1084:                                  are not being changed, so the effect
                   1085:                                  is as if they were all 1.  */
                   1086:                               & INTVAL (XEXP (to, 1))));
                   1087:     } 
                   1088:   /* (and (zero_extend <foo>) <constant>)
                   1089:      often results from storing in a bit-field something
                   1090:      that was calculated as a short.  Replace with a single `and'
                   1091:      in whose constant all bits not in <foo>'s mode are zero.  */
                   1092:   if (varop == from
                   1093:       && GET_CODE (to) == ZERO_EXTEND)
                   1094:     {
                   1095:       if (!undobuf.storage)
                   1096:        undobuf.storage = (char *) oballoc (0);
                   1097:       return gen_rtx (AND, GET_MODE (x),
                   1098:                      gen_rtx (SUBREG, GET_MODE (x),
                   1099:                               XEXP (to, 0), 0),
                   1100:                      gen_rtx (CONST_INT, VOIDmode,
                   1101:                               constop
                   1102:                               & ((1 << (BITS_PER_UNIT * GET_MODE_SIZE (GET_MODE (XEXP (to, 0))))) - 1)));
                   1103:     }
                   1104:   /* (and (sign_extend <foo>) <constant>)
                   1105:      can be replaced with (and (subreg <foo>) <constant>)
                   1106:      if <constant> is narrower than <foo>'s mode,
                   1107:      or with (zero_extend <foo>) if <constant> is a mask for that mode.  */
                   1108:   if (varop == from
                   1109:       && GET_CODE (to) == SIGN_EXTEND
                   1110:       && ((unsigned) constop
                   1111:          <= ((1 << (BITS_PER_UNIT
                   1112:                     * GET_MODE_SIZE (GET_MODE (XEXP (to, 0)))))
                   1113:              - 1)))
                   1114:     {
                   1115:       if (!undobuf.storage)
                   1116:        undobuf.storage = (char *) oballoc (0);
                   1117:       if (constop == ((1 << (BITS_PER_UNIT
                   1118:                             * GET_MODE_SIZE (GET_MODE (XEXP (to, 0)))))
                   1119:                      - 1))
                   1120:        return gen_rtx (ZERO_EXTEND, GET_MODE (x), XEXP (to, 0));
                   1121:       return gen_rtx (AND, GET_MODE (x),
                   1122:                      gen_rtx (SUBREG, GET_MODE (x),
                   1123:                               XEXP (to, 0), 0),
                   1124:                      XEXP (x, 1));
                   1125:     }
                   1126:   /* (and (and <foo> <constant>) <constant>)
                   1127:      comes from two and instructions in a row.  */
                   1128:   if (varop == from
                   1129:       && GET_CODE (to) == AND
                   1130:       && GET_CODE (XEXP (to, 1)) == CONST_INT)
                   1131:     {
                   1132:       if (!undobuf.storage)
                   1133:        undobuf.storage = (char *) oballoc (0);
                   1134:       return gen_rtx (AND, GET_MODE (x),
                   1135:                      XEXP (to, 0),
                   1136:                      gen_rtx (CONST_INT, VOIDmode,
                   1137:                               constop
                   1138:                               & INTVAL (XEXP (to, 1))));
                   1139:     }
                   1140:   /* (and (ashiftrt (ashift FOO N) N) CONST)
                   1141:      may be simplified to (and FOO CONST) if CONST masks off the bits
                   1142:      changed by the two shifts.  */
                   1143:   if (GET_CODE (varop) == ASHIFTRT
                   1144:       && GET_CODE (XEXP (varop, 1)) == CONST_INT
                   1145:       && XEXP (varop, 0) == from
                   1146:       && GET_CODE (to) == ASHIFT
                   1147:       && GET_CODE (XEXP (to, 1)) == CONST_INT
                   1148:       && INTVAL (XEXP (varop, 1)) == INTVAL (XEXP (to, 1))
                   1149:       && ((unsigned) constop >> INTVAL (XEXP (varop, 1))) == 0)
                   1150:     {
                   1151:       if (!undobuf.storage)
                   1152:        undobuf.storage = (char *) oballoc (0);
                   1153:       /* If CONST is a mask for the low byte,
                   1154:         change this into a zero-extend instruction
                   1155:         from just the low byte of FOO.  */
                   1156:       if (constop == (1 << BITS_PER_UNIT) - 1)
                   1157:        {
                   1158:          rtx temp = gen_lowpart_for_combine (QImode, XEXP (to, 0));
                   1159:          if (temp)
                   1160:            return gen_rtx (ZERO_EXTEND, GET_MODE (x), temp);
                   1161:        }
                   1162:       return gen_rtx (AND, GET_MODE (x),
                   1163:                      XEXP (to, 0), XEXP (x, 1));
                   1164:     }
                   1165: 
                   1166:   /* No simplification applies.  */
                   1167:   return 0;
                   1168: }
                   1169: 
                   1170: /* Like gen_lowpart but for use by combine.  In combine it is not possible
                   1171:    to create any new pseudoregs.  However, it is safe to create
                   1172:    invalid memory addresses, because combine will try to recognize
                   1173:    them and all they will do is make the combine attempt fail.
                   1174: 
                   1175:    Also, return zero if we don't see a way to make a lowpart.  */
                   1176: 
                   1177: static rtx
                   1178: gen_lowpart_for_combine (mode, x)
                   1179:      enum machine_mode mode;
                   1180:      register rtx x;
                   1181: {
                   1182:   if (GET_CODE (x) == SUBREG || GET_CODE (x) == REG)
                   1183:     return gen_lowpart (mode, x);
                   1184:   if (GET_MODE (x) == mode)
                   1185:     return 0;
                   1186:   if (GET_CODE (x) == VOLATILE)
                   1187:     return 0;
                   1188:   if (GET_CODE (x) == MEM)
                   1189:     {
                   1190:       register int offset = 0;
                   1191: #ifdef WORDS_BIG_ENDIAN
                   1192:       offset = (max (GET_MODE_SIZE (GET_MODE (x)), UNITS_PER_WORD)
                   1193:                - max (GET_MODE_SIZE (mode), UNITS_PER_WORD));
                   1194: #endif
                   1195: #ifdef BYTES_BIG_ENDIAN
                   1196:       if (GET_MODE_SIZE (mode) < UNITS_PER_WORD)
                   1197:        offset -= (GET_MODE_SIZE (mode)
                   1198:                   - min (UNITS_PER_WORD,
                   1199:                          GET_MODE_SIZE (GET_MODE (x))));
                   1200: #endif
                   1201:       return gen_rtx (MEM, mode, plus_constant (XEXP (x, 0),
                   1202:                                                offset));
                   1203:     }
                   1204:   else
                   1205:     return 0;
                   1206: }
                   1207: 
                   1208: /* After substitution, if the resulting pattern looks like
                   1209:    (set (cc0) (and ...)), this function is called to simplify the
                   1210:    pattern into a bit-field operation if possible.  */
                   1211: 
                   1212: static void
                   1213: simplify_set_cc0_and (insn)
                   1214:      rtx insn;
                   1215: {
                   1216:   register rtx value = XEXP (PATTERN (insn), 1);
                   1217:   register rtx op0 = XEXP (value, 0);
                   1218:   register rtx op1 = XEXP (value, 1);
                   1219:   int offset = 0;
                   1220:   rtx var = 0;
                   1221:   rtx bitnum = 0;
                   1222:   int temp;
                   1223:   int unit;
                   1224: 
                   1225:   /* Look for a constant power of 2 or a shifted 1
                   1226:      on either side of the AND.  Set VAR to the other side.
                   1227:      Set BITNUM to the shift count of the 1 (as an rtx).
                   1228:      Or, if bit number is constant, set OFFSET to the bit number.  */
                   1229: 
                   1230:   switch (GET_CODE (op0))
                   1231:     {
                   1232:     case CONST_INT:
                   1233:       temp = exact_log2 (INTVAL (op0));
                   1234:       if (temp < 0)
                   1235:        return;
                   1236:       offset = temp;
                   1237:       var = op1;
                   1238:       break;
                   1239: 
                   1240:     case ASHIFT:
                   1241:     case LSHIFT:
                   1242:       if (XEXP (op0, 0) == const1_rtx)
                   1243:        {
                   1244:          bitnum = XEXP (op0, 1);
                   1245:          var = op1;
                   1246:        }
                   1247:     }
                   1248:   if (var == 0)
                   1249:     switch (GET_CODE (op1))
                   1250:       {
                   1251:       case CONST_INT:
                   1252:        temp = exact_log2 (INTVAL (op1));
                   1253:        if (temp < 0)
                   1254:          return;
                   1255:        offset = temp;
                   1256:        var = op0;
                   1257:        break;
                   1258: 
                   1259:       case ASHIFT:
                   1260:       case LSHIFT:
                   1261:        if (XEXP (op1, 0) == const1_rtx)
                   1262:          {
                   1263:            bitnum = XEXP (op1, 1);
                   1264:            var = op0;
                   1265:          }
                   1266:       }
                   1267: 
                   1268:   /* If VAR is 0, we didn't find something recognizable.  */
                   1269:   if (var == 0)
                   1270:     return;
                   1271: 
                   1272:   if (!undobuf.storage)
                   1273:     undobuf.storage = (char *) oballoc (0);
                   1274: 
                   1275:   /* If the bit position is currently exactly 0,
                   1276:      extract a right-shift from the variable portion.  */
                   1277:   if (offset == 0
                   1278:       && (GET_CODE (var) == ASHIFTRT || GET_CODE (var) == LSHIFTRT))
                   1279:     {
                   1280:       bitnum = XEXP (var, 1);
                   1281:       var = XEXP (var, 0);
                   1282:     }
                   1283: 
                   1284: #ifdef BITS_BIG_ENDIAN
                   1285:   unit = GET_MODE_SIZE (GET_MODE (var)) * BITS_PER_UNIT - 1;
                   1286: 
                   1287:   if (bitnum != 0)
                   1288:     bitnum = gen_rtx (MINUS, SImode,
                   1289:                      gen_rtx (CONST_INT, VOIDmode, unit), bitnum);
                   1290:   else
                   1291:     offset = unit - offset;
                   1292: #endif
                   1293: 
                   1294:   if (bitnum == 0)
                   1295:     bitnum = gen_rtx (CONST_INT, VOIDmode, offset);
                   1296: 
                   1297:   if (GET_CODE (var) == SUBREG && SUBREG_WORD (var) == 0)
                   1298:     var = SUBREG_REG (var);
                   1299: 
                   1300:   if (undobuf.num_undo < MAX_UNDO)
                   1301:     {
                   1302:       undobuf.undo[undobuf.num_undo].where = &XEXP (PATTERN (insn), 1);
                   1303:       undobuf.undo[undobuf.num_undo].old_contents = value;
                   1304:       XEXP (PATTERN (insn), 1)
                   1305:        = gen_rtx (ZERO_EXTRACT, VOIDmode, var, const1_rtx, bitnum);
                   1306:     }
                   1307:   undobuf.num_undo++;
                   1308: }
                   1309: 
                   1310: /* Update the records of when each REG was most recently set or killed
                   1311:    for the things done by INSN.  This is the last thing done in processing
                   1312:    INSN in the combiner loop.
                   1313: 
                   1314:    We update reg_last_set, reg_last_death, and also the similar information
                   1315:    mem_last_set (which insn most recently modified memory)
                   1316:    and last_call_cuid (which insn was the most recent subroutine call).  */
                   1317: 
                   1318: static void
                   1319: record_dead_and_set_regs (insn)
                   1320:      rtx insn;
                   1321: {
                   1322:   register rtx link;
                   1323:   for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
                   1324:     {
                   1325:       if ((enum reg_note) GET_MODE (link) == REG_DEAD)
                   1326:        reg_last_death[REGNO (XEXP (link, 0))] = insn;
                   1327:       else if ((enum reg_note) GET_MODE (link) == REG_INC)
                   1328:        reg_last_set[REGNO (XEXP (link, 0))] = insn;
                   1329:     }
                   1330: 
                   1331:   if (GET_CODE (insn) == CALL_INSN)
                   1332:     last_call_cuid = mem_last_set = INSN_CUID (insn);
                   1333: 
                   1334:   if (GET_CODE (PATTERN (insn)) == PARALLEL)
                   1335:     {
                   1336:       register int i;
                   1337:       for (i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--)
                   1338:        {
                   1339:          register rtx elt = XVECEXP (PATTERN (insn), 0, i);
                   1340:          register enum rtx_code code = GET_CODE (elt);
                   1341:          if (code == SET || code == CLOBBER)
                   1342:            {
                   1343:              if (GET_CODE (XEXP (elt, 0)) == REG)
                   1344:                reg_last_set[REGNO (XEXP (elt, 0))] = insn;
                   1345:              else if (GET_CODE (XEXP (elt, 0)) == MEM)
                   1346:                mem_last_set = INSN_CUID (insn);
                   1347:            }
                   1348:        }
                   1349:     }
                   1350:   else if (GET_CODE (PATTERN (insn)) == SET
                   1351:           || GET_CODE (PATTERN (insn)) == CLOBBER)
                   1352:     {
                   1353:       register rtx x = XEXP (PATTERN (insn), 0);
                   1354:       if (GET_CODE (x) == REG)
                   1355:        reg_last_set[REGNO (x)] = insn;
                   1356:       else if (GET_CODE (x) == MEM)
                   1357:        mem_last_set = INSN_CUID (insn);
                   1358:     }
                   1359: }
                   1360: 
                   1361: /* Return nonzero if expression X refers to a REG or to memory
                   1362:    that is set in an instruction more recent than FROM_CUID.  */
                   1363: 
                   1364: static int
                   1365: use_crosses_set_p (x, from_cuid)
                   1366:      register rtx x;
                   1367:      int from_cuid;
                   1368: {
                   1369:   register char *fmt;
                   1370:   register int i;
                   1371:   register enum rtx_code code = GET_CODE (x);
                   1372: 
                   1373:   if (code == REG)
                   1374:     {
                   1375:       register int regno = REGNO (x);
                   1376:       return (reg_last_set[regno]
                   1377:              && INSN_CUID (reg_last_set[regno]) > from_cuid);
                   1378:     }
                   1379: 
                   1380:   if (code == MEM && mem_last_set > from_cuid)
                   1381:     return 1;
                   1382: 
                   1383:   fmt = GET_RTX_FORMAT (code);
                   1384: 
                   1385:   for (i = GET_RTX_LENGTH (code); i >= 0; i--)
                   1386:     {
                   1387:       if (fmt[i] == 'E')
                   1388:        {
                   1389:          register int j;
                   1390:          for (j = XVECLEN (x, i) - 1; j >= 0; j--)
                   1391:            if (use_crosses_set_p (XVECEXP (x, i, j), from_cuid))
                   1392:              return 1;
                   1393:        }
                   1394:       else if (fmt[i] == 'e'
                   1395:               && use_crosses_set_p (XEXP (x, i), from_cuid))
                   1396:        return 1;
                   1397:     }
                   1398:   return 0;
                   1399: }
                   1400: 
                   1401: /* Return nonzero if reg REGNO is marked as dying in INSN.  */
                   1402: 
                   1403: int
                   1404: regno_dead_p (regno, insn)
                   1405:      int regno;
                   1406:      rtx insn;
                   1407: {
                   1408:   register rtx link;
                   1409: 
                   1410:   for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
                   1411:     if (REGNO (XEXP (link, 0)) == regno
                   1412:        && ((enum reg_note) GET_MODE (link) == REG_DEAD
                   1413:            || (enum reg_note) GET_MODE (link) == REG_INC))
                   1414:       return 1;
                   1415: 
                   1416:   return 0;
                   1417: }
                   1418: 
                   1419: /* Remove register number REGNO from the dead registers list of INSN.  */
                   1420: 
                   1421: static void
                   1422: remove_death (regno, insn)
                   1423:      int regno;
                   1424:      rtx insn;
                   1425: {
                   1426:   register rtx link, next;
                   1427:   while ((link = REG_NOTES (insn))
                   1428:         && REGNO (XEXP (link, 0)) == regno
                   1429:         && (enum reg_note) GET_MODE (link) == REG_DEAD)
                   1430:     REG_NOTES (insn) = XEXP (link, 1);
                   1431: 
                   1432:   if (link)
                   1433:     while (next = XEXP (link, 1))
                   1434:       {
                   1435:        if (REGNO (XEXP (next, 0)) == regno
                   1436:            && (enum reg_note) GET_MODE (next) == REG_DEAD)
                   1437:          XEXP (link, 1) = XEXP (next, 1);
                   1438:        else
                   1439:          link = next;
                   1440:       }
                   1441: }
                   1442: 
                   1443: /* Return nonzero if J is the first insn following I,
                   1444:    not counting labels, line numbers, etc.
                   1445:    We assume that J follows I.  */
                   1446: 
                   1447: static int
                   1448: adjacent_insns_p (i, j)
                   1449:      rtx i, j;
                   1450: {
                   1451:   register rtx insn;
                   1452:   for (insn = NEXT_INSN (i); insn != j; insn = NEXT_INSN (insn))
                   1453:     if (GET_CODE (insn) == INSN
                   1454:        || GET_CODE (insn) == CALL_INSN
                   1455:        || GET_CODE (insn) == JUMP_INSN)
                   1456:       return 0;
                   1457:   return 1;
                   1458: }
                   1459: 
                   1460: /* Concatenate the list of logical links LINKS
                   1461:    into INSN's list of logical links.
                   1462:    Modifies LINKS destructively.  */
                   1463: 
                   1464: static void
                   1465: add_links (insn, links)
                   1466:      rtx insn, links;
                   1467: {
                   1468:   if (LOG_LINKS (insn) == 0)
                   1469:     LOG_LINKS (insn) = links;
                   1470:   else
                   1471:     {
                   1472:       register rtx next, prev = LOG_LINKS (insn);
                   1473:       while (next = XEXP (prev, 1))
                   1474:        prev = next;
                   1475:       XEXP (prev, 1) = links;
                   1476:     }
                   1477: }
                   1478: 
                   1479: /* Concatenate the any elements of the list of reg-notes INCS
                   1480:    which are of type REG_INC
                   1481:    into INSN's list of reg-notes.  */
                   1482: 
                   1483: static void
                   1484: add_incs (insn, incs)
                   1485:      rtx insn, incs;
                   1486: {
                   1487:   register rtx tail;
                   1488: 
                   1489:   for (tail = incs; tail; tail = XEXP (tail, 1))
                   1490:     if ((enum reg_note) GET_MODE (tail) == REG_INC)
                   1491:       REG_NOTES (insn)
                   1492:        = gen_rtx (EXPR_LIST, REG_INC, XEXP (tail, 0), REG_NOTES (insn));
                   1493: }
                   1494: 
                   1495: /* For each register (hardware or pseudo) used within expression X,
                   1496:    if its death is in an instruction with cuid
                   1497:    between FROM_CUID (inclusive) and TO_INSN (exclusive),
                   1498:    mark it as dead in TO_INSN instead.
                   1499: 
                   1500:    This is done when X is being merged by combination into TO_INSN.  */
                   1501: 
                   1502: static void
                   1503: move_deaths (x, from_cuid, to_insn)
                   1504:      rtx x;
                   1505:      int from_cuid;
                   1506:      rtx to_insn;
                   1507: {
                   1508:   register char *fmt;
                   1509:   register int len, i;
                   1510:   register enum rtx_code code = GET_CODE (x);
                   1511: 
                   1512:   if (code == REG)
                   1513:     {
                   1514:       register rtx where_dead = reg_last_death[REGNO (x)];
                   1515: 
                   1516:       if (where_dead && INSN_CUID (where_dead) >= from_cuid
                   1517:          && INSN_CUID (where_dead) < INSN_CUID (to_insn))
                   1518:        {
                   1519:          remove_death (REGNO (x), reg_last_death[REGNO (x)]);
                   1520:          if (! dead_or_set_p (to_insn, x))
                   1521:            REG_NOTES (to_insn)
                   1522:              = gen_rtx (EXPR_LIST, REG_DEAD, x, REG_NOTES (to_insn));
                   1523:        }
                   1524:       return;
                   1525:     }
                   1526: 
                   1527:   len = GET_RTX_LENGTH (code);
                   1528:   fmt = GET_RTX_FORMAT (code);
                   1529: 
                   1530:   for (i = 0; i < len; i++)
                   1531:     {
                   1532:       if (fmt[i] == 'E')
                   1533:        {
                   1534:          register int j;
                   1535:          for (j = XVECLEN (x, i) - 1; j >= 0; j--)
                   1536:            move_deaths (XVECEXP (x, i, j), from_cuid, to_insn);
                   1537:        }
                   1538:       else if (fmt[i] == 'e')
                   1539:        move_deaths (XEXP (x, i), from_cuid, to_insn);
                   1540:     }
                   1541: }
                   1542: 
                   1543: dump_combine_stats (file)
                   1544:      char *file;
                   1545: {
                   1546:   fprintf
                   1547:     (file,
                   1548:      ";; Combiner statistics: %d attempts, %d substitutions (%d requiring new space),\n;; %d successes.\n\n"
                   1549:      , combine_attempts, combine_merges, combine_extras, combine_successes);
                   1550: }
                   1551: 
                   1552: dump_combine_total_stats (file)
                   1553:      char *file;
                   1554: {
                   1555:   fprintf
                   1556:     (file,
                   1557:      "\n;; Combiner totals: %d attempts, %d substitutions (%d requiring new space),\n;; %d successes.\n",
                   1558:      total_attempts, total_merges, total_extras, total_successes);
                   1559: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.