Annotation of gcc/loop.c, revision 1.1.1.4

1.1       root        1: /* Move constant computations out of loops.
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 is the loop optimization pass of the compiler.
                     23:    It finds invariant computations within loops and moves them
                     24:    to the beginning of the loop.
                     25: 
                     26:    It also finds cases where
                     27:    a register is set within the loop by zero-extending a narrower value
                     28:    and changes these to zero the entire register once before the loop
                     29:    and merely copy the low part within the loop.
                     30: 
                     31:    Most of the complexity is in heuristics to decide when it is worth
                     32:    while to do these things.  */
                     33: 
                     34: /* ??? verify_loop would run faster if we made one table
                     35:    of the minimum and maximum luids from which each label is reached.
                     36:    Also, it would be faster if loop_store_addrs were a hash table.  */
                     37: 
                     38: #include "config.h"
                     39: #include "rtl.h"
                     40: #include "insn-config.h"
                     41: #include "regs.h"
                     42: #include "recog.h"
1.1.1.2   root       43: #include <stdio.h>
1.1       root       44: 
                     45: /* Vector mapping INSN_UIDs to luids.
                     46:    The luids are like uids but increase monononically always.
                     47:    We use them to see whether a jump comes from outside a given loop.  */
                     48: 
                     49: static short *uid_luid;
                     50: 
                     51: /* Get the luid of an insn.  */
                     52: 
                     53: #define INSN_LUID(INSN) (uid_luid[INSN_UID (INSN)])
                     54: 
                     55: /* 1 + largest uid of any insn.  */
                     56: 
                     57: static int max_uid;
                     58: 
                     59: /* 1 + luid of last insn.  */
                     60: 
                     61: static int max_luid;
                     62: 
                     63: /* Nonzero if somewhere in the current loop
                     64:    there is either a subroutine call,
                     65:    or a store into a memory address that is not fixed,
                     66:    or a store in a BLKmode memory operand,
                     67:    or too many different fixed addresses stored in
                     68:    to record them all in `loop_store_addrs'.
                     69: 
                     70:    In any of these cases, no memory location can be regarded
                     71:    as invariant.  */
                     72: 
                     73: static int unknown_address_altered;
                     74: 
                     75: /* Nonzero if somewhere in the current loop there is a store
                     76:    into a memory address that is not fixed but is known to be
                     77:    part of an aggregate.
                     78: 
                     79:    In this case, no memory reference in an aggregate may be
                     80:    considered invariant.  */
                     81: 
                     82: static int unknown_aggregate_altered;
                     83: 
                     84: /* Nonzero if somewhere in the current loop there is a store
                     85:    into a memory address other than a fixed address not in an aggregate.
                     86: 
                     87:    In this case, no memory reference in an aggregate at a varying address
                     88:    may be considered invariant.  */
                     89: 
                     90: static int fixed_aggregate_altered;
                     91: 
                     92: /* Nonzero if there is a subroutine call in the current loop.
                     93:    (unknown_address_altered is also nonzero in this case.)  */
                     94: 
                     95: static int loop_has_call;
                     96: 
                     97: /* Array of fixed memory addresses that are stored in this loop.
                     98:    If there are too many to fit here,
                     99:    we just turn on unknown_address_altered.  */
                    100: 
                    101: #define NUM_STORES 10
                    102: static rtx loop_store_addrs[NUM_STORES];
                    103: static int loop_store_widths[NUM_STORES];
                    104: 
                    105: /* Index of first available slot in above array.  */
                    106: static int loop_store_addrs_idx;
                    107: 
                    108: /* During the analysis of a loop, a chain of `struct movable's
                    109:    is made to record all the movable insns found.
                    110:    Then the entire chain can be scanned to decide which to move.  */
                    111: 
                    112: struct movable
                    113: {
                    114:   rtx insn;                    /* A movable insn */
1.1.1.2   root      115:   int consec;                  /* Number of consecutive following insns 
                    116:                                   that must be moved with this one.  */
1.1       root      117:   int regno;                   /* The register it sets */
                    118:   short lifetime;              /* lifetime of that register;
                    119:                                   may be adjusted when matching movables
                    120:                                   that load the same value are found.  */
1.1.1.2   root      121:   short times_used;            /* Number of times the register is used,
                    122:                                   plus uses of related insns that could
                    123:                                   be moved if this one is.  */
1.1       root      124:   unsigned int cond : 1;       /* 1 if only conditionally movable */
                    125:   unsigned int force : 1;      /* 1 means MUST move this insn */
                    126:   unsigned int global : 1;     /* 1 means reg is live outside this loop */
1.1.1.2   root      127:   unsigned int done : 1;       /* 1 inhibits further processing of this */
                    128:   unsigned int partial : 1;    /* Moving this doesn't make it invariant.  */
1.1       root      129:   struct movable *match;       /* First entry for same value */
                    130:   struct movable *forces;      /* An insn that must be moved if this is */
                    131:   struct movable *next;
                    132: };
                    133: 
1.1.1.2   root      134: static FILE *loop_dump_stream;
                    135: 
1.1       root      136: static rtx verify_loop ();
                    137: static int invariant_p ();
1.1.1.4 ! root      138: static int consec_sets_invariant_p ();
1.1       root      139: static int can_jump_into_range_p ();
                    140: static void count_loop_regs_set ();
                    141: static void note_addr_stored ();
                    142: static int loop_reg_used_before_p ();
                    143: static void constant_high_bytes ();
                    144: static void scan_loop ();
                    145: static rtx replace_regs ();
1.1.1.2   root      146: static void move_movables ();
                    147: static int may_trap_p ();
1.1       root      148: 
                    149: /* Entry point of this file.  Perform loop optimization
                    150:    on the current function.  F is the first insn of the function
                    151:    and NREGS is the number of register numbers used.  */
                    152: 
1.1.1.2   root      153: void
                    154: loop_optimize (f, nregs, dumpfile)
1.1       root      155:      /* f is the first instruction of a chain of insns for one function */
                    156:      rtx f;
                    157:      /* nregs is the total number of registers used in it */
                    158:      int nregs;
