Annotation of gcc/combine.c, revision 1.1.1.2

1.1       root        1: /* Optimize by combining instructions for GNU compiler.
1.1.1.2 ! root        2:    Copyright (C) 1987, 1988 Free Software Foundation, Inc.
1.1       root        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"
1.1.1.2 ! root       66: #include "flags.h"
1.1       root       67: #include "regs.h"
                     68: #include "basic-block.h"
                     69: #include "insn-config.h"
                     70: #include "recog.h"
                     71: 
                     72: #define max(A,B) ((A) > (B) ? (A) : (B))
                     73: #define min(A,B) ((A) < (B) ? (A) : (B))
                     74: 
1.1.1.2 ! root       75: /* It is not safe to use ordinary gen_lowpart in combine.
        !            76:    Use gen_lowpart_for_combine instead.  See comments there.  */
        !            77: #define gen_lowpart dont_use_gen_lowpart_you_dummy
        !            78: 
1.1       root       79: /* Number of attempts to combine instructions in this function.  */
                     80: 
                     81: static int combine_attempts;
                     82: 
                     83: /* Number of attempts that got as far as substitution in this function.  */
                     84: 
                     85: static int combine_merges;
                     86: 
                     87: /* Number of instructions combined with added SETs in this function.  */
                     88: 
                     89: static int combine_extras;
                     90: 
                     91: /* Number of instructions combined in this function.  */
                     92: 
                     93: static int combine_successes;
                     94: 
                     95: /* Totals over entire compilation.  */
                     96: 
                     97: static int total_attempts, total_merges, total_extras, total_successes;
                     98: 
                     99: 
                    100: /* Vector mapping INSN_UIDs to cuids.
                    101:    The cuids are like uids but increase monononically always.
                    102:    Combine always uses cuids so that it can compare them.
                    103:    But actually renumbering the uids, which we used to do,
                    104:    proves to be a bad idea because it makes it hard to compare
                    105:    the dumps produced by earlier passes with those from later passes.  */
                    106: 
                    107: static short *uid_cuid;
                    108: 
                    109: /* Get the cuid of an insn.  */
                    110: 
                    111: #define INSN_CUID(INSN) (uid_cuid[INSN_UID (INSN)])
                    112: 
                    113: 
                    114: /* Record last point of death of (hard or pseudo) register n.  */
                    115: 
                    116: static rtx *reg_last_death;
                    117: 
                    118: /* Record last point of modification of (hard or pseudo) register n.  */
                    119: 
                    120: static rtx *reg_last_set;
                    121: 
                    122: /* Record the cuid of the last insn that invalidated memory
                    123:    (anything that writes memory, and subroutine calls).  */
                    124: 
                    125: static int mem_last_set;
                    126: 
                    127: /* Record the cuid of the last CALL_INSN
                    128:    so we can tell whether a potential combination crosses any calls.  */
                    129: 
                    130: static int last_call_cuid;
                    131: 
                    132: /* When `subst' is called, this is the insn that is being modified
                    133:    (by combining in a previous insn).  The PATTERN of this insn
                    134:    is still the old pattern partially modified and it should not be
                    135:    looked at, but this may be used to examine the successors of the insn
                    136:    to judge whether a simplification is valid.  */
                    137: 
                    138: static rtx subst_insn;
                    139: 
                    140: /* Record one modification to rtl structure
                    141:    to be undone by storing old_contents into *where.  */
                    142: 
                    143: struct undo
                    144: {
                    145:   rtx *where;
                    146:   rtx old_contents;
                    147: };
                    148: 
                    149: /* Record a bunch of changes to be undone, up to MAX_UNDO of them.
                    150:    num_undo says how many are currently recorded.
                    151:    storage is nonzero if we must undo the allocation of new storage.
                    152:    The value of storage is what to pass to obfree.  */
                    153: 
                    154: #define MAX_UNDO 10
                    155: 
                    156: struct undobuf
                    157: {
                    158:   int num_undo;
                    159:   char *storage;
                    160:   struct undo undo[MAX_UNDO];
                    161: };
                    162: 
                    163: static struct undobuf undobuf;
                    164: 
1.1.1.2 ! root      165: /* Number of times the pseudo being substituted for
        !           166:    was found and replaced.  */
        !           167: 
        !           168: static int n_occurrences;
        !           169: 
1.1       root      170: static void move_deaths ();
                    171: static void remove_death ();
                    172: static void record_dead_and_set_regs ();
                    173: int regno_dead_p ();
                    174: static int use_crosses_set_p ();
                    175: static rtx subst ();
                    176: static void undo_all ();
1.1.1.2 ! root      177: static void copy_substitutions ();
1.1       root      178: static void add_links ();
                    179: static void add_incs ();
