Annotation of gcc/loop.c, revision 1.1.1.3

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

unix.superglobalmegacorp.com

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