1.1.1.2   root      159:      FILE *dumpfile;
1.1       root      160: {
                    161:   register rtx insn;
                    162:   register int i;
                    163:   rtx end;
                    164:   rtx last_insn;
                    165: 
1.1.1.2   root      166:   loop_dump_stream = dumpfile;
                    167: 
1.1       root      168:   init_recog ();
                    169: 
                    170:   /* First find the last real insn, and count the number of insns,
                    171:      and assign insns their suids.  */
                    172: 
                    173:   for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
                    174:     if (INSN_UID (insn) > i)
                    175:       i = INSN_UID (insn);
                    176: 
                    177:   max_uid = i + 1;
                    178:   uid_luid = (short *) alloca ((i + 1) * sizeof (short));
                    179:   bzero (uid_luid, (i + 1) * sizeof (short));
                    180: 
                    181:   /* Compute the mapping from uids to luids.
                    182:      LUIDs are numbers assigned to insns, like uids,
                    183:      except that luids increase monotonically through the code.  */
                    184: 
                    185:   for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
                    186:     {
                    187:       last_insn = insn;
                    188:       INSN_LUID (insn) = ++i;
                    189:     }
                    190: 
                    191:   max_luid = i;
                    192: 
                    193:   /* Don't leave gaps in uid_luid for insns that have been
                    194:      deleted.  It is possible that the first or last insn
                    195:      using some register has been deleted by cross-jumping.
                    196:      Make sure that uid_luid for that former insn's uid
                    197:      points to the general area where that insn used to be.  */
                    198:   for (i = 0; i < max_uid; i++)
1.1.1.2   root      199:     {
                    200:       uid_luid[0] = uid_luid[i];
                    201:       if (uid_luid[0] != 0)
                    202:        break;
                    203:     }
                    204:   for (i = 0; i < max_uid; i++)
1.1       root      205:     if (uid_luid[i] == 0)
                    206:       uid_luid[i] = uid_luid[i - 1];
                    207: 
                    208:   /* Find and process each loop.
                    209:      We scan from the end, and process each loop when its start is seen,
                    210:      so we process innermost loops first.  */
                    211: 
                    212:   for (insn = last_insn; insn; insn = PREV_INSN (insn))
                    213:     if (GET_CODE (insn) == NOTE
1.1.1.4 ! root      214:        && NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG)
        !           215:       {
1.1       root      216:        /* Make sure it really is a loop -- no jumps in from outside.  */
1.1.1.4 ! root      217:        end = verify_loop (f, insn);
        !           218:        if (end != 0)
        !           219:          /* If so, optimize this loop.  */
        !           220:          scan_loop (insn, end, nregs);
        !           221:        else if (loop_dump_stream)
        !           222:          fprintf (loop_dump_stream,
        !           223:                   "\nLoop at %d ignored due to multiple entry points.\n",
        !           224:                   INSN_UID (insn));
        !           225:       }
1.1       root      226: }
                    227: 
                    228: /* Optimize one loop whose start is LOOP_START and end is END.
                    229:    LOOP_START is the NOTE_INSN_LOOP_BEG and END is the matching
                    230:    NOTE_INSN_LOOP_END.  */
                    231: 
                    232: static void
                    233: scan_loop (loop_start, end, nregs)
                    234:      rtx loop_start, end;
                    235:      int nregs;
                    236: {
                    237:   register int i;
                    238:   register rtx p = NEXT_INSN (loop_start);
                    239:   /* 1 if we are scanning insns that could be executed zero times.  */
                    240:   int maybe_never = 0;
1.1.1.3   root      241:   /* 1 if we are scanning insns that might never be executed
                    242:      due to a subroutine call which might exit before they are reached.  */
                    243:   int call_passed = 0;
1.1       root      244:   /* For a rotated loop that is entered near the bottom,
                    245:      this is the label at the top.  Otherwise it is zero.  */
                    246:   rtx loop_top = 0;
1.1.1.2   root      247:   /* This is the insn (whatever kind) before the NOTE that starts the loop.
                    248:      Any insns moved out of the loop will follow it.  */
                    249:   rtx before_start = PREV_INSN (loop_start);
1.1       root      250:   /* Jump insn that enters the loop, or 0 if control drops in.  */
                    251:   rtx loop_entry_jump = 0;
                    252:   /* Place in the loop where control enters.  */
                    253:   rtx scan_start;
                    254:   /* Number of insns in the loop.  */
                    255:   int insn_count;
                    256:   int tem;
                    257:   /* Indexed by register number, contains the number of times the reg
                    258:      is set during the loop being scanned, or -1 if the insns that set it
                    259:      have all been scanned as candidates for being moved out of the loop.
                    260:      0 indicates an invariant register; -1 a conditionally invariant one.  */
                    261:   short *n_times_set;
                    262:   /* Indexed by register number, contains the number of times the reg
1.1.1.3   root      263:      was used during the loop being scanned, not counting changes due
1.1       root      264:      to moving these insns out of the loop.  */
                    265:   short *n_times_used;
                    266:   /* Indexed by register number, contains 1 for a register whose
                    267:      assignments may not be moved out of the loop.  */
                    268:   char *may_not_move;
                    269:   /* Chain describing insns movable in current loop.  */
                    270:   struct movable *movables = 0;
                    271:   /* Last element in `movables' -- so we can add elements at the end.  */
                    272:   struct movable *last_movable = 0;
                    273:   /* Ratio of extra register life span we can justify
                    274:      for saving an instruction.  More if loop doesn't call subroutines
                    275:      since in that case saving an insn makes more difference
                    276:      and more registers are available.  */
1.1.1.2   root      277:   int threshold = loop_has_call ? 17 : 34;
1.1       root      278: 
                    279:   n_times_set = (short *) alloca (nregs * sizeof (short));
                    280:   n_times_used = (short *) alloca (nregs * sizeof (short));
                    281:   may_not_move = (char *) alloca (nregs);
                    282: 
                    283:   /* Determine whether this loop starts with a jump down
                    284:      to a test at the end.  */
                    285:   while (p != end
                    286:         && GET_CODE (p) != CODE_LABEL && GET_CODE (p) != JUMP_INSN)
                    287:     p = NEXT_INSN (p);
                    288: 
                    289:   /* "Loop" contains neither jumps nor labels;
                    290:      it must have been a dummy.  Think no more about it.  */
                    291:   if (p == end)
                    292:     return;
                    293: 
1.1.1.2   root      294:   scan_start = p;
                    295: 
1.1       root      296:   /* If loop has a jump before the first label,
                    297:      the true entry is the target of that jump.
                    298:      Start scan from there.
                    299:      But record in LOOP_TOP the place where the end-test jumps
                    300:      back to so we can scan that after the end of the loop.  */
                    301:   if (GET_CODE (p) == JUMP_INSN)
                    302:     {
                    303:       loop_entry_jump = p;
                    304:       loop_top = NEXT_INSN (p);
                    305:       /* Loop entry will never be a conditional jump.
                    306:         If we see one, this must not be a real loop.  */
                    307:       if (GET_CODE (loop_top) != BARRIER)
                    308:        return;
                    309:       p = JUMP_LABEL (p);
                    310:       /* Check to see whether the jump actually
                    311:         jumps out of the loop (meaning it's no loop).
                    312:         This case can happen for things like
                    313:         do {..} while (0).  */
1.1.1.2   root      314:       if (p == 0
                    315:          || INSN_LUID (p) < INSN_LUID (loop_start)
1.1       root      316:          || INSN_LUID (p) >= INSN_LUID (end))
1.1.1.2   root      317:        {
                    318:          if (loop_dump_stream)
                    319:            fprintf (loop_dump_stream, "\nLoop from %d to %d is phony.\n\n",
                    320:                     INSN_UID (loop_start), INSN_UID (end));
                    321:          return;
                    322:        }
                    323: 
                    324:       /* Find the first label after the entry-jump.  */
                    325:       while (GET_CODE (loop_top) != CODE_LABEL)
                    326:        {
                    327:          loop_top = NEXT_INSN (loop_top);
                    328:          if (loop_top == 0)
                    329:            abort ();
                    330:        }
                    331: 
                    332:       /* Maybe rearrange the loop to drop straight in
                    333:         with a new test to jump around it entirely.
                    334:         (The latter is considered outside the loop.)
                    335:         If this is done, we no longer enter with a jump.  */
                    336:       if (loop_skip_over (loop_start, end, loop_entry_jump))
                    337:        loop_top = 0;
                    338:       else
                    339:        /* We really do enter with a jump;
                    340:           scan the loop from the place where the jump jumps to.  */
                    341:        scan_start = p;
1.1       root      342:     }
                    343: 
                    344:   /* Count number of times each reg is set during this loop.
                    345:      Set MAY_NOT_MOVE[I] if it is not safe to move out
                    346:      the setting of register I.  */
                    347: 
                    348:   bzero (n_times_set, nregs * sizeof (short));
                    349:   bzero (may_not_move, nregs);
1.1.1.2   root      350:   count_loop_regs_set (loop_top ? loop_top : loop_start, end,
                    351:                       n_times_set, may_not_move, 
1.1       root      352:                       &insn_count, nregs);
                    353:   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
                    354:     may_not_move[i] = 1, n_times_set[i] = 1;
                    355:   bcopy (n_times_set, n_times_used, nregs * sizeof (short));
                    356: 
1.1.1.2   root      357:   if (loop_dump_stream)
                    358:     fprintf (loop_dump_stream, "\nLoop from %d to %d: %d real insns\n\n",
                    359:             INSN_UID (loop_start), INSN_UID (end), insn_count);
                    360: 
1.1       root      361:   /* Scan through the loop finding insns that are safe to move.
                    362:      In each such insn, store QImode as the mode, to mark it.
                    363:      Then set n_times_set to -1 for the reg being set, so that
                    364:      this reg will be considered invariant for subsequent insns.
                    365:      We consider whether subsequent insns use the reg
                    366:      in deciding whether it is worth actually moving.
                    367: 
                    368:      MAYBE_NEVER is nonzero if we have passed a conditional jump insn
                    369:      and therefore it is possible that the insns we are scanning
                    370:      would never be executed.  At such times, we must make sure
                    371:      that it is safe to execute the insn once instead of zero times.
                    372:      When MAYBE_NEVER is 0, all insns will be executed at least once
                    373:      so that is not a problem.  */
                    374: 
1.1.1.2   root      375:   p = scan_start;
1.1       root      376:   while (1)
                    377:     {
                    378:       p = NEXT_INSN (p);
                    379:       /* At end of a straight-in loop, we are done.
                    380:         At end of a loop entered at the bottom, scan the top.  */
                    381:       if (p == scan_start)
                    382:        break;
                    383:       if (p == end)
                    384:        {
                    385:          if (loop_top != 0)
                    386:            p = NEXT_INSN (loop_top);
                    387:          else
                    388:            break;
                    389:          if (p == scan_start)
                    390:            break;
                    391:        }
                    392:       if (GET_CODE (p) == INSN
                    393:          && GET_CODE (PATTERN (p)) == SET
                    394:          && GET_CODE (SET_DEST (PATTERN (p))) == REG
                    395:          && ! may_not_move[REGNO (SET_DEST (PATTERN (p)))])
                    396:        {
1.1.1.4 ! root      397:          int tem1 = 0;
1.1       root      398:          /* If this register is used or set outside the loop,
                    399:             then we can move it only if we know this insn is
                    400:             executed exactly once per iteration,
                    401:             and we can check all the insns executed before it
                    402:             to make sure none of them used the value that
                    403:             was lying around at entry to the loop.  */
                    404:          if ((uid_luid[regno_last_uid[REGNO (SET_DEST (PATTERN (p)))]] > INSN_LUID (end)
                    405:               || uid_luid[regno_first_uid[REGNO (SET_DEST (PATTERN (p)))]] < INSN_LUID (loop_start))
                    406:              && (maybe_never
                    407:                  || loop_reg_used_before_p (p, loop_start, scan_start, end)))
                    408:            ;
                    409:          else if ((tem = invariant_p (SET_SRC (PATTERN (p)), n_times_set))
                    410:                   && (n_times_set[REGNO (SET_DEST (PATTERN (p)))] == 1
1.1.1.4 ! root      411:                       || (tem1
        !           412:                           = consec_sets_invariant_p (SET_DEST (PATTERN (p)),
        !           413:                                                      n_times_set[REGNO (SET_DEST (PATTERN (p)))],
        !           414:                                                      p, n_times_set)))
1.1.1.3   root      415:                   /* If the insn can cause a trap (such as divide by zero),
                    416:                      can't move it unless it's guaranteed to be executed
                    417:                      once loop is entered.  Even a function call might
                    418:                      prevent the trap insn from being reached
                    419:                      (since it might exit!)  */
                    420:                   && ! ((maybe_never || call_passed)
                    421:                         && may_trap_p (SET_SRC (PATTERN (p)))))
1.1       root      422:            {
                    423:              register struct movable *m;
                    424:              register int regno = REGNO (SET_DEST (PATTERN (p)));
1.1.1.2   root      425:              int count;
1.1       root      426:              m = (struct movable *) alloca (sizeof (struct movable));
                    427:              m->next = 0;
                    428:              m->insn = p;
                    429:              m->force = 0;
1.1.1.2   root      430:              m->consec = n_times_set[REGNO (SET_DEST (PATTERN (p)))] - 1;
                    431:              m->done = 0;
1.1       root      432:              m->forces = 0;
1.1.1.2   root      433:              m->partial = 0;
1.1       root      434:              m->regno = regno;
1.1.1.4 ! root      435:              /* Set M->cond if either invariant_p or consec_sets_invariant_p
        !           436:                 returned 2 (only conditionally invariant).  */
        !           437:              m->cond = ((tem | tem1) > 1);
1.1       root      438:              m->global = (uid_luid[regno_last_uid[regno]] > INSN_LUID (end)
                    439:                           || uid_luid[regno_first_uid[regno]] < INSN_LUID (loop_start));
                    440:              m->match = 0;
                    441:              m->lifetime = (uid_luid[regno_last_uid[regno]]
                    442:                             - uid_luid[regno_first_uid[regno]]);
1.1.1.2   root      443:              m->times_used = n_times_used[regno];
1.1       root      444:              n_times_set[regno] = -1;
                    445:              /* Add M to the end of the chain MOVABLES.  */
                    446:              if (movables == 0)
                    447:                movables = m;
                    448:              else
                    449:                last_movable->next = m;
                    450:              last_movable = m;
1.1.1.2   root      451:              /* Skip the consecutive insns, if there are any.  */
                    452:              for (count = m->consec - 1; count >= 0; count--)
                    453:                {
                    454:                  do p = NEXT_INSN (p);
                    455:                  while (GET_CODE (p) == NOTE);
                    456:                }
1.1       root      457:            }
1.1.1.2   root      458:          /* If this register is always set within a STRICT_LOW_PART
                    459:             or set to zero, then its high bytes are constant.
1.1       root      460:             So clear them outside the loop and within the loop
                    461:             just load the low bytes.
                    462:             We must check that the machine has an instruction to do so.
                    463:             Also, if the value loaded into the register
                    464:             depends on the same register, this cannot be done.  */
1.1.1.2   root      465:          else if (SET_SRC (PATTERN (p)) == const0_rtx
                    466:                   && GET_CODE (NEXT_INSN (p)) == INSN
                    467:                   && GET_CODE (PATTERN (NEXT_INSN (p))) == SET
                    468:                   && (GET_CODE (SET_DEST (PATTERN (NEXT_INSN (p))))
                    469:                       == STRICT_LOW_PART)
                    470:                   && (GET_CODE (XEXP (SET_DEST (PATTERN (NEXT_INSN (p))), 0))
                    471:                       == SUBREG)
                    472:                   && (SUBREG_REG (XEXP (SET_DEST (PATTERN (NEXT_INSN (p))), 0))
                    473:                       == SET_DEST (PATTERN (p)))
1.1       root      474:                   && !reg_mentioned_p (SET_DEST (PATTERN (p)),
1.1.1.2   root      475:                                        SET_SRC (PATTERN (NEXT_INSN (p)))))
1.1       root      476:            {
                    477:              register int regno = REGNO (SET_DEST (PATTERN (p)));
1.1.1.2   root      478:              if (n_times_set[regno] == 2)
                    479:                {
                    480:                  register struct movable *m;
                    481:                  int count;
                    482:                  m = (struct movable *) alloca (sizeof (struct movable));
                    483:                  m->next = 0;
                    484:                  m->insn = p;
                    485:                  m->force = 0;
                    486:                  m->consec = 0;
                    487:                  m->done = 0;
                    488:                  m->forces = 0;
                    489:                  m->partial = 1;
                    490:                  m->regno = regno;
                    491:                  m->cond = 0;
                    492:                  /* Say "global" so this register is not combined
                    493:                     with any other.  In fact, it is sometimes possible
                    494:                     to combine two of these registers, but the criteria
                    495:                     are special and have not been programmed in.  */
                    496:                  m->global = 1;
                    497:                  m->match = 0;
                    498:                  m->lifetime = (uid_luid[regno_last_uid[regno]]
                    499:                                 - uid_luid[regno_first_uid[regno]]);
                    500:                  m->times_used = n_times_used[regno];
                    501:                  n_times_set[regno] = -1;
                    502:                  /* Add M to the end of the chain MOVABLES.  */
                    503:                  if (movables == 0)
                    504:                    movables = m;
                    505:                  else
                    506:                    last_movable->next = m;
                    507:                  last_movable = m;
                    508:                  /* Skip the consecutive insns, if there are any.  */
                    509:                  for (count = m->consec - 1; count >= 0; count--)
                    510:                    {
                    511:                      do p = NEXT_INSN (p);
                    512:                      while (GET_CODE (p) == NOTE);
                    513:                    }
                    514:                }
1.1       root      515:            }
                    516:        }
1.1.1.3   root      517:       /* Past a call insn, we get to insns which might not be executed
                    518:         because the call might exit.  This matters for insns that trap.  */
                    519:       else if (GET_CODE (p) == CALL_INSN)
                    520:        call_passed = 1;
1.1       root      521:       /* Past a label or a jump, we get to insns for which we
                    522:         can't count on whether or how many times they will be
                    523:         executed during each iteration.  Therefore, we can
                    524:         only move out sets of trivial variables
                    525:         (those not used after the loop).  */
                    526:       else if (GET_CODE (p) == CODE_LABEL || GET_CODE (p) == JUMP_INSN)
                    527:        maybe_never = 1;
                    528:     }
                    529: 
                    530:   /* For each movable insn, see if the reg that it loads
1.1.1.2   root      531:      leads when it dies right into another conditionally movable insn.
                    532:      If so, record that the second insn "forces" the first one,
                    533:      since the second can be moved only if the first is.  */
                    534: 
1.1       root      535:   {
                    536:     register struct movable *m, *m1;
                    537:     for (m1 = movables; m1; m1 = m1->next)
                    538:       {
                    539:        int regno = m1->regno;
                    540:        for (m = m1->next; m; m = m->next)
                    541:          if (INSN_UID (m->insn) == regno_last_uid[regno])
                    542:            break;
                    543:        if (m != 0 && SET_SRC (PATTERN (m->insn)) == SET_DEST (PATTERN (m1->insn)))
                    544:          m = 0;
1.1.1.2   root      545: 
                    546:        /* Increase the priority of the moving the first insn
                    547:           since it permits the second to be moved as well.  */
                    548:        if (m != 0)
                    549:          {
                    550:            m->forces = m1;
                    551:            m1->lifetime += m->lifetime;
                    552:            m1->times_used += m1->times_used;
                    553:          }
1.1       root      554:       }
                    555:   }
                    556: 
                    557:   /* See if there are multiple movable insns that load the same value.
                    558:      If there are, make all but the first point at the first one
                    559:      through the `match' field, and add the priorities of them
                    560:      all together as the priority of the first.  */
1.1.1.2   root      561: 
1.1       root      562:   {
                    563:     register struct movable *m;
                    564:     char *matched_regs = (char *) alloca (nregs);
                    565: 
1.1.1.2   root      566:     /* Regs that are used more than once are not allowed to match
                    567:        or be matched.  I'm no longer sure why not.  */
1.1       root      568: 
                    569:     for (m = movables; m; m = m->next)
1.1.1.2   root      570:       if (m->match == 0 && n_times_used[m->regno] == 1)
1.1       root      571:        {
                    572:          register struct movable *m1;
1.1.1.2   root      573:          int regno = m->regno;
1.1       root      574: 
                    575:          bzero (matched_regs, nregs);
1.1.1.2   root      576:          matched_regs[regno] = 1;
1.1       root      577: 
                    578:          for (m1 = m->next; m1; m1 = m1->next)
1.1.1.2   root      579:            if (m1->match == 0 && n_times_used[m1->regno] == 1
                    580:                /* A reg used outside the loop mustn't be eliminated.  */
                    581:                && !m1->global
                    582:                && (matched_regs[m1->regno]
                    583:                    ||
                    584:                    (
                    585:                     /* Can't combine regs with different modes
                    586:                        even if loaded from the same constant.  */
                    587:                     (GET_MODE (SET_DEST (PATTERN (m->insn)))
                    588:                      == GET_MODE (SET_DEST (PATTERN (m1->insn))))
                    589:                     /* See if the source of M1 says it matches M.  */
                    590:                     && ((GET_CODE (SET_SRC (PATTERN (m1->insn))) == REG
                    591:                          && matched_regs[REGNO (SET_SRC (PATTERN (m1->insn)))])
                    592:                         || rtx_equal_p (SET_SRC (PATTERN (m->insn)),
                    593:                                         SET_SRC (PATTERN (m1->insn)))
                    594:                         || (REG_NOTES (m->insn) && REG_NOTES (m1->insn)
                    595:                             && REG_NOTE_KIND (REG_NOTES (m->insn)) == REG_EQUIV
                    596:                             && REG_NOTE_KIND (REG_NOTES (m1->insn)) == REG_EQUIV
                    597:                             && rtx_equal_p (XEXP (REG_NOTES (m->insn), 0),
                    598:                                             XEXP (REG_NOTES (m1->insn), 0)))))))
                    599:              {
                    600:                m->lifetime += m1->lifetime;
                    601:                m->times_used += m1->times_used;
                    602:                m1->match = m;
                    603:                matched_regs[m1->regno] = 1;
                    604:              }
                    605:        }
                    606:   }
                    607:        
                    608:   /* Now consider each movable insn to decide whether it is worth moving.  */
                    609: 
                    610:   move_movables (movables, n_times_set, n_times_used, threshold,
                    611:                 insn_count, loop_start, end, nregs);
                    612: }
                    613: 
                    614: /* Scan MOVABLES, and move the insns that deserve to be moved.
                    615:    If two matching movables are combined, replace one reg with the
                    616:    other throughout.  */
                    617: 
                    618: static void
                    619: move_movables (movables, n_times_set, n_times_used, threshold,
                    620:               insn_count, loop_start, end, nregs)
                    621:      struct movable *movables;
                    622:      short *n_times_set;
                    623:      short *n_times_used;
                    624:      int threshold;
                    625:      int insn_count;
                    626:      rtx loop_start;
                    627:      rtx end;
                    628:      int nregs;
                    629: {
                    630:   rtx new_start = 0;
                    631:   register struct movable *m;
                    632:   register rtx p;
                    633:   /* Map of pseudo-register replacements to handle combining
                    634:      when we move several insns that load the same value
                    635:      into different pseudo-registers.  */
                    636:   rtx *reg_map = (rtx *) alloca (nregs * sizeof (rtx));
                    637:   char *already_moved = (char *) alloca (nregs);
                    638: 
                    639:   bzero (already_moved, nregs);
                    640:   bzero (reg_map, nregs * sizeof (rtx));
                    641: 
                    642:   for (m = movables; m; m = m->next)
                    643:     {
                    644:       /* Describe this movable insn.  */
                    645: 
                    646:       if (loop_dump_stream)
                    647:        {
                    648:          fprintf (loop_dump_stream, "Insn %d: regno %d (life %d), ",
                    649:                   INSN_UID (m->insn), m->regno, m->lifetime);
                    650:          if (m->consec > 0)
                    651:            fprintf (loop_dump_stream, "consec %d, ", m->consec);
                    652:          if (m->cond)
                    653:            fprintf (loop_dump_stream, "cond ");
                    654:          if (m->force)
                    655:            fprintf (loop_dump_stream, "force ");
                    656:          if (m->global)
                    657:            fprintf (loop_dump_stream, "global ");
                    658:          if (m->done)
                    659:            fprintf (loop_dump_stream, "done ");
                    660:          if (m->match)
                    661:            fprintf (loop_dump_stream, "matches %d ",
                    662:                     INSN_UID (m->match->insn));
                    663:          if (m->forces)
                    664:            fprintf (loop_dump_stream, "forces %d ",
                    665:                     INSN_UID (m->forces->insn));
                    666:        }
                    667: 
                    668:       /* Ignore the insn if it's already done (it matched something else).
                    669:         Otherwise, see if it is now safe to move.  */
                    670: 
                    671:       if (!m->done
                    672:          && (! m->cond
1.1.1.4 ! root      673:              || (1 == invariant_p (SET_SRC (PATTERN (m->insn)), n_times_set)
        !           674:                  && (m->consec == 0
        !           675:                      || 1 == consec_sets_invariant_p (SET_DEST (PATTERN (m->insn)),
        !           676:                                                       m->consec + 1,
        !           677:                                                       m->insn, n_times_set))))
1.1.1.2   root      678:          && (! m->forces || m->forces->done))
                    679:        {
                    680:          register int regno;
                    681:          register rtx p;
                    682:          int times_used = m->times_used + m->consec;
                    683: 
                    684:          /* We have an insn that is safe to move.
                    685:             Compute its desirability.  */
                    686: 
                    687:          p = m->insn;
                    688:          regno = m->regno;
                    689: 
                    690:          if (loop_dump_stream)
                    691:            fprintf (loop_dump_stream, "reg uses %d ", times_used);
                    692: 
                    693:          /* An insn MUST be moved if we already moved something else
                    694:             which is safe only if this one is moved too: that is,
                    695:             if already_moved[REGNO] is nonzero.  */
                    696: 
                    697:          /* An insn is desirable to move if the new lifetime of the
                    698:             register is no more than THRESHOLD times the old lifetime.
                    699:             If it's not desirable, it means the loop is so big
                    700:             that moving won't speed things up much,
                    701:             and it is liable to make register usage worse.  */
                    702: 
                    703:          /* It is also desirable to move if it can be moved at no
                    704:             extra cost because something else was already moved.  */
                    705: 
                    706:          if (already_moved[regno]
                    707:              || (threshold * times_used * m->lifetime) >= insn_count
                    708:              || (m->forces && m->forces->done
                    709:                  && n_times_used[m->forces->regno] == 1))
1.1       root      710:            {
1.1.1.2   root      711:              int count;
                    712:              register struct movable *m1;
                    713: 
                    714:              for (count = m->consec; count >= 0; count--)
1.1       root      715:                {
1.1.1.2   root      716:                  rtx i1 = emit_insn_before (PATTERN (p), loop_start);
                    717:                  if (new_start == 0)
                    718:                    new_start = i1;
                    719: 
                    720:                  if (loop_dump_stream)
                    721:                    fprintf (loop_dump_stream, "moved to %d", INSN_UID (i1));
                    722: 
                    723:                  /* Mark the moved, invariant reg as being equivalent to
                    724:                     its constant value.  */
                    725:                  REG_NOTES (i1) = REG_NOTES (p);
                    726:                  if (REG_NOTES (i1) == 0
                    727:                      && ! m->partial /* But not if its a zero-extend clr. */
                    728:                      && ! m->global /* and not if used outside the loop
                    729:                                        (since it might get set outside).  */
                    730:                      && CONSTANT_P (SET_SRC (PATTERN (p))))
                    731:                    REG_NOTES (i1)
                    732:                      = gen_rtx (EXPR_LIST, REG_EQUIV,
                    733:                                 SET_SRC (PATTERN (p)), REG_NOTES (i1));
                    734:                  delete_insn (p);
                    735:                  do p = NEXT_INSN (p);
                    736:                  while (GET_CODE (p) == NOTE);
                    737: 
                    738:                  /* The more insns we move, the less we like moving them.  */
                    739:                  threshold -= 2;
1.1       root      740:                }
1.1.1.2   root      741: 
                    742:              /* Any other movable that loads the same register
                    743:                 MUST be moved.  */
                    744:              already_moved[regno] = 1;
                    745: 
                    746:              /* The reg set here is now invariant.  */
                    747:              if (! m->partial)
                    748:                n_times_set[regno] = 0;
                    749: 
                    750:              m->done = 1;
                    751: 
                    752:              /* Combine with this moved insn any other matching movables.  */
1.1       root      753: 
                    754:              for (m1 = m->next; m1; m1 = m1->next)
                    755:                if (m1->match == m)
                    756:                  {
                    757:                    /* Schedule the reg loaded by M1
                    758:                       for replacement so that shares the reg of M.  */
                    759:                    reg_map[m1->regno] = SET_DEST (PATTERN (m->insn));
1.1.1.2   root      760:                    /* Get rid of the matching insn
1.1       root      761:                       and prevent further processing of it.  */
1.1.1.2   root      762:                    m1->done = 1;
1.1       root      763:                    delete_insn (m1->insn);
1.1.1.2   root      764: 
                    765:                    /* Any other movable that loads the same register
                    766:                       MUST be moved.  */
                    767:                    already_moved[m1->regno] = 1;
                    768: 
                    769:                    /* The reg merged here is now invariant.  */
                    770:                    if (m->partial)
                    771:                      n_times_set[m1->regno] = 0;
1.1       root      772:                  }
                    773:            }
1.1.1.2   root      774:          else if (loop_dump_stream)
                    775:            fprintf (loop_dump_stream, "not desirable");
1.1       root      776:        }
1.1.1.2   root      777:       else if (loop_dump_stream && !m->match)
                    778:        fprintf (loop_dump_stream, "not safe");
1.1       root      779: 
1.1.1.2   root      780:       if (loop_dump_stream)
                    781:        fprintf (loop_dump_stream, "\n");
                    782:     }
1.1       root      783: 
1.1.1.2   root      784:   if (new_start == 0)
                    785:     new_start = loop_start;
1.1       root      786: 
1.1.1.2   root      787:   /* Go through all the instructions in the loop, making
                    788:      all the register substitutions scheduled in REG_MAP.  */
                    789:   for (p = new_start; p != end; p = NEXT_INSN (p))
                    790:     if (GET_CODE (p) == INSN || GET_CODE (p) == JUMP_INSN
                    791:        || GET_CODE (p) == CALL_INSN)
                    792:       replace_regs (PATTERN (p), reg_map);
                    793: }
                    794: 
                    795: /* Optionally change a loop which enters just before the endtest
                    796:    to one which falls straight in
                    797:    after skipping around the entire loop if the endtest would drop out.
                    798:    Returns 1 if the change was made, 0 if the loop was not really suitable.  */
                    799: 
                    800: int
                    801: loop_skip_over (start, end, loop_entry_jump)
                    802:      rtx start;
                    803:      rtx end;
                    804:      rtx loop_entry_jump;
                    805: {
                    806:   rtx endtestjump;
                    807:   register rtx p = JUMP_LABEL (loop_entry_jump);
1.1       root      808: 
1.1.1.2   root      809:   while (GET_CODE (p) != INSN && GET_CODE (p) != JUMP_INSN
                    810:         && GET_CODE (p) != CALL_INSN)
                    811:     p = NEXT_INSN (p);
                    812:   endtestjump = next_real_insn (p);
                    813: 
                    814:   /* Check that we (1) enter at a compare insn and (2)
                    815:      the insn (presumably a jump) following that compare
                    816:      is the last in the loop and jumps back to the loop beginning.  */
                    817: 
                    818:   if (GET_CODE (PATTERN (p)) == SET
                    819:       && SET_DEST (PATTERN (p)) == cc0_rtx
                    820:       && endtestjump == prev_real_insn (end)
                    821:       && prev_real_insn (JUMP_LABEL (endtestjump)) == loop_entry_jump)
1.1       root      822:     {
1.1.1.2   root      823:       rtx newlab;
                    824:       /* This is the jump that we insert.  */
                    825:       rtx new_jump;
                    826: 
                    827:       /* Ok, duplicate that test before start of loop.  */
                    828:       emit_insn_before (copy_rtx (PATTERN (p)), start);
                    829:       /* Make a new entry-jump (before the original one)
                    830:         whose condition is opposite to the loop-around endtest
                    831:         and which jumps around the loop (to just after the endtest).  */
                    832:       newlab = gen_label_rtx ();
                    833:       emit_label_after (newlab, endtestjump);
                    834:       emit_jump_insn_before (copy_rtx (PATTERN (endtestjump)), start);
                    835:       new_jump = PREV_INSN (start);
                    836:       JUMP_LABEL (new_jump) = JUMP_LABEL (endtestjump);
                    837:       LABEL_NUSES (JUMP_LABEL (endtestjump))++;
                    838:       invert_jump (new_jump, newlab);
                    839:       /* Delete the original entry-jump.  */
                    840:       delete_insn (loop_entry_jump);
1.1       root      841: 
1.1.1.2   root      842:       return 1;
1.1       root      843:     }
1.1.1.2   root      844: 
                    845:   return 0;
1.1       root      846: }
                    847: 
                    848: /* Throughout the rtx X, replace many registers according to REG_MAP.
                    849:    Return the replacement for X (which may be X with altered contents).
                    850:    REG_MAP[R] is the replacement for register R, or 0 for don't replace.  */
                    851: 
                    852: static rtx
                    853: replace_regs (x, reg_map)
                    854:      rtx x;
                    855:      rtx *reg_map;
                    856: {
                    857:   register RTX_CODE code = GET_CODE (x);
                    858:   register int i;
                    859:   register char *fmt;
                    860: 
                    861:   switch (code)
                    862:     {
                    863:     case PC:
                    864:     case CC0:
                    865:     case CONST_INT:
                    866:     case CONST_DOUBLE:
                    867:     case CONST:
                    868:     case SYMBOL_REF:
                    869:     case LABEL_REF:
                    870:       return x;
                    871: 
                    872:     case REG:
                    873:       if (reg_map[REGNO (x)] != 0)
                    874:        return reg_map[REGNO (x)];
                    875:       return x;
                    876:     }
                    877: 
                    878:   fmt = GET_RTX_FORMAT (code);
                    879:   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
                    880:     {
                    881:       if (fmt[i] == 'e')
                    882:        XEXP (x, i) = replace_regs (XEXP (x, i), reg_map);
                    883:       if (fmt[i] == 'E')
                    884:        {
                    885:          register int j;
                    886:          for (j = 0; j < XVECLEN (x, i); j++)
                    887:            XVECEXP (x, i, j) = replace_regs (XVECEXP (x, i, j), reg_map);
                    888:        }
                    889:     }
                    890:   return x;
                    891: }
                    892: 