1.1.1.2 ! root      180: static int insn_has_inc_p ();
1.1       root      181: static int adjacent_insns_p ();
                    182: static rtx simplify_and_const_int ();
                    183: static rtx gen_lowpart_for_combine ();
                    184: static void simplify_set_cc0_and ();
                    185: 
                    186: /* Main entry point for combiner.  F is the first insn of the function.
                    187:    NREGS is the first unused pseudo-reg number.  */
                    188: 
                    189: void
                    190: combine_instructions (f, nregs)
                    191:      rtx f;
                    192:      int nregs;
                    193: {
                    194:   register rtx insn;
                    195:   register int i;
                    196:   register rtx links, nextlinks;
                    197:   rtx prev;
                    198: 
                    199:   combine_attempts = 0;
                    200:   combine_merges = 0;
                    201:   combine_extras = 0;
                    202:   combine_successes = 0;
                    203: 
                    204:   reg_last_death = (rtx *) alloca (nregs * sizeof (rtx));
                    205:   reg_last_set = (rtx *) alloca (nregs * sizeof (rtx));
                    206:   bzero (reg_last_death, nregs * sizeof (rtx));
                    207:   bzero (reg_last_set, nregs * sizeof (rtx));
                    208: 
                    209:   init_recog ();
                    210: 
                    211:   /* Compute maximum uid value so uid_cuid can be allocated.  */
                    212: 
                    213:   for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
                    214:     if (INSN_UID (insn) > i)
                    215:       i = INSN_UID (insn);
                    216: 
                    217:   uid_cuid = (short *) alloca ((i + 1) * sizeof (short));
                    218: 
                    219:   /* Compute the mapping from uids to cuids.
                    220:      Cuids are numbers assigned to insns, like uids,
                    221:      except that cuids increase monotonically through the code.  */
                    222: 
                    223:   for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
                    224:     INSN_CUID (insn) = ++i;
                    225: 
                    226:   /* Now scan all the insns in forward order.  */
                    227: 
                    228:   last_call_cuid = 0;
                    229:   mem_last_set = 0;
                    230:   prev = 0;
                    231: 
                    232:   for (insn = f; insn; insn = NEXT_INSN (insn))
                    233:     {
                    234:       if (GET_CODE (insn) == INSN
                    235:          || GET_CODE (insn) == CALL_INSN
                    236:          || GET_CODE (insn) == JUMP_INSN)
                    237:        {
                    238:        retry:
                    239:          /* Try this insn with each insn it links back to.  */
                    240: 
                    241:          for (links = LOG_LINKS (insn); links; links = XEXP (links, 1))
                    242:            if (try_combine (insn, XEXP (links, 0), 0))
                    243:              goto retry;
                    244: 
                    245:          /* Try each sequence of three linked insns ending with this one.  */
                    246: 
                    247:          for (links = LOG_LINKS (insn); links; links = XEXP (links, 1))
                    248:            if (GET_CODE (XEXP (links, 0)) != NOTE)
                    249:              for (nextlinks = LOG_LINKS (XEXP (links, 0)); nextlinks;
                    250:                   nextlinks = XEXP (nextlinks, 1))
                    251:                if (try_combine (insn, XEXP (links, 0), XEXP (nextlinks, 0)))
                    252:                  goto retry;
                    253: 
                    254:          /* Try to combine a jump insn that uses CC0
                    255:             with a preceding insn that sets CC0, and maybe with its
                    256:             logical predecessor as well.
                    257:             This is how we make decrement-and-branch insns.
                    258:             We need this special code because data flow connections
                    259:             via CC0 do not get entered in LOG_LINKS.  */
                    260: 
                    261:          if (GET_CODE (insn) == JUMP_INSN
                    262:              && prev != 0
                    263:              && GET_CODE (prev) == INSN
                    264:              && GET_CODE (PATTERN (prev)) == SET
                    265:              && GET_CODE (SET_DEST (PATTERN (prev))) == CC0)
                    266:            {
                    267:              if (try_combine (insn, prev, 0))
                    268:                  goto retry;
                    269: 
                    270:              if (GET_CODE (prev) != NOTE)
                    271:                for (nextlinks = LOG_LINKS (prev); nextlinks;
                    272:                     nextlinks = XEXP (nextlinks, 1))
                    273:                  if (try_combine (insn, prev, XEXP (nextlinks, 0)))
                    274:                    goto retry;
                    275:            }
                    276: #if 0
                    277: /* Turned off because on 68020 it takes four insns to make
                    278:    something like (a[b / 32] & (1 << (31 - (b % 32)))) != 0
                    279:    that could actually be optimized, and that's an unlikely piece of code.  */
                    280:          /* If an insn gets or sets a bit field, try combining it
                    281:             with two different insns whose results it uses.  */
                    282:          if (GET_CODE (insn) == INSN
                    283:              && GET_CODE (PATTERN (insn)) == SET
                    284:              && (GET_CODE (SET_DEST (PATTERN (insn))) == ZERO_EXTRACT
                    285:                  || GET_CODE (SET_DEST (PATTERN (insn))) == SIGN_EXTRACT
                    286:                  || GET_CODE (SET_SRC (PATTERN (insn))) == ZERO_EXTRACT
                    287:                  || GET_CODE (SET_SRC (PATTERN (insn))) == SIGN_EXTRACT))
                    288:            {
                    289:              for (links = LOG_LINKS (insn); links; links = XEXP (links, 1))
                    290:                if (GET_CODE (XEXP (links, 0)) != NOTE)
                    291:                  for (nextlinks = XEXP (links, 1); nextlinks;
                    292:                       nextlinks = XEXP (nextlinks, 1))
                    293:                    if (try_combine (insn, XEXP (links, 0), XEXP (nextlinks, 0)))
                    294:                      goto retry;
                    295:            }
                    296: #endif
                    297:          record_dead_and_set_regs (insn);
                    298:          prev = insn;
                    299:        }
                    300:       else if (GET_CODE (insn) != NOTE)
                    301:        prev = 0;
                    302:     }
                    303:   total_attempts += combine_attempts;
                    304:   total_merges += combine_merges;
                    305:   total_extras += combine_extras;
                    306:   total_successes += combine_successes;
                    307: }
                    308: 
                    309: /* Try to combine the insns I1 and I2 into I3.
                    310:    Here I1 appears earlier than I2, which is earlier than I3.
                    311:    I1 can be zero; then we combine just I2 into I3.
                    312:  
                    313:    Return 1 if successful; if that happens, I1 and I2 are pseudo-deleted
                    314:    by turning them into NOTEs, and I3 is modified.
                    315:    Return 0 if the combination does not work.  Then nothing is changed.  */
                    316: 
                    317: static int
                    318: try_combine (i3, i2, i1)
                    319:      register rtx i3, i2, i1;
                    320: {
                    321:   register rtx newpat;
                    322:   int added_sets_1 = 0;
                    323:   int added_sets_2 = 0;
                    324:   int total_sets;
                    325:   int i2_is_used;
                    326:   register rtx link;
                    327:   int insn_code_number;
                    328:   int recog_flags = 0;
                    329:   rtx i2dest, i2src;
                    330:   rtx i1dest, i1src;
1.1.1.2 ! root      331:   int maxreg;
1.1       root      332: 
                    333:   combine_attempts++;
                    334: 
                    335:   /* Don't combine with something already used up by combination.  */
                    336: 
                    337:   if (GET_CODE (i2) == NOTE
                    338:       || (i1 && GET_CODE (i1) == NOTE))
                    339:     return 0;
                    340: 
                    341:   /* Don't combine across a CALL_INSN, because that would possibly
                    342:      change whether the life span of some REGs crosses calls or not,
                    343:      and it is a pain to update that information.  */
                    344: 
                    345:   if (INSN_CUID (i2) < last_call_cuid
                    346:       || (i1 && INSN_CUID (i1) < last_call_cuid))
                    347:     return 0;
                    348: 
                    349:   /* Can combine only if previous insn is a SET of a REG, a SUBREG or CC0.
                    350:      That REG must be either set or dead by the final instruction
                    351:      (so that we can safely forget about setting it).
                    352:      Also test use_crosses_set_p to make sure that the value
                    353:      that is to be substituted for the register
                    354:      does not use any registers whose values alter in between.
                    355:      Do not try combining with moves from one register to another
                    356:      since it is better to let them be tied by register allocation.
1.1.1.2 ! root      357:      (There is a switch to permit such combination; except the insns
        !           358:      that copy a function value into another register are never combined
        !           359:      because moving that too far away from the function call could cause
        !           360:      something else to be stored in that register in the interim.)
1.1       root      361: 
                    362:      A set of a SUBREG is considered as if it were a set from
                    363:      SUBREG.  Thus, (SET (SUBREG:X (REG:Y...)) (something:X...))
                    364:      is handled by substituting (SUBREG:Y (something:X...)) for (REG:Y...).  */
                    365: 
                    366:   if (GET_CODE (PATTERN (i2)) != SET)
                    367:     return 0;
                    368:   i2dest = SET_DEST (PATTERN (i2));
                    369:   i2src = SET_SRC (PATTERN (i2));
                    370:   if (GET_CODE (i2dest) == SUBREG)
                    371:     {
                    372:       i2dest = SUBREG_REG (i2dest);
                    373:       i2src = gen_rtx (SUBREG, GET_MODE (i2dest), i2src, 0);
                    374:     }
                    375:   if (GET_CODE (i2dest) != CC0
                    376:       && (GET_CODE (i2dest) != REG
1.1.1.2 ! root      377:          || (GET_CODE (i2src) == REG
        !           378:              && (!flag_combine_regs
        !           379:                  || FUNCTION_VALUE_REGNO_P (REGNO (i2src))))
        !           380:          || GET_CODE (i2src) == CALL
1.1       root      381:          || use_crosses_set_p (i2src, INSN_CUID (i2))))
                    382:     return 0;
                    383: 
                    384:   if (i1 != 0)
                    385:     {
                    386:       if (GET_CODE (PATTERN (i1)) != SET)
                    387:        return 0;
                    388:       i1dest = SET_DEST (PATTERN (i1));
                    389:       i1src = SET_SRC (PATTERN (i1));
                    390:       if (GET_CODE (i1dest) == SUBREG)
                    391:        {
                    392:          i1dest = SUBREG_REG (i1dest);
                    393:          i1src = gen_rtx (SUBREG, GET_MODE (i1dest), i1src, 0);
                    394:        }
                    395:       if (GET_CODE (i1dest) != CC0
                    396:          && (GET_CODE (i1dest) != REG
1.1.1.2 ! root      397:              || (GET_CODE (i1src) == REG
        !           398:                  && (!flag_combine_regs
        !           399:                      || FUNCTION_VALUE_REGNO_P (REGNO (i1src))))
        !           400:              || GET_CODE (i1src) == CALL
1.1       root      401:              || use_crosses_set_p (i1src, INSN_CUID (i1))))
                    402:        return 0;
                    403:     }
                    404: 
                    405:   /* If I1 or I2 contains an autoincrement or autodecrement,
                    406:      make sure that register is not used between there and I3.
                    407:      Also insist that I3 not be a jump; if it were one
                    408:      and the incremented register were spilled, we would lose.  */
1.1.1.2 ! root      409:   if ((link = find_reg_note (i2, REG_INC, 0)) != 0
        !           410:       && (GET_CODE (i3) == JUMP_INSN
        !           411:          || reg_used_between_p (XEXP (link, 0), i2, i3)))
        !           412:     return 0;
1.1       root      413: 
1.1.1.2 ! root      414:   if (i1 && (link = find_reg_note (i1, REG_INC, 0)) != 0
        !           415:       && (GET_CODE (i3) == JUMP_INSN
        !           416:          || reg_used_between_p (XEXP (link, 0), i1, i3)))
        !           417:     return 0;
1.1       root      418: 
                    419:   /* See if the SETs in i1 or i2 need to be kept around in the merged
                    420:      instruction: whenever the value set there is still needed past i3.  */
                    421:   added_sets_2 = (GET_CODE (i2dest) != CC0
                    422:                  && ! dead_or_set_p (i3, i2dest));
                    423:   if (i1)
                    424:     added_sets_1 = ! (dead_or_set_p (i3, i1dest)
                    425:                      || dead_or_set_p (i2, i1dest));
                    426: 
                    427:   combine_merges++;
                    428: 
                    429:   undobuf.num_undo = 0;
                    430:   undobuf.storage = 0;
                    431: 
                    432:   /* Substitute in the latest insn for the regs set by the earlier ones.  */
                    433: 
1.1.1.2 ! root      434:   maxreg = max_reg_num ();
        !           435: 
1.1       root      436:   subst_insn = i3;
1.1.1.2 ! root      437:   n_occurrences = 0;           /* `subst' counts here */
        !           438: 
1.1       root      439:   newpat = subst (PATTERN (i3), i2dest, i2src);
                    440:   /* Record whether i2's body now appears within i3's body.  */
1.1.1.2 ! root      441:   i2_is_used = n_occurrences;
1.1       root      442: 
                    443:   if (i1)
1.1.1.2 ! root      444:     {
        !           445:       n_occurrences = 0;
        !           446:       newpat = subst (newpat, i1dest, i1src);
        !           447:     }
1.1       root      448: 
                    449:   if (GET_CODE (PATTERN (i3)) == SET
                    450:       && SET_DEST (PATTERN (i3)) == cc0_rtx
1.1.1.2 ! root      451:       && (GET_CODE (SET_SRC (PATTERN (i3))) == AND
        !           452:          || GET_CODE (SET_SRC (PATTERN (i3))) == LSHIFTRT)
1.1       root      453:       && next_insn_tests_no_inequality (i3))
                    454:     simplify_set_cc0_and (i3);
                    455: 
1.1.1.2 ! root      456:   if (max_reg_num () != maxreg)
        !           457:     abort ();
        !           458: 
1.1       root      459:   /* If the actions of the earler insns must be kept
                    460:      in addition to substituting them into the latest one,
                    461:      we must make a new PARALLEL for the latest insn
                    462:      to hold additional the SETs.  */
                    463: 
                    464:   if (added_sets_1 || added_sets_2)
                    465:     {
                    466:       combine_extras++;
                    467: 
                    468:       /* Arrange to free later what we allocate now
                    469:         if we don't accept this combination.  */
                    470:       if (!undobuf.storage)
                    471:        undobuf.storage = (char *) oballoc (0);
                    472: 
                    473:       if (GET_CODE (newpat) == PARALLEL)
                    474:        {
1.1.1.2 ! root      475:          rtvec old = XVEC (newpat, 0);
1.1       root      476:          total_sets = XVECLEN (newpat, 0) + added_sets_1 + added_sets_2;
1.1.1.2 ! root      477:          newpat = gen_rtx (PARALLEL, VOIDmode, rtvec_alloc (total_sets));
        !           478:          bcopy (&old->elem[0], &XVECEXP (newpat, 0, 0),
        !           479:                 sizeof (old->elem[0]) * old->num_elem);
1.1       root      480:        }
                    481:       else
                    482:        {
1.1.1.2 ! root      483:          rtx old = newpat;
1.1       root      484:          total_sets = 1 + added_sets_1 + added_sets_2;
1.1.1.2 ! root      485:          newpat = gen_rtx (PARALLEL, VOIDmode, rtvec_alloc (total_sets));
        !           486:          XVECEXP (newpat, 0, 0) = old;
1.1       root      487:        }
                    488:      if (added_sets_1)
                    489:        {
                    490:          XVECEXP (newpat, 0, --total_sets) = PATTERN (i1);
                    491:        }
                    492:      if (added_sets_2)
                    493:        {
                    494:          /* If there is no I1, use I2's body as is.  */
                    495:          if (i1 == 0
                    496:          /* If I2 was stuck into I3, then anything within it has
                    497:             already had I1 substituted into it when that was done to I3.  */
                    498:              || i2_is_used)
                    499:            {
                    500:              XVECEXP (newpat, 0, --total_sets) = PATTERN (i2);
                    501:            }
                    502:          else
                    503:            XVECEXP (newpat, 0, --total_sets)
                    504:              = subst (PATTERN (i2), i1dest, i1src);
                    505:        }
                    506:     }
                    507: 
1.1.1.2 ! root      508:   /* Fail if an autoincrement side-effect has been duplicated.  */
        !           509:   if ((i2_is_used > 1 && find_reg_note (i2, REG_INC, 0) != 0)
        !           510:       || (i1 != 0 && n_occurrences > 1 && find_reg_note (i1, REG_INC, 0) != 0))
        !           511:     {
        !           512:       undo_all ();
        !           513:       return 0;
        !           514:     }
        !           515: 
1.1       root      516:   /* Is the result of combination a valid instruction?  */
                    517:   insn_code_number = recog (newpat, i3);
                    518: 
                    519:   if (insn_code_number >= 0)
                    520:     {
                    521:       /* Yes.  Install it.  */
                    522:       register int regno;
                    523:       INSN_CODE (i3) = insn_code_number;
                    524:       PATTERN (i3) = newpat;
1.1.1.2 ! root      525:       /* If anything was substituted more than once,
        !           526:         copy it to avoid invalid shared rtl structure.  */
        !           527:       copy_substitutions ();
        !           528:       /* The data flowing into I2 now flows into I3.
        !           529:         But we cannot always move all of I2's LOG_LINKS into I3,
        !           530:         since they must go to a setting of a REG from the
        !           531:         first use following.  If I2 was the first use following a set,
        !           532:         I3 is now a use, but it is not the first use
        !           533:         if some instruction between I2 and I3 is also a use.
        !           534:         Here, for simplicity, we move all the links only if
        !           535:         there are no real insns between I2 and I3.
        !           536:         Otherwise, we move only links that correspond to regs
        !           537:         that used to die in I2.  They are always safe to move.  */
        !           538:       add_links (i3, i2, adjacent_insns_p (i2, i3));
1.1       root      539:       /* Most REGs that previously died in I2 now die in I3.  */ 
                    540:       move_deaths (i2src, INSN_CUID (i2), i3);
                    541:       if (GET_CODE (i2dest) == REG)
                    542:        {
                    543:          /* If the reg formerly set in I2 died only once and that was in I3,
                    544:             zero its use count so it won't make `reload' do any work.  */
                    545:          regno = REGNO (i2dest);
                    546:          if (! added_sets_2)
1.1.1.2 ! root      547:            {
        !           548:              reg_n_sets[regno]--;
        !           549:              /* Used to check  && regno_dead_p (regno, i3)  also here.  */
        !           550:              if (reg_n_sets[regno] == 0
        !           551:                  && ! (basic_block_live_at_start[0][regno / HOST_BITS_PER_INT]
        !           552:                        & (1 << (regno % HOST_BITS_PER_INT))))
        !           553:                reg_n_refs[regno] = 0;
        !           554:            }
1.1       root      555:          /* If a ref to REGNO was substituted into I3 from I2,
                    556:             then it still dies there if it previously did.
                    557:             Otherwise either REGNO never did die in I3 so remove_death is safe
                    558:             or this entire life of REGNO is gone so remove its death.  */
                    559:          if (!added_sets_2
                    560:              && ! reg_mentioned_p (i2dest, PATTERN (i3)))
                    561:            remove_death (regno, i3);
                    562:        }
                    563:       /* Any registers previously autoincremented in I2
                    564:         are now incremented in I3.  */
                    565:       add_incs (i3, REG_NOTES (i2));
                    566:       if (i1)
                    567:        {
                    568:          /* Likewise, merge the info from I1 and get rid of it.  */
1.1.1.2 ! root      569:          add_links (i3, i1,
        !           570:                     adjacent_insns_p (i1, i2) && adjacent_insns_p (i2, i3));
1.1       root      571:          move_deaths (i1src, INSN_CUID (i1), i3);
                    572:          if (GET_CODE (i1dest) == REG)
                    573:            {
                    574:              regno = REGNO (i1dest);
                    575:              if (! added_sets_1)
1.1.1.2 ! root      576:                {
        !           577:                  reg_n_sets[regno]--;
        !           578:                  /* Used to also check  && regno_dead_p (regno, i3) here.  */
        !           579: 
        !           580:                  if (reg_n_sets[regno] == 0
        !           581:                      && ! (basic_block_live_at_start[0][regno / HOST_BITS_PER_INT]
        !           582:                            & (1 << (regno % HOST_BITS_PER_INT))))
        !           583: 
        !           584:                    reg_n_refs[regno] = 0;
        !           585:                }
1.1       root      586:              /* If a ref to REGNO was substituted into I3 from I1,
                    587:                 then it still dies there if it previously did.
                    588:                 Else either REGNO never did die in I3 so remove_death is safe
                    589:                 or this entire life of REGNO is gone so remove its death.  */
                    590:              if (! added_sets_1
                    591:                  && ! reg_mentioned_p (i1dest, PATTERN (i3)))
                    592:                remove_death (regno, i3);
                    593:            }
                    594:          add_incs (i3, REG_NOTES (i1));
                    595:          LOG_LINKS (i1) = 0;
                    596:          PUT_CODE (i1, NOTE);
                    597:          NOTE_LINE_NUMBER (i1) = NOTE_INSN_DELETED;
                    598:          NOTE_SOURCE_FILE (i1) = 0;
                    599:        }
1.1.1.2 ! root      600:       /* Get rid of I2.  */
        !           601:       LOG_LINKS (i2) = 0;
        !           602:       PUT_CODE (i2, NOTE);
        !           603:       NOTE_LINE_NUMBER (i2) = NOTE_INSN_DELETED;
        !           604:       NOTE_SOURCE_FILE (i2) = 0;
1.1       root      605: 
                    606:       combine_successes++;
                    607:       return 1;
                    608:     }
                    609: 
                    610:   /* Failure: change I3 back the way it was.  */
                    611:   undo_all ();
                    612: 
                    613:   return 0;
                    614: }
                    615: 
                    616: /* Undo all the modifications recorded in undobuf.  */
                    617: 
                    618: static void
                    619: undo_all ()
                    620: {
                    621:   register int i;
                    622:   if (undobuf.num_undo > MAX_UNDO)
                    623:     undobuf.num_undo = MAX_UNDO;
                    624:   for (i = undobuf.num_undo - 1; i >= 0; i--)
                    625:     *undobuf.undo[i].where = undobuf.undo[i].old_contents;
                    626:   if (undobuf.storage)
                    627:     obfree (undobuf.storage);
                    628:   undobuf.num_undo = 0;
                    629:   undobuf.storage = 0;
                    630: }
                    631: 
1.1.1.2 ! root      632: /* If this insn had more than one substitution,
        !           633:    copy all but one, so that no invalid shared substructure is introduced.  */
        !           634: 
        !           635: static void
        !           636: copy_substitutions ()
        !           637: {
        !           638:   register int i;
        !           639:   if (undobuf.num_undo > 1)
        !           640:     {
        !           641:       for (i = undobuf.num_undo - 1; i >= 1; i--)
        !           642:        *undobuf.undo[i].where = copy_rtx (*undobuf.undo[i].where);
        !           643:     }
        !           644: }
        !           645: 
1.1       root      646: /* Throughout X, replace FROM with TO, and return the result.
                    647:    The result is TO if X is FROM;
                    648:    otherwise the result is X, but its contents may have been modified.
                    649:    If they were modified, a record was made in undobuf so that
                    650:    undo_all will (among other things) return X to its original state.
                    651: 
                    652:    If the number of changes necessary is too much to record to undo,
                    653:    the excess changes are not made, so the result is invalid.
                    654:    The changes already made can still be undone.
                    655:    undobuf.num_undo is incremented for such changes, so by testing that
1.1.1.2 ! root      656:    the caller can tell whether the result is valid.
        !           657: 
        !           658:    `n_occurrences' is incremented each time FROM is replaced.  */