1.1.1.4 ! root      893: #if 0
1.1       root      894: /* P is an instruction that sets a register to the result of a ZERO_EXTEND.
                    895:    Replace it with an instruction to load just the low bytes
                    896:    if the machine supports such an instruction,
                    897:    and insert above LOOP_START an instruction to clear the register.  */
                    898: 
                    899: static void
                    900: constant_high_bytes (p, loop_start)
                    901:      rtx p, loop_start;
                    902: {
                    903:   register rtx new;
                    904:   register int insn_code_number;
                    905: 
                    906:   /* Try to change (SET (REG ...) (ZERO_EXTEND (..:B ...)))
                    907:      to (SET (STRICT_LOW_PART (SUBREG:B (REG...))) ...).  */
                    908: 
                    909:   new = gen_rtx (SET, VOIDmode,
                    910:                 gen_rtx (STRICT_LOW_PART, VOIDmode,
                    911:                          gen_rtx (SUBREG, GET_MODE (XEXP (SET_SRC (PATTERN (p)), 0)),
                    912:                                   SET_DEST (PATTERN (p)),
                    913:                                   0)),
                    914:                 XEXP (SET_SRC (PATTERN (p)), 0));
                    915:   insn_code_number = recog (new, p);
                    916: 
                    917:   if (insn_code_number)
                    918:     {
                    919:       register int i;
                    920: 
                    921:       /* Clear destination register before the loop.  */
                    922:       emit_insn_before (gen_rtx (SET, VOIDmode,
                    923:                                 SET_DEST (PATTERN (p)),
                    924:                                 const0_rtx),
                    925:                        loop_start);
                    926: 
                    927:       /* Inside the loop, just load the low part.  */
                    928:       PATTERN (p) = new;
                    929:     }
                    930: }
1.1.1.4 ! root      931: #endif
1.1       root      932: 
                    933: /* Verify that the ostensible loop starting at START
                    934:    really is a loop: nothing jumps into it from outside.
                    935:    Return the marker for the end of the loop, or zero if not a real loop.
                    936: 
                    937:    Also set the variables `unknown_*_altered' and `loop_has_call',
                    938:    and fill in the array `loop_store_addrs'.  */
                    939: 
                    940: static rtx
                    941: verify_loop (f, start)
                    942:      rtx f, start;
                    943: {
                    944:   register int level = 1;
                    945:   register rtx insn, end;
                    946: 
                    947:   /* First find the LOOP_END that matches.
                    948:      Also check each insn for storing in memory and record where.  */
                    949: 
                    950:   unknown_address_altered = 0;
                    951:   unknown_aggregate_altered = 0;
                    952:   fixed_aggregate_altered = 0;
                    953:   loop_has_call = 0;
                    954:   loop_store_addrs_idx = 0;
                    955: 
                    956:   for (insn = NEXT_INSN (start); level > 0; insn = NEXT_INSN (insn))
                    957:     {
                    958:       if (insn == 0)
1.1.1.2   root      959:        /* Parse errors can cause a loop-beg with no loop-end.  */
                    960:        return 0;
1.1       root      961:       if (GET_CODE (insn) == NOTE)
                    962:        {
                    963:          if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG)
                    964:            ++level;
                    965:          else if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END)
1.1.1.2   root      966:            {
                    967:              --level;
                    968:              if (level == 0)
                    969:                {
                    970:                  end = insn;
                    971:                  break;
                    972:                }
                    973:            }
1.1       root      974:        }
                    975:       else if (GET_CODE (insn) == CALL_INSN)
                    976:        {
                    977:          unknown_address_altered = 1;
                    978:          loop_has_call = 1;
                    979:        }
                    980:       else if (! unknown_address_altered)
                    981:        {
                    982:          if (GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN)
                    983:            note_stores (PATTERN (insn), note_addr_stored);
                    984:        }
                    985:     }
                    986: 
                    987:   /* Now scan all jumps in the function and see if any of them can
                    988:      reach a label within the range of the loop.  */
                    989: 
                    990:   for (insn = f; insn; insn = NEXT_INSN (insn))
                    991:     if (GET_CODE (insn) == JUMP_INSN
                    992:        /* Don't get fooled by jumps inserted by loop-optimize.
                    993:           They don't have valid LUIDs, and they never jump into loops.  */
                    994:        && INSN_UID (insn) < max_uid
                    995:        && (INSN_LUID (insn) < INSN_LUID (start)
                    996:            || INSN_LUID (insn) > INSN_LUID (end))
                    997:        /* We have a jump that is outside the loop.
                    998:           Does it jump into the loop?  */
                    999:        && can_jump_into_range_p (PATTERN (insn),
                   1000:                                  INSN_LUID (start), INSN_LUID (end)))
                   1001:       return 0;
                   1002: 
                   1003: #if 0      
                   1004:   /* Now scan all labels between them and check for any jumps from outside.
                   1005:      This uses the ref-chains set up by find_basic_blocks.
                   1006:      This code is not used because it's more convenient for other reasons
                   1007:      to do the loop optimization before find_basic_blocks.  */
                   1008: 
                   1009:   for (insn = start; insn != end; insn = NEXT_INSN (insn))
                   1010:     if (GET_CODE (insn) == CODE_LABEL)
                   1011:       {
                   1012:        register rtx y;
                   1013:        for (y = LABEL_REFS (insn); y != insn; y = LABEL_NEXTREF (y))
                   1014:          if (INSN_LUID (CONTAINING_INSN (y)) < INSN_LUID (start)
                   1015:              || INSN_LUID (CONTAINING_INSN (y)) > INSN_LUID (end))
                   1016:            return 0;
                   1017:       }
                   1018: #endif
                   1019: 
                   1020:   return end;
                   1021: }
                   1022: 
                   1023: /* Return 1 if somewhere in X is a LABEL_REF to a label
                   1024:    located between BEG and END.  */
                   1025: 
                   1026: static int
                   1027: can_jump_into_range_p (x, beg, end)
                   1028:      rtx x;
                   1029:      int beg, end;
                   1030: {
                   1031:   register RTX_CODE code = GET_CODE (x);
                   1032:   register int i;
                   1033:   register char *fmt;
                   1034: 
                   1035:   if (code == LABEL_REF)
                   1036:     {
                   1037:       register int luid = INSN_LUID (XEXP (x, 0));
                   1038:       return luid > beg && luid < end;
                   1039:     }
                   1040: 
                   1041:   fmt = GET_RTX_FORMAT (code);
                   1042:   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
                   1043:     {
                   1044:       if (fmt[i] == 'e')
                   1045:        {
                   1046:          if (can_jump_into_range_p (XEXP (x, i), beg, end))
                   1047:            return 1;
                   1048:        }
                   1049:       else if (fmt[i] == 'E')
                   1050:        {
                   1051:          register int j;
                   1052:          for (j = 0; j < XVECLEN (x, i); j++)
                   1053:            if (can_jump_into_range_p (XVECEXP (x, i, j), beg, end))
                   1054:              return 1;
                   1055:        }
                   1056:     }
                   1057: 
                   1058:   return 0;
                   1059: }
                   1060: 
                   1061: /* Record that a memory reference X is being set.  */
                   1062: 
                   1063: static void
                   1064: note_addr_stored (x)
                   1065:      rtx x;
                   1066: {
                   1067:   rtx addr;
                   1068:   if (x == 0 || GET_CODE (x) != MEM)
                   1069:     return;
1.1.1.2   root     1070:   if (GET_MODE (x) == BLKmode)
                   1071:     unknown_address_altered = 1;
                   1072:   else if (rtx_addr_varies_p (x))
1.1       root     1073:     {
                   1074:       if (GET_CODE (XEXP (x, 0)) == PLUS)
                   1075:        unknown_aggregate_altered = 1;
                   1076:       else
                   1077:        unknown_address_altered = 1;
                   1078:     }
                   1079:   else
                   1080:     {
                   1081:       register int i;
                   1082:       register rtx addr = XEXP (x, 0);
                   1083: 
                   1084:       if (x->in_struct)
                   1085:        fixed_aggregate_altered = 1;
                   1086:       for (i = 0; i < loop_store_addrs_idx; i++)
                   1087:        if (rtx_equal_p (loop_store_addrs[i], addr))
                   1088:          {
                   1089:            if (loop_store_widths[i] < GET_MODE_SIZE (GET_MODE (x)))
                   1090:              loop_store_widths[i] = GET_MODE_SIZE (GET_MODE (x));
                   1091:            break;
                   1092:          }
                   1093:       if (i == NUM_STORES)
                   1094:        unknown_address_altered = 1;
                   1095:       else if (i == loop_store_addrs_idx)
                   1096:        {
1.1.1.2   root     1097:          loop_store_widths[i] = GET_MODE_SIZE (GET_MODE (x));
1.1       root     1098:          loop_store_addrs[loop_store_addrs_idx++] = addr;
                   1099:        }
                   1100:     }
                   1101: }
                   1102: 
                   1103: /* Return nonzero if the rtx X is invariant over the current loop.
                   1104:    N_TIMES_SET is a vector whose element I is nonzero if register I
                   1105:    is set during the loop.
                   1106: 
                   1107:    The value is 2 if we refer to something only conditionally invariant.
                   1108: 
                   1109:    If `unknown_address_altered' is nonzero, no memory ref is invariant.
                   1110:    Otherwise if `unknown_aggregate_altered' is nonzero,
                   1111:    a memory ref is invariant if it is not part of an aggregate
                   1112:    and its address is fixed and not in `loop_store_addrs'.
                   1113:    Otherwise if `fixed_aggregate_altered' is nonzero,
                   1114:    a memory ref is invariant
                   1115:    if its address is fixed and not in `loop_store_addrs'.
                   1116:    Otherwise, a memory ref is invariant if its address is fixed and not in
                   1117:    `loop_store_addrs' or if it is not an aggregate.  */
                   1118: 
                   1119: static int
                   1120: invariant_p (x, n_times_set)
                   1121:      register rtx x;
                   1122:      short *n_times_set;
                   1123: {
                   1124:   register int i;
                   1125:   register RTX_CODE code = GET_CODE (x);
                   1126:   register char *fmt;
                   1127:   int conditional = 0;
                   1128: 
                   1129:   switch (code)
                   1130:     {
                   1131:     case CONST_INT:
                   1132:     case CONST_DOUBLE:
                   1133:     case SYMBOL_REF:
                   1134:     case LABEL_REF:
                   1135:     case CONST:
                   1136:       return 1;
                   1137: 
                   1138:     case PC:
                   1139:     case CC0:
                   1140:       return 0;
                   1141: 
                   1142:     case REG:
1.1.1.2   root     1143:       if (x == frame_pointer_rtx || x == arg_pointer_rtx
                   1144:          || x->unchanging)
                   1145:        return 1;
1.1       root     1146:       if (n_times_set[REGNO (x)] == -1)
                   1147:        return 2;
                   1148:       return n_times_set[REGNO (x)] == 0;
                   1149: 
                   1150:     case MEM:
                   1151:       /* A store in a varying-address scalar (or a subroutine call)
                   1152:         could clobber anything in memory.  */
                   1153:       if (unknown_address_altered)
                   1154:        return 0;
1.1.1.2   root     1155:       /* Don't mess with volatile memory references.  */
                   1156:       if (x->volatil)
                   1157:        return 0;
                   1158:       /* If it's declared read-only, it is invariant
                   1159:         if its address is invariant.  */
                   1160:       if (x->unchanging)
                   1161:        return invariant_p (XEXP (x, 0), n_times_set);
1.1       root     1162:       /* A store in a varying-address aggregate component
                   1163:         could clobber anything except a scalar with a fixed address.  */
                   1164:       if (unknown_aggregate_altered
                   1165:          && ((x->in_struct || GET_CODE (XEXP (x, 0)) == PLUS)
                   1166:              || rtx_addr_varies_p (x)))
                   1167:        return 0;
                   1168:       /* A store in a fixed-address aggregate component
                   1169:         could clobber anything whose address is not fixed,
                   1170:         even an aggregate component.  */
                   1171:       if (fixed_aggregate_altered
                   1172:          && rtx_addr_varies_p (x))
                   1173:        return 0;
                   1174:       /* Any store could clobber a varying-address scalar.  */
                   1175:       if (loop_store_addrs_idx
                   1176:          && !(x->in_struct || GET_CODE (XEXP (x, 0)) == PLUS)
                   1177:          && rtx_addr_varies_p (x))
                   1178:        return 0;
                   1179:       /* A store in a fixed address clobbers overlapping references.  */
                   1180:       for (i = loop_store_addrs_idx - 1; i >= 0; i--)
1.1.1.2   root     1181:        if (addr_overlap_p (x, loop_store_addrs[i], loop_store_widths[i]))
1.1       root     1182:          return 0;
                   1183:       /* It's not invalidated by a store in memory
                   1184:         but we must still verify the address is invariant.  */
1.1.1.2   root     1185:       break;
                   1186: 
                   1187:     case ASM_OPERANDS:
                   1188:       /* Don't mess with insns declared volatile.  */
                   1189:       if (x->volatil)
                   1190:        return 0;
1.1       root     1191:     }
                   1192: 
                   1193:   fmt = GET_RTX_FORMAT (code);
                   1194:   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
                   1195:     {
                   1196:       if (fmt[i] == 'e')
                   1197:        {
                   1198:          int tem = invariant_p (XEXP (x, i), n_times_set);
                   1199:          if (tem == 0)
                   1200:            return 0;
                   1201:          if (tem == 2)
                   1202:            conditional = 1;
                   1203:        }
1.1.1.2   root     1204:       else if (fmt[i] == 'E')
                   1205:        {
                   1206:          register int j;
                   1207:          for (j = 0; j < XVECLEN (x, i); j++)
                   1208:            {
                   1209:              int tem = invariant_p (XVECEXP (x, i, j), n_times_set);
                   1210:              if (tem == 0)
                   1211:                return 0;
                   1212:              if (tem == 2)
                   1213:                conditional = 1;
                   1214:            }
                   1215: 
                   1216:        }
1.1       root     1217:     }
                   1218: 
                   1219:   return 1 + conditional;
                   1220: }
                   1221: 
                   1222: /* Return 1 if OTHER (a mem ref) overlaps the area of memory
                   1223:    which is SIZE bytes starting at BASE.  */
                   1224: 
                   1225: int
                   1226: addr_overlap_p (other, base, size)
                   1227:      rtx other;
                   1228:      rtx base;
                   1229:      int size;
                   1230: {
                   1231:   int start = 0, end;
                   1232: 
                   1233:   if (GET_CODE (base) == CONST)
                   1234:     base = XEXP (base, 0);
                   1235:   if (GET_CODE (base) == PLUS
                   1236:       && GET_CODE (XEXP (base, 1)) == CONST_INT)
                   1237:     {
                   1238:       start = INTVAL (XEXP (base, 1));
                   1239:       base = XEXP (base, 0);
                   1240:     }
                   1241: 
                   1242:   end = start + size;
                   1243:   return refers_to_mem_p (other, base, start, end);
                   1244: }