1.1       root      659: 
                    660: static rtx
                    661: subst (x, from, to)
                    662:      register rtx x, from, to;
                    663: {
                    664:   register char *fmt;
                    665:   register int len, i;
                    666:   register enum rtx_code code;
1.1.1.2 ! root      667:   char was_replaced[2];
1.1       root      668: 
1.1.1.2 ! root      669: #define SUBST(INTO, NEWVAL)  \
        !           670:  do { if (undobuf.num_undo < MAX_UNDO)                                 \
        !           671:        {                                                               \
        !           672:          undobuf.undo[undobuf.num_undo].where = &INTO;                 \
        !           673:          undobuf.undo[undobuf.num_undo].old_contents = INTO;           \
        !           674:          INTO = NEWVAL;                                                \
        !           675:        }                                                               \
        !           676:       undobuf.num_undo++; } while (0)
        !           677: 
        !           678: /* FAKE_EXTEND_SAFE_P (MODE, FROM) is 1 if (subreg:MODE FROM 0) is a safe
        !           679:    replacement for (zero_extend:MODE FROM) or (sign_extend:MODE FROM).
        !           680:    If it is 0, that cannot be done because it might cause a badly aligned
        !           681:    memory reference.  */
        !           682: 
        !           683: #ifndef STRICT_ALIGNMENT
        !           684: #define FAKE_EXTEND_SAFE_P(MODE, FROM)  \
        !           685:    (GET_CODE (FROM) == REG ||                          \
        !           686:     (GET_CODE (FROM) == MEM                            \
        !           687:      && offsetable_address_p ((MODE), XEXP ((FROM), 0))        \
        !           688:      && ! mode_dependent_address_p ((XEXP ((FROM), 0)))))
        !           689: #else
        !           690: #define FAKE_EXTEND_SAFE_P(MODE, FROM) (GET_CODE (FROM) == REG)
        !           691: #endif
1.1       root      692: 
                    693:   if (x == from)
                    694:     return to;
                    695: 
1.1.1.2 ! root      696:   /* It is possible to have a subexpression appear twice in the insn.
        !           697:      Suppose that FROM is a register that appears within TO.
        !           698:      Then, after that subexpression has been scanned once by `subst',
        !           699:      the second time it is scanned, TO may be found.  If we were
        !           700:      to scan TO here, we would find FROM within it and create a
        !           701:      self-referent rtl structure which is completely wrong.  */
        !           702:   if (x == to)
        !           703:     return to;
        !           704: 
1.1       root      705:   code = GET_CODE (x);
                    706: 
                    707:   /* A little bit of algebraic simplification here.  */
                    708:   switch (code)
                    709:     {
                    710:       /* This case has no effect except to speed things up.  */
                    711:     case REG:
                    712:     case CONST_INT:
                    713:     case CONST:
                    714:     case SYMBOL_REF:
                    715:     case LABEL_REF:
                    716:     case PC:
                    717:     case CC0:
                    718:       return x;
1.1.1.2 ! root      719:     }
        !           720: 
        !           721:   was_replaced[0] = 0;
        !           722:   was_replaced[1] = 0;
        !           723: 
        !           724:   len = GET_RTX_LENGTH (code);
        !           725:   fmt = GET_RTX_FORMAT (code);
        !           726: 
        !           727:   /* Don't replace FROM where it is being stored in rather than used.  */
        !           728:   if (code == SET && SET_DEST (x) == from)
        !           729:     fmt = "ie";
        !           730:   if (code == SET && GET_CODE (SET_DEST (x)) == SUBREG
        !           731:       && SUBREG_REG (SET_DEST (x)) == from)
        !           732:     fmt = "ie";
        !           733: 
        !           734:   for (i = 0; i < len; i++)
        !           735:     {
        !           736:       if (fmt[i] == 'E')
        !           737:        {
        !           738:          register int j;
        !           739:          for (j = XVECLEN (x, i) - 1; j >= 0; j--)
        !           740:            {
        !           741:              register rtx new;
        !           742:              if (XVECEXP (x, i, j) == from)
        !           743:                new = to, n_occurrences++;
        !           744:              else
        !           745:                new = subst (XVECEXP (x, i, j), from, to);
        !           746:              if (new != XVECEXP (x, i, j))
        !           747:                SUBST (XVECEXP (x, i, j), new);
        !           748:            }
        !           749:        }
        !           750:       else if (fmt[i] == 'e')
        !           751:        {
        !           752:          register rtx new;
        !           753: 
        !           754:          if (XEXP (x, i) == from)
        !           755:            {
        !           756:              new = to;
        !           757:              n_occurrences++;
        !           758:              if (i < 2)
        !           759:                was_replaced[i] = 1;
        !           760:            }
        !           761:          else
        !           762:            new = subst (XEXP (x, i), from, to);
        !           763: 
        !           764:          if (new != XEXP (x, i))
        !           765:            SUBST (XEXP (x, i), new);
        !           766:        }
        !           767:     }
        !           768: 
        !           769:   /* A little bit of algebraic simplification here.  */
        !           770:   switch (code)
        !           771:     {
        !           772:     case SUBREG:
        !           773:       /* Changing mode twice with SUBREG => just change it once,
        !           774:         or not at all if changing back to starting mode.  */
        !           775:       if (SUBREG_REG (x) == to
        !           776:          && GET_CODE (to) == SUBREG
        !           777:          && SUBREG_WORD (x) == 0
        !           778:          && SUBREG_WORD (to) == 0)
        !           779:        {
        !           780:          if (GET_MODE (x) == GET_MODE (SUBREG_REG (to)))
        !           781:            return SUBREG_REG (to);
        !           782:          SUBST (SUBREG_REG (x), SUBREG_REG (to));
        !           783:        }
        !           784:       break;
1.1       root      785: 
                    786:     case NOT:
                    787:     case NEG:
                    788:       /* Don't let substitution introduce double-negatives.  */
1.1.1.2 ! root      789:       if (was_replaced[0]
1.1       root      790:          && GET_CODE (to) == code)
                    791:        return XEXP (to, 0);
                    792:       break;
                    793: 
1.1.1.2 ! root      794:     case FLOAT_TRUNCATE:
        !           795:       /* (float_truncate:SF (float_extend:DF foo:SF)) = foo:SF.  */
        !           796:       if (was_replaced[0]
        !           797:          && GET_CODE (to) == FLOAT_EXTEND
        !           798:          && GET_MODE (XEXP (to, 0)) == GET_MODE (x))
        !           799:        return XEXP (to, 0);
        !           800:       break;
        !           801: 
1.1       root      802:     case PLUS:
                    803:       /* In (plus <foo> (ashift <bar> <n>))
                    804:         change the shift to a multiply so we can recognize
                    805:         scaled indexed addresses.  */
1.1.1.2 ! root      806:       if ((was_replaced[0]
        !           807:           || was_replaced[1])
1.1       root      808:          && GET_CODE (to) == ASHIFT
1.1.1.2 ! root      809:          && GET_CODE (XEXP (to, 1)) == CONST_INT
        !           810:          && INTVAL (XEXP (to, 1)) < HOST_BITS_PER_INT)
        !           811:        {
        !           812:          rtx temp;
        !           813:          if (!undobuf.storage)
        !           814:            undobuf.storage = (char *) oballoc (0);
        !           815:          temp = gen_rtx (MULT, GET_MODE (to),
        !           816:                          XEXP (to, 0),
        !           817:                          gen_rtx (CONST_INT, VOIDmode,
        !           818:                                   1 << INTVAL (XEXP (to, 1))));
        !           819:          if (was_replaced[0])
        !           820:            SUBST (XEXP (x, 0), temp);
        !           821:          else
        !           822:            SUBST (XEXP (x, 1), temp);
        !           823:        }
        !           824:       /* (plus X (neg Y)) becomes (minus X Y).  */
        !           825:       if (GET_CODE (XEXP (x, 1)) == NEG)
        !           826:        {
        !           827:          if (!undobuf.storage)
        !           828:            undobuf.storage = (char *) oballoc (0);
        !           829:          return gen_rtx (MINUS, GET_MODE (x),
        !           830:                          XEXP (x, 0), XEXP (XEXP (x, 1), 0));
        !           831:        }
        !           832:       /* (plus (neg X) Y) becomes (minus Y X).  */
        !           833:       if (GET_CODE (XEXP (x, 0)) == NEG)
1.1       root      834:        {
                    835:          if (!undobuf.storage)
                    836:            undobuf.storage = (char *) oballoc (0);
1.1.1.2 ! root      837:          return gen_rtx (MINUS, GET_MODE (x),
        !           838:                          XEXP (x, 1), XEXP (XEXP (x, 0), 0));
        !           839:        }
        !           840:       /* (plus (plus x c1) c2) => (plus x c1+c2) */
        !           841:       if (GET_CODE (XEXP (x, 1)) == CONST_INT
        !           842:          && GET_CODE (XEXP (x, 0)) == PLUS
        !           843:          && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)
        !           844:        {
        !           845:          int sum = (INTVAL (XEXP (x, 1))
        !           846:                     + INTVAL (XEXP (XEXP (x, 0), 1)));
        !           847:          if (sum == 0)
        !           848:            return XEXP (XEXP (x, 0), 0);
        !           849:          if (!undobuf.storage)
        !           850:            undobuf.storage = (char *) oballoc (0);
        !           851:          SUBST (XEXP (x, 1), gen_rtx (CONST_INT, VOIDmode, sum));
        !           852:          SUBST (XEXP (x, 0), XEXP (XEXP (x, 0), 0));
        !           853:          break;
1.1       root      854:        }
                    855:       /* If we have something (putative index) being added to a sum,
                    856:         associate it so that any constant term is outermost.
                    857:         That's because that's the way indexed addresses are
                    858:         now supposed to appear.  */
1.1.1.2 ! root      859:       if (((was_replaced[0] && GET_CODE (XEXP (x, 1)) == PLUS)
        !           860:           || (was_replaced[1] && GET_CODE (XEXP (x, 0)) == PLUS))
1.1       root      861:          ||
1.1.1.2 ! root      862:          ((was_replaced[0] || was_replaced[1])
        !           863:           && GET_CODE (to) == PLUS))
1.1       root      864:        {
                    865:          rtx offset = 0, base, index;
1.1.1.2 ! root      866:          if (GET_CODE (to) != PLUS)
1.1       root      867:            {
1.1.1.2 ! root      868:              index = to;
        !           869:              base = was_replaced[0] ? XEXP (x, 1) : XEXP (x, 0);
1.1       root      870:            }
                    871:          else
                    872:            {
1.1.1.2 ! root      873:              index = was_replaced[0] ? XEXP (x, 1) : XEXP (x, 0);
        !           874:              base = to;
1.1       root      875:            }
                    876:          if (CONSTANT_ADDRESS_P (XEXP (base, 0)))
                    877:            {
                    878:              offset = XEXP (base, 0);
                    879:              base = XEXP (base, 1);
                    880:            }
                    881:          else if (CONSTANT_ADDRESS_P (XEXP (base, 1)))
                    882:            {
                    883:              offset = XEXP (base, 1);
                    884:              base = XEXP (base, 0);
                    885:            }
                    886:          if (offset != 0)
                    887:            {
                    888:              if (!undobuf.storage)
                    889:                undobuf.storage = (char *) oballoc (0);
1.1.1.2 ! root      890:              if (GET_CODE (offset) == CONST_INT)
        !           891:                return plus_constant (gen_rtx (PLUS, GET_MODE (index),
        !           892:                                               base, index),
        !           893:                                      INTVAL (offset));
        !           894:              if (GET_CODE (index) == CONST_INT)
        !           895:                return plus_constant (gen_rtx (PLUS, GET_MODE (offset),
        !           896:                                               base, offset),
        !           897:                                      INTVAL (index));
        !           898:              return gen_rtx (PLUS, GET_MODE (index),
1.1       root      899:                              gen_rtx (PLUS, GET_MODE (index),
1.1.1.2 ! root      900:                                       base, index),
        !           901:                              offset);
1.1       root      902:            }
                    903:        }
                    904:       break;
                    905: 
                    906:     case MINUS:
                    907:       /* Can simplify (minus:VOIDmode (zero/sign_extend FOO) CONST)
                    908:         (which is a compare instruction, not a subtract instruction)
                    909:         to (minus FOO CONST) if CONST fits in FOO's mode
                    910:         and we are only testing equality.
                    911:         In fact, this is valid for zero_extend if what follows is an
                    912:         unsigned comparison, and for sign_extend with a signed comparison.  */
                    913:       if (GET_MODE (x) == VOIDmode
1.1.1.2 ! root      914:          && was_replaced[0]
1.1       root      915:          && (GET_CODE (to) == ZERO_EXTEND || GET_CODE (to) == SIGN_EXTEND)
                    916:          && next_insn_tests_no_inequality (subst_insn)
                    917:          && GET_CODE (XEXP (x, 1)) == CONST_INT
1.1.1.2 ! root      918:          /* This is overly cautious by one bit, but saves worrying about
        !           919:             whether it is zero-extension or sign extension.  */
1.1       root      920:          && ((unsigned) INTVAL (XEXP (x, 1))
1.1.1.2 ! root      921:              < (1 << (GET_MODE_BITSIZE (GET_MODE (XEXP (to, 0))) - 1))))
        !           922:        SUBST (XEXP (x, 0), XEXP (to, 0));
1.1       root      923:       break;
                    924: 
                    925:     case EQ:
                    926:     case NE:
                    927:       /* If comparing a subreg against zero, discard the subreg.  */
1.1.1.2 ! root      928:       if (was_replaced[0]
1.1       root      929:          && GET_CODE (to) == SUBREG
                    930:          && SUBREG_WORD (to) == 0
                    931:          && XEXP (x, 1) == const0_rtx)
1.1.1.2 ! root      932:        SUBST (XEXP (x, 0), SUBREG_REG (to));
1.1       root      933: 
                    934:       /* If comparing a ZERO_EXTRACT against zero,
                    935:         canonicalize to a SIGN_EXTRACT,
                    936:         since the two are equivalent here.  */
1.1.1.2 ! root      937:       if (was_replaced[0]
        !           938:          && GET_CODE (to) == ZERO_EXTRACT
1.1       root      939:          && XEXP (x, 1) == const0_rtx)
                    940:        {
                    941:          if (!undobuf.storage)
                    942:            undobuf.storage = (char *) oballoc (0);
1.1.1.2 ! root      943:          SUBST (XEXP (x, 0),
        !           944:                 gen_rtx (SIGN_EXTRACT, GET_MODE (to),
        !           945:                          XEXP (to, 0), XEXP (to, 1),
        !           946:                          XEXP (to, 2)));
1.1       root      947:        }
                    948:       /* If we are putting (ASHIFT 1 x) into (EQ (AND ... y) 0),
                    949:         arrange to return (EQ (SIGN_EXTRACT y 1 x) 0),
                    950:         which is what jump-on-bit instructions are written with.  */
                    951:       else if (XEXP (x, 1) == const0_rtx
                    952:               && GET_CODE (XEXP (x, 0)) == AND
1.1.1.2 ! root      953:               && (XEXP (XEXP (x, 0), 0) == to
        !           954:                   || XEXP (XEXP (x, 0), 1) == to)
        !           955:               && GET_CODE (to) == ASHIFT
        !           956:               && XEXP (to, 0) == const1_rtx)
1.1       root      957:        {
                    958:          register rtx y = XEXP (XEXP (x, 0),
1.1.1.2 ! root      959:                                 XEXP (XEXP (x, 0), 0) == to);
1.1       root      960:          if (!undobuf.storage)
                    961:            undobuf.storage = (char *) oballoc (0);
1.1.1.2 ! root      962:          SUBST (XEXP (x, 0),
        !           963:                 gen_rtx (SIGN_EXTRACT, GET_MODE (to),
        !           964:                          y,
        !           965:                          const1_rtx, XEXP (to, 1)));
1.1       root      966:        }
                    967: 
                    968:       break;
                    969: 
                    970:     case ZERO_EXTEND:
1.1.1.2 ! root      971:       if (was_replaced[0]
1.1       root      972:          && GET_CODE (to) == ZERO_EXTEND)
1.1.1.2 ! root      973:        SUBST (XEXP (x, 0), XEXP (to, 0));
1.1       root      974:       /* Zero-extending the result of an and with a constant can be done
                    975:         with a wider and.  */
1.1.1.2 ! root      976:       if (was_replaced[0]
1.1       root      977:          && GET_CODE (to) == AND
                    978:          && GET_CODE (XEXP (to, 1)) == CONST_INT
1.1.1.2 ! root      979:          && FAKE_EXTEND_SAFE_P (GET_MODE (x), XEXP (to, 0))
1.1       root      980:          /* Avoid getting wrong result if the constant has high bits set
                    981:             that are irrelevant in the narrow mode where it is being used.  */
1.1.1.2 ! root      982:          && 0 == (INTVAL (XEXP (to, 1))
        !           983:                   & ~ GET_MODE_MASK (GET_MODE (to))))
1.1       root      984:        {
                    985:          if (!undobuf.storage)
                    986:            undobuf.storage = (char *) oballoc (0);
                    987:          return gen_rtx (AND, GET_MODE (x),
1.1.1.2 ! root      988:                          gen_lowpart_for_combine (GET_MODE (x), XEXP (to, 0)),
1.1       root      989:                          XEXP (to, 1));
1.1.1.2 ! root      990:        } 
        !           991:       /* Change (zero_extend:M (subreg:N (zero_extract:M ...) 0))
        !           992:         to (zero_extract:M ...) if the field extracted fits in mode N.  */
        !           993:       if (GET_CODE (XEXP (x, 0)) == SUBREG
        !           994:          && GET_CODE (XEXP (XEXP (x, 0), 0)) == ZERO_EXTRACT
        !           995:          && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1)) == CONST_INT
        !           996:          && (INTVAL (XEXP (XEXP (XEXP (x, 0), 0), 1))
        !           997:              <= GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0)))))
        !           998:        {
        !           999:          return XEXP (XEXP (x, 0), 0);
        !          1000:        }
1.1       root     1001:       break;
                   1002: 
                   1003:     case SIGN_EXTEND:
1.1.1.2 ! root     1004:       if (was_replaced[0]
1.1       root     1005:          && GET_CODE (to) == SIGN_EXTEND)
1.1.1.2 ! root     1006:        SUBST (XEXP (x, 0), XEXP (to, 0));
1.1       root     1007:       /* Sign-extending the result of an and with a constant can be done
                   1008:         with a wider and, provided the high bit of the constant is 0.  */
1.1.1.2 ! root     1009:       if (was_replaced[0]
1.1       root     1010:          && GET_CODE (to) == AND
                   1011:          && GET_CODE (XEXP (to, 1)) == CONST_INT
1.1.1.2 ! root     1012:          && FAKE_EXTEND_SAFE_P (GET_MODE (x), XEXP (to, 0))
1.1       root     1013:          && ((INTVAL (XEXP (to, 1))
1.1.1.2 ! root     1014:               & (-1 << (GET_MODE_BITSIZE (GET_MODE (to)) - 1)))
1.1       root     1015:              == 0))
                   1016:        {
                   1017:          if (!undobuf.storage)
                   1018:            undobuf.storage = (char *) oballoc (0);
                   1019:          return gen_rtx (AND, GET_MODE (x),
1.1.1.2 ! root     1020:                          gen_lowpart_for_combine (GET_MODE (x), XEXP (to, 0)),
1.1       root     1021:                          XEXP (to, 1));
                   1022:         } 
                   1023:       break;
                   1024: 
                   1025:     case SET:
1.1.1.2 ! root     1026:       /* In (set (zero-extract <x> <n> <y>) (and <foo> <(2**n-1) | anything>))
1.1       root     1027:         the `and' can be deleted.  This can happen when storing a bit
1.1.1.2 ! root     1028:         that came from a set-flag insn followed by masking to one bit.  */
1.1       root     1029:       if (GET_CODE (XEXP (x, 0)) == ZERO_EXTRACT
1.1.1.2 ! root     1030:          && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
        !          1031:          && was_replaced[1]
1.1       root     1032:          && GET_CODE (to) == AND
1.1.1.2 ! root     1033:          && GET_CODE (XEXP (to, 1)) == CONST_INT
        !          1034:          && 0 == (((1 << INTVAL (XEXP (XEXP (x, 0), 1))) - 1)
        !          1035:                   & ~ INTVAL (XEXP (to, 1))))
1.1       root     1036:        {
1.1.1.2 ! root     1037:          SUBST (XEXP (x, 1), XEXP (to, 0));
        !          1038:        } 
        !          1039:       /* In (set (zero-extract <x> <n> <y>)
        !          1040:                 (subreg (and <foo> <(2**n-1) | anything>)))
        !          1041:         the `and' can be deleted.  */
        !          1042:       if (GET_CODE (XEXP (x, 0)) == ZERO_EXTRACT
        !          1043:          && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
        !          1044:          && GET_CODE (XEXP (x, 1)) == SUBREG
        !          1045:          && SUBREG_WORD (XEXP (x, 1)) == 0
        !          1046:          && GET_CODE (SUBREG_REG (XEXP (x, 1))) == AND
        !          1047:          && GET_CODE (XEXP (SUBREG_REG (XEXP (x, 1)), 1)) == CONST_INT
        !          1048:          && 0 == (((1 << INTVAL (XEXP (XEXP (x, 0), 1))) - 1)
        !          1049:                   & ~ INTVAL (XEXP (SUBREG_REG (XEXP (x, 1)), 1))))
        !          1050:        {
        !          1051:          SUBST (SUBREG_REG (XEXP (x, 1)), XEXP (SUBREG_REG (XEXP (x, 1)), 0));
        !          1052:        } 
        !          1053:       /* (set (zero_extract ...) (and/or/xor (zero_extract ...) const)),
        !          1054:         if both zero_extracts have the byte size and position,
        !          1055:         can be changed to avoid the byte extracts.  */
        !          1056:       if ((GET_CODE (XEXP (x, 0)) == ZERO_EXTRACT
        !          1057:           || GET_CODE (XEXP (x, 0)) == SIGN_EXTRACT)
        !          1058:          && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
        !          1059:          && (GET_CODE (XEXP (x, 1)) == AND
        !          1060:              || GET_CODE (XEXP (x, 1)) == IOR
        !          1061:              || GET_CODE (XEXP (x, 1)) == XOR)
        !          1062:          && (GET_CODE (XEXP (XEXP (x, 1), 0)) == ZERO_EXTRACT
        !          1063:              || GET_CODE (XEXP (XEXP (x, 1), 0)) == SIGN_EXTRACT)
        !          1064:          && rtx_equal_p (XEXP (XEXP (XEXP (x, 1), 0), 1),
        !          1065:                          XEXP (XEXP (x, 0), 1))
        !          1066:          && rtx_equal_p (XEXP (XEXP (XEXP (x, 1), 0), 2),
        !          1067:                          XEXP (XEXP (x, 0), 2))
        !          1068:          && GET_CODE (XEXP (XEXP (x, 1), 0)) == GET_CODE (XEXP (x, 0))
        !          1069:          && GET_CODE (XEXP (XEXP (x, 1), 1)) == CONST_INT)
        !          1070:        {
        !          1071: #ifdef BITS_BIG_ENDIAN
        !          1072:          int shiftcount
        !          1073:            = GET_MODE_BITSIZE (GET_MODE (XEXP (XEXP (x, 0), 0)))
        !          1074:              - INTVAL (XEXP (XEXP (x, 0), 1)) - INTVAL (XEXP (XEXP (x, 0), 2));
        !          1075: #else
        !          1076:          int shiftcount
        !          1077:            = INTVAL (XEXP (XEXP (x, 0), 2));
        !          1078: #endif
        !          1079:          if (!undobuf.storage)
        !          1080:            undobuf.storage = (char *) oballoc (0);
        !          1081:          return
        !          1082:            gen_rtx (SET, VOIDmode,
        !          1083:                     XEXP (XEXP (x, 0), 0),
        !          1084:                     gen_rtx (GET_CODE (XEXP (x, 1)),
        !          1085:                              GET_MODE (XEXP (XEXP (x, 0), 0)),
        !          1086:                              XEXP (XEXP (XEXP (x, 1), 0), 0),
        !          1087:                              gen_rtx (CONST_INT, VOIDmode,
        !          1088:                                       (INTVAL (XEXP (XEXP (x, 1), 1))
        !          1089:                                        << shiftcount)
        !          1090:                                       + (GET_CODE (XEXP (x, 1)) == AND
        !          1091:                                          ? (1 << shiftcount) - 1
        !          1092:                                          : 0))));
        !          1093:        }
1.1       root     1094:       break;
                   1095: 
                   1096:     case AND:
                   1097:       if (GET_CODE (XEXP (x, 1)) == CONST_INT)
                   1098:        {
1.1.1.2 ! root     1099:          rtx tem = simplify_and_const_int (x, to);
1.1       root     1100:          if (tem)
                   1101:            return tem;
                   1102:        }
                   1103:       break;
                   1104: 
                   1105:     case FLOAT:
                   1106:       /* (float (sign_extend <X>)) = (float <X>).  */
1.1.1.2 ! root     1107:       if (was_replaced[0]
1.1       root     1108:          && GET_CODE (to) == SIGN_EXTEND)
1.1.1.2 ! root     1109:        SUBST (XEXP (x, 0), XEXP (to, 0));
1.1       root     1110:       break;
                   1111: 
                   1112:     case ZERO_EXTRACT:
1.1.1.2 ! root     1113:       /* (ZERO_EXTRACT (TRUNCATE x)...)
        !          1114:         can become (ZERO_EXTRACT x ...).  */
        !          1115:       if (was_replaced[0]
        !          1116:          && GET_CODE (to) == TRUNCATE)
        !          1117:        {
        !          1118: #ifdef BITS_BIG_ENDIAN
        !          1119:          if (GET_CODE (XEXP (x, 2)) == CONST_INT)
        !          1120:            {
        !          1121:              if (!undobuf.storage)
        !          1122:                undobuf.storage = (char *) oballoc (0);
        !          1123:              /* On a big-endian machine, must increment the bit-number
        !          1124:                 since sign bit is farther away in the pre-truncated value.  */
        !          1125:              return gen_rtx (ZERO_EXTRACT, GET_MODE (x),
        !          1126:                              XEXP (to, 0),
        !          1127:                              XEXP (x, 1),
        !          1128:                              gen_rtx (CONST_INT, VOIDmode,
        !          1129:                                       (INTVAL (XEXP (x, 2))
        !          1130:                                        + GET_MODE_BITSIZE (GET_MODE (XEXP (to, 0)))
        !          1131:                                        - GET_MODE_BITSIZE (GET_MODE (to)))));
        !          1132:            }
        !          1133: #else
        !          1134:          SUBST (XEXP (x, 0), XEXP (to, 0));
        !          1135: #endif
        !          1136:        }
1.1       root     1137:       /* Extracting a single bit from the result of a shift:
                   1138:         see which bit it was before the shift and extract that directly.  */
1.1.1.2 ! root     1139:       if (was_replaced[0]
1.1       root     1140:          && (GET_CODE (to) == ASHIFTRT || GET_CODE (to) == LSHIFTRT
                   1141:              || GET_CODE (to) == ASHIFT || GET_CODE (to) == LSHIFT)
                   1142:          && GET_CODE (XEXP (to, 1)) == CONST_INT
                   1143:          && XEXP (x, 1) == const1_rtx
                   1144:          && GET_CODE (XEXP (x, 2)) == CONST_INT)
                   1145:        {
                   1146:          int shift = INTVAL (XEXP (to, 1));
                   1147:          int newpos;
                   1148:          if (GET_CODE (to) == ASHIFT || GET_CODE (to) == LSHIFT)
                   1149:            shift = - shift;
                   1150: #ifdef BITS_BIG_ENDIAN
                   1151:          shift = - shift;
                   1152: #endif
                   1153:          newpos = INTVAL (XEXP (x, 2)) + shift;
                   1154:          if (newpos >= 0 &&
1.1.1.2 ! root     1155:              newpos < GET_MODE_BITSIZE (GET_MODE (to)))
1.1       root     1156:            {
                   1157:              if (!undobuf.storage)
                   1158:                undobuf.storage = (char *) oballoc (0);
                   1159:              return gen_rtx (ZERO_EXTRACT, GET_MODE (x),
                   1160:                              XEXP (to, 0), const1_rtx,
                   1161:                              gen_rtx (CONST_INT, VOIDmode, newpos));
                   1162:            }
                   1163:        }
                   1164:       break;
                   1165: 
                   1166:     case LSHIFTRT:
                   1167:     case ASHIFTRT:
                   1168:     case ROTATE:
                   1169:     case ROTATERT:
                   1170: #ifdef SHIFT_COUNT_TRUNCATED
                   1171:       /* (lshift <X> (sign_extend <Y>)) = (lshift <X> <Y>) (most machines).
                   1172:         True for all kinds of shifts and also for zero_extend.  */
1.1.1.2 ! root     1173:       if (was_replaced[1]
1.1       root     1174:          && (GET_CODE (to) == SIGN_EXTEND
1.1.1.2 ! root     1175:              || GET_CODE (to) == ZERO_EXTEND)
        !          1176:          && FAKE_EXTEND_SAFE_P (GET_MODE (to), XEXP (to, 0)))
1.1       root     1177:        {
                   1178:          if (!undobuf.storage)
                   1179:            undobuf.storage = (char *) oballoc (0);
1.1.1.2 ! root     1180:          SUBST (XEXP (x, 1),
        !          1181:                 /* This is a perverse SUBREG, wider than its base.  */
        !          1182:                 gen_lowpart_for_combine (GET_MODE (to), XEXP (to, 0)));
1.1       root     1183:        }
                   1184: #endif
                   1185:       /* Two shifts in a row of same kind
                   1186:         in same direction with constant counts
                   1187:         may be combined.  */
1.1.1.2 ! root     1188:       if (was_replaced[0]
1.1       root     1189:          && GET_CODE (to) == GET_CODE (x)
                   1190:          && GET_CODE (XEXP (x, 1)) == CONST_INT
                   1191:          && GET_CODE (XEXP (to, 1)) == CONST_INT
                   1192:          && INTVAL (XEXP (to, 1)) > 0
                   1193:          && INTVAL (XEXP (x, 1)) > 0
                   1194:          && (INTVAL (XEXP (x, 1)) + INTVAL (XEXP (to, 1))
1.1.1.2 ! root     1195:              < GET_MODE_BITSIZE (GET_MODE (x))))
1.1       root     1196:        {
                   1197:          if (!undobuf.storage)
                   1198:            undobuf.storage = (char *) oballoc (0);
                   1199:          return gen_rtx (GET_CODE (x), GET_MODE (x),
                   1200:                          XEXP (to, 0),
                   1201:                          gen_rtx (CONST_INT, VOIDmode,
                   1202:                                   INTVAL (XEXP (x, 1))
                   1203:                                   + INTVAL (XEXP (to, 1))));
                   1204:        }
                   1205:       break;
                   1206: 
                   1207:     case LSHIFT:
                   1208:     case ASHIFT:
                   1209: #ifdef SHIFT_COUNT_TRUNCATED
                   1210:       /* (lshift <X> (sign_extend <Y>)) = (lshift <X> <Y>) (most machines).
                   1211:         True for all kinds of shifts and also for zero_extend.  */