1.1.1.2   root     1245: 
1.1.1.4 ! root     1246: /* Return nonzero if all the insns in the loop that set REG
1.1.1.2   root     1247:    are INSN and the immediately following insns,
                   1248:    and if each of those insns sets REG in an invariant way
                   1249:    according to TABLE (not counting uses of REG in them).
                   1250: 
1.1.1.4 ! root     1251:    The value is 2 if some of these insns are only conditionally invariant.
        !          1252: 
1.1.1.2   root     1253:    We assume that INSN itself is the first set of REG
                   1254:    and that its source is invariant.  */
                   1255: 
                   1256: static int
1.1.1.4 ! root     1257: consec_sets_invariant_p (reg, n_sets, insn, table)
        !          1258:      int n_sets;
1.1.1.2   root     1259:      rtx reg, insn;
                   1260:      short *table;
                   1261: {
                   1262:   register rtx p = insn;
                   1263:   register int regno = REGNO (reg);
                   1264:   /* Number of sets we have to insist on finding after INSN.  */
1.1.1.4 ! root     1265:   int count = n_sets - 1;
1.1.1.2   root     1266:   int old = table[regno];
1.1.1.4 ! root     1267:   int tem = 0;
1.1.1.2   root     1268: 
                   1269:   table[regno] = 0;
                   1270: 
                   1271:   while (count > 0)
                   1272:     {
                   1273:       register enum rtx_code code;
                   1274:       p = NEXT_INSN (p);
                   1275:       code = GET_CODE (p);
                   1276:       if (code == INSN && GET_CODE (PATTERN (p)) == SET
                   1277:          && GET_CODE (SET_DEST (PATTERN (p))) == REG
                   1278:          && REGNO (SET_DEST (PATTERN (p))) == regno
1.1.1.4 ! root     1279:          && (tem |= invariant_p (SET_SRC (PATTERN (p)), table)))
1.1.1.2   root     1280:        count--;
                   1281:       else if (code != NOTE)
                   1282:        {
                   1283:          table[regno] = old;
                   1284:          return 0;
                   1285:        }
                   1286:     }
                   1287: 
                   1288:   table[regno] = old;
1.1.1.4 ! root     1289:   /* If invariant_p ever returned 2, we return 2.  */
        !          1290:   return 1 + (tem & 2);
1.1.1.2   root     1291: }
                   1292: 
                   1293: #if 0
                   1294: /* I don't think this condition is sufficient to allow INSN
                   1295:    to be moved, so we no longer test it.  */
1.1       root     1296: 
                   1297: /* Return 1 if all insns in the basic block of INSN and following INSN
                   1298:    that set REG are invariant according to TABLE.  */
                   1299: 
                   1300: static int
                   1301: all_sets_invariant_p (reg, insn, table)
                   1302:      rtx reg, insn;
1.1.1.2   root     1303:      short *table;
1.1       root     1304: {
                   1305:   register rtx p = insn;
                   1306:   register int regno = REGNO (reg);
                   1307: 
                   1308:   while (1)
                   1309:     {
                   1310:       register enum rtx_code code;
                   1311:       p = NEXT_INSN (p);
                   1312:       code = GET_CODE (p);
                   1313:       if (code == CODE_LABEL || code == JUMP_INSN)
                   1314:        return 1;
                   1315:       if (code == INSN && GET_CODE (PATTERN (p)) == SET
                   1316:          && GET_CODE (SET_DEST (PATTERN (p))) == REG
                   1317:          && REGNO (SET_DEST (PATTERN (p))) == regno)
                   1318:        {
                   1319:          if (!invariant_p (SET_SRC (PATTERN (p)), table))
                   1320:            return 0;
                   1321:        }
                   1322:     }
                   1323: }
1.1.1.2   root     1324: #endif /* 0 */
1.1       root     1325: 
                   1326: /* Increment N_TIMES_SET at the index of each register
                   1327:    that is modified by an insn between FROM and TO.
                   1328:    If the value of an element of N_TIMES_SET becomes 2 or more,
                   1329:    do not keep incrementing it; all values >= 2 would be
                   1330:    equivalent anyway, and this way we avoid danger of overflow.
                   1331: 
                   1332:    Store in *COUNT_PTR the number of actual instruction
                   1333:    in the loop.  We use this to decide what is worth moving out.  */
                   1334: 
                   1335: /* last_set[n] is nonzero iff reg n has been set in the current basic block.
                   1336:    In that case, it is the insn that last set reg n.  */
                   1337: 
                   1338: static void
                   1339: count_loop_regs_set (from, to, n_times_set, may_not_move, count_ptr, nregs)
                   1340:      register rtx from, to;
                   1341:      short *n_times_set;
                   1342:      char *may_not_move;
                   1343:      int *count_ptr;
                   1344:      int nregs;
                   1345: {
                   1346:   register rtx *last_set = (rtx *) alloca (nregs * sizeof (rtx));
                   1347:   register rtx insn;
                   1348:   register int count = 0;
                   1349:   register rtx dest;
                   1350: 
                   1351:   bzero (last_set, nregs * sizeof (rtx));
                   1352:   for (insn = from; insn != to; insn = NEXT_INSN (insn))
                   1353:     {
1.1.1.2   root     1354:       if (GET_CODE (insn) == CALL_INSN)
                   1355:        {
                   1356:          /* If a register is used as a subroutine address,
                   1357:             don't allow this register's setting to be moved out of the loop.
                   1358:             This condition is not at all logically correct
                   1359:             but it averts a very common lossage pattern
                   1360:             and creates lossage much less often.  */
                   1361:          if (GET_CODE (PATTERN (insn)) == CALL
                   1362:              && GET_CODE (XEXP (PATTERN (insn), 0)) == MEM
                   1363:              && GET_CODE (XEXP (XEXP (PATTERN (insn), 0), 0)) == REG)
                   1364:            {
                   1365:              register int regno
                   1366:                = REGNO (XEXP (XEXP (PATTERN (insn), 0), 0));
                   1367:              may_not_move[regno] = 1;
                   1368:            }
                   1369:          else if (GET_CODE (PATTERN (insn)) == SET
                   1370:              && GET_CODE (SET_SRC (PATTERN (insn))) == CALL
                   1371:              && GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 0)) == MEM
                   1372:              && GET_CODE (XEXP (XEXP (SET_SRC (PATTERN (insn)), 0), 0)) == REG)
                   1373:            {
                   1374:              register int regno
                   1375:                = REGNO (XEXP (XEXP (SET_SRC (PATTERN (insn)), 0), 0));
                   1376:              may_not_move[regno] = 1;
                   1377:              /* The call insn itself sets a reg, which cannot be moved.  */
                   1378:              may_not_move[REGNO (SET_DEST (PATTERN (insn)))] = 1;
                   1379:              n_times_set[REGNO (SET_DEST (PATTERN (insn)))]++;
                   1380:            }
                   1381:        }
                   1382:       if (GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN) 