1.1.1.2 ! root     1212:       if (was_replaced[1]
1.1       root     1213:          && (GET_CODE (to) == SIGN_EXTEND
                   1214:              || GET_CODE (to) == ZERO_EXTEND))
                   1215:        {
                   1216:          if (!undobuf.storage)
                   1217:            undobuf.storage = (char *) oballoc (0);
1.1.1.2 ! root     1218:          SUBST (XEXP (x, 1), gen_rtx (SUBREG, GET_MODE (to), XEXP (to, 0), 0));
1.1       root     1219:        }
                   1220: #endif
                   1221:       /* (lshift (and (lshiftrt <foo> <X>) <Y>) <X>)
                   1222:         happens copying between bit fields in similar structures.
                   1223:         It can be replaced by one and instruction.
                   1224:         It does not matter whether the shifts are logical or arithmetic.  */
                   1225:       if (GET_CODE (XEXP (x, 0)) == AND
                   1226:          && GET_CODE (XEXP (x, 1)) == CONST_INT
                   1227:          && INTVAL (XEXP (x, 1)) > 0
                   1228:          && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
1.1.1.2 ! root     1229:          && XEXP (XEXP (x, 0), 0) == to
1.1       root     1230:          && (GET_CODE (to) == LSHIFTRT
                   1231:              || GET_CODE (to) == ASHIFTRT)
                   1232: #if 0
                   1233: /* I now believe this restriction is unnecessary.
                   1234:    The outer shift will discard those bits in any case, right?  */
                   1235: 
                   1236:              /* If inner shift is arithmetic, either it shifts left or
                   1237:                 the bits it shifts the sign into are zeroed by the and.  */
                   1238:                  && (INTVAL (XEXP (x, 1)) < 0
                   1239:                      || ((unsigned) INTVAL (XEXP (XEXP (x, 0), 1))
                   1240:                          < 1 << (GET_MODE_BITSIZE (GET_MODE (x))
                   1241:                                  - INTVAL (XEXP (x, 0)))))
                   1242: #endif
                   1243:          && GET_CODE (XEXP (to, 1)) == CONST_INT
                   1244:          && INTVAL (XEXP (x, 1)) == INTVAL (XEXP (to, 1)))
                   1245:        {
                   1246:          if (!undobuf.storage)
                   1247:            undobuf.storage = (char *) oballoc (0);
                   1248:          /* The constant in the new `and' is <Y> << <X>
                   1249:             but clear out all bits that don't belong in our mode.  */
                   1250:          return gen_rtx (AND, GET_MODE (x), XEXP (to, 0),
                   1251:                          gen_rtx (CONST_INT, VOIDmode,
                   1252:                                   (GET_MODE_MASK (GET_MODE (x))
                   1253:                                    & ((GET_MODE_MASK (GET_MODE (x))
                   1254:                                        & INTVAL (XEXP (XEXP (x, 0), 1)))
                   1255:                                       << INTVAL (XEXP (x, 1))))));
                   1256:        } 
                   1257:       /* Two shifts in a row in same direction with constant counts
                   1258:         may be combined.  */
1.1.1.2 ! root     1259:       if (was_replaced[0]
1.1       root     1260:          && (GET_CODE (to) == ASHIFT || GET_CODE (to) == LSHIFT)
                   1261:          && GET_CODE (XEXP (x, 1)) == CONST_INT
                   1262:          && GET_CODE (XEXP (to, 1)) == CONST_INT
                   1263:          && INTVAL (XEXP (to, 1)) > 0
                   1264:          && INTVAL (XEXP (x, 1)) > 0
                   1265:          && (INTVAL (XEXP (x, 1)) + INTVAL (XEXP (to, 1))
1.1.1.2 ! root     1266:              < GET_MODE_BITSIZE (GET_MODE (x))))
1.1       root     1267:        {
                   1268:          if (!undobuf.storage)
                   1269:            undobuf.storage = (char *) oballoc (0);
                   1270:          return gen_rtx (GET_CODE (x), GET_MODE (x),
                   1271:                          XEXP (to, 0),
                   1272:                          gen_rtx (CONST_INT, VOIDmode,
                   1273:                                   INTVAL (XEXP (x, 1))
                   1274:                                   + INTVAL (XEXP (to, 1))));
                   1275:        }
                   1276:       /* (ashift (ashiftrt <foo> <X>) <X>)
                   1277:         (or, on some machines, (ashift (ashift <foo> <-X>) <X>) instead)
                   1278:         happens if you divide by 2**N and then multiply by 2**N.
                   1279:         It can be replaced by one `and' instruction.
                   1280:         It does not matter whether the shifts are logical or arithmetic.  */
                   1281:       if (GET_CODE (XEXP (x, 1)) == CONST_INT
                   1282:          && INTVAL (XEXP (x, 1)) > 0
1.1.1.2 ! root     1283:          && was_replaced[0]
1.1       root     1284:          && (((GET_CODE (to) == LSHIFTRT || GET_CODE (to) == ASHIFTRT)
                   1285:               && GET_CODE (XEXP (to, 1)) == CONST_INT
                   1286:               && INTVAL (XEXP (x, 1)) == INTVAL (XEXP (to, 1)))
                   1287:              ||
                   1288:              ((GET_CODE (to) == LSHIFT || GET_CODE (to) == ASHIFT)
                   1289:               && GET_CODE (XEXP (to, 1)) == CONST_INT
                   1290:               && INTVAL (XEXP (x, 1)) == - INTVAL (XEXP (to, 1)))))
                   1291:        {
                   1292:          if (!undobuf.storage)
                   1293:            undobuf.storage = (char *) oballoc (0);
1.1.1.2 ! root     1294:          /* The constant in the new `and' is -1 << <X>
1.1       root     1295:             but clear out all bits that don't belong in our mode.  */
                   1296:          return gen_rtx (AND, GET_MODE (x), XEXP (to, 0),
                   1297:                          gen_rtx (CONST_INT, VOIDmode,
                   1298:                                   (GET_MODE_MASK (GET_MODE (x))
                   1299:                                    & (GET_MODE_MASK (GET_MODE (x))
                   1300:                                       << INTVAL (XEXP (x, 1))))));
                   1301:        } 
                   1302: 
                   1303:     }
                   1304: 
                   1305:   return x;
                   1306: }
                   1307: 
                   1308: /* This is the AND case of the function subst.  */
                   1309: 
                   1310: static rtx
1.1.1.2 ! root     1311: simplify_and_const_int (x, to)
        !          1312:      rtx x, to;
1.1       root     1313: {
                   1314:   register rtx varop = XEXP (x, 0);
                   1315:   register int constop = INTVAL (XEXP (x, 1));
                   1316: 
                   1317:   /* (and (subreg (and <foo> <constant>) 0) <constant>)
                   1318:      results from an andsi followed by an andqi,
                   1319:      which happens frequently when storing bit-fields
                   1320:      on something whose result comes from an andsi.  */
                   1321:   if (GET_CODE (varop) == SUBREG
1.1.1.2 ! root     1322:       && XEXP (varop, 0) == to
1.1       root     1323:       && subreg_lowpart_p (varop)
                   1324:       && GET_CODE (to) == AND
                   1325:       && GET_CODE (XEXP (to, 1)) == CONST_INT
                   1326:       /* Verify that the result of the outer `and'
                   1327:         is not affected by any bits not defined in the inner `and'.
                   1328:         True if the outer mode is narrower, or if the outer constant
                   1329:         masks to zero all the bits that the inner mode doesn't have.  */
1.1.1.2 ! root     1330:       && (GET_MODE_SIZE (GET_MODE (x)) < GET_MODE_SIZE (GET_MODE (to))
        !          1331:          || (constop & ~ GET_MODE_MASK (GET_MODE (to))) == 0))
1.1       root     1332:     {
                   1333:       if (!undobuf.storage)
                   1334:        undobuf.storage = (char *) oballoc (0);
                   1335:       return gen_rtx (AND, GET_MODE (x),
1.1.1.2 ! root     1336:                      gen_lowpart_for_combine (GET_MODE (x), XEXP (to, 0)),
1.1       root     1337:                      gen_rtx (CONST_INT, VOIDmode,
                   1338:                               constop
                   1339:                               /* Remember that the bits outside that mode
                   1340:                                  are not being changed, so the effect
                   1341:                                  is as if they were all 1.  */
                   1342:                               & INTVAL (XEXP (to, 1))));
                   1343:     } 
1.1.1.2 ! root     1344:   /* (and:SI (zero_extract:SI ...) <constant>)
        !          1345:      results from an andsi following a byte-fetch on risc machines.
        !          1346:      When the constant includes all bits extracted, eliminate the `and'.  */
        !          1347:   if (GET_CODE (varop) == ZERO_EXTRACT
        !          1348:       && GET_CODE (XEXP (varop, 1)) == CONST_INT
        !          1349:       /* The `and' must not clear any bits that the extract can give.  */
        !          1350:       && (~ constop & ((1 << INTVAL (XEXP (varop, 1))) - 1)) == 0)
        !          1351:     return varop;
1.1       root     1352:   /* (and (zero_extend <foo>) <constant>)
                   1353:      often results from storing in a bit-field something
                   1354:      that was calculated as a short.  Replace with a single `and'
                   1355:      in whose constant all bits not in <foo>'s mode are zero.  */
1.1.1.2 ! root     1356:   if (varop == to
        !          1357:       && GET_CODE (to) == ZERO_EXTEND
        !          1358:       && FAKE_EXTEND_SAFE_P (GET_MODE (x), XEXP (to, 0)))
1.1       root     1359:     {
                   1360:       if (!undobuf.storage)
                   1361:        undobuf.storage = (char *) oballoc (0);
                   1362:       return gen_rtx (AND, GET_MODE (x),
1.1.1.2 ! root     1363:                      /* This is a perverse SUBREG, wider than its base.  */
        !          1364:                      gen_lowpart_for_combine (GET_MODE (x), XEXP (to, 0)),
1.1       root     1365:                      gen_rtx (CONST_INT, VOIDmode,
1.1.1.2 ! root     1366:                               constop & GET_MODE_MASK (GET_MODE (XEXP (to, 0)))));
1.1       root     1367:     }
                   1368:   /* (and (sign_extend <foo>) <constant>)
                   1369:      can be replaced with (and (subreg <foo>) <constant>)
                   1370:      if <constant> is narrower than <foo>'s mode,
                   1371:      or with (zero_extend <foo>) if <constant> is a mask for that mode.  */
1.1.1.2 ! root     1372:   if (varop == to
1.1       root     1373:       && GET_CODE (to) == SIGN_EXTEND
1.1.1.2 ! root     1374:       && ((unsigned) constop <= GET_MODE_MASK (GET_MODE (XEXP (to, 0))))
        !          1375:       && FAKE_EXTEND_SAFE_P (GET_MODE (x), XEXP (to, 0)))
1.1       root     1376:     {
                   1377:       if (!undobuf.storage)
                   1378:        undobuf.storage = (char *) oballoc (0);
1.1.1.2 ! root     1379:       if (constop == GET_MODE_MASK (GET_MODE (XEXP (to, 0))))
1.1       root     1380:        return gen_rtx (ZERO_EXTEND, GET_MODE (x), XEXP (to, 0));
                   1381:       return gen_rtx (AND, GET_MODE (x),
1.1.1.2 ! root     1382:                      /* This is a perverse SUBREG, wider than its base.  */
        !          1383:                      gen_lowpart_for_combine (GET_MODE (x), XEXP (to, 0)),
1.1       root     1384:                      XEXP (x, 1));
                   1385:     }
                   1386:   /* (and (and <foo> <constant>) <constant>)
                   1387:      comes from two and instructions in a row.  */
1.1.1.2 ! root     1388:   if (varop == to
1.1       root     1389:       && GET_CODE (to) == AND
                   1390:       && GET_CODE (XEXP (to, 1)) == CONST_INT)
                   1391:     {
                   1392:       if (!undobuf.storage)
                   1393:        undobuf.storage = (char *) oballoc (0);
                   1394:       return gen_rtx (AND, GET_MODE (x),
                   1395:                      XEXP (to, 0),
                   1396:                      gen_rtx (CONST_INT, VOIDmode,
                   1397:                               constop
                   1398:                               & INTVAL (XEXP (to, 1))));
                   1399:     }
                   1400:   /* (and (ashiftrt (ashift FOO N) N) CONST)
                   1401:      may be simplified to (and FOO CONST) if CONST masks off the bits
                   1402:      changed by the two shifts.  */
                   1403:   if (GET_CODE (varop) == ASHIFTRT
                   1404:       && GET_CODE (XEXP (varop, 1)) == CONST_INT
1.1.1.2 ! root     1405:       && XEXP (varop, 0) == to
1.1       root     1406:       && GET_CODE (to) == ASHIFT
                   1407:       && GET_CODE (XEXP (to, 1)) == CONST_INT
                   1408:       && INTVAL (XEXP (varop, 1)) == INTVAL (XEXP (to, 1))
                   1409:       && ((unsigned) constop >> INTVAL (XEXP (varop, 1))) == 0)
                   1410:     {
                   1411:       if (!undobuf.storage)
                   1412:        undobuf.storage = (char *) oballoc (0);
                   1413:       /* If CONST is a mask for the low byte,
                   1414:         change this into a zero-extend instruction
                   1415:         from just the low byte of FOO.  */
1.1.1.2 ! root     1416:       if (constop == GET_MODE_MASK (QImode))
1.1       root     1417:        {
                   1418:          rtx temp = gen_lowpart_for_combine (QImode, XEXP (to, 0));
1.1.1.2 ! root     1419:          if (GET_CODE (temp) != CLOBBER)
1.1       root     1420:            return gen_rtx (ZERO_EXTEND, GET_MODE (x), temp);
                   1421:        }
                   1422:       return gen_rtx (AND, GET_MODE (x),
                   1423:                      XEXP (to, 0), XEXP (x, 1));
                   1424:     }
1.1.1.2 ! root     1425:   /* (and x const) may be converted to (zero_extend (subreg x 0)).  */
        !          1426:   if (constop == GET_MODE_MASK (QImode))
        !          1427:     {
        !          1428:       if (!undobuf.storage)
        !          1429:        undobuf.storage = (char *) oballoc (0);
        !          1430:       return gen_rtx (ZERO_EXTEND, GET_MODE (x),
        !          1431:                      gen_rtx (SUBREG, QImode, varop, 0));
        !          1432:     }
        !          1433:   if (constop == GET_MODE_MASK (HImode))
        !          1434:     {
        !          1435:       if (!undobuf.storage)
        !          1436:        undobuf.storage = (char *) oballoc (0);
        !          1437:       return gen_rtx (ZERO_EXTEND, GET_MODE (x),
        !          1438:                      gen_rtx (SUBREG, HImode, varop, 0));
        !          1439:     }
1.1       root     1440:   /* No simplification applies.  */
                   1441:   return 0;
                   1442: }
                   1443: 
                   1444: /* Like gen_lowpart but for use by combine.  In combine it is not possible
                   1445:    to create any new pseudoregs.  However, it is safe to create
                   1446:    invalid memory addresses, because combine will try to recognize
                   1447:    them and all they will do is make the combine attempt fail.
                   1448: 
1.1.1.2 ! root     1449:    If for some reason this cannot do its job, an rtx
        !          1450:    (clobber (const_int 0)) is returned.
        !          1451:    An insn containing that will not be recognized.  */
        !          1452: 
        !          1453: #undef gen_lowpart