1.1       root     1383:        {
                   1384:          ++count;
1.1.1.2   root     1385:          if (GET_CODE (PATTERN (insn)) == CLOBBER
                   1386:              && GET_CODE (XEXP (PATTERN (insn), 0)) == REG)
                   1387:            /* Don't move a reg that has an explicit clobber.
                   1388:               We might do so sometimes, but it's not worth the pain.  */
                   1389:            may_not_move[REGNO (XEXP (PATTERN (insn), 0))] = 1;
                   1390:          else if (GET_CODE (PATTERN (insn)) == SET)
1.1       root     1391:            {
                   1392:              dest = SET_DEST (PATTERN (insn));
                   1393:              while (GET_CODE (dest) == SUBREG
                   1394:                     || GET_CODE (dest) == ZERO_EXTRACT
                   1395:                     || GET_CODE (dest) == SIGN_EXTRACT
                   1396:                     || GET_CODE (dest) == STRICT_LOW_PART)
                   1397:                dest = XEXP (dest, 0);
                   1398:              if (GET_CODE (dest) == REG)
                   1399:                {
                   1400:                  register int regno = REGNO (dest);
                   1401:                  /* If this is the first setting of this reg
                   1402:                     in current basic block, and it was set before,
                   1403:                     it must be set in two basic blocks, so it cannot
                   1404:                     be moved out of the loop.  */
                   1405:                  if (n_times_set[regno] > 0 && last_set[regno] == 0)
                   1406:                    may_not_move[regno] = 1;
                   1407:                  /* If this is not first setting in current basic block,
                   1408:                     see if reg was used in between previous one and this.
                   1409:                     If so, neither one can be moved.  */
                   1410:                  if (last_set[regno] != 0
                   1411:                      && reg_used_between_p (dest, last_set[regno], insn))
                   1412:                    may_not_move[regno] = 1;
                   1413:                  ++n_times_set[regno];
                   1414:                  last_set[regno] = insn;
                   1415:                }
                   1416:            }
                   1417:          else if (GET_CODE (PATTERN (insn)) == PARALLEL)
                   1418:            {
                   1419:              register int i;
                   1420:              for (i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--)
                   1421:                {
                   1422:                  register rtx x = XVECEXP (PATTERN (insn), 0, i);
1.1.1.2   root     1423:                  if (GET_CODE (x) == CLOBBER && GET_CODE (XEXP (x, 0)) == REG)
                   1424:                    /* Don't move a reg that has an explicit clobber.
                   1425:                       It's not worth the pain to try to do it correctly.  */
                   1426:                    may_not_move[REGNO (XEXP (x, 0))] = 1;
1.1       root     1427:                  if (GET_CODE (x) == SET)
                   1428:                    {
                   1429:                      dest = SET_DEST (x);
                   1430:                      while (GET_CODE (dest) == SUBREG
                   1431:                             || GET_CODE (dest) == ZERO_EXTRACT
                   1432:                             || GET_CODE (dest) == SIGN_EXTRACT
                   1433:                             || GET_CODE (dest) == STRICT_LOW_PART)
                   1434:                        dest = XEXP (dest, 0);
                   1435:                      if (GET_CODE (dest) == REG)
                   1436:                        {
                   1437:                          register int regno = REGNO (dest);
                   1438:                          ++n_times_set[regno];
                   1439:                          may_not_move[regno] = 1;
                   1440:                          last_set[regno] = insn;
                   1441:                        }
                   1442:                    }
                   1443:                }
                   1444:            }
                   1445:        }
                   1446:       if (GET_CODE (insn) == CODE_LABEL || GET_CODE (insn) == JUMP_INSN)
                   1447:        bzero (last_set, nregs * sizeof (rtx));
                   1448:     }
                   1449:   *count_ptr = count;
                   1450: }
                   1451: 
                   1452: /* Given a loop that is bounded by LOOP_START and LOOP_END
                   1453:    and that is entered at SCAN_START,
                   1454:    return 1 if the register set by insn INSN is used by
                   1455:    any insn that precedes INSN in cyclic order starting
                   1456:    from the loop entry point.  */
                   1457: 
                   1458: static int
                   1459: loop_reg_used_before_p (insn, loop_start, scan_start, loop_end)
                   1460:      rtx insn, loop_start, scan_start, loop_end;
                   1461: {
                   1462:   rtx reg = SET_DEST (PATTERN (insn));
                   1463:   if (INSN_LUID (scan_start) > INSN_LUID (insn))
                   1464:     return (reg_used_between_p (reg, scan_start, loop_end)
                   1465:            || reg_used_between_p (reg, loop_start, insn));
                   1466:   else
                   1467:     return reg_used_between_p (reg, scan_start, insn);
                   1468: }