1.1       root     1454: 
                   1455: static rtx
                   1456: gen_lowpart_for_combine (mode, x)
                   1457:      enum machine_mode mode;
                   1458:      register rtx x;
                   1459: {
                   1460:   if (GET_CODE (x) == SUBREG || GET_CODE (x) == REG)
                   1461:     return gen_lowpart (mode, x);
1.1.1.2 ! root     1462:   if (GET_MODE (x) == mode || x->volatil)
        !          1463:     return gen_rtx (CLOBBER, VOIDmode, const0_rtx);
1.1       root     1464:   if (GET_CODE (x) == MEM)
                   1465:     {
                   1466:       register int offset = 0;
                   1467: #ifdef WORDS_BIG_ENDIAN
                   1468:       offset = (max (GET_MODE_SIZE (GET_MODE (x)), UNITS_PER_WORD)
                   1469:                - max (GET_MODE_SIZE (mode), UNITS_PER_WORD));
                   1470: #endif
                   1471: #ifdef BYTES_BIG_ENDIAN
1.1.1.2 ! root     1472:       /* Adjust the address so that the address-after-the-data
        !          1473:         is unchanged.  */
        !          1474:       offset -= (min (UNITS_PER_WORD, GET_MODE_SIZE (mode))
        !          1475:                 - min (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (x))));
1.1       root     1476: #endif
                   1477:       return gen_rtx (MEM, mode, plus_constant (XEXP (x, 0),
                   1478:                                                offset));
                   1479:     }
                   1480:   else
1.1.1.2 ! root     1481:     return gen_rtx (CLOBBER, VOIDmode, const0_rtx);
1.1       root     1482: }
                   1483: 
                   1484: /* After substitution, if the resulting pattern looks like
1.1.1.2 ! root     1485:    (set (cc0) (and ...)) or (set (cc0) (lshiftrt ...)),
        !          1486:    this function is called to simplify the
1.1       root     1487:    pattern into a bit-field operation if possible.  */
                   1488: 
                   1489: static void
                   1490: simplify_set_cc0_and (insn)
                   1491:      rtx insn;
                   1492: {
                   1493:   register rtx value = XEXP (PATTERN (insn), 1);
                   1494:   register rtx op0 = XEXP (value, 0);
                   1495:   register rtx op1 = XEXP (value, 1);
                   1496:   int offset = 0;
                   1497:   rtx var = 0;
                   1498:   rtx bitnum = 0;
                   1499:   int temp;
                   1500:   int unit;
1.1.1.2 ! root     1501:   rtx newpat;
        !          1502: 
        !          1503:   if (GET_CODE (value) == AND)
        !          1504:     {
        !          1505:       op0 = XEXP (value, 0);
        !          1506:       op1 = XEXP (value, 1);
        !          1507:     }
        !          1508:   else if (GET_CODE (value) == LSHIFTRT)
        !          1509:     {
        !          1510:       /* If there is no AND, but there is a shift that discards
        !          1511:         all but the sign bit, we can pretend that the shift result
        !          1512:         is ANDed with 1.  Otherwise we cannot handle just a shift.  */
        !          1513:       if (GET_CODE (XEXP (value, 1)) == CONST_INT
        !          1514:          && (INTVAL (XEXP (value, 1))
        !          1515:              == GET_MODE_BITSIZE (GET_MODE (value)) - 1))
        !          1516:        {
        !          1517:          op0 = value;
        !          1518:          op1 = const1_rtx;
        !          1519:        }
        !          1520:       else
        !          1521:        return;
        !          1522:     }
        !          1523:   else
        !          1524:     abort ();
1.1       root     1525: 
                   1526:   /* Look for a constant power of 2 or a shifted 1
                   1527:      on either side of the AND.  Set VAR to the other side.
                   1528:      Set BITNUM to the shift count of the 1 (as an rtx).
                   1529:      Or, if bit number is constant, set OFFSET to the bit number.  */
                   1530: 
                   1531:   switch (GET_CODE (op0))
                   1532:     {
                   1533:     case CONST_INT:
                   1534:       temp = exact_log2 (INTVAL (op0));
                   1535:       if (temp < 0)
                   1536:        return;
                   1537:       offset = temp;
                   1538:       var = op1;
                   1539:       break;
                   1540: 
                   1541:     case ASHIFT:
                   1542:     case LSHIFT:
                   1543:       if (XEXP (op0, 0) == const1_rtx)
                   1544:        {
                   1545:          bitnum = XEXP (op0, 1);
                   1546:          var = op1;
                   1547:        }
                   1548:     }
                   1549:   if (var == 0)
                   1550:     switch (GET_CODE (op1))
                   1551:       {
                   1552:       case CONST_INT:
                   1553:        temp = exact_log2 (INTVAL (op1));
                   1554:        if (temp < 0)
                   1555:          return;
                   1556:        offset = temp;
                   1557:        var = op0;
                   1558:        break;
                   1559: 
                   1560:       case ASHIFT:
                   1561:       case LSHIFT:
                   1562:        if (XEXP (op1, 0) == const1_rtx)
                   1563:          {
                   1564:            bitnum = XEXP (op1, 1);
                   1565:            var = op0;
                   1566:          }
                   1567:       }
                   1568: 
                   1569:   /* If VAR is 0, we didn't find something recognizable.  */
                   1570:   if (var == 0)
                   1571:     return;
                   1572: 
                   1573:   if (!undobuf.storage)
                   1574:     undobuf.storage = (char *) oballoc (0);
                   1575: 
                   1576:   /* If the bit position is currently exactly 0,
                   1577:      extract a right-shift from the variable portion.  */
                   1578:   if (offset == 0
                   1579:       && (GET_CODE (var) == ASHIFTRT || GET_CODE (var) == LSHIFTRT))
                   1580:     {
                   1581:       bitnum = XEXP (var, 1);
                   1582:       var = XEXP (var, 0);
                   1583:     }
                   1584: 
1.1.1.2 ! root     1585:   if (GET_CODE (var) == SUBREG && SUBREG_WORD (var) == 0)
        !          1586:     var = SUBREG_REG (var);
        !          1587: 
        !          1588:   /* Note that BITNUM and OFFSET are always little-endian thru here
        !          1589:      even on a big-endian machine.  */
        !          1590: 
1.1       root     1591: #ifdef BITS_BIG_ENDIAN
1.1.1.2 ! root     1592:   unit = GET_MODE_BITSIZE (GET_MODE (var)) - 1;
1.1       root     1593: 
                   1594:   if (bitnum != 0)
                   1595:     bitnum = gen_rtx (MINUS, SImode,
                   1596:                      gen_rtx (CONST_INT, VOIDmode, unit), bitnum);
                   1597:   else
                   1598:     offset = unit - offset;
                   1599: #endif
                   1600: 
                   1601:   if (bitnum == 0)
                   1602:     bitnum = gen_rtx (CONST_INT, VOIDmode, offset);
                   1603: 
1.1.1.2 ! root     1604:   newpat = gen_rtx (SET, VOIDmode, cc0_rtx,
        !          1605:                    gen_rtx (ZERO_EXTRACT, VOIDmode, var, const1_rtx, bitnum));
        !          1606:   if (recog (newpat, insn) >= 0)
1.1       root     1607:     {
1.1.1.2 ! root     1608:       if (undobuf.num_undo < MAX_UNDO)
        !          1609:        {
        !          1610:          undobuf.undo[undobuf.num_undo].where = &XEXP (PATTERN (insn), 1);
        !          1611:          undobuf.undo[undobuf.num_undo].old_contents = value;
        !          1612:          XEXP (PATTERN (insn), 1) = XEXP (newpat, 1);
        !          1613:        }
        !          1614:       undobuf.num_undo++;
1.1       root     1615:     }
                   1616: }
                   1617: 
                   1618: /* Update the records of when each REG was most recently set or killed
                   1619:    for the things done by INSN.  This is the last thing done in processing
                   1620:    INSN in the combiner loop.
                   1621: 
                   1622:    We update reg_last_set, reg_last_death, and also the similar information
                   1623:    mem_last_set (which insn most recently modified memory)
                   1624:    and last_call_cuid (which insn was the most recent subroutine call).  */
                   1625: 
                   1626: static void
                   1627: record_dead_and_set_regs (insn)
                   1628:      rtx insn;
                   1629: {
                   1630:   register rtx link;
                   1631:   for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
                   1632:     {
1.1.1.2 ! root     1633:       if (REG_NOTE_KIND (link) == REG_DEAD)
1.1       root     1634:        reg_last_death[REGNO (XEXP (link, 0))] = insn;
1.1.1.2 ! root     1635:       else if (REG_NOTE_KIND (link) == REG_INC)
1.1       root     1636:        reg_last_set[REGNO (XEXP (link, 0))] = insn;
                   1637:     }
                   1638: 
                   1639:   if (GET_CODE (insn) == CALL_INSN)
                   1640:     last_call_cuid = mem_last_set = INSN_CUID (insn);
                   1641: 
                   1642:   if (GET_CODE (PATTERN (insn)) == PARALLEL)
                   1643:     {
                   1644:       register int i;
                   1645:       for (i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--)
                   1646:        {
                   1647:          register rtx elt = XVECEXP (PATTERN (insn), 0, i);
                   1648:          register enum rtx_code code = GET_CODE (elt);
                   1649:          if (code == SET || code == CLOBBER)
                   1650:            {
                   1651:              if (GET_CODE (XEXP (elt, 0)) == REG)
                   1652:                reg_last_set[REGNO (XEXP (elt, 0))] = insn;
1.1.1.2 ! root     1653:              if (GET_CODE (XEXP (elt, 0)) == SUBREG
        !          1654:                  && GET_CODE (SUBREG_REG (XEXP (elt, 0))) == REG)
        !          1655:                reg_last_set[REGNO (SUBREG_REG (XEXP (elt, 0)))] = insn;
1.1       root     1656:              else if (GET_CODE (XEXP (elt, 0)) == MEM)
                   1657:                mem_last_set = INSN_CUID (insn);
                   1658:            }
                   1659:        }
                   1660:     }
                   1661:   else if (GET_CODE (PATTERN (insn)) == SET
                   1662:           || GET_CODE (PATTERN (insn)) == CLOBBER)
                   1663:     {
                   1664:       register rtx x = XEXP (PATTERN (insn), 0);
                   1665:       if (GET_CODE (x) == REG)
                   1666:        reg_last_set[REGNO (x)] = insn;
1.1.1.2 ! root     1667:       if (GET_CODE (x) == SUBREG
        !          1668:          && GET_CODE (SUBREG_REG (x)) == REG)
        !          1669:        reg_last_set[REGNO (SUBREG_REG (x))] = insn;
1.1       root     1670:       else if (GET_CODE (x) == MEM)
                   1671:        mem_last_set = INSN_CUID (insn);
                   1672:     }
                   1673: }
                   1674: 
                   1675: /* Return nonzero if expression X refers to a REG or to memory
                   1676:    that is set in an instruction more recent than FROM_CUID.  */
                   1677: 
                   1678: static int
                   1679: use_crosses_set_p (x, from_cuid)
                   1680:      register rtx x;
                   1681:      int from_cuid;
                   1682: {
                   1683:   register char *fmt;
                   1684:   register int i;
                   1685:   register enum rtx_code code = GET_CODE (x);
                   1686: 
                   1687:   if (code == REG)
                   1688:     {
                   1689:       register int regno = REGNO (x);
                   1690:       return (reg_last_set[regno]
                   1691:              && INSN_CUID (reg_last_set[regno]) > from_cuid);
                   1692:     }
                   1693: 
                   1694:   if (code == MEM && mem_last_set > from_cuid)
                   1695:     return 1;
                   1696: 
                   1697:   fmt = GET_RTX_FORMAT (code);
                   1698: 
                   1699:   for (i = GET_RTX_LENGTH (code); i >= 0; i--)
                   1700:     {
                   1701:       if (fmt[i] == 'E')
                   1702:        {
                   1703:          register int j;
                   1704:          for (j = XVECLEN (x, i) - 1; j >= 0; j--)
                   1705:            if (use_crosses_set_p (XVECEXP (x, i, j), from_cuid))
                   1706:              return 1;
                   1707:        }
                   1708:       else if (fmt[i] == 'e'
                   1709:               && use_crosses_set_p (XEXP (x, i), from_cuid))
                   1710:        return 1;
                   1711:     }
                   1712:   return 0;
                   1713: }
                   1714: 
                   1715: /* Return nonzero if reg REGNO is marked as dying in INSN.  */
                   1716: 
                   1717: int
                   1718: regno_dead_p (regno, insn)
                   1719:      int regno;
                   1720:      rtx insn;
                   1721: {
                   1722:   register rtx link;
                   1723: 
                   1724:   for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
1.1.1.2 ! root     1725:     if ((REG_NOTE_KIND (link) == REG_DEAD
        !          1726:         || REG_NOTE_KIND (link) == REG_INC)
        !          1727:        && REGNO (XEXP (link, 0)) == regno)
1.1       root     1728:       return 1;
                   1729: 
                   1730:   return 0;
                   1731: }
                   1732: 
                   1733: /* Remove register number REGNO from the dead registers list of INSN.  */
                   1734: 
                   1735: static void
                   1736: remove_death (regno, insn)
                   1737:      int regno;
                   1738:      rtx insn;
                   1739: {
                   1740:   register rtx link, next;
                   1741:   while ((link = REG_NOTES (insn))
1.1.1.2 ! root     1742:         && REG_NOTE_KIND (link) == REG_DEAD
        !          1743:         && REGNO (XEXP (link, 0)) == regno)
1.1       root     1744:     REG_NOTES (insn) = XEXP (link, 1);
                   1745: 
                   1746:   if (link)
                   1747:     while (next = XEXP (link, 1))
                   1748:       {
1.1.1.2 ! root     1749:        if (REG_NOTE_KIND (next) == REG_DEAD
        !          1750:            && REGNO (XEXP (next, 0)) == regno)
1.1       root     1751:          XEXP (link, 1) = XEXP (next, 1);
                   1752:        else
                   1753:          link = next;
                   1754:       }
                   1755: }
                   1756: 
                   1757: /* Return nonzero if J is the first insn following I,
                   1758:    not counting labels, line numbers, etc.
                   1759:    We assume that J follows I.  */
                   1760: 
                   1761: static int
                   1762: adjacent_insns_p (i, j)
                   1763:      rtx i, j;
                   1764: {
                   1765:   register rtx insn;
                   1766:   for (insn = NEXT_INSN (i); insn != j; insn = NEXT_INSN (insn))
                   1767:     if (GET_CODE (insn) == INSN
                   1768:        || GET_CODE (insn) == CALL_INSN
                   1769:        || GET_CODE (insn) == JUMP_INSN)
                   1770:       return 0;
                   1771:   return 1;
                   1772: }
                   1773: 