1.1.1.2   root     1469: 
1.1.1.3   root     1470: /* Return nonzero if evaluating rtx X might cause a trap.  */
1.1.1.2   root     1471: 
                   1472: static int
                   1473: may_trap_p (x)
                   1474:      rtx x;
                   1475: {
1.1.1.3   root     1476:   int i;
                   1477:   enum rtx_code code = GET_CODE (x);
                   1478:   char *fmt;
                   1479: 
                   1480:   switch (code)
1.1.1.2   root     1481:     {
1.1.1.3   root     1482:       /* Handle these cases fast.  */
                   1483:     case CONST_INT:
                   1484:     case CONST_DOUBLE:
                   1485:     case SYMBOL_REF:
                   1486:     case LABEL_REF:
                   1487:     case CONST:
                   1488:     case PC:
                   1489:     case CC0:
                   1490:     case REG:
                   1491:       return 0;
                   1492: 
                   1493:       /* Division by a non-constant might trap.  */
1.1.1.2   root     1494:     case DIV:
                   1495:     case MOD:
                   1496:     case UDIV:
                   1497:     case UMOD:
                   1498:       if (! CONSTANT_P (XEXP (x, 1))
                   1499:          && GET_CODE (XEXP (x, 1)) != CONST_DOUBLE)
                   1500:        return 1;
1.1.1.3   root     1501:       break;
                   1502: 
                   1503:       /* Memory ref can trap unless it's a static var or a stack slot.  */
                   1504:     case MEM:
                   1505:       return rtx_varies_p (XEXP (x, 0));
1.1.1.4 ! root     1506: 
        !          1507:     case SET:
        !          1508:       /* Any floating arithmetic may trap.  */
        !          1509:       if (GET_MODE_CLASS (GET_MODE (SET_DEST (x))) == MODE_FLOAT
        !          1510:          && GET_CODE (SET_SRC (x)) != REG
        !          1511:          && GET_CODE (SET_SRC (x)) != MEM)
        !          1512:        return 1;
1.1.1.3   root     1513:     }
                   1514: 
                   1515:   fmt = GET_RTX_FORMAT (code);
                   1516:   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
                   1517:     {
                   1518:       if (fmt[i] == 'e')
                   1519:        {
                   1520:          if (may_trap_p (XEXP (x, i)))
                   1521:            return 1;
                   1522:        }
                   1523:       else if (fmt[i] == 'E')
                   1524:        {
                   1525:          register int j;
                   1526:          for (j = 0; j < XVECLEN (x, i); j++)
                   1527:            if (may_trap_p (XVECEXP (x, i, j)))
                   1528:              return 1;
                   1529:        }
1.1.1.2   root     1530:     }
                   1531:   return 0;
                   1532: }

unix.superglobalmegacorp.com

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