1.1.1.2 ! root     1774: /* Concatenate the list of logical links of OINSN
1.1       root     1775:    into INSN's list of logical links.
1.1.1.2 ! root     1776:    Modifies OINSN destructively.
        !          1777: 
        !          1778:    If ALL_LINKS is nonzero, move all the links that OINSN has.
        !          1779:    Otherwise, move only those that point to insns that set regs
        !          1780:    that die in the insn OINSN.
        !          1781:    Other links are clobbered so that they are no longer effective.  */
1.1       root     1782: 
                   1783: static void
1.1.1.2 ! root     1784: add_links (insn, oinsn, all_links)
        !          1785:      rtx insn, oinsn;
        !          1786:      int all_links;
1.1       root     1787: {
1.1.1.2 ! root     1788:   register rtx links = LOG_LINKS (oinsn);
        !          1789:   if (! all_links)
        !          1790:     {
        !          1791:       rtx tail;
        !          1792:       for (tail = links; tail; tail = XEXP (tail, 1))
        !          1793:        {
        !          1794:          rtx target = XEXP (tail, 0);
        !          1795:          if (GET_CODE (target) != INSN
        !          1796:              || GET_CODE (PATTERN (target)) != SET
        !          1797:              || GET_CODE (SET_DEST (PATTERN (target))) != REG
        !          1798:              || ! dead_or_set_p (oinsn, SET_DEST (PATTERN (target))))
        !          1799:            /* OINSN is going to become a NOTE 
        !          1800:               so a link pointing there will have no effect.  */
        !          1801:            XEXP (tail, 0) = oinsn;
        !          1802:        }
        !          1803:     }
1.1       root     1804:   if (LOG_LINKS (insn) == 0)
                   1805:     LOG_LINKS (insn) = links;
                   1806:   else
                   1807:     {
                   1808:       register rtx next, prev = LOG_LINKS (insn);
                   1809:       while (next = XEXP (prev, 1))
                   1810:        prev = next;
                   1811:       XEXP (prev, 1) = links;
                   1812:     }
                   1813: }
                   1814: 
                   1815: /* Concatenate the any elements of the list of reg-notes INCS
                   1816:    which are of type REG_INC
                   1817:    into INSN's list of reg-notes.  */
                   1818: 
                   1819: static void
                   1820: add_incs (insn, incs)
                   1821:      rtx insn, incs;
                   1822: {
                   1823:   register rtx tail;
                   1824: 
                   1825:   for (tail = incs; tail; tail = XEXP (tail, 1))
1.1.1.2 ! root     1826:     if (REG_NOTE_KIND (tail) == REG_INC)
1.1       root     1827:       REG_NOTES (insn)
                   1828:        = gen_rtx (EXPR_LIST, REG_INC, XEXP (tail, 0), REG_NOTES (insn));
                   1829: }
                   1830: 
                   1831: /* For each register (hardware or pseudo) used within expression X,
                   1832:    if its death is in an instruction with cuid
                   1833:    between FROM_CUID (inclusive) and TO_INSN (exclusive),
                   1834:    mark it as dead in TO_INSN instead.
                   1835: 
                   1836:    This is done when X is being merged by combination into TO_INSN.  */
                   1837: 
                   1838: static void
                   1839: move_deaths (x, from_cuid, to_insn)
                   1840:      rtx x;
                   1841:      int from_cuid;
                   1842:      rtx to_insn;
                   1843: {
                   1844:   register char *fmt;
                   1845:   register int len, i;
                   1846:   register enum rtx_code code = GET_CODE (x);
                   1847: 
                   1848:   if (code == REG)
                   1849:     {
                   1850:       register rtx where_dead = reg_last_death[REGNO (x)];
                   1851: 
                   1852:       if (where_dead && INSN_CUID (where_dead) >= from_cuid
                   1853:          && INSN_CUID (where_dead) < INSN_CUID (to_insn))
                   1854:        {
                   1855:          remove_death (REGNO (x), reg_last_death[REGNO (x)]);
                   1856:          if (! dead_or_set_p (to_insn, x))
                   1857:            REG_NOTES (to_insn)
                   1858:              = gen_rtx (EXPR_LIST, REG_DEAD, x, REG_NOTES (to_insn));
                   1859:        }
                   1860:       return;
                   1861:     }
                   1862: 
                   1863:   len = GET_RTX_LENGTH (code);
                   1864:   fmt = GET_RTX_FORMAT (code);
                   1865: 
                   1866:   for (i = 0; i < len; i++)
                   1867:     {
                   1868:       if (fmt[i] == 'E')
                   1869:        {
                   1870:          register int j;
                   1871:          for (j = XVECLEN (x, i) - 1; j >= 0; j--)
                   1872:            move_deaths (XVECEXP (x, i, j), from_cuid, to_insn);
                   1873:        }
                   1874:       else if (fmt[i] == 'e')
                   1875:        move_deaths (XEXP (x, i), from_cuid, to_insn);
                   1876:     }
                   1877: }
                   1878: 
1.1.1.2 ! root     1879: void
1.1       root     1880: dump_combine_stats (file)
                   1881:      char *file;
                   1882: {
                   1883:   fprintf
                   1884:     (file,
                   1885:      ";; Combiner statistics: %d attempts, %d substitutions (%d requiring new space),\n;; %d successes.\n\n"
                   1886:      , combine_attempts, combine_merges, combine_extras, combine_successes);
                   1887: }
                   1888: 
1.1.1.2 ! root     1889: void
1.1       root     1890: dump_combine_total_stats (file)
                   1891:      char *file;
                   1892: {
                   1893:   fprintf
                   1894:     (file,
                   1895:      "\n;; Combiner totals: %d attempts, %d substitutions (%d requiring new space),\n;; %d successes.\n",
                   1896:      total_attempts, total_merges, total_extras, total_successes);
                   1897: }

unix.superglobalmegacorp.com

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