Annotation of gcc/loop.c, revision 1.1.1.11

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
1.1.1.8   root       24:    to the beginning of the loop.  Then it identifies basic and 
                     25:    general induction variables.  Strength reduction is applied to the general
                     26:    induction variables, and induction variable elimination is applied to
                     27:    the basic induction variables.
1.1       root       28: 
                     29:    It also finds cases where
                     30:    a register is set within the loop by zero-extending a narrower value
                     31:    and changes these to zero the entire register once before the loop
                     32:    and merely copy the low part within the loop.
                     33: 
                     34:    Most of the complexity is in heuristics to decide when it is worth
                     35:    while to do these things.  */
                     36: 
                     37: /* ??? verify_loop would run faster if we made one table
                     38:    of the minimum and maximum luids from which each label is reached.
                     39:    Also, it would be faster if loop_store_addrs were a hash table.  */
                     40: 
                     41: #include "config.h"
                     42: #include "rtl.h"
1.1.1.10  root       43: #include "expr.h"
1.1       root       44: #include "insn-config.h"
                     45: #include "regs.h"
                     46: #include "recog.h"
1.1.1.8   root       47: #include "flags.h"
1.1.1.2   root       48: #include <stdio.h>
1.1       root       49: 
                     50: /* Vector mapping INSN_UIDs to luids.
                     51:    The luids are like uids but increase monononically always.
                     52:    We use them to see whether a jump comes from outside a given loop.  */
                     53: 
                     54: static short *uid_luid;
                     55: 
                     56: /* Get the luid of an insn.  */
                     57: 
                     58: #define INSN_LUID(INSN) (uid_luid[INSN_UID (INSN)])
                     59: 
                     60: /* 1 + largest uid of any insn.  */
                     61: 
                     62: static int max_uid;
                     63: 
                     64: /* 1 + luid of last insn.  */
                     65: 
                     66: static int max_luid;
                     67: 
                     68: /* Nonzero if somewhere in the current loop
                     69:    there is either a subroutine call,
                     70:    or a store into a memory address that is not fixed,
                     71:    or a store in a BLKmode memory operand,
                     72:    or too many different fixed addresses stored in
                     73:    to record them all in `loop_store_addrs'.
                     74: 
                     75:    In any of these cases, no memory location can be regarded
                     76:    as invariant.  */
                     77: 
                     78: static int unknown_address_altered;
                     79: 
                     80: /* Nonzero if somewhere in the current loop there is a store
                     81:    into a memory address that is not fixed but is known to be
                     82:    part of an aggregate.
                     83: 
                     84:    In this case, no memory reference in an aggregate may be
                     85:    considered invariant.  */
                     86: 
                     87: static int unknown_aggregate_altered;
                     88: 
                     89: /* Nonzero if somewhere in the current loop there is a store
                     90:    into a memory address other than a fixed address not in an aggregate.
                     91: 
                     92:    In this case, no memory reference in an aggregate at a varying address
                     93:    may be considered invariant.  */
                     94: 
                     95: static int fixed_aggregate_altered;
                     96: 
                     97: /* Nonzero if there is a subroutine call in the current loop.
                     98:    (unknown_address_altered is also nonzero in this case.)  */
                     99: 
                    100: static int loop_has_call;
                    101: 
1.1.1.8   root      102: /* Indexed by register number, contains the number of times the reg
1.1.1.10  root      103:    is set during the loop being scanned.
                    104:    During code motion, -1 indicates a reg that has been made a candidate.
                    105:    After code motion, regs moved have 0 (which is accurate now)
                    106:    while the failed candidates have the original number of times set.
                    107: 
                    108:    Therefore, at all times, 0 indicates an invariant register;
                    109:    -1 a conditionally invariant one.  */
1.1.1.8   root      110: 
                    111: static short *n_times_set;
                    112: 
1.1.1.10  root      113: /* Original value of n_times_set; same except that this value
                    114:    is not set to -1 for a reg whose sets have been made candidates
                    115:    and not set to 0 for a reg that is moved.  */
1.1.1.8   root      116: 
                    117: static short *n_times_used;
                    118: 
1.1       root      119: /* Array of fixed memory addresses that are stored in this loop.
                    120:    If there are too many to fit here,
                    121:    we just turn on unknown_address_altered.  */
                    122: 
                    123: #define NUM_STORES 10
                    124: static rtx loop_store_addrs[NUM_STORES];
                    125: static int loop_store_widths[NUM_STORES];
                    126: 
                    127: /* Index of first available slot in above array.  */
                    128: static int loop_store_addrs_idx;
                    129: 
1.1.1.8   root      130: /* Count of movable (i.e. invariant) instructions discovered in the loop.  */
                    131: static int num_movables;
                    132: 
                    133: /* Count of memory write instructions discovered in the loop.  */
                    134: static int num_mem_sets;
                    135: 
                    136: /* Number of loops contained within the current one, including itself.  */
                    137: static int loops_enclosed;
                    138: 
                    139: /* Bound on pseudo register number before loop optimization.
                    140:    A pseudo has valid regscan info if its number is < old_max_reg.  */
                    141: static int old_max_reg;
                    142: 
1.1       root      143: /* During the analysis of a loop, a chain of `struct movable's
                    144:    is made to record all the movable insns found.
                    145:    Then the entire chain can be scanned to decide which to move.  */
                    146: 
                    147: struct movable
                    148: {
                    149:   rtx insn;                    /* A movable insn */
1.1.1.8   root      150:   rtx set_src;                  /* The expression this reg is set from.
                    151:                                   Either SET_SRC (body) or a REG_EQUAL.  */
1.1.1.2   root      152:   int consec;                  /* Number of consecutive following insns 
                    153:                                   that must be moved with this one.  */
1.1       root      154:   int regno;                   /* The register it sets */
                    155:   short lifetime;              /* lifetime of that register;
                    156:                                   may be adjusted when matching movables
                    157:                                   that load the same value are found.  */
1.1.1.10  root      158:   short savings;               /* Number of insns we can move for this reg,
                    159:                                   including other movables that force this
                    160:                                   or match this one.  */
1.1       root      161:   unsigned int cond : 1;       /* 1 if only conditionally movable */
                    162:   unsigned int force : 1;      /* 1 means MUST move this insn */
                    163:   unsigned int global : 1;     /* 1 means reg is live outside this loop */
1.1.1.2   root      164:   unsigned int done : 1;       /* 1 inhibits further processing of this */
                    165:   unsigned int partial : 1;    /* Moving this doesn't make it invariant.  */
1.1       root      166:   struct movable *match;       /* First entry for same value */
                    167:   struct movable *forces;      /* An insn that must be moved if this is */
                    168:   struct movable *next;
                    169: };
                    170: 
1.1.1.2   root      171: static FILE *loop_dump_stream;
                    172: 
1.1       root      173: static rtx verify_loop ();
                    174: static int invariant_p ();
1.1.1.4   root      175: static int consec_sets_invariant_p ();
1.1       root      176: static int can_jump_into_range_p ();
                    177: static void count_loop_regs_set ();
                    178: static void note_addr_stored ();
                    179: static int loop_reg_used_before_p ();
                    180: static void constant_high_bytes ();
                    181: static void scan_loop ();
                    182: static rtx replace_regs ();
1.1.1.9   root      183: static void replace_call_address ();
1.1.1.2   root      184: static void move_movables ();
                    185: static int may_trap_p ();
1.1.1.8   root      186: static void strength_reduce ();
                    187: static void find_mem_givs ();
                    188: static void record_giv ();
                    189: static void delete_insn_forces ();
                    190: static int basic_induction_var ();
                    191: static int general_induction_var ();
                    192: static int consec_sets_giv ();
                    193: static int check_dbra_loop ();
                    194: static void emit_iv_init_code ();
                    195: static int product_cheap_p ();
                    196: static void emit_iv_inc ();
                    197: static int can_eliminate_biv_p ();
                    198: static void eliminate_biv ();
                    199: static rtx final_biv_value ();
1.1.1.11! root      200: static int last_use_this_basic_block ();
1.1       root      201: 
                    202: /* Entry point of this file.  Perform loop optimization
                    203:    on the current function.  F is the first insn of the function
                    204:    and NREGS is the number of register numbers used.  */
                    205: 
1.1.1.2   root      206: void
1.1.1.8   root      207: loop_optimize (f, dumpfile)
1.1       root      208:      /* f is the first instruction of a chain of insns for one function */
                    209:      rtx f;
1.1.1.2   root      210:      FILE *dumpfile;
1.1       root      211: {
                    212:   register rtx insn;
                    213:   register int i;
                    214:   rtx end;
                    215:   rtx last_insn;
                    216: 
1.1.1.2   root      217:   loop_dump_stream = dumpfile;
                    218: 
1.1       root      219:   init_recog ();
                    220: 
1.1.1.10  root      221:   old_max_reg = max_reg_num ();
1.1.1.8   root      222: 
1.1       root      223:   /* First find the last real insn, and count the number of insns,
                    224:      and assign insns their suids.  */
                    225: 
                    226:   for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
                    227:     if (INSN_UID (insn) > i)
                    228:       i = INSN_UID (insn);
                    229: 
                    230:   max_uid = i + 1;
                    231:   uid_luid = (short *) alloca ((i + 1) * sizeof (short));
                    232:   bzero (uid_luid, (i + 1) * sizeof (short));
                    233: 
                    234:   /* Compute the mapping from uids to luids.
                    235:      LUIDs are numbers assigned to insns, like uids,
                    236:      except that luids increase monotonically through the code.  */
                    237: 
                    238:   for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
                    239:     {
                    240:       last_insn = insn;
                    241:       INSN_LUID (insn) = ++i;
                    242:     }
                    243: 
                    244:   max_luid = i;
                    245: 
                    246:   /* Don't leave gaps in uid_luid for insns that have been
                    247:      deleted.  It is possible that the first or last insn
                    248:      using some register has been deleted by cross-jumping.
                    249:      Make sure that uid_luid for that former insn's uid
                    250:      points to the general area where that insn used to be.  */
                    251:   for (i = 0; i < max_uid; i++)
1.1.1.2   root      252:     {
                    253:       uid_luid[0] = uid_luid[i];
                    254:       if (uid_luid[0] != 0)
                    255:        break;
                    256:     }
                    257:   for (i = 0; i < max_uid; i++)
1.1       root      258:     if (uid_luid[i] == 0)
                    259:       uid_luid[i] = uid_luid[i - 1];
                    260: 
                    261:   /* Find and process each loop.
                    262:      We scan from the end, and process each loop when its start is seen,
                    263:      so we process innermost loops first.  */
                    264: 
                    265:   for (insn = last_insn; insn; insn = PREV_INSN (insn))
                    266:     if (GET_CODE (insn) == NOTE
1.1.1.4   root      267:        && NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG)
                    268:       {
1.1       root      269:        /* Make sure it really is a loop -- no jumps in from outside.  */
1.1.1.4   root      270:        end = verify_loop (f, insn);
                    271:        if (end != 0)
                    272:          /* If so, optimize this loop.  */
1.1.1.8   root      273:          scan_loop (insn, end, max_reg_num ());
1.1.1.4   root      274:        else if (loop_dump_stream)
                    275:          fprintf (loop_dump_stream,
                    276:                   "\nLoop at %d ignored due to multiple entry points.\n",
                    277:                   INSN_UID (insn));
                    278:       }
1.1       root      279: }
                    280: 
                    281: /* Optimize one loop whose start is LOOP_START and end is END.
                    282:    LOOP_START is the NOTE_INSN_LOOP_BEG and END is the matching
                    283:    NOTE_INSN_LOOP_END.  */
                    284: 
1.1.1.8   root      285: /* ??? can also move memory writes out of loop if destination
                    286:    address is invariant? */
                    287: 
1.1       root      288: static void
                    289: scan_loop (loop_start, end, nregs)
                    290:      rtx loop_start, end;
                    291:      int nregs;
                    292: {
                    293:   register int i;
                    294:   register rtx p = NEXT_INSN (loop_start);
                    295:   /* 1 if we are scanning insns that could be executed zero times.  */
                    296:   int maybe_never = 0;
1.1.1.3   root      297:   /* 1 if we are scanning insns that might never be executed
                    298:      due to a subroutine call which might exit before they are reached.  */
                    299:   int call_passed = 0;
1.1       root      300:   /* For a rotated loop that is entered near the bottom,
                    301:      this is the label at the top.  Otherwise it is zero.  */
                    302:   rtx loop_top = 0;
1.1.1.2   root      303:   /* This is the insn (whatever kind) before the NOTE that starts the loop.
                    304:      Any insns moved out of the loop will follow it.  */
                    305:   rtx before_start = PREV_INSN (loop_start);
1.1       root      306:   /* Jump insn that enters the loop, or 0 if control drops in.  */
                    307:   rtx loop_entry_jump = 0;
                    308:   /* Place in the loop where control enters.  */
                    309:   rtx scan_start;
                    310:   /* Number of insns in the loop.  */
                    311:   int insn_count;
                    312:   int tem;
1.1.1.8   root      313:   rtx temp;
1.1       root      314:   /* Indexed by register number, contains 1 for a register whose
                    315:      assignments may not be moved out of the loop.  */
                    316:   char *may_not_move;
                    317:   /* Chain describing insns movable in current loop.  */
                    318:   struct movable *movables = 0;
                    319:   /* Last element in `movables' -- so we can add elements at the end.  */
                    320:   struct movable *last_movable = 0;
                    321:   /* Ratio of extra register life span we can justify
                    322:      for saving an instruction.  More if loop doesn't call subroutines
                    323:      since in that case saving an insn makes more difference
                    324:      and more registers are available.  */
1.1.1.10  root      325:   int threshold = loop_has_call ? 15 : 30;
1.1.1.7   root      326:   /* Nonzero if the insn that jumps into the real loop
                    327:      is not the very first thing after the loop-beginning note.  */
                    328:   int something_before_entry_jump = 0;
1.1       root      329: 
                    330:   n_times_set = (short *) alloca (nregs * sizeof (short));
                    331:   n_times_used = (short *) alloca (nregs * sizeof (short));
                    332:   may_not_move = (char *) alloca (nregs);
                    333: 
                    334:   /* Determine whether this loop starts with a jump down
                    335:      to a test at the end.  */
                    336:   while (p != end
                    337:         && GET_CODE (p) != CODE_LABEL && GET_CODE (p) != JUMP_INSN)
1.1.1.7   root      338:     {
                    339:       if (GET_CODE (p) == CALL_INSN || GET_CODE (p) == INSN)
                    340:        something_before_entry_jump = 1;
                    341:       p = NEXT_INSN (p);
                    342:     }
1.1       root      343: 
                    344:   /* "Loop" contains neither jumps nor labels;
                    345:      it must have been a dummy.  Think no more about it.  */
                    346:   if (p == end)
                    347:     return;
                    348: 
1.1.1.2   root      349:   scan_start = p;
                    350: 
1.1       root      351:   /* If loop has a jump before the first label,
                    352:      the true entry is the target of that jump.
                    353:      Start scan from there.
                    354:      But record in LOOP_TOP the place where the end-test jumps
                    355:      back to so we can scan that after the end of the loop.  */
                    356:   if (GET_CODE (p) == JUMP_INSN)
                    357:     {
                    358:       loop_entry_jump = p;
                    359:       loop_top = NEXT_INSN (p);
                    360:       /* Loop entry will never be a conditional jump.
1.1.1.8   root      361:         If we see one, this must not be a real loop.
                    362:         Also, a return-insn isn't a jump to enter the loop.  */
                    363:       if (GET_CODE (loop_top) != BARRIER
                    364:          || GET_CODE (PATTERN (p)) != SET)
1.1       root      365:        return;
1.1.1.5   root      366:       /* Get the label at which the loop is entered.  */
                    367:       p = XEXP (SET_SRC (PATTERN (p)), 0);
1.1       root      368:       /* Check to see whether the jump actually
                    369:         jumps out of the loop (meaning it's no loop).
                    370:         This case can happen for things like
                    371:         do {..} while (0).  */
1.1.1.2   root      372:       if (p == 0
                    373:          || INSN_LUID (p) < INSN_LUID (loop_start)
1.1       root      374:          || INSN_LUID (p) >= INSN_LUID (end))
1.1.1.2   root      375:        {
                    376:          if (loop_dump_stream)
                    377:            fprintf (loop_dump_stream, "\nLoop from %d to %d is phony.\n\n",
                    378:                     INSN_UID (loop_start), INSN_UID (end));
                    379:          return;
                    380:        }
                    381: 
                    382:       /* Find the first label after the entry-jump.  */
                    383:       while (GET_CODE (loop_top) != CODE_LABEL)
                    384:        {
                    385:          loop_top = NEXT_INSN (loop_top);
                    386:          if (loop_top == 0)
                    387:            abort ();
                    388:        }
                    389: 
                    390:       /* Maybe rearrange the loop to drop straight in
                    391:         with a new test to jump around it entirely.
                    392:         (The latter is considered outside the loop.)
                    393:         If this is done, we no longer enter with a jump.  */
1.1.1.7   root      394:       if (! something_before_entry_jump
                    395:          && loop_skip_over (loop_start, end, loop_entry_jump))
1.1.1.8   root      396:        {
                    397:          scan_start = loop_top;
                    398:          loop_top = 0;
                    399:        }
1.1.1.2   root      400:       else
                    401:        /* We really do enter with a jump;
                    402:           scan the loop from the place where the jump jumps to.  */
                    403:        scan_start = p;
1.1       root      404:     }
                    405: 
                    406:   /* Count number of times each reg is set during this loop.
                    407:      Set MAY_NOT_MOVE[I] if it is not safe to move out
                    408:      the setting of register I.  */
                    409: 
                    410:   bzero (n_times_set, nregs * sizeof (short));
                    411:   bzero (may_not_move, nregs);
1.1.1.2   root      412:   count_loop_regs_set (loop_top ? loop_top : loop_start, end,
1.1.1.8   root      413:                       may_not_move, &insn_count, nregs);
1.1       root      414:   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
                    415:     may_not_move[i] = 1, n_times_set[i] = 1;
                    416:   bcopy (n_times_set, n_times_used, nregs * sizeof (short));
                    417: 
1.1.1.2   root      418:   if (loop_dump_stream)
                    419:     fprintf (loop_dump_stream, "\nLoop from %d to %d: %d real insns\n\n",
                    420:             INSN_UID (loop_start), INSN_UID (end), insn_count);
                    421: 
1.1       root      422:   /* Scan through the loop finding insns that are safe to move.
                    423:      In each such insn, store QImode as the mode, to mark it.
                    424:      Then set n_times_set to -1 for the reg being set, so that
                    425:      this reg will be considered invariant for subsequent insns.
                    426:      We consider whether subsequent insns use the reg
                    427:      in deciding whether it is worth actually moving.
                    428: 
                    429:      MAYBE_NEVER is nonzero if we have passed a conditional jump insn
                    430:      and therefore it is possible that the insns we are scanning
                    431:      would never be executed.  At such times, we must make sure
                    432:      that it is safe to execute the insn once instead of zero times.
                    433:      When MAYBE_NEVER is 0, all insns will be executed at least once
                    434:      so that is not a problem.  */
                    435: 
1.1.1.2   root      436:   p = scan_start;
1.1       root      437:   while (1)
                    438:     {
                    439:       p = NEXT_INSN (p);
                    440:       /* At end of a straight-in loop, we are done.
                    441:         At end of a loop entered at the bottom, scan the top.  */
                    442:       if (p == scan_start)
                    443:        break;
                    444:       if (p == end)
                    445:        {
                    446:          if (loop_top != 0)
                    447:            p = NEXT_INSN (loop_top);
                    448:          else
                    449:            break;
                    450:          if (p == scan_start)
                    451:            break;
                    452:        }
                    453:       if (GET_CODE (p) == INSN
                    454:          && GET_CODE (PATTERN (p)) == SET
                    455:          && GET_CODE (SET_DEST (PATTERN (p))) == REG
                    456:          && ! may_not_move[REGNO (SET_DEST (PATTERN (p)))])
                    457:        {
1.1.1.4   root      458:          int tem1 = 0;
1.1.1.11! root      459:          /* Don't try to optimize a register that was made
        !           460:             by loop-optimization for an inner loop.
        !           461:             We don't know its life-span, so we can't compute the benefit.  */
        !           462:          if (REGNO (SET_DEST (PATTERN (p))) >= old_max_reg)
        !           463:            ;
1.1       root      464:          /* If this register is used or set outside the loop,
                    465:             then we can move it only if we know this insn is
                    466:             executed exactly once per iteration,
                    467:             and we can check all the insns executed before it
                    468:             to make sure none of them used the value that
                    469:             was lying around at entry to the loop.  */
1.1.1.11! root      470:          else if ((uid_luid[regno_last_uid[REGNO (SET_DEST (PATTERN (p)))]] > INSN_LUID (end)
        !           471:                    || uid_luid[regno_first_uid[REGNO (SET_DEST (PATTERN (p)))]] < INSN_LUID (loop_start))
        !           472:                   && (maybe_never
        !           473:                       || loop_reg_used_before_p (p, loop_start, scan_start, end)))
1.1       root      474:            ;
1.1.1.8   root      475:          else if (((tem = invariant_p (SET_SRC (PATTERN (p))))
                    476:                    || ((temp = find_reg_note (p, REG_EQUAL, 0)) 
                    477:                        && (tem = invariant_p (XEXP (temp, 0)))))
1.1       root      478:                   && (n_times_set[REGNO (SET_DEST (PATTERN (p)))] == 1
1.1.1.4   root      479:                       || (tem1
                    480:                           = consec_sets_invariant_p (SET_DEST (PATTERN (p)),
                    481:                                                      n_times_set[REGNO (SET_DEST (PATTERN (p)))],
1.1.1.8   root      482:                                                      p)))
1.1.1.3   root      483:                   /* If the insn can cause a trap (such as divide by zero),
                    484:                      can't move it unless it's guaranteed to be executed
                    485:                      once loop is entered.  Even a function call might
                    486:                      prevent the trap insn from being reached
                    487:                      (since it might exit!)  */
                    488:                   && ! ((maybe_never || call_passed)
1.1.1.8   root      489:                         && (may_trap_p (SET_SRC (PATTERN (p)))
                    490:                             || ((temp = find_reg_note (p, REG_EQUAL, 0))
                    491:                                 && may_trap_p (XEXP (temp, 0))))))
1.1       root      492:            {
                    493:              register struct movable *m;
                    494:              register int regno = REGNO (SET_DEST (PATTERN (p)));
1.1.1.2   root      495:              int count;
1.1       root      496:              m = (struct movable *) alloca (sizeof (struct movable));
                    497:              m->next = 0;
                    498:              m->insn = p;
1.1.1.8   root      499:              temp = find_reg_note (p, REG_EQUAL, 0);
                    500:              if (temp)
                    501:                m->set_src = XEXP (temp, 0);
                    502:              else
                    503:                m->set_src = SET_SRC (PATTERN (p));
1.1       root      504:              m->force = 0;
1.1.1.2   root      505:              m->consec = n_times_set[REGNO (SET_DEST (PATTERN (p)))] - 1;
                    506:              m->done = 0;
1.1       root      507:              m->forces = 0;
1.1.1.2   root      508:              m->partial = 0;
1.1       root      509:              m->regno = regno;
1.1.1.4   root      510:              /* Set M->cond if either invariant_p or consec_sets_invariant_p
                    511:                 returned 2 (only conditionally invariant).  */
                    512:              m->cond = ((tem | tem1) > 1);
1.1       root      513:              m->global = (uid_luid[regno_last_uid[regno]] > INSN_LUID (end)
                    514:                           || uid_luid[regno_first_uid[regno]] < INSN_LUID (loop_start));
                    515:              m->match = 0;
                    516:              m->lifetime = (uid_luid[regno_last_uid[regno]]
                    517:                             - uid_luid[regno_first_uid[regno]]);
1.1.1.10  root      518:              m->savings = n_times_used[regno];
1.1       root      519:              n_times_set[regno] = -1;
                    520:              /* Add M to the end of the chain MOVABLES.  */
                    521:              if (movables == 0)
                    522:                movables = m;
                    523:              else
                    524:                last_movable->next = m;
                    525:              last_movable = m;
1.1.1.2   root      526:              /* Skip the consecutive insns, if there are any.  */
                    527:              for (count = m->consec - 1; count >= 0; count--)
                    528:                {
                    529:                  do p = NEXT_INSN (p);
                    530:                  while (GET_CODE (p) == NOTE);
                    531:                }
1.1       root      532:            }
1.1.1.2   root      533:          /* If this register is always set within a STRICT_LOW_PART
                    534:             or set to zero, then its high bytes are constant.
1.1       root      535:             So clear them outside the loop and within the loop
                    536:             just load the low bytes.
                    537:             We must check that the machine has an instruction to do so.
                    538:             Also, if the value loaded into the register
                    539:             depends on the same register, this cannot be done.  */
1.1.1.2   root      540:          else if (SET_SRC (PATTERN (p)) == const0_rtx
                    541:                   && GET_CODE (NEXT_INSN (p)) == INSN
                    542:                   && GET_CODE (PATTERN (NEXT_INSN (p))) == SET
                    543:                   && (GET_CODE (SET_DEST (PATTERN (NEXT_INSN (p))))
                    544:                       == STRICT_LOW_PART)
                    545:                   && (GET_CODE (XEXP (SET_DEST (PATTERN (NEXT_INSN (p))), 0))
                    546:                       == SUBREG)
                    547:                   && (SUBREG_REG (XEXP (SET_DEST (PATTERN (NEXT_INSN (p))), 0))
                    548:                       == SET_DEST (PATTERN (p)))
1.1       root      549:                   && !reg_mentioned_p (SET_DEST (PATTERN (p)),
1.1.1.2   root      550:                                        SET_SRC (PATTERN (NEXT_INSN (p)))))
1.1       root      551:            {
                    552:              register int regno = REGNO (SET_DEST (PATTERN (p)));
1.1.1.2   root      553:              if (n_times_set[regno] == 2)
                    554:                {
                    555:                  register struct movable *m;
                    556:                  int count;
                    557:                  m = (struct movable *) alloca (sizeof (struct movable));
                    558:                  m->next = 0;
                    559:                  m->insn = p;
                    560:                  m->force = 0;
                    561:                  m->consec = 0;
                    562:                  m->done = 0;
                    563:                  m->forces = 0;
                    564:                  m->partial = 1;
                    565:                  m->regno = regno;
                    566:                  m->cond = 0;
                    567:                  /* Say "global" so this register is not combined
                    568:                     with any other.  In fact, it is sometimes possible
                    569:                     to combine two of these registers, but the criteria
                    570:                     are special and have not been programmed in.  */
                    571:                  m->global = 1;
                    572:                  m->match = 0;
                    573:                  m->lifetime = (uid_luid[regno_last_uid[regno]]
                    574:                                 - uid_luid[regno_first_uid[regno]]);
1.1.1.10  root      575:                  m->savings = 1;
1.1.1.2   root      576:                  n_times_set[regno] = -1;
                    577:                  /* Add M to the end of the chain MOVABLES.  */
                    578:                  if (movables == 0)
                    579:                    movables = m;
                    580:                  else
                    581:                    last_movable->next = m;
                    582:                  last_movable = m;
                    583:                  /* Skip the consecutive insns, if there are any.  */
                    584:                  for (count = m->consec - 1; count >= 0; count--)
                    585:                    {
1.1.1.8   root      586:                      /* If first insn of libcall sequence, skip to end.  */
                    587:                      /* Do this at start of loop, since p is guaranteed to 
                    588:                         be an insn here.  */
                    589:                      if (temp = find_reg_note (p, REG_LIBCALL, 0))
                    590:                        {
                    591:                          p = XEXP (temp, 0);
                    592:                          /* Count the libcall as ten insns in terms of
                    593:                             importance of moving it.  */
1.1.1.10  root      594:                          m->savings += 10;
1.1.1.8   root      595:                        }
                    596:                      
1.1.1.2   root      597:                      do p = NEXT_INSN (p);
                    598:                      while (GET_CODE (p) == NOTE);
                    599:                    }
                    600:                }
1.1       root      601:            }
                    602:        }
1.1.1.3   root      603:       /* Past a call insn, we get to insns which might not be executed
                    604:         because the call might exit.  This matters for insns that trap.  */
                    605:       else if (GET_CODE (p) == CALL_INSN)
                    606:        call_passed = 1;
1.1       root      607:       /* Past a label or a jump, we get to insns for which we
                    608:         can't count on whether or how many times they will be
                    609:         executed during each iteration.  Therefore, we can
                    610:         only move out sets of trivial variables
                    611:         (those not used after the loop).  */
                    612:       else if (GET_CODE (p) == CODE_LABEL || GET_CODE (p) == JUMP_INSN)
                    613:        maybe_never = 1;
                    614:     }
                    615: 
                    616:   /* For each movable insn, see if the reg that it loads
1.1.1.2   root      617:      leads when it dies right into another conditionally movable insn.
                    618:      If so, record that the second insn "forces" the first one,
                    619:      since the second can be moved only if the first is.  */
                    620: 
1.1       root      621:   {
                    622:     register struct movable *m, *m1;
                    623:     for (m1 = movables; m1; m1 = m1->next)
1.1.1.10  root      624:       /* Omit this if moving just the (SET (REG) 0) of a zero-extend.  */
                    625:       if (!m1->partial)
                    626:        {
                    627:          int regno = m1->regno;
                    628:          for (m = m1->next; m; m = m->next)
                    629:            /* ??? Could this be a bug?  What if CSE caused the
                    630:               register of M1 to be used after this insn?
                    631:               Since CSE does not update regno_last_uid,
                    632:               this insn M->insn might not be where it dies.
                    633:               But very likely this doesn't matter; what matters is
                    634:               that M's reg is computed from M1's reg.  */
                    635:            if (INSN_UID (m->insn) == regno_last_uid[regno])
                    636:              break;
                    637:          if (m != 0 && m->set_src == SET_DEST (PATTERN (m1->insn)))
                    638:            m = 0;
1.1.1.2   root      639: 
1.1.1.10  root      640:          /* Increase the priority of the moving the first insn
                    641:             since it permits the second to be moved as well.  */
                    642:          if (m != 0)
                    643:            {
                    644:              m->forces = m1;
                    645:              m1->lifetime += m->lifetime;
                    646:              m1->savings += m1->savings;
                    647:            }
                    648:        }
1.1       root      649:   }
                    650: 
                    651:   /* See if there are multiple movable insns that load the same value.
                    652:      If there are, make all but the first point at the first one
                    653:      through the `match' field, and add the priorities of them
                    654:      all together as the priority of the first.  */
1.1.1.2   root      655: 
1.1       root      656:   {
                    657:     register struct movable *m;
                    658:     char *matched_regs = (char *) alloca (nregs);
                    659: 
1.1.1.10  root      660:     /* Regs that are set more than once are not allowed to match
1.1.1.2   root      661:        or be matched.  I'm no longer sure why not.  */
1.1.1.8   root      662:     /* Perhaps testing m->consec_sets would be more appropriate here?  */
1.1       root      663: 
                    664:     for (m = movables; m; m = m->next)
1.1.1.2   root      665:       if (m->match == 0 && n_times_used[m->regno] == 1)
1.1       root      666:        {
                    667:          register struct movable *m1;
1.1.1.2   root      668:          int regno = m->regno;
1.1       root      669: 
                    670:          bzero (matched_regs, nregs);
1.1.1.2   root      671:          matched_regs[regno] = 1;
1.1       root      672: 
                    673:          for (m1 = m->next; m1; m1 = m1->next)
1.1.1.2   root      674:            if (m1->match == 0 && n_times_used[m1->regno] == 1
                    675:                /* A reg used outside the loop mustn't be eliminated.  */
                    676:                && !m1->global
                    677:                && (matched_regs[m1->regno]
                    678:                    ||
                    679:                    (
                    680:                     /* Can't combine regs with different modes
                    681:                        even if loaded from the same constant.  */
                    682:                     (GET_MODE (SET_DEST (PATTERN (m->insn)))
                    683:                      == GET_MODE (SET_DEST (PATTERN (m1->insn))))
                    684:                     /* See if the source of M1 says it matches M.  */
1.1.1.8   root      685:                     && ((GET_CODE (m1->set_src) == REG
                    686:                          && matched_regs[REGNO (m1->set_src)])
                    687:                         || rtx_equal_p (m->set_src, m1->set_src)
1.1.1.2   root      688:                         || (REG_NOTES (m->insn) && REG_NOTES (m1->insn)
                    689:                             && REG_NOTE_KIND (REG_NOTES (m->insn)) == REG_EQUIV
                    690:                             && REG_NOTE_KIND (REG_NOTES (m1->insn)) == REG_EQUIV
                    691:                             && rtx_equal_p (XEXP (REG_NOTES (m->insn), 0),
                    692:                                             XEXP (REG_NOTES (m1->insn), 0)))))))
                    693:              {
                    694:                m->lifetime += m1->lifetime;
1.1.1.10  root      695:                m->savings += m1->savings;
1.1.1.2   root      696:                m1->match = m;
                    697:                matched_regs[m1->regno] = 1;
                    698:              }
                    699:        }
                    700:   }
                    701:        
1.1.1.10  root      702:   /* Now consider each movable insn to decide whether it is worth moving.
                    703:      Store 0 in n_times_set for each reg that is moved.  */
1.1.1.2   root      704: 
1.1.1.8   root      705:   move_movables (movables, threshold,
1.1.1.2   root      706:                 insn_count, loop_start, end, nregs);
1.1.1.8   root      707: 
1.1.1.10  root      708:   /* Now candidates that still have -1 are those not moved.
                    709:      Change n_times_set to indicate that those are not actually invariant.  */
                    710:   for (i = 0; i < nregs; i++)
                    711:     if (n_times_set[i] < 0)
                    712:       n_times_set[i] = n_times_used[i];
                    713: 
1.1.1.8   root      714:   if (flag_strength_reduce)
                    715:     strength_reduce (scan_start, end, loop_top,
                    716:                     insn_count, loop_start, end, nregs);
1.1.1.2   root      717: }
                    718: 
                    719: /* Scan MOVABLES, and move the insns that deserve to be moved.
                    720:    If two matching movables are combined, replace one reg with the
                    721:    other throughout.  */
                    722: 
                    723: static void
1.1.1.8   root      724: move_movables (movables, threshold, insn_count, loop_start, end, nregs)
1.1.1.2   root      725:      struct movable *movables;
                    726:      int threshold;
                    727:      int insn_count;
                    728:      rtx loop_start;
                    729:      rtx end;
                    730:      int nregs;
                    731: {
                    732:   rtx new_start = 0;
                    733:   register struct movable *m;
                    734:   register rtx p;
                    735:   /* Map of pseudo-register replacements to handle combining
                    736:      when we move several insns that load the same value
                    737:      into different pseudo-registers.  */
                    738:   rtx *reg_map = (rtx *) alloca (nregs * sizeof (rtx));
                    739:   char *already_moved = (char *) alloca (nregs);
                    740: 
                    741:   bzero (already_moved, nregs);
                    742:   bzero (reg_map, nregs * sizeof (rtx));
                    743: 
1.1.1.8   root      744:   num_movables = 0;
                    745: 
1.1.1.2   root      746:   for (m = movables; m; m = m->next)
                    747:     {
                    748:       /* Describe this movable insn.  */
                    749: 
                    750:       if (loop_dump_stream)
                    751:        {
                    752:          fprintf (loop_dump_stream, "Insn %d: regno %d (life %d), ",
                    753:                   INSN_UID (m->insn), m->regno, m->lifetime);
                    754:          if (m->consec > 0)
                    755:            fprintf (loop_dump_stream, "consec %d, ", m->consec);
                    756:          if (m->cond)
                    757:            fprintf (loop_dump_stream, "cond ");
                    758:          if (m->force)
                    759:            fprintf (loop_dump_stream, "force ");
                    760:          if (m->global)
                    761:            fprintf (loop_dump_stream, "global ");
                    762:          if (m->done)
                    763:            fprintf (loop_dump_stream, "done ");
                    764:          if (m->match)
                    765:            fprintf (loop_dump_stream, "matches %d ",
                    766:                     INSN_UID (m->match->insn));
                    767:          if (m->forces)
                    768:            fprintf (loop_dump_stream, "forces %d ",
                    769:                     INSN_UID (m->forces->insn));
                    770:        }
                    771: 
1.1.1.8   root      772:       /* Count movables.  Value used in heuristics in strength_reduce.  */
                    773:       num_movables++;
                    774: 
1.1.1.2   root      775:       /* Ignore the insn if it's already done (it matched something else).
                    776:         Otherwise, see if it is now safe to move.  */
                    777: 
                    778:       if (!m->done
                    779:          && (! m->cond
1.1.1.8   root      780:              || (1 == invariant_p (m->set_src)
1.1.1.4   root      781:                  && (m->consec == 0
                    782:                      || 1 == consec_sets_invariant_p (SET_DEST (PATTERN (m->insn)),
                    783:                                                       m->consec + 1,
1.1.1.8   root      784:                                                       m->insn))))
1.1.1.2   root      785:          && (! m->forces || m->forces->done))
                    786:        {
                    787:          register int regno;
                    788:          register rtx p;
1.1.1.10  root      789:          int savings = m->savings;
1.1.1.2   root      790: 
                    791:          /* We have an insn that is safe to move.
                    792:             Compute its desirability.  */
                    793: 
                    794:          p = m->insn;
                    795:          regno = m->regno;
                    796: 
                    797:          if (loop_dump_stream)
1.1.1.10  root      798:            fprintf (loop_dump_stream, "savings %d ", savings);
1.1.1.2   root      799: 
                    800:          /* An insn MUST be moved if we already moved something else
                    801:             which is safe only if this one is moved too: that is,
                    802:             if already_moved[REGNO] is nonzero.  */
                    803: 
                    804:          /* An insn is desirable to move if the new lifetime of the
                    805:             register is no more than THRESHOLD times the old lifetime.
                    806:             If it's not desirable, it means the loop is so big
                    807:             that moving won't speed things up much,
                    808:             and it is liable to make register usage worse.  */
                    809: 
                    810:          /* It is also desirable to move if it can be moved at no
                    811:             extra cost because something else was already moved.  */
                    812: 
                    813:          if (already_moved[regno]
1.1.1.10  root      814:              || (threshold * savings * m->lifetime) >= insn_count
1.1.1.2   root      815:              || (m->forces && m->forces->done
                    816:                  && n_times_used[m->forces->regno] == 1))
1.1       root      817:            {
1.1.1.2   root      818:              int count;
                    819:              register struct movable *m1;
1.1.1.8   root      820:              rtx first;
1.1.1.2   root      821: 
                    822:              for (count = m->consec; count >= 0; count--)
1.1       root      823:                {
1.1.1.8   root      824:                  rtx i1, temp;
                    825: 
                    826:                  /* If first insn of gnulib call sequence, skip to end.  */
                    827:                  /* Do this at start of loop, since p is guaranteed to 
                    828:                     be an insn here.  */
                    829:                  if (temp = find_reg_note (p, REG_LIBCALL, 0))
                    830:                    p = XEXP (temp, 0);
                    831:                  
                    832:                  /* If last insn of gnulib call sequence, move all
                    833:                     insns except the last before the loop.  The last insn is
                    834:                     handled in the normal manner.  */
                    835:                  if (temp = find_reg_note (p, REG_RETVAL, 0))
                    836:                    {
1.1.1.9   root      837:                      rtx fn_address = 0;
                    838:                      rtx fn_reg = 0;
1.1.1.8   root      839:                      first = 0;
                    840:                      for (temp = XEXP (temp, 0); temp != p;
                    841:                           temp = NEXT_INSN (temp))
                    842:                        {
1.1.1.9   root      843:                          rtx body = PATTERN (temp);
                    844:                          rtx n;
                    845:                          /* Extract the function address from the insn
                    846:                             that loads it into a register.
                    847:                             If this insn was cse'd, we get incorrect code.
                    848:                             So delete it and stick the fn address right
                    849:                             into the call insn.  Since the moved insns
                    850:                             won't be cse'd, that does no harm.  */
                    851:                          if (GET_CODE (NEXT_INSN (temp)) == CALL_INSN
                    852:                              && GET_CODE (body) == SET
                    853:                              && GET_CODE (SET_DEST (body)) == REG
                    854:                              && (n = find_reg_note (temp, REG_EQUIV, 0)))
                    855:                            {
                    856:                              fn_reg = SET_SRC (body);
                    857:                              if (GET_CODE (fn_reg) != REG)
                    858:                                fn_reg = SET_DEST (body);
                    859:                              fn_address = XEXP (n, 0);
                    860:                              continue;
                    861:                            }
                    862:                          /* We have the call insn.
                    863:                             Substitute the fn address for the reg
                    864:                             that we believe this insn will use.  */
                    865:                          if (GET_CODE (temp) == CALL_INSN
                    866:                              && fn_address != 0)
                    867:                            replace_call_address (body, fn_reg, fn_address);
1.1.1.10  root      868:                          if (GET_CODE (temp) == CALL_INSN)
                    869:                            i1 = emit_call_insn_before (body, loop_start);
                    870:                          else
                    871:                            i1 = emit_insn_before (body, loop_start);
1.1.1.8   root      872:                          if (first == 0)
                    873:                            first = i1;
                    874:                          REG_NOTES (i1) = REG_NOTES (temp);
                    875:                          delete_insn (temp);
                    876:                        }
                    877:                    }
1.1.1.10  root      878:                  if (GET_CODE (PATTERN (p)) == CALL_INSN)
                    879:                    i1 = emit_call_insn_before (PATTERN (p), loop_start);
                    880:                  else
                    881:                    i1 = emit_insn_before (PATTERN (p), loop_start);
1.1.1.8   root      882: 
1.1.1.2   root      883:                  if (new_start == 0)
                    884:                    new_start = i1;
                    885: 
                    886:                  if (loop_dump_stream)
                    887:                    fprintf (loop_dump_stream, "moved to %d", INSN_UID (i1));
                    888: 
                    889:                  /* Mark the moved, invariant reg as being equivalent to
                    890:                     its constant value.  */
                    891:                  REG_NOTES (i1) = REG_NOTES (p);
                    892:                  if (REG_NOTES (i1) == 0
1.1.1.8   root      893:                      && ! m->partial /* But not if it's a zero-extend clr. */
1.1.1.2   root      894:                      && ! m->global /* and not if used outside the loop
                    895:                                        (since it might get set outside).  */
                    896:                      && CONSTANT_P (SET_SRC (PATTERN (p))))
                    897:                    REG_NOTES (i1)
                    898:                      = gen_rtx (EXPR_LIST, REG_EQUIV,
                    899:                                 SET_SRC (PATTERN (p)), REG_NOTES (i1));
1.1.1.8   root      900: 
                    901:                  /* If library call, now fix the REG_NOTES that contain
                    902:                     insn pointers, namely REG_LIBCALL on FIRST
                    903:                     and REG_RETVAL on I1.  */
                    904:                  if (temp = find_reg_note (i1, REG_RETVAL, 0))
                    905:                    {
                    906:                      XEXP (temp, 0) = first;
                    907:                      temp = find_reg_note (first, REG_LIBCALL, 0);
                    908:                      XEXP (temp, 0) = i1;
                    909:                    }
                    910: 
1.1.1.2   root      911:                  delete_insn (p);
                    912:                  do p = NEXT_INSN (p);
                    913:                  while (GET_CODE (p) == NOTE);
1.1       root      914:                }
1.1.1.2   root      915: 
1.1.1.10  root      916:              /* The more regs we move, the less we like moving them.  */
                    917:              threshold -= 3;
                    918: 
1.1.1.2   root      919:              /* Any other movable that loads the same register
                    920:                 MUST be moved.  */
                    921:              already_moved[regno] = 1;
                    922: 
                    923:              /* The reg set here is now invariant.  */
                    924:              if (! m->partial)
                    925:                n_times_set[regno] = 0;
                    926: 
                    927:              m->done = 1;
                    928: 
1.1.1.10  root      929:              /* Change the length-of-life info for the register
                    930:                 to say it lives at least the full length of this loop.
                    931:                 This will help guide optimizations in outer loops.  */
                    932: 
                    933:              if (uid_luid[regno_first_uid[regno]] > INSN_LUID (loop_start))
                    934:                /* This is the old insn before all the moved insns.
                    935:                   We can't use the moved insn because it is out of range
                    936:                   in uid_luid.  Only the old insns have luids.  */
                    937:                regno_first_uid[regno] = INSN_UID (loop_start);
                    938:              if (uid_luid[regno_last_uid[regno]] < INSN_LUID (end))
                    939:                regno_last_uid[regno] = INSN_UID (end);
                    940: 
1.1.1.2   root      941:              /* Combine with this moved insn any other matching movables.  */
1.1       root      942: 
                    943:              for (m1 = m->next; m1; m1 = m1->next)
                    944:                if (m1->match == m)
                    945:                  {
1.1.1.8   root      946:                    rtx temp;
                    947: 
1.1       root      948:                    /* Schedule the reg loaded by M1
                    949:                       for replacement so that shares the reg of M.  */
                    950:                    reg_map[m1->regno] = SET_DEST (PATTERN (m->insn));
1.1.1.2   root      951:                    /* Get rid of the matching insn
1.1       root      952:                       and prevent further processing of it.  */
1.1.1.2   root      953:                    m1->done = 1;
1.1.1.8   root      954: 
                    955:                    /* if library call, delete all insn except last, which
                    956:                       is deleted below */
                    957:                    if (temp = find_reg_note (m1->insn, REG_RETVAL, 0))
                    958:                      {
                    959:                        for (temp = XEXP (temp, 0); temp != m1->insn;
                    960:                             temp = NEXT_INSN (temp))
                    961:                            delete_insn (temp);
                    962:                      }
1.1       root      963:                    delete_insn (m1->insn);
1.1.1.2   root      964: 
                    965:                    /* Any other movable that loads the same register
                    966:                       MUST be moved.  */
                    967:                    already_moved[m1->regno] = 1;
                    968: 
                    969:                    /* The reg merged here is now invariant.  */
                    970:                    if (m->partial)
                    971:                      n_times_set[m1->regno] = 0;
1.1       root      972:                  }
                    973:            }
1.1.1.2   root      974:          else if (loop_dump_stream)
                    975:            fprintf (loop_dump_stream, "not desirable");
1.1       root      976:        }
1.1.1.2   root      977:       else if (loop_dump_stream && !m->match)
                    978:        fprintf (loop_dump_stream, "not safe");
1.1       root      979: 
1.1.1.2   root      980:       if (loop_dump_stream)
                    981:        fprintf (loop_dump_stream, "\n");
                    982:     }
1.1       root      983: 
1.1.1.2   root      984:   if (new_start == 0)
                    985:     new_start = loop_start;
1.1       root      986: 
1.1.1.2   root      987:   /* Go through all the instructions in the loop, making
                    988:      all the register substitutions scheduled in REG_MAP.  */
                    989:   for (p = new_start; p != end; p = NEXT_INSN (p))
                    990:     if (GET_CODE (p) == INSN || GET_CODE (p) == JUMP_INSN
                    991:        || GET_CODE (p) == CALL_INSN)
1.1.1.8   root      992:       replace_regs (PATTERN (p), reg_map, nregs);
1.1.1.2   root      993: }
                    994: 
                    995: /* Optionally change a loop which enters just before the endtest
                    996:    to one which falls straight in
                    997:    after skipping around the entire loop if the endtest would drop out.
                    998:    Returns 1 if the change was made, 0 if the loop was not really suitable.  */
                    999: 
                   1000: int
                   1001: loop_skip_over (start, end, loop_entry_jump)
                   1002:      rtx start;
                   1003:      rtx end;
                   1004:      rtx loop_entry_jump;
                   1005: {
                   1006:   rtx endtestjump;
                   1007:   register rtx p = JUMP_LABEL (loop_entry_jump);
1.1       root     1008: 
1.1.1.2   root     1009:   while (GET_CODE (p) != INSN && GET_CODE (p) != JUMP_INSN
                   1010:         && GET_CODE (p) != CALL_INSN)
                   1011:     p = NEXT_INSN (p);
                   1012:   endtestjump = next_real_insn (p);
                   1013: 
                   1014:   /* Check that we (1) enter at a compare insn and (2)
                   1015:      the insn (presumably a jump) following that compare
                   1016:      is the last in the loop and jumps back to the loop beginning.  */
                   1017: 
1.1.1.8   root     1018:   if (sets_cc0_p (PATTERN (p)) > 0
1.1.1.2   root     1019:       && endtestjump == prev_real_insn (end)
                   1020:       && prev_real_insn (JUMP_LABEL (endtestjump)) == loop_entry_jump)
1.1       root     1021:     {
1.1.1.2   root     1022:       rtx newlab;
                   1023:       /* This is the jump that we insert.  */
                   1024:       rtx new_jump;
                   1025: 
                   1026:       /* Ok, duplicate that test before start of loop.  */
                   1027:       emit_insn_before (copy_rtx (PATTERN (p)), start);
                   1028:       /* Make a new entry-jump (before the original one)
                   1029:         whose condition is opposite to the loop-around endtest
1.1.1.8   root     1030:         and which jumps around the loop (to just after the ending NOTE).  */
1.1.1.2   root     1031:       newlab = gen_label_rtx ();
1.1.1.8   root     1032:       emit_label_after (newlab, end);
1.1.1.2   root     1033:       emit_jump_insn_before (copy_rtx (PATTERN (endtestjump)), start);
                   1034:       new_jump = PREV_INSN (start);
                   1035:       JUMP_LABEL (new_jump) = JUMP_LABEL (endtestjump);
                   1036:       LABEL_NUSES (JUMP_LABEL (endtestjump))++;
                   1037:       invert_jump (new_jump, newlab);
                   1038:       /* Delete the original entry-jump.  */
                   1039:       delete_insn (loop_entry_jump);
1.1       root     1040: 
1.1.1.2   root     1041:       return 1;
1.1       root     1042:     }
1.1.1.2   root     1043: 
                   1044:   return 0;
1.1       root     1045: }
                   1046: 
                   1047: /* Throughout the rtx X, replace many registers according to REG_MAP.
                   1048:    Return the replacement for X (which may be X with altered contents).
1.1.1.8   root     1049:    REG_MAP[R] is the replacement for register R, or 0 for don't replace.
                   1050:    NREGS is the length of REG_MAP; regs >= NREGS are not mapped.  */
1.1       root     1051: 
                   1052: static rtx
1.1.1.8   root     1053: replace_regs (x, reg_map, nregs)
1.1       root     1054:      rtx x;
                   1055:      rtx *reg_map;
1.1.1.8   root     1056:      int nregs;
1.1       root     1057: {
                   1058:   register RTX_CODE code = GET_CODE (x);
                   1059:   register int i;
                   1060:   register char *fmt;
                   1061: 
                   1062:   switch (code)
                   1063:     {
                   1064:     case PC:
                   1065:     case CC0:
                   1066:     case CONST_INT:
                   1067:     case CONST_DOUBLE:
                   1068:     case CONST:
                   1069:     case SYMBOL_REF:
                   1070:     case LABEL_REF:
                   1071:       return x;
                   1072: 
                   1073:     case REG:
1.1.1.8   root     1074:       /* Verify that the register has an entry before trying to access it.  */
                   1075:       if (REGNO (x) < nregs && reg_map[REGNO (x)] != 0)
1.1       root     1076:        return reg_map[REGNO (x)];
                   1077:       return x;
                   1078:     }
                   1079: 
                   1080:   fmt = GET_RTX_FORMAT (code);
                   1081:   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
                   1082:     {
                   1083:       if (fmt[i] == 'e')
1.1.1.8   root     1084:        XEXP (x, i) = replace_regs (XEXP (x, i), reg_map, nregs);
1.1       root     1085:       if (fmt[i] == 'E')
                   1086:        {
                   1087:          register int j;
                   1088:          for (j = 0; j < XVECLEN (x, i); j++)
1.1.1.8   root     1089:            XVECEXP (x, i, j) = replace_regs (XVECEXP (x, i, j), reg_map, nregs);
1.1       root     1090:        }
                   1091:     }
                   1092:   return x;
                   1093: }
                   1094: 
1.1.1.9   root     1095: /* Scan X and replace the address of any MEM in it with ADDR.
                   1096:    REG is the address that MEM should have before the replacement.  */
                   1097: 
                   1098: static void
                   1099: replace_call_address (x, reg, addr)
                   1100:      rtx x, reg, addr;
                   1101: {
                   1102:   register RTX_CODE code = GET_CODE (x);
                   1103:   register int i;
                   1104:   register char *fmt;
                   1105: 
                   1106:   switch (code)
                   1107:     {
                   1108:     case PC:
                   1109:     case CC0:
                   1110:     case CONST_INT:
                   1111:     case CONST_DOUBLE:
                   1112:     case CONST:
                   1113:     case SYMBOL_REF:
                   1114:     case LABEL_REF:
                   1115:     case REG:
                   1116:       return;
                   1117: 
                   1118:     case SET:
                   1119:       /* Short cut for very common case.  */
                   1120:       replace_call_address (XEXP (x, 1), reg, addr);
                   1121:       return;
                   1122: 
                   1123:     case CALL:
                   1124:       /* Short cut for very common case.  */
                   1125:       replace_call_address (XEXP (x, 0), reg, addr);
                   1126:       return;
                   1127: 
                   1128:     case MEM:
                   1129:       /* If this MEM uses a reg other than the one we expected,
                   1130:         something is wrong.  */
                   1131:       if (XEXP (x, 0) != reg)
                   1132:        abort ();
                   1133:       XEXP (x, 0) = addr;
                   1134:       return;
                   1135:     }
                   1136: 
                   1137:   fmt = GET_RTX_FORMAT (code);
                   1138:   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
                   1139:     {
                   1140:       if (fmt[i] == 'e')
                   1141:        replace_call_address (XEXP (x, i), reg, addr);
                   1142:       if (fmt[i] == 'E')
                   1143:        {
                   1144:          register int j;
                   1145:          for (j = 0; j < XVECLEN (x, i); j++)
                   1146:            replace_call_address (XVECEXP (x, i, j), reg, addr);
                   1147:        }
                   1148:     }
                   1149: }
                   1150: 
1.1.1.4   root     1151: #if 0
1.1       root     1152: /* P is an instruction that sets a register to the result of a ZERO_EXTEND.
                   1153:    Replace it with an instruction to load just the low bytes
                   1154:    if the machine supports such an instruction,
                   1155:    and insert above LOOP_START an instruction to clear the register.  */
                   1156: 
                   1157: static void
                   1158: constant_high_bytes (p, loop_start)
                   1159:      rtx p, loop_start;
                   1160: {
                   1161:   register rtx new;
                   1162:   register int insn_code_number;
                   1163: 
                   1164:   /* Try to change (SET (REG ...) (ZERO_EXTEND (..:B ...)))
                   1165:      to (SET (STRICT_LOW_PART (SUBREG:B (REG...))) ...).  */
                   1166: 
                   1167:   new = gen_rtx (SET, VOIDmode,
                   1168:                 gen_rtx (STRICT_LOW_PART, VOIDmode,
                   1169:                          gen_rtx (SUBREG, GET_MODE (XEXP (SET_SRC (PATTERN (p)), 0)),
                   1170:                                   SET_DEST (PATTERN (p)),
                   1171:                                   0)),
                   1172:                 XEXP (SET_SRC (PATTERN (p)), 0));
                   1173:   insn_code_number = recog (new, p);
                   1174: 
                   1175:   if (insn_code_number)
                   1176:     {
                   1177:       register int i;
                   1178: 
                   1179:       /* Clear destination register before the loop.  */
                   1180:       emit_insn_before (gen_rtx (SET, VOIDmode,
                   1181:                                 SET_DEST (PATTERN (p)),
                   1182:                                 const0_rtx),
                   1183:                        loop_start);
                   1184: 
                   1185:       /* Inside the loop, just load the low part.  */
                   1186:       PATTERN (p) = new;
                   1187:     }
                   1188: }
1.1.1.4   root     1189: #endif
1.1       root     1190: 
                   1191: /* Verify that the ostensible loop starting at START
                   1192:    really is a loop: nothing jumps into it from outside.
                   1193:    Return the marker for the end of the loop, or zero if not a real loop.
                   1194: 
                   1195:    Also set the variables `unknown_*_altered' and `loop_has_call',
                   1196:    and fill in the array `loop_store_addrs'.  */
                   1197: 
                   1198: static rtx
                   1199: verify_loop (f, start)
                   1200:      rtx f, start;
                   1201: {
                   1202:   register int level = 1;
                   1203:   register rtx insn, end;
                   1204: 
                   1205:   /* First find the LOOP_END that matches.
                   1206:      Also check each insn for storing in memory and record where.  */
                   1207: 
                   1208:   unknown_address_altered = 0;
                   1209:   unknown_aggregate_altered = 0;
                   1210:   fixed_aggregate_altered = 0;
                   1211:   loop_has_call = 0;
                   1212:   loop_store_addrs_idx = 0;
                   1213: 
1.1.1.8   root     1214:   num_mem_sets = 0;
                   1215:   loops_enclosed = 1;
                   1216: 
1.1       root     1217:   for (insn = NEXT_INSN (start); level > 0; insn = NEXT_INSN (insn))
                   1218:     {
                   1219:       if (insn == 0)
1.1.1.2   root     1220:        /* Parse errors can cause a loop-beg with no loop-end.  */
                   1221:        return 0;
1.1       root     1222:       if (GET_CODE (insn) == NOTE)
                   1223:        {
                   1224:          if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG)
1.1.1.8   root     1225:            {
                   1226:              ++level;
                   1227:              /* Count number of loops contained in this one.  */
                   1228:              loops_enclosed++;
                   1229:            }
1.1       root     1230:          else if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END)
1.1.1.2   root     1231:            {
                   1232:              --level;
                   1233:              if (level == 0)
                   1234:                {
                   1235:                  end = insn;
                   1236:                  break;
                   1237:                }
                   1238:            }
1.1.1.11! root     1239:          /* Don't optimize loops containing setjmps.
        !          1240:             On some machines, longjmp does not restore the reg
        !          1241:             values as of the time of the setjmp.  */
        !          1242:          else if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_SETJMP)
        !          1243:            return 0;
1.1       root     1244:        }
                   1245:       else if (GET_CODE (insn) == CALL_INSN)
                   1246:        {
                   1247:          unknown_address_altered = 1;
                   1248:          loop_has_call = 1;
                   1249:        }
1.1.1.8   root     1250: /* ???
                   1251:       else if (! unknown_address_altered) */
                   1252:       else
1.1       root     1253:        {
                   1254:          if (GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN)
                   1255:            note_stores (PATTERN (insn), note_addr_stored);
                   1256:        }
                   1257:     }
                   1258: 
                   1259:   /* Now scan all jumps in the function and see if any of them can
                   1260:      reach a label within the range of the loop.  */
                   1261: 
                   1262:   for (insn = f; insn; insn = NEXT_INSN (insn))
                   1263:     if (GET_CODE (insn) == JUMP_INSN
                   1264:        /* Don't get fooled by jumps inserted by loop-optimize.
                   1265:           They don't have valid LUIDs, and they never jump into loops.  */
                   1266:        && INSN_UID (insn) < max_uid
                   1267:        && (INSN_LUID (insn) < INSN_LUID (start)
                   1268:            || INSN_LUID (insn) > INSN_LUID (end))
                   1269:        /* We have a jump that is outside the loop.
                   1270:           Does it jump into the loop?  */
                   1271:        && can_jump_into_range_p (PATTERN (insn),
                   1272:                                  INSN_LUID (start), INSN_LUID (end)))
                   1273:       return 0;
                   1274: 
                   1275: #if 0      
                   1276:   /* Now scan all labels between them and check for any jumps from outside.
                   1277:      This uses the ref-chains set up by find_basic_blocks.
                   1278:      This code is not used because it's more convenient for other reasons
                   1279:      to do the loop optimization before find_basic_blocks.  */
                   1280: 
                   1281:   for (insn = start; insn != end; insn = NEXT_INSN (insn))
                   1282:     if (GET_CODE (insn) == CODE_LABEL)
                   1283:       {
                   1284:        register rtx y;
                   1285:        for (y = LABEL_REFS (insn); y != insn; y = LABEL_NEXTREF (y))
                   1286:          if (INSN_LUID (CONTAINING_INSN (y)) < INSN_LUID (start)
                   1287:              || INSN_LUID (CONTAINING_INSN (y)) > INSN_LUID (end))
                   1288:            return 0;
                   1289:       }
                   1290: #endif
                   1291: 
                   1292:   return end;
                   1293: }
                   1294: 
                   1295: /* Return 1 if somewhere in X is a LABEL_REF to a label
                   1296:    located between BEG and END.  */
                   1297: 
                   1298: static int
                   1299: can_jump_into_range_p (x, beg, end)
                   1300:      rtx x;
                   1301:      int beg, end;
                   1302: {
                   1303:   register RTX_CODE code = GET_CODE (x);
                   1304:   register int i;
                   1305:   register char *fmt;
                   1306: 
                   1307:   if (code == LABEL_REF)
                   1308:     {
                   1309:       register int luid = INSN_LUID (XEXP (x, 0));
                   1310:       return luid > beg && luid < end;
                   1311:     }
                   1312: 
                   1313:   fmt = GET_RTX_FORMAT (code);
                   1314:   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
                   1315:     {
                   1316:       if (fmt[i] == 'e')
                   1317:        {
                   1318:          if (can_jump_into_range_p (XEXP (x, i), beg, end))
                   1319:            return 1;
                   1320:        }
                   1321:       else if (fmt[i] == 'E')
                   1322:        {
                   1323:          register int j;
                   1324:          for (j = 0; j < XVECLEN (x, i); j++)
                   1325:            if (can_jump_into_range_p (XVECEXP (x, i, j), beg, end))
                   1326:              return 1;
                   1327:        }
                   1328:     }
                   1329: 
                   1330:   return 0;
                   1331: }
                   1332: 
                   1333: /* Record that a memory reference X is being set.  */
                   1334: 
                   1335: static void
                   1336: note_addr_stored (x)
                   1337:      rtx x;
                   1338: {
                   1339:   if (x == 0 || GET_CODE (x) != MEM)
                   1340:     return;
1.1.1.8   root     1341: 
                   1342:   /* Count number of memory writes.
                   1343:      This affects heuristics in strength_reduce.  */
                   1344:   num_mem_sets++;
                   1345:   if (unknown_address_altered)
                   1346:     return;
                   1347: 
1.1.1.2   root     1348:   if (GET_MODE (x) == BLKmode)
                   1349:     unknown_address_altered = 1;
                   1350:   else if (rtx_addr_varies_p (x))
1.1       root     1351:     {
                   1352:       if (GET_CODE (XEXP (x, 0)) == PLUS)
                   1353:        unknown_aggregate_altered = 1;
                   1354:       else
                   1355:        unknown_address_altered = 1;
                   1356:     }
                   1357:   else
                   1358:     {
                   1359:       register int i;
                   1360:       register rtx addr = XEXP (x, 0);
                   1361: 
1.1.1.8   root     1362:       if (MEM_IN_STRUCT_P (x))
1.1       root     1363:        fixed_aggregate_altered = 1;
                   1364:       for (i = 0; i < loop_store_addrs_idx; i++)
                   1365:        if (rtx_equal_p (loop_store_addrs[i], addr))
                   1366:          {
                   1367:            if (loop_store_widths[i] < GET_MODE_SIZE (GET_MODE (x)))
                   1368:              loop_store_widths[i] = GET_MODE_SIZE (GET_MODE (x));
                   1369:            break;
                   1370:          }
                   1371:       if (i == NUM_STORES)
                   1372:        unknown_address_altered = 1;
                   1373:       else if (i == loop_store_addrs_idx)
                   1374:        {
1.1.1.2   root     1375:          loop_store_widths[i] = GET_MODE_SIZE (GET_MODE (x));
1.1       root     1376:          loop_store_addrs[loop_store_addrs_idx++] = addr;
                   1377:        }
                   1378:     }
                   1379: }
                   1380: 
                   1381: /* Return nonzero if the rtx X is invariant over the current loop.
                   1382: 
                   1383:    The value is 2 if we refer to something only conditionally invariant.
                   1384: 
                   1385:    If `unknown_address_altered' is nonzero, no memory ref is invariant.
                   1386:    Otherwise if `unknown_aggregate_altered' is nonzero,
                   1387:    a memory ref is invariant if it is not part of an aggregate
                   1388:    and its address is fixed and not in `loop_store_addrs'.
                   1389:    Otherwise if `fixed_aggregate_altered' is nonzero,
                   1390:    a memory ref is invariant
                   1391:    if its address is fixed and not in `loop_store_addrs'.
                   1392:    Otherwise, a memory ref is invariant if its address is fixed and not in
                   1393:    `loop_store_addrs' or if it is not an aggregate.  */
                   1394: 
                   1395: static int
1.1.1.8   root     1396: invariant_p (x)
1.1       root     1397:      register rtx x;
                   1398: {
                   1399:   register int i;
                   1400:   register RTX_CODE code = GET_CODE (x);
                   1401:   register char *fmt;
                   1402:   int conditional = 0;
                   1403: 
                   1404:   switch (code)
                   1405:     {
                   1406:     case CONST_INT:
                   1407:     case CONST_DOUBLE:
                   1408:     case SYMBOL_REF:
                   1409:     case LABEL_REF:
                   1410:     case CONST:
                   1411:       return 1;
                   1412: 
                   1413:     case PC:
                   1414:     case CC0:
                   1415:       return 0;
                   1416: 
                   1417:     case REG:
1.1.1.8   root     1418:       /* We used to check RTX_UNCHANGING_P (x) here, but that is invalid
1.1.1.6   root     1419:         since the reg might be set by initialization within the loop.  */
                   1420:       if (x == frame_pointer_rtx || x == arg_pointer_rtx)
1.1.1.2   root     1421:        return 1;
1.1       root     1422:       if (n_times_set[REGNO (x)] == -1)
                   1423:        return 2;
                   1424:       return n_times_set[REGNO (x)] == 0;
                   1425: 
                   1426:     case MEM:
                   1427:       /* A store in a varying-address scalar (or a subroutine call)
                   1428:         could clobber anything in memory.  */
                   1429:       if (unknown_address_altered)
                   1430:        return 0;
1.1.1.2   root     1431:       /* Don't mess with volatile memory references.  */
1.1.1.8   root     1432:       if (MEM_VOLATILE_P (x))
1.1.1.2   root     1433:        return 0;
1.1.1.6   root     1434: #if 0
1.1.1.2   root     1435:       /* If it's declared read-only, it is invariant
                   1436:         if its address is invariant.  */
1.1.1.8   root     1437:       if (RTX_UNCHANGING_P (x))
                   1438:        return invariant_p (XEXP (x, 0));
1.1.1.6   root     1439: #endif
1.1       root     1440:       /* A store in a varying-address aggregate component
                   1441:         could clobber anything except a scalar with a fixed address.  */
                   1442:       if (unknown_aggregate_altered
1.1.1.8   root     1443:          && ((MEM_IN_STRUCT_P (x) || GET_CODE (XEXP (x, 0)) == PLUS)
1.1       root     1444:              || rtx_addr_varies_p (x)))
                   1445:        return 0;
                   1446:       /* A store in a fixed-address aggregate component
                   1447:         could clobber anything whose address is not fixed,
                   1448:         even an aggregate component.  */
                   1449:       if (fixed_aggregate_altered
                   1450:          && rtx_addr_varies_p (x))
                   1451:        return 0;
                   1452:       /* Any store could clobber a varying-address scalar.  */
                   1453:       if (loop_store_addrs_idx
1.1.1.8   root     1454:          && !(MEM_IN_STRUCT_P (x) || GET_CODE (XEXP (x, 0)) == PLUS)
1.1       root     1455:          && rtx_addr_varies_p (x))
                   1456:        return 0;
                   1457:       /* A store in a fixed address clobbers overlapping references.  */
                   1458:       for (i = loop_store_addrs_idx - 1; i >= 0; i--)
1.1.1.2   root     1459:        if (addr_overlap_p (x, loop_store_addrs[i], loop_store_widths[i]))
1.1       root     1460:          return 0;
                   1461:       /* It's not invalidated by a store in memory
                   1462:         but we must still verify the address is invariant.  */
1.1.1.2   root     1463:       break;
                   1464: 
                   1465:     case ASM_OPERANDS:
                   1466:       /* Don't mess with insns declared volatile.  */
1.1.1.8   root     1467:       if (MEM_VOLATILE_P (x))
1.1.1.2   root     1468:        return 0;
1.1       root     1469:     }
                   1470: 
                   1471:   fmt = GET_RTX_FORMAT (code);
                   1472:   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
                   1473:     {
                   1474:       if (fmt[i] == 'e')
                   1475:        {
1.1.1.8   root     1476:          int tem = invariant_p (XEXP (x, i));
1.1       root     1477:          if (tem == 0)
                   1478:            return 0;
                   1479:          if (tem == 2)
                   1480:            conditional = 1;
                   1481:        }
1.1.1.2   root     1482:       else if (fmt[i] == 'E')
                   1483:        {
                   1484:          register int j;
                   1485:          for (j = 0; j < XVECLEN (x, i); j++)
                   1486:            {
1.1.1.8   root     1487:              int tem = invariant_p (XVECEXP (x, i, j));
1.1.1.2   root     1488:              if (tem == 0)
                   1489:                return 0;
                   1490:              if (tem == 2)
                   1491:                conditional = 1;
                   1492:            }
                   1493: 
                   1494:        }
1.1       root     1495:     }
                   1496: 
                   1497:   return 1 + conditional;
                   1498: }
                   1499: 
                   1500: /* Return 1 if OTHER (a mem ref) overlaps the area of memory
                   1501:    which is SIZE bytes starting at BASE.  */
                   1502: 
                   1503: int
                   1504: addr_overlap_p (other, base, size)
                   1505:      rtx other;
                   1506:      rtx base;
                   1507:      int size;
                   1508: {
                   1509:   int start = 0, end;
                   1510: 
                   1511:   if (GET_CODE (base) == CONST)
                   1512:     base = XEXP (base, 0);
                   1513:   if (GET_CODE (base) == PLUS
                   1514:       && GET_CODE (XEXP (base, 1)) == CONST_INT)
                   1515:     {
                   1516:       start = INTVAL (XEXP (base, 1));
                   1517:       base = XEXP (base, 0);
                   1518:     }
                   1519: 
                   1520:   end = start + size;
                   1521:   return refers_to_mem_p (other, base, start, end);
                   1522: }
1.1.1.2   root     1523: 
1.1.1.4   root     1524: /* Return nonzero if all the insns in the loop that set REG
1.1.1.2   root     1525:    are INSN and the immediately following insns,
                   1526:    and if each of those insns sets REG in an invariant way
1.1.1.8   root     1527:    (not counting uses of REG in them).
1.1.1.2   root     1528: 
1.1.1.4   root     1529:    The value is 2 if some of these insns are only conditionally invariant.
                   1530: 
1.1.1.2   root     1531:    We assume that INSN itself is the first set of REG
                   1532:    and that its source is invariant.  */
                   1533: 
                   1534: static int
1.1.1.8   root     1535: consec_sets_invariant_p (reg, n_sets, insn)
1.1.1.4   root     1536:      int n_sets;
1.1.1.2   root     1537:      rtx reg, insn;
                   1538: {
                   1539:   register rtx p = insn;
                   1540:   register int regno = REGNO (reg);
1.1.1.8   root     1541:   rtx temp;
1.1.1.2   root     1542:   /* Number of sets we have to insist on finding after INSN.  */
1.1.1.4   root     1543:   int count = n_sets - 1;
1.1.1.8   root     1544:   int old = n_times_set[regno];
1.1.1.4   root     1545:   int tem = 0;
1.1.1.2   root     1546: 
1.1.1.8   root     1547:   /* If N_SETS hit the limit, we can't rely on its value.  */
                   1548:   if (n_sets == 127)
                   1549:     return 0;
                   1550: 
                   1551:   n_times_set[regno] = 0;
1.1.1.2   root     1552: 
                   1553:   while (count > 0)
                   1554:     {
                   1555:       register enum rtx_code code;
                   1556:       p = NEXT_INSN (p);
                   1557:       code = GET_CODE (p);
1.1.1.8   root     1558: 
                   1559:       /* If library call, skip to end of of it.  */
                   1560:       if (code == INSN && (temp = find_reg_note (p, REG_LIBCALL, 0)))
                   1561:        p = XEXP (temp, 0);
                   1562: 
1.1.1.2   root     1563:       if (code == INSN && GET_CODE (PATTERN (p)) == SET
                   1564:          && GET_CODE (SET_DEST (PATTERN (p))) == REG
                   1565:          && REGNO (SET_DEST (PATTERN (p))) == regno
1.1.1.11! root     1566:          && ((tem |= invariant_p (SET_SRC (PATTERN (p))))
1.1.1.8   root     1567:              || ((temp = find_reg_note (p, REG_EQUAL, 0))
                   1568:                  && (tem |= invariant_p (XEXP (temp, 0))))))
1.1.1.2   root     1569:        count--;
                   1570:       else if (code != NOTE)
                   1571:        {
1.1.1.8   root     1572:          n_times_set[regno] = old;
1.1.1.2   root     1573:          return 0;
                   1574:        }
                   1575:     }
                   1576: 
1.1.1.8   root     1577:   n_times_set[regno] = old;
1.1.1.4   root     1578:   /* If invariant_p ever returned 2, we return 2.  */
                   1579:   return 1 + (tem & 2);
1.1.1.2   root     1580: }
                   1581: 
                   1582: #if 0
                   1583: /* I don't think this condition is sufficient to allow INSN
                   1584:    to be moved, so we no longer test it.  */
1.1       root     1585: 
                   1586: /* Return 1 if all insns in the basic block of INSN and following INSN
                   1587:    that set REG are invariant according to TABLE.  */
                   1588: 
                   1589: static int
                   1590: all_sets_invariant_p (reg, insn, table)
                   1591:      rtx reg, insn;
1.1.1.2   root     1592:      short *table;
1.1       root     1593: {
                   1594:   register rtx p = insn;
                   1595:   register int regno = REGNO (reg);
                   1596: 
                   1597:   while (1)
                   1598:     {
                   1599:       register enum rtx_code code;
                   1600:       p = NEXT_INSN (p);
                   1601:       code = GET_CODE (p);
                   1602:       if (code == CODE_LABEL || code == JUMP_INSN)
                   1603:        return 1;
                   1604:       if (code == INSN && GET_CODE (PATTERN (p)) == SET
                   1605:          && GET_CODE (SET_DEST (PATTERN (p))) == REG
                   1606:          && REGNO (SET_DEST (PATTERN (p))) == regno)
                   1607:        {
                   1608:          if (!invariant_p (SET_SRC (PATTERN (p)), table))
                   1609:            return 0;
                   1610:        }
                   1611:     }
                   1612: }
1.1.1.2   root     1613: #endif /* 0 */
1.1       root     1614: 
                   1615: /* Increment N_TIMES_SET at the index of each register
                   1616:    that is modified by an insn between FROM and TO.
1.1.1.8   root     1617:    If the value of an element of N_TIMES_SET becomes 127 or more,
                   1618:    stop incrementing it, to avoid overflow.
1.1       root     1619: 
                   1620:    Store in *COUNT_PTR the number of actual instruction
                   1621:    in the loop.  We use this to decide what is worth moving out.  */
                   1622: 
                   1623: /* last_set[n] is nonzero iff reg n has been set in the current basic block.
                   1624:    In that case, it is the insn that last set reg n.  */
                   1625: 
                   1626: static void
1.1.1.8   root     1627: count_loop_regs_set (from, to, may_not_move, count_ptr, nregs)
1.1       root     1628:      register rtx from, to;
                   1629:      char *may_not_move;
                   1630:      int *count_ptr;
                   1631:      int nregs;
                   1632: {
                   1633:   register rtx *last_set = (rtx *) alloca (nregs * sizeof (rtx));
                   1634:   register rtx insn;
                   1635:   register int count = 0;
                   1636:   register rtx dest;
                   1637: 
                   1638:   bzero (last_set, nregs * sizeof (rtx));
                   1639:   for (insn = from; insn != to; insn = NEXT_INSN (insn))
                   1640:     {
1.1.1.2   root     1641:       if (GET_CODE (insn) == CALL_INSN)
                   1642:        {
                   1643:          /* If a register is used as a subroutine address,
                   1644:             don't allow this register's setting to be moved out of the loop.
                   1645:             This condition is not at all logically correct
                   1646:             but it averts a very common lossage pattern
                   1647:             and creates lossage much less often.  */
                   1648:          if (GET_CODE (PATTERN (insn)) == CALL
                   1649:              && GET_CODE (XEXP (PATTERN (insn), 0)) == MEM
                   1650:              && GET_CODE (XEXP (XEXP (PATTERN (insn), 0), 0)) == REG)
                   1651:            {
                   1652:              register int regno
                   1653:                = REGNO (XEXP (XEXP (PATTERN (insn), 0), 0));
                   1654:              may_not_move[regno] = 1;
                   1655:            }
                   1656:          else if (GET_CODE (PATTERN (insn)) == SET
                   1657:              && GET_CODE (SET_SRC (PATTERN (insn))) == CALL
                   1658:              && GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 0)) == MEM
                   1659:              && GET_CODE (XEXP (XEXP (SET_SRC (PATTERN (insn)), 0), 0)) == REG)
                   1660:            {
                   1661:              register int regno
                   1662:                = REGNO (XEXP (XEXP (SET_SRC (PATTERN (insn)), 0), 0));
                   1663:              may_not_move[regno] = 1;
                   1664:              /* The call insn itself sets a reg, which cannot be moved.  */
                   1665:              may_not_move[REGNO (SET_DEST (PATTERN (insn)))] = 1;
1.1.1.8   root     1666:              if (n_times_set[REGNO (SET_DEST (PATTERN (insn)))] < 127)
                   1667:                n_times_set[REGNO (SET_DEST (PATTERN (insn)))]++;
1.1.1.2   root     1668:            }
                   1669:        }
                   1670:       if (GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN) 
1.1       root     1671:        {
                   1672:          ++count;
1.1.1.2   root     1673:          if (GET_CODE (PATTERN (insn)) == CLOBBER
                   1674:              && GET_CODE (XEXP (PATTERN (insn), 0)) == REG)
                   1675:            /* Don't move a reg that has an explicit clobber.
                   1676:               We might do so sometimes, but it's not worth the pain.  */
                   1677:            may_not_move[REGNO (XEXP (PATTERN (insn), 0))] = 1;
                   1678:          else if (GET_CODE (PATTERN (insn)) == SET)
1.1       root     1679:            {
                   1680:              dest = SET_DEST (PATTERN (insn));
                   1681:              while (GET_CODE (dest) == SUBREG
                   1682:                     || GET_CODE (dest) == ZERO_EXTRACT
                   1683:                     || GET_CODE (dest) == SIGN_EXTRACT
                   1684:                     || GET_CODE (dest) == STRICT_LOW_PART)
                   1685:                dest = XEXP (dest, 0);
                   1686:              if (GET_CODE (dest) == REG)
                   1687:                {
                   1688:                  register int regno = REGNO (dest);
                   1689:                  /* If this is the first setting of this reg
                   1690:                     in current basic block, and it was set before,
                   1691:                     it must be set in two basic blocks, so it cannot
                   1692:                     be moved out of the loop.  */
                   1693:                  if (n_times_set[regno] > 0 && last_set[regno] == 0)
                   1694:                    may_not_move[regno] = 1;
                   1695:                  /* If this is not first setting in current basic block,
                   1696:                     see if reg was used in between previous one and this.
                   1697:                     If so, neither one can be moved.  */
                   1698:                  if (last_set[regno] != 0
                   1699:                      && reg_used_between_p (dest, last_set[regno], insn))
                   1700:                    may_not_move[regno] = 1;
1.1.1.8   root     1701:                  if (n_times_set[regno] < 127)
                   1702:                    ++n_times_set[regno];
1.1       root     1703:                  last_set[regno] = insn;
                   1704:                }
                   1705:            }
                   1706:          else if (GET_CODE (PATTERN (insn)) == PARALLEL)
                   1707:            {
                   1708:              register int i;
                   1709:              for (i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--)
                   1710:                {
                   1711:                  register rtx x = XVECEXP (PATTERN (insn), 0, i);
1.1.1.2   root     1712:                  if (GET_CODE (x) == CLOBBER && GET_CODE (XEXP (x, 0)) == REG)
                   1713:                    /* Don't move a reg that has an explicit clobber.
                   1714:                       It's not worth the pain to try to do it correctly.  */
                   1715:                    may_not_move[REGNO (XEXP (x, 0))] = 1;
1.1       root     1716:                  if (GET_CODE (x) == SET)
                   1717:                    {
                   1718:                      dest = SET_DEST (x);
                   1719:                      while (GET_CODE (dest) == SUBREG
                   1720:                             || GET_CODE (dest) == ZERO_EXTRACT
                   1721:                             || GET_CODE (dest) == SIGN_EXTRACT
                   1722:                             || GET_CODE (dest) == STRICT_LOW_PART)
                   1723:                        dest = XEXP (dest, 0);
                   1724:                      if (GET_CODE (dest) == REG)
                   1725:                        {
                   1726:                          register int regno = REGNO (dest);
1.1.1.8   root     1727:                          if (n_times_set[regno] < 127)
                   1728:                            ++n_times_set[regno];
1.1       root     1729:                          may_not_move[regno] = 1;
                   1730:                          last_set[regno] = insn;
                   1731:                        }
                   1732:                    }
                   1733:                }
                   1734:            }
                   1735:        }
                   1736:       if (GET_CODE (insn) == CODE_LABEL || GET_CODE (insn) == JUMP_INSN)
                   1737:        bzero (last_set, nregs * sizeof (rtx));
                   1738:     }
                   1739:   *count_ptr = count;
                   1740: }
                   1741: 
                   1742: /* Given a loop that is bounded by LOOP_START and LOOP_END
                   1743:    and that is entered at SCAN_START,
                   1744:    return 1 if the register set by insn INSN is used by
                   1745:    any insn that precedes INSN in cyclic order starting
                   1746:    from the loop entry point.  */
                   1747: 
                   1748: static int
                   1749: loop_reg_used_before_p (insn, loop_start, scan_start, loop_end)
                   1750:      rtx insn, loop_start, scan_start, loop_end;
                   1751: {
                   1752:   rtx reg = SET_DEST (PATTERN (insn));
                   1753:   if (INSN_LUID (scan_start) > INSN_LUID (insn))
                   1754:     return (reg_used_between_p (reg, scan_start, loop_end)
                   1755:            || reg_used_between_p (reg, loop_start, insn));
                   1756:   else
                   1757:     return reg_used_between_p (reg, scan_start, insn);
                   1758: }
1.1.1.2   root     1759: 
1.1.1.3   root     1760: /* Return nonzero if evaluating rtx X might cause a trap.  */
1.1.1.2   root     1761: 
                   1762: static int
                   1763: may_trap_p (x)
                   1764:      rtx x;
                   1765: {
1.1.1.3   root     1766:   int i;
                   1767:   enum rtx_code code = GET_CODE (x);
                   1768:   char *fmt;
                   1769: 
                   1770:   switch (code)
1.1.1.2   root     1771:     {
1.1.1.3   root     1772:       /* Handle these cases fast.  */
                   1773:     case CONST_INT:
                   1774:     case CONST_DOUBLE:
                   1775:     case SYMBOL_REF:
                   1776:     case LABEL_REF:
                   1777:     case CONST:
                   1778:     case PC:
                   1779:     case CC0:
                   1780:     case REG:
                   1781:       return 0;
                   1782: 
1.1.1.5   root     1783:       /* Memory ref can trap unless it's a static var or a stack slot.  */
                   1784:     case MEM:
                   1785:       return rtx_varies_p (XEXP (x, 0));
                   1786: 
1.1.1.3   root     1787:       /* Division by a non-constant might trap.  */
1.1.1.2   root     1788:     case DIV:
                   1789:     case MOD:
                   1790:     case UDIV:
                   1791:     case UMOD:
                   1792:       if (! CONSTANT_P (XEXP (x, 1))
                   1793:          && GET_CODE (XEXP (x, 1)) != CONST_DOUBLE)
                   1794:        return 1;
1.1.1.5   root     1795:     default:
1.1.1.4   root     1796:       /* Any floating arithmetic may trap.  */
1.1.1.5   root     1797:       if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
1.1.1.4   root     1798:        return 1;
1.1.1.3   root     1799:     }
                   1800: 
                   1801:   fmt = GET_RTX_FORMAT (code);
                   1802:   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
                   1803:     {
                   1804:       if (fmt[i] == 'e')
                   1805:        {
                   1806:          if (may_trap_p (XEXP (x, i)))
                   1807:            return 1;
                   1808:        }
                   1809:       else if (fmt[i] == 'E')
                   1810:        {
                   1811:          register int j;
                   1812:          for (j = 0; j < XVECLEN (x, i); j++)
                   1813:            if (may_trap_p (XVECEXP (x, i, j)))
                   1814:              return 1;
                   1815:        }
1.1.1.2   root     1816:     }
                   1817:   return 0;
                   1818: }
1.1.1.8   root     1819: 
                   1820: /* A "basic induction variable" or biv is a pseudo reg that is set
                   1821:    (within this loop) only by incrementing or decrementing it.  */
                   1822: /* A "general induction variable" or giv is a pseudo reg whose
                   1823:    value is a linear function of a biv.  */
                   1824: 
                   1825: /* Bivs are recognized by `basic_induction_var';
                   1826:    Givs by `general_induct_var'.  */
                   1827: 
                   1828: /* An enum for the two different types of givs, those that are used
                   1829:    as memory addresses and those that are calculated into registers.  */
                   1830: enum g_types { DEST_ADDR, DEST_REG };
                   1831: 
                   1832: /* A `struct induction' is created for every instruction that sets
                   1833:    an induction variable (either a biv or a giv).  */
                   1834: 
                   1835: struct induction
                   1836: {
                   1837:   rtx insn;                   /* The insn that sets a biv or giv */
                   1838:   rtx new_reg;                /* New register, containing strength reduced
                   1839:                                  version of this giv.  */
                   1840:   int src_regno;              /* Biv from which this giv is computed.
                   1841:                                  (If this is a biv, then this is the biv.)  */
                   1842:   enum g_types giv_type;       /* Indicate whether DEST_ADDR or DEST_REG giv */
                   1843:   int dest_regno;             /* Destination register for insn: this is the
                   1844:                                  register which was the biv or giv.
                   1845:                                  For a biv, this equals src_reg.
                   1846:                                  For a DEST_ADDR type giv, this is 0.  */
                   1847:   rtx *location;              /* Place in the insn where this giv occurs.
                   1848:                                  If GIV_TYPE is DEST_REG, this is 0.  */
                   1849:   rtx mult_val;                       /* Multiplicative factor for src_reg.  */
                   1850:   rtx add_val;                /* Additive constant for that product.  */
                   1851:   int benefit;                /* Gain from eliminating this insn.  */
                   1852:   int consec;                 /* The number of consecutive insn that set this
                   1853:                                  register; they are all eliminated if this
                   1854:                                  one is.  */
                   1855:   char replaceable;           /* 1 if we can substitute the strength-reduced
                   1856:                                  variable for the original variable.
                   1857:                                  0 means they must be kept separate and the
                   1858:                                  new one must be copied into the old pseudo
                   1859:                                  reg each time the old one is set.  */
                   1860:   char ignore;                /* 1 prohibits further processing of this giv */
                   1861:   int lifetime;                       /* Length of life of this giv */
                   1862:   int times_used;             /* # times this giv is used. */
                   1863:   struct induction *family;    /* Links together all induction variables that
                   1864:                                  have the same src register.  */
                   1865:   struct induction *forces;    /* Points to an induction variable insn which
                   1866:                                  is used only once, to compute this giv,
                   1867:                                  and hence can be deleted if this insn is
                   1868:                                  strength reduced.  */
                   1869:   struct induction *forces2;   /* Likewise.  */
                   1870:   struct induction *same;      /* Links together all induction variables that
                   1871:                                  have the same tuple (src, mult, add).  */
                   1872: };
                   1873: 
                   1874: /* A `struct iv_class' is created for each biv.  */
                   1875: 
                   1876: struct iv_class {
                   1877:   int regno;                   /* Pseudo reg which is the biv.  */
                   1878:   int biv_count;               /* Number of insns setting this reg.  */
                   1879:   struct induction *biv;       /* List of all insns that set this reg.  */
                   1880:   int giv_count;               /* Number of givs computed from this biv.  */
                   1881:   struct induction *giv;       /* List of all insns that compute a giv
                   1882:                                  from this reg.  */
                   1883:   int total_benefit;           /* Sum of BENEFITs of all those givs */
                   1884:   rtx initial_value;           /* Value of reg at loop start */
                   1885:   struct iv_class *next;       /* Links all class structures together */
                   1886:   char init_val_set;           /* Used during scan for initial value,
                   1887:                                  1 if assignment seen, 0 otherwise.  */
                   1888:   char eliminable;            /* 1 if plausible candidate for elimination.  */
                   1889:   char nonneg;                /* 1 if we added a REG_NONNEG note for this.  */
                   1890: };
                   1891: 
                   1892: /* Definitions used by the basic induction variable discovery code.  */
                   1893: enum iv_mode { UNKNOWN_INDUCT, BASIC_INDUCT, NOT_BASIC_INDUCT,
                   1894:                 GENERAL_INDUCT };
                   1895: 
                   1896: /* Relative gain of eliminating various kinds of operations.  */
                   1897: #define NO_BENEFIT    0
                   1898: #define ADD_BENEFIT   1
                   1899: #define SHIFT_BENEFIT 2
                   1900: #define MULT_BENEFIT  4
                   1901: #define LIBCALL_BENEFIT 15
                   1902: /* Benefit penalty, if a giv is not replaceable, i.e. must emit an insn to
                   1903:    copy the value of the strength reduced giv to its original register.  */
                   1904: #define COPY_PENALTY  2
                   1905: 
                   1906: /* Indexed by register number, indicates whether or not register is an
                   1907:    induction variable, and if so what type.  */
                   1908: 
                   1909: static enum iv_mode *induct_var;
                   1910: 
                   1911: /* Indexed by register number, contains pointer to `struct induction'
                   1912:    if register is a general induction variable.  */
                   1913: 
                   1914: static struct induction **induct_struct;
                   1915: 
                   1916: /* Indexed by register number, contains pointer to `struct iv_class'
                   1917:    if register is a basic induction variable.  */
                   1918: 
                   1919: static struct iv_class **class_struct;
                   1920: 
                   1921: /*********************************/
                   1922: 
                   1923: /* ??? Unfinished optimizations, [email protected] */
                   1924: 
                   1925: /* strength reduce addresses found in sources (set () (mem ())*/
                   1926: 
                   1927: /* There is one more optimization you might be interested in doing: to
                   1928:    allocate pseudo registers for frequently-accessed memory locations.
                   1929:    If the same memory location is referenced each time around, it might
                   1930:    be possible to copy it into a register before and out after.
                   1931:    This is especially useful when the memory location is a variable which
                   1932:    is in a stack slot because somewhere its address is taken.  If the
                   1933:    loop doesn't contain a function call and the variable isn't volatile,
                   1934:    it is safe to keep the value in a register for the duration of the
                   1935:    loop. One tricky thing is that the copying of the value back from the
                   1936:    register has to be done on all exits from the loop.  You need to check that
                   1937:    all the exits from the loop go to the same place. */
                   1938: 
                   1939: /* WARNING: the interaction of biv elimination, and recognizing 'constant'
                   1940:    bivs may cause problems */
                   1941: 
                   1942: /* add heuristic so that DEST_ADDR strength reduction does not cause
                   1943:    performance problems */
                   1944: 
                   1945: /* don't eliminate things that can be combined with an addressing mode?
                   1946:    find all giv that have same biv and mult_val (now must also have
                   1947:    same add_val), then for each giv, check to see if its only use
                   1948:    dies in a following memory address, generate a new memory address
                   1949:    and check to see if valid, if valid then store modified mem addr,
                   1950:    else if not valid addr mark giv as not done so that it will get its
                   1951:    own iv */
                   1952: 
                   1953: /* consec_sets_giv does not calculate replaceable and forces correctly,
                   1954:    forces should be a more general linked list instead of two entries */
                   1955: 
                   1956: /* try to optimize branches when it is known that a biv is always positive */
                   1957: 
                   1958: /* when replace biv in compare insn, should replace with closest giv so that
                   1959:    an optimized branch can still be recognized by combiner, i.e. VAXen acb */
                   1960: 
                   1961: /* should merge final_value calculation in check_dbra_loop with the 
                   1962:    new final_biv_value function */
                   1963: 
                   1964: /* many of the checks involving uid_luid could be simplified if regscan
                   1965:    was rerun in loop_optimize() whenever a register was added or moved,
                   1966:    also some of the optimizations could be a little less conservative */
                   1967: 
                   1968: /* Perform strength reduction and induction variable elimination.  */
                   1969: 
                   1970: /* Pseudo registers created during this function will be beyond the last
                   1971:    valid index in several tables including n_times_set and regno_last_uid.
                   1972:    This does not cause a problem here, because the added registers cannot be
                   1973:    givs outside of their loop, and hence will never be reconsidered.
                   1974:    But scan_loop must check regnos to make sure they are in bounds.  */
                   1975: 
                   1976: static void
                   1977: strength_reduce (scan_start, end, loop_top, insn_count,
                   1978:                 loop_start, loop_end, nregs)
                   1979:      rtx scan_start;
                   1980:      rtx end;
                   1981:      rtx loop_top;
                   1982:      int insn_count;
                   1983:      rtx loop_start;
                   1984:      rtx loop_end;
                   1985:      int nregs;
                   1986: {
                   1987:   rtx p;
                   1988:   rtx inc_val;
                   1989:   rtx mult_val;
                   1990:   int dest_regno;
                   1991:   int biv_found;
                   1992:   /* This is 1 if current insn could be executed zero times in the loop.  */
                   1993:   int maybe_never = 0;
                   1994:   /* List of all possible basic induction variables.  */
                   1995:   struct iv_class *iv_list = 0;
                   1996:   /* Temporary list pointers for traversing iv_list.  */
                   1997:   struct iv_class *bl, *backbl;
                   1998:   /* Ratio of extra register life span we can justify
                   1999:      for saving an instruction.  More if loop doesn't call subroutines
                   2000:      since in that case saving an insn makes more difference
                   2001:      and more registers are available.  */
                   2002:   /* ??? could set this to last value of threshold in move_movables */
                   2003:   int threshold = loop_has_call ? 17 : 34;
                   2004:   /* Map of pseudo-register replacements.  */
                   2005:   rtx *reg_map;
                   2006: 
                   2007:   induct_var = (enum iv_mode *) alloca (nregs * sizeof (induct_var[0]));
                   2008:   bzero ((char *)induct_var, nregs * sizeof (induct_var[0]));
                   2009:   induct_struct = (struct induction **)
                   2010:     alloca (nregs * sizeof (struct induction *));
                   2011:   bzero ((char *)induct_struct, nregs * sizeof (struct induction *));
                   2012:   class_struct = (struct iv_class **)
                   2013:     alloca (nregs * sizeof (struct iv_class *));
                   2014:   bzero ((char *)class_struct, nregs * sizeof (struct iv_class *));
                   2015: 
                   2016:   /* Scan through loop to find all possible bivs.  */
                   2017: 
                   2018:   for (p = NEXT_INSN (loop_start); p != end; p = NEXT_INSN (p))
                   2019:     {
                   2020:       if (GET_CODE (p) == INSN
                   2021:          && GET_CODE (PATTERN (p)) == SET
                   2022:          && GET_CODE (SET_DEST (PATTERN (p))) == REG)
                   2023:        {
                   2024:          dest_regno = REGNO (SET_DEST (PATTERN (p)));
                   2025:          if (induct_var[dest_regno] != NOT_BASIC_INDUCT)
                   2026:            {
                   2027:              if (basic_induction_var (SET_SRC (PATTERN (p)), dest_regno,
                   2028:                                      &inc_val, &mult_val))
                   2029:                {
                   2030:                  /* It is a possible basic induction variable.
                   2031:                     Create and initialize an induction structure for it.  */
                   2032: 
                   2033:                  struct induction *v =
                   2034:                    (struct induction *) alloca (sizeof (struct induction));
                   2035: 
                   2036:                  v->insn = p;
                   2037:                  v->src_regno = dest_regno;
                   2038:                  v->dest_regno = dest_regno;
                   2039:                  v->mult_val = mult_val;
                   2040:                  v->add_val = inc_val;
                   2041: 
                   2042:                  /* Add this to the reg's iv_class, creating a class
                   2043:                     if this is the first incrementation of the reg.  */
                   2044: 
                   2045:                  bl = class_struct[dest_regno];
                   2046:                  if (bl)
                   2047:                    {
                   2048:                      v->family = bl->biv;
                   2049:                      bl->biv = v;
                   2050:                      bl->biv_count++;
                   2051:                    }
                   2052:                  else
                   2053:                    {
                   2054:                      /* Create and initialize new iv_class.  */
                   2055: 
                   2056:                      bl = (struct iv_class *) alloca (sizeof (struct iv_class));
                   2057: 
                   2058:                      bl->regno = dest_regno;
                   2059:                      bl->biv = v;
                   2060:                      v->family = 0;
                   2061:                      bl->giv = 0;
                   2062:                      bl->biv_count = 1;
                   2063:                      bl->giv_count = 0;
                   2064: 
                   2065:                      /* Set initial value to the reg itself.  */
                   2066:                      bl->initial_value = SET_DEST (PATTERN (p));
                   2067:                      bl->init_val_set = 0;
                   2068:                      bl->eliminable = 0;
                   2069:                      bl->nonneg = 0;
                   2070: 
                   2071:                      /* Add this insn to iv_list.  */
                   2072:                      bl->next = iv_list;
                   2073:                      iv_list = bl;
                   2074: 
                   2075:                      /* Put it in the array of iv_lists.  */
                   2076:                      class_struct[dest_regno] = bl;
                   2077:                    }
                   2078: 
                   2079:                  induct_var[dest_regno] = BASIC_INDUCT;
                   2080: 
                   2081:                  if (loop_dump_stream)
                   2082:                    {
                   2083:                      fprintf (loop_dump_stream,
                   2084:                               "Insn %d: possible biv, reg %d,",
                   2085:                               INSN_UID (p), dest_regno);
                   2086:                      if (GET_CODE (inc_val) == CONST_INT)
                   2087:                        fprintf (loop_dump_stream, " const = %d\n",
                   2088:                                 INTVAL (inc_val));
                   2089:                      else
                   2090:                        {
                   2091:                          fprintf (loop_dump_stream, " const = ");
                   2092:                          print_rtl (loop_dump_stream, inc_val);
                   2093:                          fprintf (loop_dump_stream, "\n");
                   2094:                        }
                   2095:                    }
                   2096:                }
                   2097:              else
                   2098:                induct_var[dest_regno] = NOT_BASIC_INDUCT;
                   2099:            }
                   2100:        }
                   2101:     }
                   2102: 
                   2103:   /* Scan iv_list to remove all regs that proved not to be bivs.
                   2104:      Make a sanity check against n_times_set.  */
                   2105: 
                   2106:   biv_found = 0;
                   2107: 
                   2108:   for (backbl = bl = iv_list; bl; backbl = bl, bl = bl->next)
                   2109:     {
                   2110:       if (induct_var[bl->regno] != BASIC_INDUCT)
                   2111:        {
                   2112:          /* Not a basic induction variable, remove this iv_class.  */
                   2113: 
                   2114:          if (backbl == bl)
                   2115:            iv_list = bl->next;
                   2116:          else
                   2117:            backbl->next = bl->next;
                   2118: 
                   2119:          if (loop_dump_stream)
                   2120:            fprintf (loop_dump_stream, "Reg %d: biv discarded, not induct\n",
                   2121:                    bl->regno);
                   2122:        }
                   2123:       else if (n_times_set[bl->regno] != bl->biv_count)
                   2124:        {
                   2125:          /* This happens if register modified by subreg, etc.  */
                   2126:          /* Make sure it is not recognized as a basic induction var: */
                   2127:          /* remove this iv_class from iv_list.  */
                   2128: 
                   2129:          induct_var[bl->regno] = NOT_BASIC_INDUCT;
                   2130: 
                   2131:          if (backbl == bl)
                   2132:            iv_list = bl->next;
                   2133:          else
                   2134:            backbl->next = bl->next;
                   2135: 
                   2136:          if (loop_dump_stream)
                   2137:            fprintf (loop_dump_stream, "Reg %d: biv discarded, count error\n",
                   2138:                    bl->regno);
                   2139:        }
                   2140:       else
                   2141:        {
                   2142:          /* This is a valid basic induction variable.  */
                   2143: 
                   2144:          biv_found++;
                   2145: 
                   2146:          if (loop_dump_stream)
                   2147:            fprintf (loop_dump_stream, "Reg %d: biv verified\n", bl->regno);
                   2148:        }
                   2149:     }
                   2150: 
                   2151:   /* Exit if there are no bivs.  */
                   2152:   if (!iv_list)
                   2153:     return;
                   2154: 
                   2155:   /* Find initial value for each biv.  */
                   2156:   /* Search backwards from loop_start, halting at first label
                   2157:      or when all bivs have been seen.  */
                   2158: 
                   2159:   p = loop_start;
                   2160:   while (biv_found)
                   2161:     {
                   2162:       p = PREV_INSN (p);
                   2163:       if (p == 0)
                   2164:        break;
                   2165: 
                   2166:       if (GET_CODE (p) == INSN
                   2167:          && GET_CODE (PATTERN (p)) == SET
                   2168:          && GET_CODE (SET_DEST (PATTERN (p))) == REG)
                   2169:        {
                   2170:          int dest_regno = REGNO (SET_DEST (PATTERN (p)));
                   2171: 
                   2172:          if (induct_var[dest_regno] == BASIC_INDUCT
                   2173:              && class_struct[dest_regno]->init_val_set == 0)
                   2174:            {
                   2175:              /* This is the first modification found for this reg.  */
                   2176: 
                   2177:              /* Save value if it is a constant or register.  */
                   2178:              if (GET_CODE (SET_SRC (PATTERN (p))) == CONST_INT
                   2179:                  || GET_CODE (SET_SRC (PATTERN (p))) == REG)
                   2180:                {
                   2181:                  class_struct[dest_regno]->initial_value
                   2182:                    = SET_SRC (PATTERN (p));
                   2183:                  
                   2184:                  if (loop_dump_stream)
                   2185:                    fprintf (loop_dump_stream, "Reg %d: initial value ",
                   2186:                             dest_regno);
                   2187:                  if (loop_dump_stream)
                   2188:                    {
                   2189:                      if (GET_CODE (SET_SRC (PATTERN (p))) == CONST_INT)
                   2190:                        fprintf (loop_dump_stream, "%d\n", 
                   2191:                                 INTVAL (SET_SRC (PATTERN (p))));
                   2192:                      else
                   2193:                        fprintf (loop_dump_stream, "reg %d\n", 
                   2194:                                 REGNO (SET_SRC (PATTERN (p))));
                   2195:                    }
                   2196:                }
                   2197:              else
                   2198:                {
                   2199:                  /* Biv initial value is not simple move,
                   2200:                     so let it keep intial value of "itself".  */
                   2201: 
                   2202:                  if (loop_dump_stream)
                   2203:                    fprintf (loop_dump_stream, "Reg %d: complex initial value\n",
                   2204:                             dest_regno);
                   2205:                }
                   2206: 
                   2207:              class_struct[dest_regno]->init_val_set = 1;
                   2208:              biv_found--;
                   2209:            }
                   2210:        }
                   2211:       else if (GET_CODE (p) == CODE_LABEL)
                   2212:        break;
                   2213:     }
                   2214: 
                   2215:   /* Search the loop for general induction variables.  */
                   2216: 
                   2217:   /* A register is a giv if: it is only set once, it is a function of a
                   2218:      biv and a constant (or invariant), and it is not a biv.  */
                   2219: 
                   2220:   p = scan_start;
                   2221:   while (1)
                   2222:     {
                   2223:       p = NEXT_INSN (p);
                   2224:       /* At end of a straight-in loop, we are done.
                   2225:         At end of a loop entered at the bottom, scan the top.  */
                   2226:       if (p == scan_start)
                   2227:        break;
                   2228:       if (p == end)
                   2229:        {
                   2230:          if (loop_top != 0)
                   2231:            p = NEXT_INSN (loop_top);
                   2232:          else
                   2233:            break;
                   2234:          if (p == scan_start)
                   2235:            break;
                   2236:        }
                   2237: 
                   2238:       /* Look for a general induction variable in a register.  */
                   2239:       if (GET_CODE (p) == INSN
                   2240:          && GET_CODE (PATTERN (p)) == SET
                   2241:          && GET_CODE (SET_DEST (PATTERN (p))) == REG)
                   2242:        {
                   2243:          int src_regno;
                   2244:          rtx add_val;
                   2245:          rtx mult_val;
                   2246:          int benefit;
                   2247:          rtx regnote = 0;
                   2248:          struct induction *forces = 0;
                   2249:          struct induction *forces2 = 0;
                   2250: 
                   2251:          dest_regno = REGNO (SET_DEST (PATTERN (p)));
                   2252: 
                   2253:          if (/* Normal giv.  */
                   2254:              ((benefit = general_induction_var (SET_SRC (PATTERN (p)),
                   2255:                                                 &src_regno, &add_val,
                   2256:                                                 &mult_val,
                   2257:                                                 &forces, &forces2))
                   2258:               /* Giv set with call to a library routine.  */
                   2259:               || ((regnote = find_reg_note (p, REG_EQUAL, 0))
                   2260:                   &&
                   2261:                   (benefit = general_induction_var (XEXP (regnote, 0),
                   2262:                                                     &src_regno,
                   2263:                                                     &add_val, &mult_val,
                   2264:                                                     &forces, &forces2))))
1.1.1.11! root     2265:              /* Don't try to handle any regs made by loop optimization.
        !          2266:                 We have nothing on them in regno_first_uid, etc.  */
        !          2267:              && dest_regno < old_max_reg
1.1.1.8   root     2268:              /* Don't recognize a BASIC_INDUCT_VAR here.  */
                   2269:              && dest_regno != src_regno
                   2270:              /* This must be the only place where the register is set.  */
                   2271:              && (n_times_set[dest_regno] == 1
                   2272:                  || (benefit = consec_sets_giv (benefit, p,
                   2273:                                                 src_regno, dest_regno,
                   2274:                                                 &add_val, &mult_val))))
                   2275:            {
                   2276:              int count;
                   2277:              struct induction *v =
                   2278:                (struct induction *) alloca (sizeof (struct induction));
                   2279:              rtx temp;
                   2280: 
                   2281:              record_giv (v, p, src_regno, dest_regno, mult_val, add_val, benefit,
                   2282:                          forces, forces2, DEST_REG, maybe_never, 0);
                   2283: 
                   2284:              /* Skip the consecutive insns, if there are any.  */
                   2285:              for (count = v->consec - 1; count >= 0; count--)
                   2286:                {
                   2287:                  /* If first insn of libcall sequence, skip to end.  */
                   2288:                  /* Do this at start of loop, since INSN is guaranteed to
                   2289:                     be an insn here.  */
                   2290:                  if (temp = find_reg_note (p, REG_LIBCALL, 0))
                   2291:                    {
                   2292:                      /* Eliminating a libcall does more good than
                   2293:                         eliminating a single insn to do the same job.  */
                   2294:                      benefit += LIBCALL_BENEFIT;
                   2295:                      p = XEXP (temp, 0);
                   2296:                    }
                   2297: 
                   2298:                  do p = NEXT_INSN (p);
                   2299:                  while (GET_CODE (p) == NOTE);
                   2300:                }
                   2301:            }
                   2302:        }
                   2303: 
                   2304: #ifndef DONT_REDUCE_ADDR
                   2305:       /* Look for givs which are memory addresses.  */
                   2306:       /* This resulted in worse code on a VAX 8600.  I wonder if it
                   2307:         still does.  */
                   2308:       if (GET_CODE (p) == INSN)
                   2309:        find_mem_givs (PATTERN (p), p, maybe_never);
                   2310: #endif
                   2311: 
                   2312:       /* Past a label or a jump, we get to insns for which we can't count
                   2313:         on whether or how many times they will be executed during each
                   2314:         iteration.  Givs found afterwards cannot be marked replaceable.  */
                   2315:       if (GET_CODE (p) == CODE_LABEL || GET_CODE (p) == JUMP_INSN)
                   2316:        maybe_never = 1;
                   2317:     }
                   2318: 
                   2319:   /* Try to prove that the loop counter variable (if any) is always
                   2320:      nonnegative; if so, record that fact with a REG_NONNEG note
                   2321:      so that "decrement and branch until zero" insn can be used.  */
                   2322:   check_dbra_loop (loop_end, iv_list, insn_count, loop_start);
                   2323: 
                   2324:   /* Create reg_map to hold substitutions for replaceable giv regs.  */
                   2325:   reg_map = (rtx *) alloca (nregs * sizeof (rtx));
                   2326:   bzero ((char *)reg_map, nregs * sizeof (rtx));
                   2327: 
                   2328:   /* Examine each iv class for feasibility of strength reduction/induction
                   2329:      variable elimination.  */
                   2330: 
                   2331:   for (bl = iv_list; bl; bl = bl->next)
                   2332:     {
                   2333:       struct induction *v;
                   2334:       int benefit;
                   2335:       int replaceable;
                   2336:       int all_reduced;
                   2337:       rtx final_value = 0;
                   2338: 
                   2339:       /* Test whether it will be possible to eliminate this biv
1.1.1.10  root     2340:         provided all givs are reduced.  This is possible if either
                   2341:         the reg is not used outside the loop, or we can compute
                   2342:         what its final value will be.
1.1.1.8   root     2343: 
                   2344:         Don't try if we put a REG_NONNEG note on the endtest for this biv.
                   2345:         ??? That should be only on machines that have dbra insns.  */
                   2346: 
                   2347:       if ((uid_luid[regno_last_uid[bl->regno]] < INSN_LUID (loop_end)
1.1.1.10  root     2348:           && uid_luid[regno_first_uid[bl->regno]] > INSN_LUID (loop_start)
1.1.1.8   root     2349:           && bl->init_val_set && ! bl->nonneg)
                   2350:          || (final_value = final_biv_value (bl, loop_end)))
                   2351:        {
                   2352:          /* Get the REG rtx for the biv.  */
                   2353:          rtx reg = SET_DEST (PATTERN (bl->biv->insn));
                   2354: 
                   2355:          for (p = loop_start; p != end; p = NEXT_INSN (p))
                   2356:            {
                   2357:              enum rtx_code code = GET_CODE (p);
                   2358:              if ((code == INSN || code == JUMP_INSN || code == CALL_INSN)
                   2359:                  && reg_mentioned_p (reg, PATTERN (p)))
                   2360:                {
                   2361:                  /* This insn uses the biv.  If we can't understand it,
                   2362:                     then we can't eliminate the biv.  */
                   2363:                  if (GET_CODE (PATTERN (p)) != SET)
                   2364:                    break;
                   2365: 
                   2366:                  /* The insns that increment the biv are no problem.  */
                   2367:                  if (SET_DEST (PATTERN (p)) == reg)
                   2368:                    continue;
                   2369: 
                   2370:                  /* If can rewrite this insn not to use the biv, it's ok.  */
                   2371:                  if (can_eliminate_biv_p (p, bl))
                   2372:                    continue;
                   2373: 
                   2374:                  /* If this is an insn which computes a giv, no problem,
                   2375:                     because it will go away if the giv is reduced.  */
                   2376:                  for (v = bl->giv; v; v = v->family)
                   2377:                    if (!v->ignore && v->insn == p && v->giv_type == DEST_REG)
                   2378:                      break;
                   2379:                  if (v)
                   2380:                    continue;
                   2381: 
                   2382:                  /* Biv is used in a way we cannot eliminate.  */
                   2383:                  break;
                   2384:                }
                   2385:            }
                   2386: 
                   2387:          if (p == end)
                   2388:            {
                   2389:              bl->eliminable = 1;
                   2390:              if (loop_dump_stream)
                   2391:                fprintf (loop_dump_stream, "Can eliminate biv %d.\n",
                   2392:                         bl->regno);
                   2393:            }
                   2394:          else if (loop_dump_stream)
                   2395:            fprintf (loop_dump_stream,
                   2396:                     "Cannot eliminate biv %d due to insn %d.\n",
                   2397:                     bl->regno, INSN_UID (p));
                   2398:        }
                   2399:       else
                   2400:        {
                   2401:          if (loop_dump_stream)
                   2402:            fprintf (loop_dump_stream,
                   2403:                     "Cannot eliminate biv %d: used outside the loop\n",
                   2404:                     bl->regno);
                   2405:        }
                   2406: 
                   2407:       /* This will be true at the end, if all givs which depend on this
                   2408:         biv have been strength reduced.
                   2409:         We can't (currently) eliminate the biv unless this is so.  */
                   2410:       all_reduced = 1;
                   2411: 
                   2412:       /* Check each giv in this class.  */
                   2413: 
                   2414:       for (v = bl->giv; v; v = v->family)
                   2415:        {
                   2416:          struct induction *tv;
                   2417: 
                   2418:          if (v->ignore)
                   2419:            continue;
                   2420: 
                   2421:          benefit = v->benefit;
                   2422:          replaceable = v->replaceable;
                   2423: 
                   2424:          /* Reduce benefit if not replaceable, since we will insert
                   2425:             a move-insn to replace the insn that calculates this giv.  */
                   2426:          if (!replaceable && ! bl->eliminable)
                   2427:            benefit -= COPY_PENALTY;
                   2428: 
                   2429:          /* Decrease the benefit to count the add-insns that we will
                   2430:             insert to increment the reduced reg for the giv.  */
                   2431:          benefit -= ADD_BENEFIT * bl->biv_count;
                   2432: 
                   2433:          /* Find all equivalent givs (that bear same relation to the biv).
                   2434:             Link them via the `same' field and add their benefits together.
                   2435:             They can be replaced with a single register.  */
                   2436: 
                   2437:          for (tv = v->family; tv; tv = tv->family)
                   2438:            {
                   2439:              if (tv->ignore == 0
                   2440:                  && tv->src_regno == v->src_regno
                   2441:                  && rtx_equal_p (tv->mult_val, v->mult_val)
                   2442:                  && rtx_equal_p (tv->add_val, v->add_val))
                   2443:                {
                   2444:                  benefit += tv->benefit;
                   2445:                  if (! tv->replaceable)
                   2446:                    benefit -= COPY_PENALTY;
                   2447:                  v->lifetime += tv->lifetime;
                   2448:                  v->times_used += tv->times_used;
                   2449:                  tv->ignore = 1;
                   2450: 
                   2451:                  /* Link them together via `same' field.  */
                   2452:                  tv->same = v->same;
                   2453:                  v->same = tv;
                   2454: 
                   2455:                  if (loop_dump_stream)
                   2456:                    fprintf (loop_dump_stream,
                   2457:                             "giv of insn %d combined with that of %d.\n",
                   2458:                             INSN_UID (v->insn), INSN_UID (tv->insn));
                   2459:                }
                   2460:            }
                   2461: 
                   2462:          /* Decide whether to strength-reduce this giv
                   2463:             or to leave the code unchanged
                   2464:             (recompute it from the biv each time it is used).
                   2465:             This decision can be made independently for each giv.  */
                   2466: 
                   2467:          /* ??? Perhaps attempt to guess whether autoincrement will handle
                   2468:             some of the new add insns; if so, can increase BENEFIT
                   2469:             (undo the subtraction of ADD_BENEFIT that was done above).  */
                   2470: 
                   2471:          /* Is it right to consider times_used?  */
                   2472: 
                   2473:          if (benefit <= 0)
                   2474:            {
                   2475:              if (loop_dump_stream)
                   2476:                fprintf (loop_dump_stream, "giv of insn %d, no benefit\n",
                   2477:                         INSN_UID (v->insn));
                   2478:              v->ignore = 1;
                   2479:            }
                   2480: 
                   2481:          if (v->lifetime * threshold * benefit < insn_count)
                   2482:            {
                   2483:              if (loop_dump_stream)
                   2484:                fprintf (loop_dump_stream,
                   2485:                         "giv of insn %d not worth while, %d vs %d.\n",
                   2486:                         INSN_UID (v->insn),
                   2487:                         v->lifetime * threshold * benefit, insn_count);
                   2488:              v->ignore = 1;
                   2489:            }
                   2490: 
                   2491:          /* Now check that we can increment the reduced giv
                   2492:             without needing a multiply insn.  If not, reject it.  */
                   2493: 
                   2494:          if (! v->ignore)
                   2495:            {
                   2496:              int success = 1;
                   2497: 
                   2498:              for (tv = bl->biv; tv; tv = tv->family)
                   2499:                if (tv->mult_val == const1_rtx)
                   2500:                  success &= product_cheap_p (tv->add_val, v->mult_val);
                   2501: 
                   2502:              if (! success)
                   2503:                {
                   2504:                  if (loop_dump_stream)
                   2505:                    fprintf (loop_dump_stream,
                   2506:                             "giv of insn %d: would need a multiply.\n",
                   2507:                             INSN_UID (v->insn));
                   2508:                  v->ignore = 1;
                   2509:                }
                   2510:            }
                   2511:        }
                   2512: 
                   2513:       /* Reduce each giv that we decided to reduce.  */
                   2514: 
                   2515:       for (v = bl->giv; v; v = v->family)
                   2516:        {
                   2517:          struct induction *tv;
                   2518:          if (! v->ignore)
                   2519:            {
1.1.1.11! root     2520:              rtx new_reg;
        !          2521: 
        !          2522:              /* Note Iris compiler dies if ?: is used inside gen_reg_rtx. */
        !          2523:              if (v->giv_type == DEST_ADDR)
        !          2524:                new_reg = gen_reg_rtx (Pmode);
        !          2525:              else
        !          2526:                new_reg = gen_reg_rtx (GET_MODE (SET_DEST (PATTERN (v->insn))));
1.1.1.8   root     2527: 
                   2528:              /* For each place where the biv is incremented,
                   2529:                 add an insn to increment the new, reduced reg for the giv.
                   2530:                 Insert it before the insn that sets the biv,
                   2531:                 so that the biv increment remains last before the endtest,
                   2532:                 so that dbra will still be recognized.  */
                   2533: 
                   2534:              for (tv = bl->biv; tv; tv = tv->family)
                   2535:                {
                   2536:                  if (tv->mult_val == const1_rtx)
                   2537:                    emit_iv_inc (tv->add_val, v->mult_val,
                   2538:                                 new_reg, tv->insn);
                   2539:                  else /* tv->mult_val == const0_rtx */
                   2540:                    /* A multiply is acceptable here
                   2541:                       since this is presumed to be seldom executed.  */
                   2542:                    emit_iv_init_code (tv->add_val, v->mult_val,
                   2543:                                       v->add_val, new_reg, tv->insn);
                   2544:                }
                   2545: 
                   2546:              /* Add code at loop start to initialize giv's reduced reg.  */
                   2547: 
                   2548:              emit_iv_init_code (bl->initial_value, v->mult_val,
                   2549:                                 v->add_val, new_reg, loop_start);
                   2550: 
                   2551:              /* For each giv register that can be reduced now:
                   2552:                 delete old insn that modifies the giv,
                   2553:                 if replaceable, substitute reduced reg
                   2554:                   wherever the old giv occurs;
                   2555:                 else add new move insn "giv_reg = reduced_reg".  */
                   2556: 
                   2557:              for (tv = v; tv; tv = tv->same)
                   2558:                {
                   2559:                  /* Record the identity of the reduced reg.  */
                   2560:                  tv->new_reg = new_reg;
                   2561: 
                   2562:                  if (tv->giv_type == DEST_ADDR)
                   2563:                    {
                   2564:                      /* Store reduced reg as the address in the memref
                   2565:                         where we found this giv.  */
                   2566:                      * tv->location = new_reg;
                   2567:                    }
                   2568:                  else if (tv->replaceable)
                   2569:                    {
                   2570:                      reg_map[tv->dest_regno] = new_reg;
                   2571:                      /* If giv lives after end of loop,
                   2572:                         emit insn to copy reduced reg into old reg,
                   2573:                         at the end of the loop.  */
                   2574:                      if (uid_luid[regno_last_uid[tv->dest_regno]]
                   2575:                          > uid_luid[INSN_UID (loop_end)])
                   2576:                        emit_insn_after (gen_rtx (SET, VOIDmode,
                   2577:                                                  SET_DEST (PATTERN (tv->insn)),
                   2578:                                                  new_reg),
                   2579:                                         loop_end);
                   2580:                    }
                   2581:                  else
                   2582:                    {
1.1.1.11! root     2583:                      /* Put new insn after, not before, in case
        !          2584:                         tv->insn is the end of a libcall.  */
        !          2585:                      emit_insn_after (gen_rtx (SET, VOIDmode,
1.1.1.8   root     2586:                                                SET_DEST (PATTERN (tv->insn)),
                   2587:                                                new_reg),
                   2588:                                       tv->insn);
                   2589:                    }
                   2590: 
                   2591:                  /* Delete the insn that used to set the old giv reg,
                   2592:                     unless we modified an address in it.
                   2593:                     In any case, delete the other insns used for this one.  */
                   2594:                  delete_insn_forces (tv, tv->giv_type != DEST_ADDR);
                   2595: 
                   2596:                  if (loop_dump_stream)
                   2597:                    fprintf (loop_dump_stream, "giv at %d reduced to reg %d\n",
                   2598:                             INSN_UID (tv->insn), REGNO (new_reg));
                   2599:                }
                   2600:              /* One set of equivalent givs has been strength-reduced.  */
                   2601:            }
                   2602:          else if (v->new_reg == 0)
                   2603:            {
                   2604:              /* This giv wasn't reduced and is not worth reducing.  */
                   2605: 
                   2606:              for (tv = v; tv; tv = tv->same)
                   2607:                if (loop_dump_stream)
                   2608:                  fprintf (loop_dump_stream, "giv at %d not reduced\n",
                   2609:                           INSN_UID (tv->insn));
                   2610: 
                   2611:              all_reduced = 0;
                   2612:            }
                   2613:        }
                   2614: 
                   2615:       /* All the givs in this family have been reduced if they merit it.  */
                   2616: 
                   2617:       /* Try to eliminate the biv, if it is a candidate.
                   2618:         This won't work if ! all_reduced,
                   2619:         since the givs we planned to use might not have been reduced.  */
                   2620: 
                   2621:       if (all_reduced == 1 && bl->eliminable)
                   2622:        {
                   2623:          /* Get the REG rtx for the biv.  */
                   2624:          rtx reg = SET_DEST (PATTERN (bl->biv->insn));
                   2625: 
                   2626:          for (p = loop_start; p != end; p = NEXT_INSN (p))
                   2627:            {
                   2628:              enum rtx_code code = GET_CODE (p);
                   2629:              if ((code == INSN || code == JUMP_INSN || code == CALL_INSN)
                   2630:                  && reg_mentioned_p (reg, PATTERN (p))
                   2631:                  && SET_DEST (PATTERN (p)) == cc0_rtx)
                   2632:                /* Found a compare instruction using this biv;
                   2633:                   rewrite it to use a related giv.  */
                   2634:                eliminate_biv (p, bl, loop_start);
                   2635:            }
                   2636: 
                   2637:          /* Biv is no longer really needed inside the loop,
                   2638:             so delete all insns that set the biv.  */
                   2639: 
                   2640:          for (v = bl->biv; v; v = v->family)
                   2641:            delete_insn (v->insn);
                   2642: 
                   2643:          /* If final_value != 0, then biv may be used after loop end
                   2644:             and we must emit an insn to set it just in case.  */
                   2645:          if (final_value != 0)
                   2646:            emit_insn_after (gen_rtx (SET, VOIDmode, reg, final_value),
                   2647:                             loop_end);
                   2648: 
                   2649:          if (loop_dump_stream)
                   2650:            fprintf (loop_dump_stream, "Reg %d: biv eliminated\n",
                   2651:                     bl->regno);
                   2652:        }
                   2653:     }
                   2654: 
                   2655:   /* Go through all the instructions in the loop, making all the
                   2656:      register substitutions scheduled in REG_MAP.  */
                   2657: 
                   2658:   for (p = loop_start; p != end; p = NEXT_INSN (p))
                   2659:     if (GET_CODE (p) == INSN || GET_CODE (p) == JUMP_INSN
                   2660:        || GET_CODE (p) == CALL_INSN)
                   2661:       replace_regs (PATTERN (p), reg_map, nregs);
                   2662: }
                   2663: 
                   2664: /* Scan X for memory refs and check each memory address
                   2665:    as a possible giv.  INSN is the insn whose pattern X comes from.
                   2666:    MAYBE_NEVER is 1 if the loop might execute INSN zero times.  */
                   2667: 
                   2668: static void
                   2669: find_mem_givs (x, insn, maybe_never)
                   2670:      rtx x;
                   2671:      rtx insn;
                   2672:      int maybe_never;
                   2673: {
                   2674:   register int i, j;
                   2675:   register enum rtx_code code;
                   2676:   register char *fmt;
                   2677: 
                   2678:   if (x == 0)
                   2679:     return;
                   2680: 
                   2681:   code = GET_CODE (x);
                   2682:   switch (code)
                   2683:     {
                   2684:     case REG:
                   2685:     case CONST_INT:
                   2686:     case CONST:
                   2687:     case CONST_DOUBLE:
                   2688:     case SYMBOL_REF:
                   2689:     case LABEL_REF:
                   2690:     case PC:
                   2691:     case CC0:
                   2692:     case ADDR_VEC:
                   2693:     case ADDR_DIFF_VEC:
                   2694:     case USE:
                   2695:     case CLOBBER:
                   2696:       return;
                   2697: 
                   2698:     case MEM:
                   2699:       {
                   2700:        int src_regno;
                   2701:        rtx add_val;
                   2702:        rtx mult_val;
                   2703:        int benefit;
                   2704:        struct induction *forces = 0;
                   2705:        struct induction *forces2 = 0;
                   2706: 
                   2707:        benefit = general_induction_var (XEXP (x, 0),
                   2708:                                         &src_regno, &add_val, &mult_val,
                   2709:                                         &forces, &forces2);
                   2710:        if (benefit > 0)
                   2711:          {
                   2712:            /* Found one; record it.  */
                   2713:            struct induction *v =
                   2714:              (struct induction *) oballoc (sizeof (struct induction));
                   2715: 
                   2716:            record_giv (v, insn, src_regno, 0, mult_val, add_val, benefit,
                   2717:                        forces, forces2, DEST_ADDR, maybe_never, &XEXP (x, 0));
                   2718:          }
                   2719:        return;
                   2720:       }
                   2721:     }
                   2722: 
                   2723:   /* Recursively scan the subexpressions for other mem refs.  */
                   2724: 
                   2725:   fmt = GET_RTX_FORMAT (code);
                   2726:   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
                   2727:     if (fmt[i] == 'e')
                   2728:       find_mem_givs (XEXP (x, i), insn, maybe_never);
                   2729:     else if (fmt[i] == 'E')
                   2730:       for (j = 0; j < XVECLEN (x, i); j++)
                   2731:        find_mem_givs (XVECEXP (x, i, j), insn, maybe_never);
                   2732: }
                   2733: 
                   2734: /* Fill in the data about one giv.
                   2735:    V is the `struct induction' in which we record the giv.  (It is
                   2736:    allocated by the caller, with alloca.)
                   2737:    INSN is the insn that sets it.
                   2738:    BENEFIT estimates the savings from deleting this insn.
                   2739:    TYPE is DEST_REG or DEST_ADDR; it says whether the giv is computed
                   2740:    into a register or is used as a memory address.
                   2741: 
                   2742:    SRC_REGNO is the biv reg number which the giv is computed from.
                   2743:    DEST_REGNO is the giv's reg number (if the giv is stored in a reg).
                   2744:    MULT_VAL and ADD_VAL are the coefficients used to compute the giv.
                   2745:    FORCES and FORCES2, if nonzero, are other `struct induction's for
                   2746:    other givs which are used to compute this giv indirectly.
                   2747:    LOCATION points to the place where this giv's value appears in INSN.  */
                   2748: 
                   2749: static void
                   2750: record_giv (v, insn, src_regno, dest_regno, mult_val, add_val, benefit,
                   2751:            forces, forces2, type, maybe_never, location)
                   2752:      struct induction *v;
                   2753:      rtx insn;
                   2754:      int src_regno, dest_regno;
                   2755:      rtx mult_val, add_val;
                   2756:      int benefit;
                   2757:      struct induction *forces, *forces2;
                   2758:      enum g_types type;
                   2759:      int maybe_never;
                   2760:      rtx *location;
                   2761: {
                   2762:   struct induction *b;
                   2763:   struct iv_class *bl;
                   2764: 
                   2765:   v->insn = insn;
                   2766:   v->src_regno = src_regno;
                   2767:   v->giv_type = type;
                   2768:   v->dest_regno = dest_regno;
                   2769:   v->mult_val = mult_val;
                   2770:   v->add_val = add_val;
                   2771:   v->benefit = benefit;
                   2772:   v->location = location;
                   2773: 
                   2774:   if (type == DEST_ADDR)
                   2775:     {
                   2776:       v->consec = 0;
                   2777:       v->lifetime = 1;
                   2778:       v->times_used = 1;
                   2779:     }
                   2780:   else
                   2781:     {
                   2782:       v->consec = n_times_set[dest_regno] - 1;
                   2783:       v->lifetime = (uid_luid[regno_last_uid[dest_regno]]
                   2784:                     - uid_luid[regno_first_uid[dest_regno]]);
                   2785:       v->times_used = n_times_used[dest_regno];
                   2786:     }
                   2787: 
                   2788:   v->same = 0;
                   2789:   v->forces = 0;
                   2790:   v->forces2 = 0;
                   2791:   v->ignore = 0;
                   2792:   v->new_reg = 0;
                   2793: 
                   2794:   /* Mark giv as forced if it is only used to compute another giv.  */
                   2795: 
                   2796:   /* This check is not sufficient as INSN may have been moved giving
                   2797:      it a new uid, so make another check by calculating lifetimes.
                   2798:      This is overconservative but seems to be correct.  */
                   2799: 
                   2800:   if (forces)
                   2801:     {
                   2802:       v->benefit += forces->benefit;
                   2803:       if ((regno_last_uid[forces->dest_regno] == INSN_UID (insn)
                   2804:           ||
                   2805:           ((uid_luid[regno_last_uid[forces->dest_regno]]
                   2806:             - uid_luid[regno_first_uid[forces->dest_regno]])
                   2807:            == (INSN_UID (insn) - INSN_UID (forces->insn))))
                   2808:          && !reg_used_between_p (SET_DEST (PATTERN (forces->insn)),
                   2809:                                  forces->insn, insn))
                   2810:        {
                   2811:          v->forces = forces;
                   2812:          forces->ignore = 1;
                   2813:        }
                   2814:     }
                   2815: 
                   2816:   if (forces2)
                   2817:     {
                   2818:       v->benefit += forces2->benefit;
                   2819:       if ((regno_last_uid[forces2->dest_regno] == INSN_UID (insn)
                   2820:           ||
                   2821:           ((uid_luid[regno_last_uid[forces2->dest_regno]]
                   2822:             - uid_luid[regno_first_uid[forces2->dest_regno]])
                   2823:            == (INSN_UID (insn) - INSN_UID (forces2->insn))))
                   2824:          && !reg_used_between_p (SET_DEST (PATTERN (forces2->insn)),
                   2825:                                  forces2->insn, insn))
                   2826:        {
                   2827:          if (v->forces)
                   2828:            v->forces2 = forces2;
                   2829:          else
                   2830:            v->forces = forces2;
                   2831:          forces2->ignore = 1;
                   2832:        }
                   2833:     }
                   2834: 
                   2835:   if (type == DEST_REG)
                   2836:     {
                   2837:       induct_var[dest_regno] = GENERAL_INDUCT;
                   2838:       induct_struct[dest_regno] = v;
                   2839:     }
                   2840: 
                   2841:   /* Add the giv to the class of givs computed from one biv.  */
                   2842: 
                   2843:   bl = class_struct[src_regno];
                   2844:   if (bl)
                   2845:     {
                   2846:       v->family = bl->giv;
                   2847:       bl->giv = v;
                   2848:       bl->giv_count++;
                   2849:       bl->total_benefit += benefit;
                   2850:     }
                   2851:   else
                   2852:     {
                   2853:       /* Fatal error, biv missing for this giv?  */
                   2854:       fflush (loop_dump_stream);
                   2855:       abort ();
                   2856:     }
                   2857: 
                   2858:   if (type == DEST_ADDR)
                   2859:     v->replaceable = 1;
                   2860:   else
                   2861:     {
                   2862:       /* The giv can be replaced outright by the reduced register if
1.1.1.11! root     2863:         - the insn that sets the giv is always executed on any iteration
        !          2864:           on which the giv is used at all
        !          2865:           (there are two ways to deduce this:
        !          2866:            either the insn is executed on every iteration,
        !          2867:            or all uses follow that insn in the same basic block),
1.1.1.8   root     2868:         - the giv is not used before the insn that sets it,
                   2869:            i.e. no definition outside loop reaches into loop
                   2870:         - no assignments to the biv occur during the giv's lifetime.  */
                   2871: 
1.1.1.11! root     2872:       if (regno_first_uid[dest_regno] == INSN_UID (insn)
        !          2873:          /* Previous line always fails if INSN was moved by loop opt.  */
        !          2874:          && (!maybe_never || last_use_this_basic_block (dest_regno, insn)))
1.1.1.8   root     2875:        {
                   2876:          v->replaceable = 1;
                   2877:          for (b = bl->biv; b; b = b->family)
                   2878:            {
                   2879:              if ((uid_luid[INSN_UID (b->insn)] >= uid_luid[regno_first_uid[dest_regno]])
                   2880:                  &&
                   2881:                  (uid_luid[INSN_UID (b->insn)]
                   2882:                   <= uid_luid[regno_last_uid[dest_regno]]))
                   2883:                {
                   2884:                  v->replaceable = 0;
                   2885:                  break;
                   2886:                }
                   2887:            }
                   2888:        }
                   2889:       else
                   2890:        v->replaceable = 0;
                   2891:     }
                   2892: 
                   2893:   if (loop_dump_stream)
                   2894:     {
                   2895:       if (type == DEST_REG)
                   2896:        fprintf (loop_dump_stream, "Insn %d: giv reg %d",
                   2897:                 INSN_UID (insn), dest_regno);
                   2898:       else
                   2899:        fprintf (loop_dump_stream, "Insn %d: dest address",
                   2900:                 INSN_UID (insn));
                   2901: 
                   2902:       fprintf (loop_dump_stream, " src reg %d benefit %d",
                   2903:               src_regno, v->benefit);
                   2904:       fprintf (loop_dump_stream, " used %d lifetime %d",
                   2905:               v->times_used, v->lifetime);
                   2906: 
                   2907:       if (v->replaceable)
                   2908:        fprintf (loop_dump_stream, " replaceable");
                   2909: 
                   2910:       if (GET_CODE (mult_val) == CONST_INT)
                   2911:        fprintf (loop_dump_stream, " mult %d",
                   2912:                 INTVAL (mult_val));
                   2913:       else
                   2914:        {
                   2915:          fprintf (loop_dump_stream, " mult ");
                   2916:          print_rtl (loop_dump_stream, mult_val);
                   2917:        }
                   2918: 
                   2919:       if (GET_CODE (add_val) == CONST_INT)
                   2920:        fprintf (loop_dump_stream, " add %d",
                   2921:                 INTVAL (add_val));
                   2922:       else
                   2923:        {
                   2924:          fprintf (loop_dump_stream, " add ");
                   2925:          print_rtl (loop_dump_stream, add_val);
                   2926:        }
                   2927:     }
                   2928: 
                   2929:   if (loop_dump_stream && v->forces)
                   2930:     fprintf (loop_dump_stream, " forces insn %d", INSN_UID (v->forces->insn));
                   2931:   if (loop_dump_stream && v->forces2)
                   2932:     fprintf (loop_dump_stream, " forces insn %d", INSN_UID (v->forces2->insn));
                   2933:   if (loop_dump_stream && v->consec)
                   2934:     fprintf (loop_dump_stream, " consec %d", v->consec);
                   2935:   if (loop_dump_stream)
                   2936:     fprintf (loop_dump_stream, "\n");
                   2937: }
                   2938: 
                   2939: /* Delete the insns forced by the insn described by V.
                   2940:    If THIS_TOO is nonzero, delete that insn itself as well.  */
                   2941: 
                   2942: static void
                   2943: delete_insn_forces (v, this_too)
                   2944:      struct induction *v;
                   2945:      int this_too;
                   2946: {
                   2947:   rtx x, p;
                   2948:   int count;
                   2949:   rtx insn;
                   2950: 
                   2951:   if (this_too)
                   2952:     {
                   2953:       insn = v->insn;
                   2954:       for (count = v->consec; count >= 0; count--)
                   2955:        {
                   2956:          /* If first insn of libcall sequence, skip to end.  */
                   2957:          /* Do this at start of loop, since p is guaranteed to
                   2958:             be an insn here.  */
                   2959:          if (x = find_reg_note (insn, REG_LIBCALL, 0))
                   2960:            insn = XEXP (x, 0);
                   2961: 
                   2962:          if (x = find_reg_note (insn, REG_EQUAL, 0))
                   2963:            {
                   2964:              /* This is a library call; delete all insns backward until get to
                   2965:                 first insn in this group.  */
                   2966:              rtx first = XEXP (find_reg_note (insn, REG_RETVAL, 0), 0);
                   2967:              for (p = insn; p != first; p = PREV_INSN (p))
                   2968:                delete_insn (p);
                   2969:              /* Delete first insn also.  */
                   2970:              delete_insn (p);
                   2971:            }
                   2972:          else
                   2973:            delete_insn (insn);
                   2974: 
                   2975:          do insn = NEXT_INSN (insn);
                   2976:          while (GET_CODE (insn) == NOTE);
                   2977:        }
                   2978:     }
                   2979: 
                   2980:   if (v->forces)
                   2981:     delete_insn_forces (v->forces, 1);
                   2982:   if (v->forces2)
                   2983:     delete_insn_forces (v->forces2, 1);
                   2984: }
                   2985: 
                   2986: /* Check whether an insn is an increment legitimate for a basic induction var.
                   2987:    X is the source of the insn.
                   2988:    DEST_REG is the putative biv, also the destination of the insn.
                   2989:    We accept patterns of these forms:
                   2990:      REG = REG + INVARIANT
                   2991:      REG = INVARIANT + REG
                   2992:      REG = REG - CONSTANT
                   2993: 
                   2994:    If X is suitable, we return 1,
                   2995:    and store the factor multiplying REF in X into *MULT_VAL
                   2996:    and the additive term into *INC_VAL.
                   2997:    Otherwise we return 0.  */
                   2998: 
                   2999: static int
                   3000: basic_induction_var (x, dest_regno, inc_val, mult_val)
                   3001:      register rtx x;
                   3002:      int dest_regno;
                   3003:      rtx *inc_val;
                   3004:      rtx *mult_val;
                   3005: {
                   3006:   register RTX_CODE code = GET_CODE (x);
                   3007:   rtx arg;
                   3008: 
                   3009:   switch (code)
                   3010:     {
                   3011:     case PLUS:
                   3012:       if (GET_CODE (XEXP (x, 0)) == REG
                   3013:          && REGNO (XEXP (x, 0)) == dest_regno)
                   3014:        arg = XEXP (x, 1);
                   3015:       else if (GET_CODE (XEXP (x, 1)) == REG
                   3016:               && REGNO (XEXP (x, 1)) == dest_regno)
                   3017:        arg = XEXP (x, 0);
                   3018:       else
                   3019:        return 0;
                   3020: 
                   3021:       if (invariant_p (arg) == 1)
                   3022:        *inc_val = arg;
                   3023:       else
                   3024:        return 0;
                   3025: 
                   3026:       *mult_val = const1_rtx;
                   3027:       return 1;
                   3028: 
                   3029:     case MINUS:
                   3030:       if (GET_CODE (XEXP (x, 0)) == REG
                   3031:          && REGNO (XEXP (x, 0)) == dest_regno
                   3032:          && GET_CODE (XEXP (x, 1)) == CONST_INT)
                   3033:        *inc_val = gen_rtx (CONST_INT, VOIDmode,
                   3034:                            - INTVAL (XEXP (x, 1)));
                   3035:       else
                   3036:        return 0;
                   3037:       *mult_val = const1_rtx;
                   3038:       return 1;
                   3039: 
                   3040:       /* Can accept constant setting of biv only when inside inner most loop.
                   3041:         Otherwise, a biv of an inner loop may be incorrectly recognized
                   3042:         as a biv of the outer loop,
                   3043:         causing code to be moved INTO the inner loop.  */
                   3044:     case REG:
                   3045:       if (!invariant_p (x))
                   3046:        return 0;
                   3047:     case CONST_INT:
                   3048:     case SYMBOL_REF:
                   3049:     case CONST:
                   3050:       if (loops_enclosed == 1)
                   3051:        {
                   3052:          *inc_val = x;
                   3053:          *mult_val = const0_rtx;
                   3054:          return 1;
                   3055:        }
                   3056:       else
                   3057:        return 0;
                   3058: 
                   3059:     default:
                   3060:       return 0;
                   3061:     }
                   3062: }
                   3063: 
                   3064: /* A general induction variable (giv) is any quantity that is a linear function
                   3065:    of a basic induction variable, i.e. giv = biv * mult_val + add_val.
                   3066:    The coefficients can be any loop invariant quantity.
                   3067:    A giv need not be computed directly from the biv;
                   3068:    it can be computed by way of other givs.  */
                   3069: 
                   3070: /* Determine whether X computes a giv.
                   3071:    If it does, return a nonzero value
                   3072:      which is the benefit from eliminating the computation of X;
                   3073:    set *SRC_REGNO to the register number of the biv that it is computed from;
                   3074:    set *ADD_VAL and *MULT_VAL to the coefficients,
                   3075:      such that the value of X is biv * mult + add;
                   3076:    set forces (and forces2) to identify any other givs that are used
                   3077:      solely to compute this one.  */
                   3078: 
                   3079: /* This routine recognizes four types of patterns that generate givs:
                   3080:    - giv = biv op invariant             v = 0,    g = 0
                   3081:    - giv1 = giv2 op invariant           v = 0,    g = giv2
                   3082:        where giv1 and giv2 are functions of the same biv
                   3083:    - giv1 = biv op giv2                 v = giv2, g = 0
                   3084:        where giv2 is a function of biv
                   3085:    - giv1 = giv2 op giv3                v = giv3, g = giv2
                   3086:        where giv2 and giv3 are functions of the save biv  */
                   3087: 
                   3088: static int
                   3089: general_induction_var (x, src_regno, add_val, mult_val, forces, forces2)
                   3090:      rtx x;
                   3091:      int *src_regno;
                   3092:      rtx *add_val;
                   3093:      rtx *mult_val;
                   3094:      struct induction **forces;
                   3095:      struct induction **forces2;
                   3096: {
                   3097:   register RTX_CODE code = GET_CODE (x);
                   3098:   rtx arg;
                   3099:   struct induction *g = 0;
                   3100:   struct induction *v = 0;
                   3101:   int subexp = 0;
                   3102:   int tem;
                   3103: 
                   3104:   switch (code)
                   3105:     {
                   3106:     case NEG:
                   3107:       /* This can generate givs also, but it is not handled.  */
                   3108:       return 0;
                   3109: 
                   3110:     case PLUS:
                   3111:     case MINUS:
                   3112:     case MULT:
                   3113:     case UMULT:
                   3114:       /* Result is linear in both operands.  */
                   3115:       /* Determine which operand is the biv, and put the other in ARG.  */
                   3116:       if (GET_CODE (XEXP (x, 0)) == REG
                   3117:          && induct_var[REGNO (XEXP (x, 0))] == BASIC_INDUCT)
                   3118:        {
                   3119:          *src_regno = REGNO (XEXP (x, 0));
                   3120:          arg = XEXP (x, 1);
                   3121: 
                   3122:        }
                   3123:       else if (GET_CODE (XEXP (x, 1)) == REG
                   3124:               && induct_var[REGNO (XEXP (x, 1))] == BASIC_INDUCT)
                   3125:        {
                   3126:          *src_regno = REGNO (XEXP (x, 1));
                   3127:          arg = XEXP (x, 0);
                   3128: 
                   3129:        }
                   3130:       /* Check for an rtl subexpression that is a giv.  Memory address
                   3131:         givs often look like (plus (reg) (mult (biv) (const))).  */
                   3132:       /* Do this before checking for a giv operand, as this function will
                   3133:         fail if this special operand is not recognized.  */
                   3134: #ifndef DONT_REDUCE_ADDR
                   3135:       else if (tem = general_induction_var (XEXP (x, 1), src_regno,
                   3136:                                            add_val, mult_val,
                   3137:                                            forces, forces2))
                   3138:        {
                   3139:          /* Set subexp true so that this can be handled a little
                   3140:             differently from the normal case of g set.  */
                   3141:          /* Note that SRC_REGNO is already set.  */
                   3142:          subexp = TRUE;
                   3143:          g = (struct induction *) alloca (sizeof (struct induction));
                   3144:          g->mult_val = *mult_val;
                   3145:          g->add_val = *add_val;
                   3146:          /* Count this multiply as a shift, since that's what it
                   3147:             really will do.  */
                   3148:          if (tem == MULT_BENEFIT)
                   3149:            g->benefit = SHIFT_BENEFIT;
                   3150:          else
                   3151:            g->benefit = tem;
                   3152:          arg = XEXP (x, 0);
                   3153:        }
                   3154: #endif
                   3155:       /* Also allow general induction variables.
                   3156:         Could have a mult followed by an add (i.e. an address calculation),
                   3157:         thereby generating two related general induction variables
                   3158:         of which only the second is actually used.  */
                   3159:       /* Do this after checking both args for basic induction variables.  */
                   3160:       else if (GET_CODE (XEXP (x, 0)) == REG
                   3161:               && induct_var[REGNO (XEXP (x, 0))] == GENERAL_INDUCT)
                   3162:        {
                   3163:          g = induct_struct[REGNO (XEXP (x, 0))];
                   3164:          *src_regno = g->src_regno;
                   3165:          arg = XEXP (x, 1);
                   3166:        }
                   3167:       else if (GET_CODE (XEXP (x, 1)) == REG
                   3168:               && induct_var[REGNO (XEXP (x, 1))] == GENERAL_INDUCT)
                   3169:        {
                   3170:          g = induct_struct[REGNO (XEXP (x, 1))];
                   3171:          *src_regno = g->src_regno;
                   3172:          arg = XEXP (x, 0);
                   3173:        }
                   3174:       else
                   3175:        return 0;
                   3176: 
                   3177:       /* Overall form of expression looks good.  */
                   3178:       break;
                   3179: 
                   3180:       /* Could handle these also.  */
                   3181:     case DIV:
                   3182:     case UDIV:
                   3183:       /* For a 68020 could handle these? */
                   3184:     case LSHIFT:
                   3185:     case ASHIFT:
                   3186:     case ASHIFTRT:
                   3187:     case LSHIFTRT:
                   3188:       /* These operations are linear only in first operand.
                   3189:         Check for a biv or giv there; if found, put other operand in ARG.  */
                   3190:       if (GET_CODE (XEXP (x, 0)) == REG
                   3191:          && induct_var[REGNO (XEXP (x, 0))] == BASIC_INDUCT)
                   3192:        {
                   3193:          *src_regno = REGNO (XEXP (x, 0));
                   3194:          arg = XEXP (x, 1);
                   3195:        }
                   3196:       /* Also allow general induction variable.  */
                   3197:       else if (GET_CODE (XEXP (x, 0)) == REG
                   3198:               && induct_var[REGNO (XEXP (x, 0))] == GENERAL_INDUCT)
                   3199:        {
                   3200:          g = induct_struct[REGNO (XEXP (x, 0))];
                   3201:          *src_regno = g->src_regno;
                   3202:          arg = XEXP (x, 1);
                   3203:        }
                   3204:       else
                   3205:        return 0;
                   3206: 
                   3207:       /* Overall form of expression looks good.  */
                   3208:       break;
                   3209: 
                   3210:     default:
                   3211:       return 0;
                   3212:     }
                   3213: 
                   3214:   /* ARG is the operand that is NOT a biv or giv.
                   3215:      Test it for superficial validity.  */
                   3216: 
                   3217:   /* This is just a special case of invariant values,
                   3218:      it is not really needed, but it's a shortcut.  */
                   3219:   if (GET_CODE (arg) == CONST_INT)
                   3220:     ;
                   3221: 
                   3222:   /* Depends on previous general induction variable, which has
                   3223:      the same basic induction variable */
                   3224:   /* This code detects mults that have been generated as shift and add.  */
                   3225:   else if (GET_CODE (arg) == REG
                   3226:           && induct_var[REGNO (arg)] == GENERAL_INDUCT
                   3227:           && induct_struct[REGNO (arg)]->src_regno == *src_regno)
                   3228:     {
                   3229:       v = induct_struct[REGNO (arg)];
                   3230:       /* Dependence indicated by forces, sort of kludgey.  */
                   3231:     }
                   3232: 
                   3233:   /* Invariant expression, could be a constant-valued register. */
                   3234:   else if (invariant_p (arg) == 1)
                   3235:     ;
                   3236: 
                   3237:   /* Failure */
                   3238:   else
                   3239:     return 0;
                   3240: 
                   3241:   /* Now we know looks like a giv; extract the coefficients.
                   3242:      We can still fail if the coefficients are not what we can handle.  */
                   3243: 
                   3244:   /* Only succeed if result mult_val and add_val are only one level of rtl,
                   3245:      for example, (NEG:SI (REG:SI 34)) is not accepted.
                   3246:      This mainly causes problems with the MINUS code.  */
                   3247: 
                   3248:   switch (code)
                   3249:     {
                   3250:     case PLUS:
                   3251:       if (v && g)
                   3252:        {
                   3253:          if (GET_CODE (g->mult_val) == CONST_INT)
                   3254:            {
                   3255:              if (g->mult_val == const0_rtx)
                   3256:                *mult_val = v->mult_val;
                   3257:              else if (GET_CODE (v->mult_val) == CONST_INT)
                   3258:                *mult_val = gen_rtx (CONST_INT, VOIDmode,
                   3259:                                       INTVAL (g->mult_val)
                   3260:                                       + INTVAL (v->mult_val));
                   3261:              else
                   3262:                return 0;
                   3263:            }
                   3264:          else if (v->mult_val == const0_rtx)
                   3265:            *mult_val = g->mult_val;
                   3266:          else
                   3267:            return 0;
                   3268: 
                   3269:          if (GET_CODE (g->add_val) == CONST_INT)
                   3270:            {
                   3271:              if (g->add_val == const0_rtx)
                   3272:                *add_val = v->add_val;
                   3273:              else if (GET_CODE (v->add_val) == CONST_INT)
                   3274:                *add_val = gen_rtx (CONST_INT, VOIDmode,
                   3275:                                       INTVAL (g->add_val)
                   3276:                                       + INTVAL (v->add_val));
                   3277:              else
                   3278:                return 0;
                   3279:            }
                   3280:          else if (v->add_val == const0_rtx)
                   3281:            *add_val = g->add_val;
                   3282:          else
                   3283:            return 0;
                   3284: 
                   3285:          if (subexp)
                   3286:            {
                   3287:              /* g deleted when return, can't return pointer to it */
                   3288:              if (*forces2 == 0)
                   3289:                *forces2 = v;
                   3290:              return ADD_BENEFIT + g->benefit;
                   3291:            }
                   3292:          else
                   3293:            {
                   3294:              *forces = g;
                   3295:              *forces2 = v;
                   3296:              return ADD_BENEFIT;
                   3297:            }
                   3298:        }
                   3299:       else if (v)
                   3300:        {
                   3301:          if (GET_CODE (v->mult_val) == CONST_INT)
                   3302:            *mult_val = gen_rtx (CONST_INT, VOIDmode,
                   3303:                                   INTVAL (v->mult_val) + 1);
                   3304:          else
                   3305:            return 0;
                   3306:          *add_val = v->add_val;
                   3307:          *forces = v;
                   3308:          return ADD_BENEFIT;
                   3309:        }
                   3310:       else if (g)
                   3311:        {
                   3312:          *mult_val = g->mult_val;
                   3313:          if (GET_CODE (g->add_val) == CONST_INT)
                   3314:            {
                   3315:              if (g->add_val == const0_rtx)
                   3316:                *add_val = arg;
                   3317:              else if (GET_CODE (arg) == CONST_INT)
                   3318:                *add_val = gen_rtx (CONST_INT, VOIDmode,
                   3319:                                      INTVAL (g->add_val) + INTVAL (arg));
                   3320:              else
                   3321:                return 0;
                   3322:            }
                   3323:          else
                   3324:            /* Could succeed if arg == 0, but that will never occur.  */
                   3325:            return 0;
                   3326: 
                   3327:          if (subexp)
                   3328:            /* g deleted when return, can't return pointer to it */
                   3329:            return ADD_BENEFIT + g->benefit;
                   3330:          else
                   3331:            {
                   3332:              *forces = g;
                   3333:              return ADD_BENEFIT;
                   3334:            }
                   3335:        }
                   3336:       else
                   3337:        {
                   3338:          *mult_val = const1_rtx;
                   3339:          *add_val = arg;
                   3340:          return ADD_BENEFIT;
                   3341:        }
                   3342: 
                   3343:       /* Takes a lot of code and will rarely succeed.  */
                   3344:     case MINUS:
                   3345:       if (v && g)
                   3346:        {
                   3347:          /* G is the first argument of MINUS.  */
                   3348: 
                   3349:          if (GET_CODE (g->mult_val) == CONST_INT)
                   3350:            {
                   3351:              if (g->mult_val == const0_rtx)
                   3352: #if 0 /* Should not have to fail here */
                   3353:                *mult_val = gen_rtx (NEG, SImode, v->mult_val);
                   3354: #endif
                   3355:                return 0;
                   3356:              else if (GET_CODE (v->mult_val) == CONST_INT)
                   3357:                *mult_val = gen_rtx (CONST_INT, VOIDmode,
                   3358:                                       INTVAL (g->mult_val)
                   3359:                                       - INTVAL (v->mult_val));
                   3360:              else
                   3361:                return 0;
                   3362:            }
                   3363:          else if (v->mult_val == const0_rtx)
                   3364:            *mult_val = g->mult_val;
                   3365:          else
                   3366:            return 0;
                   3367: 
                   3368:          if (GET_CODE (g->add_val) == CONST_INT)
                   3369:            {
                   3370:              if (g->add_val == const0_rtx)
                   3371: #if 0 /* should not have to fail here */
                   3372:                *add_val = v->add_val;
                   3373: #endif
                   3374:                return 0;
                   3375:              else if (GET_CODE (v->add_val) == CONST_INT)
                   3376:                *add_val = gen_rtx (CONST_INT, VOIDmode,
                   3377:                                       INTVAL (g->add_val)
                   3378:                                       - INTVAL (v->add_val));
                   3379:              else
                   3380:                return 0;
                   3381:            }
                   3382:          else if (v->add_val == const0_rtx)
                   3383:            *add_val = g->add_val;
                   3384:          else
                   3385:            return 0;
                   3386: 
                   3387:          if (subexp)
                   3388:            {
                   3389:              /* G deleted when return, can't return pointer to it */
                   3390:              if (*forces2 == 0)
                   3391:                *forces2 = v;
                   3392:              return ADD_BENEFIT + g->benefit;
                   3393:            }
                   3394:          else
                   3395:            {
                   3396:              *forces = g;
                   3397:              *forces2 = v;
                   3398:              return ADD_BENEFIT;
                   3399:            }
                   3400:        }
                   3401:       else if (v)
                   3402:        {
                   3403:          if (GET_CODE (v->mult_val) != CONST_INT)
                   3404:            return 0;
                   3405:          if (arg == XEXP (x, 0))             /* giv1 = giv2 - biv */
                   3406:            {
                   3407:              *mult_val = gen_rtx (CONST_INT, VOIDmode,
                   3408:                                     INTVAL (v->mult_val) - 1);
                   3409:              *add_val = v->add_val;
                   3410:            }
                   3411:          else                                /* giv1 = biv - giv2 */
                   3412:            {
                   3413:              *mult_val = gen_rtx (CONST_INT, VOIDmode,
                   3414:                                     1 - INTVAL (v->mult_val));
                   3415:              if (GET_CODE (v->add_val) == CONST_INT)
                   3416:                *add_val = gen_rtx (CONST_INT, VOIDmode,
                   3417:                                      - INTVAL (v->add_val));
                   3418:              else
                   3419:                return 0;
                   3420:            }
                   3421:          *forces = v;
                   3422:          return ADD_BENEFIT;
                   3423:        }
                   3424:       else if (g)
                   3425:        {
                   3426:          if (arg == XEXP (x, 1))
                   3427:            *mult_val = g->mult_val;
                   3428:          else
                   3429:            {
                   3430:              if (GET_CODE (g->mult_val) == CONST_INT)
                   3431:                *mult_val = gen_rtx (CONST_INT, VOIDmode,
                   3432:                                       - INTVAL (g->mult_val));
                   3433:              else
                   3434:                return 0;
                   3435:            }
                   3436:          if (GET_CODE (g->add_val) == CONST_INT)
                   3437:            {
                   3438:              if (g->add_val == const0_rtx)
                   3439:                {
                   3440:                  if (arg == XEXP (x, 1))    /* giv1 = giv2 - arg */
                   3441:                    {
                   3442:                      /* Fail unless arg is a constant.  */
                   3443:                      if (GET_CODE (arg) == CONST_INT)
                   3444:                        *add_val = gen_rtx (CONST_INT, VOIDmode,
                   3445:                                              -INTVAL (arg));
                   3446:                      else
                   3447:                        return 0;
                   3448:                    }
                   3449:                  else                       /* giv1 = arg - giv2 */
                   3450:                    *add_val = arg;
                   3451:                }
                   3452:              else if (GET_CODE (arg) == CONST_INT)
                   3453:                {
                   3454:                  if (arg == XEXP (x, 1))   /* giv1 = giv2 - arg */
                   3455:                    *add_val = gen_rtx (CONST_INT, VOIDmode,
                   3456:                                          INTVAL (g->add_val)
                   3457:                                          - INTVAL (arg));
                   3458:                  else                      /* giv1 = arg - giv2 */
                   3459:                    *add_val = gen_rtx (CONST_INT, VOIDmode,
                   3460:                                          INTVAL (arg),
                   3461:                                          - INTVAL (g->add_val));
                   3462:                }
                   3463:              else
                   3464:                return 0;
                   3465:            }
                   3466:          else
                   3467:            /* Could succeed if arg == 0, but that will never occur.  */
                   3468:            return 0;
                   3469: 
                   3470:          if (subexp)
                   3471:            /* G deleted when return, can't return pointer to it.  */
                   3472:            return ADD_BENEFIT + g->benefit;
                   3473:          else
                   3474:            {
                   3475:              *forces = g;
                   3476:              return ADD_BENEFIT;
                   3477:            }
                   3478:        }
                   3479:       else if (GET_CODE (arg) == CONST_INT)
                   3480:        {
                   3481:          if (arg == XEXP (x, 1))
                   3482:            {
                   3483:              *add_val = gen_rtx (CONST_INT, VOIDmode, - INTVAL (arg));
                   3484:              *mult_val = const1_rtx;
                   3485:            }
                   3486:          else
                   3487:            {
                   3488:              *add_val = arg;
                   3489:              *mult_val = gen_rtx (CONST_INT, VOIDmode, -1);
                   3490:            }
                   3491:          return ADD_BENEFIT;
                   3492:        }
                   3493:       else
                   3494:          return 0;
                   3495: 
                   3496:       /* UMULT can be handled like MULT since C ignores overflows.  */
                   3497:     case MULT:
                   3498:     case UMULT:
                   3499:       if (v && g)
                   3500:        {
                   3501:          /* Quadratic term, just fail.  */
                   3502:          return 0;
                   3503:        }
                   3504:       else if (v)
                   3505:        {
                   3506:          /* Quadratic term, just fail.  */
                   3507:          return 0;
                   3508:        }
                   3509:       else if (g)
                   3510:        {
                   3511:          /* Takes a lot of code and will rarely succeed.  */
                   3512:          /* dest = m * arg * b + a * arg */
                   3513:          if (GET_CODE (g->mult_val) == CONST_INT)
                   3514:            {
                   3515:              if (g->mult_val == const0_rtx)
                   3516:                *mult_val = const0_rtx;
                   3517:              else if (g->mult_val == const1_rtx)
                   3518:                *mult_val = arg;
                   3519:              else if (GET_CODE (arg) == CONST_INT)
                   3520:                *mult_val = gen_rtx (CONST_INT, VOIDmode,
                   3521:                                       INTVAL (g->mult_val) * INTVAL (arg));
                   3522:              else
                   3523:                return 0;
                   3524:            }
                   3525:          else
                   3526:            /* Could suceed if arg == 1 or 0, but this will never occur.  */
                   3527:            return 0;
                   3528: 
                   3529:          if (GET_CODE (g->add_val) == CONST_INT)
                   3530:            {
                   3531:              if (g->add_val == const0_rtx)
                   3532:                *add_val = const0_rtx;
                   3533:              else if (g->add_val == const1_rtx)
                   3534:                *add_val = arg;
                   3535:              else if (GET_CODE (arg) == CONST_INT)
                   3536:                *add_val = gen_rtx (CONST_INT, VOIDmode,
                   3537:                                       INTVAL (g->add_val) * INTVAL (arg));
                   3538:              else
                   3539:                return 0;
                   3540:            }
                   3541:          else
                   3542:            /* Could suceed if arg == 1 or 0, but this will never occur.  */
                   3543:            return 0;
                   3544: 
                   3545:          if (subexp)
                   3546:            /* G deleted when return, can't return pointer to it.  */
                   3547:            return MULT_BENEFIT + g->benefit;
                   3548:          else
                   3549:            {
                   3550:              *forces = g;
                   3551:              return MULT_BENEFIT;
                   3552:            }
                   3553:        }
                   3554:       else
                   3555:        {
                   3556:          *mult_val = arg;
                   3557:          *add_val = const0_rtx;
                   3558:          return MULT_BENEFIT;
                   3559:        }
                   3560: 
                   3561:       /* These are not worth the trouble.  */
                   3562:     case DIV:
                   3563:     case UDIV:
                   3564:       return 0;
                   3565: 
                   3566:       /* Handle these, but only for left shift.  */
                   3567:     case LSHIFT:
                   3568:     case ASHIFT:
                   3569:       if (v && g)
                   3570:        {
                   3571:          /* Quadratic term, just fail.  */
                   3572:          return 0;
                   3573:        }
                   3574:       else if (v)
                   3575:        {
                   3576:          /* Quadratic term, just fail.  */
                   3577:          return 0;
                   3578:        }
                   3579:       else if (g)
                   3580:        {
                   3581:          /* Takes a lot of code and will rarely succeed.  */
                   3582:          /* dest = ((m * b) << arg) + (a << arg) */
                   3583:          if (GET_CODE (g->mult_val) == CONST_INT)
                   3584:            {
                   3585:              if (g->mult_val == const0_rtx)
                   3586:                *mult_val = const0_rtx;
                   3587:              else if (GET_CODE (arg) == CONST_INT && INTVAL (arg) >= 0)
                   3588:                *mult_val = gen_rtx (CONST_INT, VOIDmode,
                   3589:                                       INTVAL (g->mult_val)
                   3590:                                       * (1 << INTVAL (arg)));
                   3591:              else
                   3592:                return 0;
                   3593:            }
                   3594:          else
                   3595:            /* Could suceed if arg == 0, but this will never occur.  */
                   3596:            return 0;
                   3597: 
                   3598:          if (GET_CODE (g->add_val) == CONST_INT)
                   3599:            {
                   3600:              if (g->add_val == const0_rtx)
                   3601:                *add_val = const0_rtx;
                   3602:              else if (GET_CODE (arg) == CONST_INT)
                   3603:                *add_val = gen_rtx (CONST_INT, VOIDmode,
                   3604:                                       INTVAL (g->add_val)
                   3605:                                       * (1 << INTVAL (arg)));
                   3606:              else
                   3607:                return 0;
                   3608:            }
                   3609:          else
                   3610:            /* Could suceed if arg == 0, but this will never occur.  */
                   3611:            return 0;
                   3612: 
                   3613:          if (subexp)
                   3614:            /* G deleted when return, can't return pointer to it.  */
                   3615:            return SHIFT_BENEFIT + g->benefit;
                   3616:          else
                   3617:            {
                   3618:              *forces = g;
                   3619:              return SHIFT_BENEFIT;
                   3620:            }
                   3621:        }
                   3622: 
                   3623:       if (GET_CODE (arg) == CONST_INT && INTVAL (arg) >= 0)
                   3624:        *mult_val = gen_rtx (CONST_INT, VOIDmode, 1 << INTVAL (arg));
                   3625:       else
                   3626:        return 0;
                   3627:       *add_val = const0_rtx;
                   3628:       return SHIFT_BENEFIT;
                   3629: 
                   3630:       /* These are not worth the trouble.  */
                   3631:     case ASHIFTRT:
                   3632:     case LSHIFTRT:
                   3633:       return 0;
                   3634: 
                   3635:       /* should never reach here */
                   3636:     default:
                   3637:       abort ();
                   3638:       return 0;
                   3639:     }
                   3640: }
                   3641: 
                   3642: /* Help detect a giv that is calculated by several consecutive insns;
                   3643:    for example,
                   3644:       giv = biv * M
                   3645:       giv = giv + A
                   3646:    The caller has already identified the first insn P as having a giv as dest;
                   3647:    we check that all other insns that set the same register follow
                   3648:    immediately after P, that they alter nothing else,
                   3649:    and that the result of the last is still a giv.
                   3650: 
                   3651:    The value is 0 if the reg set in P is not really a giv.
                   3652:    Otherwise, the value is the amount gained by eliminating
                   3653:    all the consecutive insns that compute the value.
                   3654: 
                   3655:    FIRST_BENEFIT is the amount gained by eliminating the first insn, P.
                   3656:    SRC_REGNO is the regno of the biv; DEST_REGNO is that of the giv.
                   3657: 
                   3658:    The coefficients of the ultimate giv value are stored in
                   3659:    *MULT_VAL and *ADD_VAL.  */
                   3660: 
                   3661: static int
                   3662: consec_sets_giv (first_benefit, p, src_regno, dest_regno,
                   3663:                 add_val, mult_val)
                   3664:      int first_benefit;
                   3665:      rtx p;
                   3666:      int src_regno;
                   3667:      int dest_regno;
                   3668:      rtx *add_val;
                   3669:      rtx *mult_val;
                   3670: {
                   3671:   int count;
                   3672:   int benefit = first_benefit;
                   3673:   enum rtx_code code;
                   3674:   rtx forces, forces2;
                   3675:   rtx temp;
                   3676:   int tem;
                   3677: 
                   3678:   /* Initialize info used by general_induction_var.  */
                   3679:   struct induction *v =
                   3680:     (struct induction *) oballoc (sizeof (struct induction));
                   3681:   v->src_regno = src_regno;
                   3682:   v->mult_val = *mult_val;
                   3683:   v->add_val = *add_val;
                   3684: 
                   3685:   induct_var[dest_regno] = GENERAL_INDUCT;
                   3686:   induct_struct[dest_regno] = v;
                   3687: 
                   3688:   count = n_times_set[dest_regno] - 1;
                   3689: 
                   3690:   while (count > 0)
                   3691:     {
                   3692:       p = NEXT_INSN (p);
                   3693:       code = GET_CODE (p);
                   3694: 
                   3695:       /* If libcall, skip to end of call sequence.  */
                   3696:       if (code == INSN && (temp = find_reg_note (p, REG_LIBCALL, 0)))
                   3697:        p = XEXP (temp, 0);
                   3698: 
                   3699:       if (code == INSN && GET_CODE (PATTERN (p)) == SET
                   3700:          && GET_CODE (SET_DEST (PATTERN (p))) == REG
                   3701:          && REGNO (SET_DEST (PATTERN (p))) == dest_regno
                   3702:          && ((tem = general_induction_var (SET_SRC (PATTERN (p)), &src_regno,
                   3703:                                            add_val, mult_val,
                   3704:                                            &forces, &forces2))
                   3705:              /* Giv created by call to library routine.  */
                   3706:              || ((temp = find_reg_note (p, REG_EQUAL, 0)) &&
                   3707:                  (tem = general_induction_var (XEXP (temp, 0), &src_regno,
                   3708:                                                add_val, mult_val,
                   3709:                                                &forces, &forces2))))
                   3710:          && src_regno == v->src_regno)
                   3711:        {
                   3712:          count--;
                   3713:          benefit += tem;
                   3714:          v->mult_val = *mult_val;
                   3715:          v->add_val = *add_val;
                   3716:        }
                   3717:       else if (code != NOTE)
                   3718:        {
                   3719:          induct_var[dest_regno] = UNKNOWN_INDUCT;
                   3720:          return 0;
                   3721:        }
                   3722:     }
                   3723: 
                   3724:   return benefit;
                   3725: }
                   3726: 
                   3727: /* Generate a SEQUENCE to multiply OP0 and OP1 with result in TARGET.
                   3728:    Use expand_mult to "optimally" do the multiply.
1.1.1.10  root     3729:    This also works for machines that do not have multiply insns.
                   3730:    If one of the operands is a constant, it must be the second.  */
1.1.1.8   root     3731: 
                   3732: static rtx
                   3733: gen_iv_mult (mode, op0, op1, target)
                   3734:      enum machine_mode mode;
                   3735:      register rtx op0, op1, target;
                   3736: {
                   3737:   extern rtx gen_sequence ();
                   3738:   extern rtx start_sequence ();
1.1.1.10  root     3739:   rtx saved, result, temp;
1.1.1.8   root     3740: 
                   3741:   saved = start_sequence ();
                   3742: 
1.1.1.10  root     3743:   /* ??? It is very unmodular to use expand_mult here!
                   3744:      This should be redesigned.  */
                   3745: 
1.1.1.8   root     3746:   /* UNSIGNEDP arg can be zero since operands/target always same width.  */
1.1.1.10  root     3747:   temp = expand_mult (mode, op0, op1, target, 0);
                   3748: 
                   3749:   /* Move to target register, if expand_mult did not put it there.  */
                   3750:   if (target != 0 && temp != target)
                   3751:     emit_move_insn (target, temp);
1.1.1.8   root     3752: 
                   3753:   result = gen_sequence ();
                   3754:   end_sequence (saved);
                   3755: 
                   3756:   return result;
                   3757: }
                   3758: 
                   3759: /* Emit code to initialize an induction variable created by strength
                   3760:    reduction.  */
                   3761: 
                   3762: /* This is necessarily long and messy because cse has already been done,
                   3763:    so we have to be careful to generate near optimal code for the sequence
                   3764:    reg = b * m;
                   3765:    reg += a
                   3766:  */
                   3767: 
                   3768: static void
                   3769: emit_iv_init_code (b, m, a, reg, loop_start)
                   3770:      rtx b;          /* initial value of basic induction variable */
                   3771:      rtx m;          /* multiplicative constant */
                   3772:      rtx a;          /* additive constant */
                   3773:      rtx reg;        /* destination register */
                   3774:      rtx loop_start;
                   3775: {
                   3776:   /* Indicates which of B/M/A are constants.  */
                   3777:   int status = 0;
                   3778:   int const_val;
                   3779:   rtx tmp;
                   3780: 
                   3781:   if (GET_CODE (b) == CONST_INT)
                   3782:     status |= 0x1;
                   3783:   if (GET_CODE (m) == CONST_INT)
                   3784:     status |= 0x2;
                   3785:   if (GET_CODE (a) == CONST_INT)
                   3786:     status |= 0x4;
                   3787: 
                   3788:   switch (status)
                   3789:     {
                   3790:     case 0:  /* nothing constant */
                   3791:     case 4:  /* A constant */
                   3792:       emit_insn_before (gen_iv_mult (GET_MODE (reg), b, m, reg), loop_start);
                   3793:       /* Don't emit add unless it is necessary.  */
                   3794:       if (a != const0_rtx)
                   3795:        emit_insn_before (gen_rtx (SET, VOIDmode, reg,
                   3796:                                   gen_rtx (PLUS, GET_MODE (reg), reg, a)),
                   3797:                          loop_start);
                   3798:       break;
                   3799: 
                   3800:     case 1:  /* B constant */
                   3801:       /* Equivalent to state 2, just need to switch values of B and M
                   3802:         and fall through.  */
                   3803:     case 5:  /* B, a constant */
                   3804:       /* Equivalent to state 6, just need to switch values of B and M
                   3805:         and fall through.  */
                   3806:       tmp = b;
                   3807:       b = m;
                   3808:       m = tmp;
                   3809: 
                   3810:     case 2:  /* M constant */
                   3811:     case 6:  /* M, A constant */
                   3812:       const_val = INTVAL (m);
                   3813:       if (const_val == 0)
                   3814:        /* REG = A */
                   3815:        emit_insn_before (gen_rtx (SET, VOIDmode, reg, a),
                   3816:                          loop_start);
                   3817:       else if (const_val == 1)
                   3818:        {
                   3819:          /* REG = A + B */
                   3820:          if (a != const0_rtx)
                   3821:            emit_insn_before (gen_rtx (SET, VOIDmode, reg,
                   3822:                                       gen_rtx (PLUS, GET_MODE (reg), b, a)),
                   3823:                              loop_start);
                   3824:          else
                   3825:            emit_insn_before (gen_rtx (SET, VOIDmode, reg, b), loop_start);
                   3826:        }
                   3827:       else if (const_val == -1)
                   3828:        {
                   3829:          /* REG = A - B */
                   3830:          if (a != const0_rtx)
                   3831:            emit_insn_before (gen_rtx (SET, VOIDmode, reg,
                   3832:                                       gen_rtx (MINUS, GET_MODE (reg), a, b)),
                   3833:                              loop_start);
                   3834:          else
                   3835:            emit_insn_before (gen_rtx (SET, VOIDmode, reg,
                   3836:                                       gen_rtx (NEG, GET_MODE (reg), b)),
                   3837:                              loop_start);
                   3838:        }
                   3839:       else
                   3840:        {
                   3841:          /* Must generate a `multiply' instruction.  */
                   3842:          emit_insn_before (gen_iv_mult (GET_MODE (reg), b, m, reg),
                   3843:                            loop_start);
                   3844: 
                   3845:          if (a != const0_rtx)
                   3846:            emit_insn_before (gen_rtx (SET, VOIDmode, reg,
                   3847:                                       gen_rtx (PLUS, GET_MODE (reg), reg, a)),
                   3848:                              loop_start);
                   3849:        }
                   3850:       break;
                   3851: 
                   3852:     case 3:  /* B, M constant */
                   3853:       const_val = INTVAL (b) * INTVAL (m);
                   3854:       if (const_val == 0)
                   3855:        emit_insn_before (gen_rtx (SET, VOIDmode, reg, a),
                   3856:                          loop_start);
                   3857:       else
                   3858:        emit_insn_before (gen_rtx (SET, VOIDmode, reg,
                   3859:                                   gen_rtx (PLUS, GET_MODE (reg),
                   3860:                                            gen_rtx (CONST_INT, VOIDmode,
                   3861:                                                     const_val),
                   3862:                                            a)),
                   3863:                        loop_start);
                   3864:       break;
                   3865: 
                   3866:     case 7:  /* all are constant */
                   3867:       emit_insn_before (gen_rtx (SET, VOIDmode, reg,
                   3868:                          gen_rtx (CONST_INT, VOIDmode,
                   3869:                                   INTVAL (b) * INTVAL (m) + INTVAL (a))),
                   3870:                 loop_start);
                   3871:       break;
                   3872: 
                   3873:     default:
                   3874:       abort ();
                   3875:     }
                   3876: }
                   3877: 
                   3878: /* Test whethen BIV_ADD * GIV_MULT can be computed without
                   3879:    an actual multiply insn.  Value is 1 if so.  */
                   3880: 
                   3881: static int
                   3882: product_cheap_p (biv_add, giv_mult)
                   3883:      rtx biv_add;
                   3884:      rtx giv_mult;
                   3885: {
                   3886:   /* Indicates which of MULT/ADD are constants.  */
                   3887:   int status = 0;
                   3888:   int const_val;
                   3889:   rtx tmp;
                   3890: 
                   3891:   if (GET_CODE (biv_add) == CONST_INT)
                   3892:     status |= 0x1;
                   3893:   if (GET_CODE (giv_mult) == CONST_INT)
                   3894:     status |= 0x2;
                   3895: 
                   3896:   switch (status)
                   3897:     {
                   3898:     case 0:
                   3899:       /* Neither is constant: would need a multiply insn, so fail.  */
                   3900:       return 0;
                   3901: 
                   3902:     case 1:
                   3903:       /* BIV_ADD value is constant */
                   3904:       /* Equivalent to state 2, just switch values of BIV_ADD and GIV_MULT
                   3905:         and fall through.  */
                   3906:       tmp = biv_add;
                   3907:       biv_add = giv_mult;
                   3908:       giv_mult = tmp;
                   3909: 
                   3910:     case 2:
                   3911:       /* GIV_MULT value is constant.
                   3912:         If it is 1, 0 or -1 then we win.  */
                   3913:       const_val = INTVAL (giv_mult);
                   3914:       if (const_val < -1 || const_val > 1)
                   3915:        {
                   3916:          tmp = gen_iv_mult (GET_MODE (biv_add), biv_add, giv_mult, 0);
                   3917:          /* Don't emit a multiply insn, just fail instead.  */
                   3918:          if ((GET_CODE (tmp) == SET && GET_CODE (SET_SRC (tmp)) == MULT)
                   3919:                 /* Also fail if library call (which generates more
                   3920:                    then two insn) is needed.  */
                   3921:              || (GET_CODE (tmp) == SEQUENCE && XVECLEN (tmp, 0) > 2))
                   3922:            return 0;
                   3923:        }
                   3924:       return 1;
                   3925: 
                   3926:     case 3:
                   3927:       /* Both BIV_ADD and GIV_MULT are constant;
                   3928:         can compute the product at compile time.  */
                   3929:       return 1;
                   3930: 
                   3931:     default:
                   3932:       abort ();
                   3933:     }
                   3934: }
                   3935: 
                   3936: 
                   3937: /* Emit code to increment the induction variable inside the loop.
                   3938:    Try to emit optimal code for the expression
                   3939:    REG = REG + BIV_ADD * GIV_MULT.  */
                   3940: 
                   3941: static void
                   3942: emit_iv_inc (biv_add, giv_mult, reg, insn)
                   3943:      rtx biv_add;                   /* increment value for biv */
                   3944:      rtx giv_mult;                  /* multiply value of giv */
                   3945:      rtx reg;                       /* create insn to set this reg */
                   3946:      rtx insn;                      /* where to insert the new insn */
                   3947: {
                   3948:   /* Indicates which of MULT/ADD are constants.  */
                   3949:   int status = 0;
                   3950:   int const_val;
                   3951:   rtx tmp, tempreg;
                   3952:   enum machine_mode mode = GET_MODE (reg);
                   3953: 
                   3954:   if (GET_CODE (biv_add) == CONST_INT)
                   3955:     status |= 0x1;
                   3956:   if (GET_CODE (giv_mult) == CONST_INT)
                   3957:     status |= 0x2;
                   3958: 
                   3959:   switch (status)
                   3960:     {
                   3961:     case 1:
                   3962:       /* BIV_ADD value is constant */
                   3963:       /* Equivalent to state 2, just switch values of BIV_ADD and GIV_MULT
                   3964:         and fall through.  */
                   3965:       tmp = biv_add;
                   3966:       biv_add = giv_mult;
                   3967:       giv_mult = tmp;
                   3968: 
                   3969:     case 2:
                   3970:       /* GIV_MULT value is constant */
                   3971:       const_val = INTVAL (giv_mult);
                   3972:       if (const_val == 0)
                   3973:        /* No code necessary.  This should be VERY rare.  */
                   3974:        break;
                   3975:       else if (const_val == 1)
                   3976:        {
                   3977:          emit_insn_before (gen_rtx (SET, VOIDmode, reg,
                   3978:                                     gen_rtx (PLUS, mode, reg, biv_add)),
                   3979:                            insn);
                   3980:          break;
                   3981:        }
                   3982:       else if (const_val == -1)
                   3983:        {
                   3984:          emit_insn_before (gen_rtx (SET, VOIDmode, reg,
                   3985:                                     gen_rtx (MINUS, mode, reg, biv_add)),
                   3986:                            insn);
                   3987:          break;
                   3988:        }
                   3989: 
                   3990:     case 0:
                   3991:       /* Variable times variable,
                   3992:         or variable times constant (not 0, -1 or 1):
                   3993:         emit a real multiply.  */
                   3994:       tempreg = gen_reg_rtx (mode);
                   3995:       tmp = gen_iv_mult (mode, biv_add, giv_mult, tempreg);
                   3996:       emit_insn_before (tmp, insn);
                   3997:       emit_insn_before (gen_rtx (SET, VOIDmode, reg,
                   3998:                                 gen_rtx (PLUS, mode, reg, tempreg)),
                   3999:                        insn);
                   4000:       break;
                   4001: 
                   4002:     case 3:
                   4003:       /* Both BIV_ADD and GIV_MULT are constant */
                   4004:       emit_insn_before (gen_rtx (SET, VOIDmode, reg,
                   4005:                                 gen_rtx (PLUS, mode, reg,
                   4006:                                          gen_rtx (CONST_INT, VOIDmode,
                   4007:                                                   INTVAL (biv_add)
                   4008:                                                   * INTVAL (giv_mult)))),
                   4009:                        insn);
                   4010:       break;
                   4011: 
                   4012:     default:
                   4013:       abort ();
                   4014:     }
                   4015: }
                   4016: 
                   4017: /* Check to see if loop can be terminated by a "decrement and branch until
                   4018:    zero" instruction.  If so, add a REG_NONNEG note to the branch insn if so.
                   4019:    Also try reversing an increment loop to a decrement loop
                   4020:    to see if the optimization can be performed.
                   4021:    Value is nonzero if optimization was performed.  */
                   4022: 
                   4023: static int
                   4024: check_dbra_loop (loop_end, iv_list, insn_count, loop_start)
                   4025:      rtx loop_end;
                   4026:      struct iv_class *iv_list;
                   4027:      int insn_count;
                   4028:      rtx loop_start;
                   4029: {
                   4030:   struct iv_class *bl;
                   4031:   rtx reg;
                   4032:   rtx jump_label;
                   4033:   rtx final_value;
                   4034:   rtx start_value;
                   4035:   enum rtx_code branch_code;
                   4036:   rtx new_add_val;
                   4037:   rtx tested_before_loop = 0;
                   4038:   rtx p;
                   4039: 
                   4040:   /* See if the loop is contained in  `if (X >= 0)' for some reg X.
                   4041:      If so, then we know X is initially nonnegative even though
                   4042:      we don't know its initial value.
                   4043:      Record X in TESTED_BEFORE_LOOP.  */
                   4044: 
                   4045:   for (p = loop_start; p != 0; p = PREV_INSN (p))
                   4046:     if (GET_CODE (p) != NOTE)
                   4047:       break;
                   4048: 
                   4049:   /* See if a conditional branch preceeds the loop.
                   4050:      There may be no other insns or labels between it and
                   4051:      the beginning of the loop.  */
                   4052:   if (p != 0 && GET_CODE (p) == JUMP_INSN && condjump_p (p)
                   4053:       && SET_SRC (PATTERN (p)) != pc_rtx
                   4054:       && ((GET_CODE (XEXP (SET_SRC (PATTERN (p)), 0)) == LT
                   4055:           && XEXP (SET_SRC (PATTERN (p)), 2) == pc_rtx)
                   4056:          ||
                   4057:          (GET_CODE (XEXP (SET_SRC (PATTERN (p)), 0)) == GE
                   4058:           && XEXP (SET_SRC (PATTERN (p)), 1) == pc_rtx))
                   4059:       && next_real_insn (JUMP_LABEL (p)) == next_real_insn (loop_end))
                   4060:     {
                   4061:       /* Before the branch should be a test or compare.
                   4062:         See if we are comparing something against zero.  */
                   4063:       p = PREV_INSN (p);
                   4064:       if (GET_CODE (p) == INSN && GET_CODE (PATTERN (p)) == SET
                   4065:          && SET_DEST (PATTERN (p)) == cc0_rtx)
                   4066:        {
                   4067:          if (GET_CODE (SET_SRC (PATTERN (p))) == REG)
                   4068:            tested_before_loop = SET_SRC (PATTERN (p));
                   4069:          else if (GET_CODE (SET_SRC (PATTERN (p))) == MINUS
                   4070:                   && GET_CODE (XEXP (SET_SRC (PATTERN (p)), 1)) == REG
                   4071:                   && XEXP (SET_SRC (PATTERN (p)), 1) == const0_rtx)
                   4072:            tested_before_loop = XEXP (SET_SRC (PATTERN (p)), 0);
                   4073:        }
                   4074:     }
                   4075: 
                   4076:   /* If last insn is a conditional branch, and the insn before tests a register
                   4077:      value, then try to optimize it.  */
                   4078: 
                   4079:   if (GET_CODE (PREV_INSN (loop_end)) == JUMP_INSN
                   4080:       && GET_CODE (PATTERN (PREV_INSN (loop_end))) == SET
                   4081:       && GET_CODE (SET_SRC (PATTERN (PREV_INSN (loop_end)))) == IF_THEN_ELSE
                   4082:       && GET_CODE (PREV_INSN (PREV_INSN (loop_end))) == INSN
                   4083:       && GET_CODE (PATTERN (PREV_INSN (PREV_INSN (loop_end)))) == SET
                   4084:       && (GET_CODE (SET_DEST (PATTERN (PREV_INSN (PREV_INSN (loop_end))))) ==
                   4085:          CC0))
                   4086:     {
                   4087:       /* Check all of the bivs to see if the compare uses one of them.  */
                   4088: 
                   4089:       for (bl = iv_list; bl; bl = bl->next)
                   4090:        {
                   4091:          if (reg_mentioned_p (SET_DEST (PATTERN (bl->biv->insn)),
                   4092:                               PREV_INSN (PREV_INSN (loop_end))))
                   4093:            break;
                   4094:        }
                   4095: 
                   4096:       /* If biv set more than once, then give up.
                   4097:         We can't guarantee that it will be zero on the last iteration.  */
                   4098:       if (bl && bl->biv_count == 1)
                   4099:        {
                   4100:          /* Look for the case where the basic induction variable is always
                   4101:             nonnegative, and equals zero on the last iteration.
                   4102:             In this case, add a reg_note REG_NONNEG, which allows the
                   4103:             m68k DBRA instruction to be used.  */
                   4104: 
                   4105:          /* the decrement case */
                   4106: 
                   4107:          if (GET_CODE (bl->biv->add_val) == CONST_INT
                   4108:              && INTVAL (bl->biv->add_val) < 0)
                   4109:            {
                   4110:              /* Initial value must be greater than 0,
                   4111:                 init_val % -dec_value == 0 to ensure that it equals zero on
                   4112:                    the last iteration */
                   4113: 
                   4114:              if (GET_CODE (bl->initial_value) == CONST_INT
                   4115:                  && INTVAL (bl->initial_value) > 0
                   4116:                  && (INTVAL (bl->initial_value) %
                   4117:                      (-INTVAL (bl->biv->add_val))) == 0)
                   4118:                {
                   4119:                  /* register always nonnegative, add REG_NOTE to branch */
                   4120:                  REG_NOTES (PREV_INSN (loop_end))
                   4121:                    = gen_rtx (EXPR_LIST, REG_NONNEG, 0,
                   4122:                               REG_NOTES (PREV_INSN (loop_end)));
                   4123:                  bl->nonneg = 1;
                   4124: 
                   4125:                  return 1;
                   4126:                }
                   4127: 
                   4128:              /* If the decrement is 1 and the value was tested as >= 0 before
                   4129:                 the loop, then we can safely optimize.  */
                   4130:              if (SET_DEST (PATTERN (bl->biv->insn)) == tested_before_loop
                   4131:                  && INTVAL (bl->biv->add_val) == -1)
                   4132:                {
                   4133:                  REG_NOTES (PREV_INSN (loop_end))
                   4134:                    = gen_rtx (EXPR_LIST, REG_NONNEG, 0,
                   4135:                               REG_NOTES (PREV_INSN (loop_end)));
                   4136:                  bl->nonneg = 1;
                   4137: 
                   4138:                  return 1;
                   4139:                }
                   4140:            }
                   4141:          else
                   4142:            {
                   4143:              /* Try to change inc to dec, so can apply above optimization.  */
                   4144:              /* Can do this if:
                   4145:                 all registers modified are induction variables or invariant,
                   4146:                 all memory references have non-overlapping addresses
                   4147:                        (obviously true if only one write)
                   4148:                 allow 2 insns for the compare/jump at the end of the loop.  */
                   4149: 
                   4150:              /* This code only acts for innermost loops.  Also it simplifies
                   4151:                 the memory address check by only reversing loops with
                   4152:                 zero or one memory access.  */
                   4153: 
                   4154:              if (num_mem_sets <= 1
                   4155:                  && !loop_has_call
                   4156:                  && (bl->giv_count + bl->biv_count + num_mem_sets
                   4157:                      + num_movables + 2 == insn_count))
                   4158:                {
                   4159:                  rtx src_two_before_end;
                   4160: 
                   4161:                  /* Loop can be reversed.  */
                   4162:                  if (loop_dump_stream)
                   4163:                    fprintf (loop_dump_stream, "Can reverse loop\n");
                   4164: 
                   4165:                  /* Now check other conditions:
                   4166:                     initial_value must be zero,
                   4167:                     final_value % add_val == 0, so that when reversed, the
                   4168:                     biv will be zero on the last iteration.  */
                   4169: 
                   4170:                  /* Calculating the final value non trivial.
                   4171:                     If branch is (LT (CC0) (CONST 0),
                   4172:                     then value in compare is final value.
                   4173:                     If branch is (LE (CC0) (CONST 0),
                   4174:                     then value in compare is final_value - add_val */
                   4175: 
                   4176:                  branch_code
                   4177:                    = GET_CODE (XEXP (SET_SRC (PATTERN (PREV_INSN (loop_end))), 0));
                   4178:                  src_two_before_end
                   4179:                    = PATTERN (PREV_INSN (PREV_INSN (loop_end)));
                   4180: 
                   4181:                  if (bl->initial_value == const0_rtx
                   4182:                      && (branch_code == LT || branch_code == LE)
                   4183:                      && XEXP (XEXP (SET_SRC (PATTERN (PREV_INSN (loop_end))), 0), 1) == const0_rtx
                   4184:                      && GET_CODE (XEXP (src_two_before_end, 1)) == CONST_INT
                   4185:                      && (INTVAL (XEXP (src_two_before_end, 1)) % INTVAL (bl->biv->add_val)) == 0)
                   4186:                    {
                   4187:                      /* Register will always be nonnegative, with value
                   4188:                         0 on last iteration if loop reversed */
                   4189: 
                   4190:                      /* Save some info needed to produce the new insns.  */
                   4191:                      reg = SET_DEST (PATTERN (bl->biv->insn));
                   4192:                      jump_label = XEXP (SET_SRC (PATTERN (PREV_INSN (loop_end))), 1);
                   4193:                      new_add_val = gen_rtx (CONST_INT, VOIDmode,
                   4194:                                             - INTVAL (bl->biv->add_val));
                   4195: 
                   4196: 
                   4197:                      if (branch_code == LT)
                   4198:                        {
                   4199:                          final_value = XEXP (src_two_before_end, 1);
                   4200:                          start_value
                   4201:                            = gen_rtx (CONST_INT, VOIDmode,
                   4202:                                       (INTVAL (XEXP (src_two_before_end, 1))
                   4203:                                        - INTVAL (bl->biv->add_val)));
                   4204:                        }
                   4205:                      else /* branch_code == LE */
                   4206:                        {
                   4207:                          start_value = XEXP (src_two_before_end, 1);
                   4208:                          final_value
                   4209:                            = gen_rtx (CONST_INT, VOIDmode,
                   4210:                                       (INTVAL (XEXP (src_two_before_end, 1))
                   4211:                                        + INTVAL (bl->biv->add_val)));
                   4212:                        }
                   4213: 
                   4214:                      /* Initialize biv to start_value before loop start.
                   4215:                         The old initializing insn will be deleted as a
                   4216:                         dead store by flow.c.  */
                   4217:                      emit_insn_before (gen_rtx (SET, VOIDmode, reg,
                   4218:                                                 start_value),
                   4219:                                        loop_start);
                   4220: 
                   4221:                      /* Add insn to decrement register, and delete insn
                   4222:                         that incremented the register.  */
                   4223:                      emit_insn_before (gen_rtx (SET, VOIDmode, reg,
                   4224:                                          gen_rtx (PLUS, GET_MODE (reg), reg,
                   4225:                                                   new_add_val)),
                   4226:                                        bl->biv->insn);
                   4227:                      /* Update biv info to reflect its new status.  */
                   4228:                      bl->biv->insn = PREV_INSN (bl->biv->insn);
                   4229:                      delete_insn (NEXT_INSN (bl->biv->insn));
                   4230: 
                   4231:                      /* Set LABEL_NUSES to two so that delete_insn will
                   4232:                         not delete the label.  */
                   4233:                      LABEL_NUSES (XEXP (jump_label, 0)) = 2;
                   4234: 
                   4235:                      if (regno_last_uid[bl->regno] != INSN_UID (PREV_INSN (loop_end)))
                   4236:                        emit_insn_after (gen_rtx (SET, VOIDmode, reg,
                   4237:                                                  final_value),
                   4238:                                         loop_end);
                   4239: 
                   4240:                      /* Delete compare/branch at end of loop.  */
                   4241:                      delete_insn (PREV_INSN (loop_end));
                   4242:                      delete_insn (PREV_INSN (loop_end));
                   4243: 
                   4244:                      /* Add new compare/branch insn at end of loop.  */
                   4245:                      emit_insn_before (gen_rtx (SET, VOIDmode, cc0_rtx, reg),
                   4246:                                        loop_end);
                   4247:                      emit_jump_insn_before (gen_rtx (SET, VOIDmode, pc_rtx,
                   4248:                                         gen_rtx (IF_THEN_ELSE, VOIDmode,
                   4249:                                             gen_rtx (GE, VOIDmode, cc0_rtx,
                   4250:                                                      const0_rtx),
                   4251:                                             jump_label,
                   4252:                                             pc_rtx)),
                   4253:                                          loop_end);
                   4254: 
                   4255:                      /* Register is now always nonnegative,
                   4256:                         so add REG_NONNEG note to the branch.  */
                   4257:                      REG_NOTES (PREV_INSN (loop_end))
                   4258:                        = gen_rtx (EXPR_LIST, REG_NONNEG, 0,
                   4259:                                   REG_NOTES (PREV_INSN (loop_end)));
                   4260:                      bl->nonneg = 1;
                   4261: 
                   4262:                      /* Update rest of biv info.  */
                   4263:                      bl->initial_value = start_value;
                   4264:                      bl->biv->add_val = new_add_val;
                   4265: 
                   4266:                      if (loop_dump_stream)
                   4267:                        fprintf (loop_dump_stream, "Reversed loop and added reg_nonneg\n");
                   4268: 
                   4269:                      return 1;
                   4270:                    }
                   4271:                }
                   4272:            }
                   4273:        }
                   4274:     }
                   4275:   return 0;
                   4276: }
                   4277: 
                   4278: /* Return 1 if INSN, a compare insn which tests the biv described by BL,
                   4279:    can be rewritten to use instead some reduced giv related to that biv.
                   4280:    Does not change the rtl.
                   4281: 
                   4282:    We make the assumption that all the givs depending on this biv
                   4283:    will be reduced, since only in that case will an attempt to eliminate
                   4284:    the biv actually be made.
                   4285: 
                   4286:    The following function is very parallel to this one.  */
                   4287: 
                   4288: static int
                   4289: can_eliminate_biv_p (insn, bl)
                   4290:      rtx insn;
                   4291:      struct iv_class *bl;
                   4292: {
                   4293:   rtx src;
                   4294:   enum rtx_code code;
                   4295:   struct induction *v, *tv;
                   4296:   rtx arg;
                   4297:   int arg_operand;
                   4298:   /* Mode of this biv.  */
                   4299:   enum machine_mode mode = GET_MODE (SET_DEST (PATTERN (bl->biv->insn)));
                   4300: 
                   4301:   if (SET_DEST (PATTERN (insn)) != cc0_rtx)
                   4302:     return 0;
                   4303: 
                   4304:   src = SET_SRC (PATTERN (insn));
                   4305:   code = GET_CODE (src);
                   4306: 
                   4307:   switch (code)
                   4308:     {
                   4309:       /* a test insn */
                   4310:     case REG:
                   4311:       /* Can replace with any giv that has (MULT_VAL != 0) and (ADD_VAL == 0)
                   4312:         and make sure it was strength reduced by checking for NEW_REG != 0 */
                   4313: 
                   4314:       for (v = bl->giv; v; v = v->family)
                   4315:        if (v->mult_val != const0_rtx && v->add_val == const0_rtx
                   4316:            && GET_MODE (SET_DEST (PATTERN (v->insn))) == mode)
                   4317:          return 1;
                   4318: 
                   4319:       /* Look for a giv with (MULT_VAL != 0) and (ADD_VAL != 0);
                   4320:         replace test insn with a compare insn (cmp REDUCED_GIV ADD_VAL) */
                   4321: 
                   4322:       for (v = bl->giv; v; v = v->family)
                   4323:        if (v->mult_val != const0_rtx
                   4324:            && GET_MODE (SET_DEST (PATTERN (v->insn))) == mode)
                   4325:          return 1;
                   4326:       return 0;
                   4327: 
                   4328:       /* a compare insn */
                   4329:     case MINUS:
                   4330:       /* Figure out which operand is the biv.  */
                   4331:       if ((GET_CODE (XEXP (src, 0)) == REG)
                   4332:          && (REGNO (XEXP (src, 0)) == bl->regno))
                   4333:        {
                   4334:          arg = XEXP (src, 1);
                   4335:          arg_operand = 1;
                   4336:        }
                   4337:       else
                   4338:        {
                   4339:          arg = XEXP (src, 0);
                   4340:          arg_operand = 0;
                   4341:        }
                   4342: 
                   4343:       if (GET_CODE (arg) == CONST_INT)
                   4344:        {
                   4345:          /* Can replace with any giv that has constant coefficients.  */
                   4346: 
                   4347:          for (v = bl->giv; v; v = v->family)
                   4348:            if (GET_CODE (v->mult_val) == CONST_INT
                   4349:                && GET_CODE (v->add_val) == CONST_INT
                   4350:                && GET_MODE (SET_DEST (PATTERN (v->insn))) == mode)
                   4351:              return 1;
                   4352: 
                   4353:          /* Look for giv with constant mult_val and nonconst add_val,
                   4354:             since we can insert add insn before loop
                   4355:             to calculate new compare value.  */
                   4356: 
                   4357:          for (v = bl->giv; v; v = v->family)
                   4358:            if (GET_CODE (v->mult_val) == CONST_INT
                   4359:                && GET_MODE (SET_DEST (PATTERN (v->insn))) == mode)
                   4360:              return 1;
                   4361:        }
                   4362:       else if (GET_CODE (arg) == REG || GET_CODE (arg) == MEM)
                   4363:        {
                   4364:          /* Comparing against invariant register or memref can be handled.  */
                   4365: 
                   4366:          if (invariant_p (arg))
                   4367:            {
                   4368:              /* Look for giv with constant mult_val and nonconst add_val.
                   4369:                 Insert add-insn before loop to compute new compare value.  */
                   4370: 
                   4371:              for (v = bl->giv; v; v = v->family)
                   4372:                if ((GET_CODE (v->mult_val) == CONST_INT)
                   4373:                    && GET_MODE (SET_DEST (PATTERN (v->insn))) == mode)
                   4374:                  return 1;
                   4375:            }
                   4376: 
                   4377:          /* Otherwise, only comparing against a biv can be handled.  */
                   4378:          if (GET_CODE (arg) != REG
                   4379:              || induct_var[REGNO (arg)] != BASIC_INDUCT)
                   4380:            return 0;
                   4381: 
                   4382:          /* Look for a giv for each biv that have identical
                   4383:             values for mult_val and add_val.  */
                   4384:          for (v = bl->giv; v; v = v->family)
                   4385:            if (GET_MODE (SET_DEST (PATTERN (v->insn))) == mode)
                   4386:              {
                   4387:                for (tv = class_struct[REGNO (arg)]->giv; tv; tv = tv->family)
                   4388:                  if ((tv->new_reg != 0)
                   4389:                      && rtx_equal_p (tv->mult_val, v->mult_val)
                   4390:                      && rtx_equal_p (tv->mult_val, v->mult_val)
                   4391:                      && GET_MODE (SET_DEST (PATTERN (tv->insn))) == mode)
                   4392:                    return 1;
                   4393:              }
                   4394:        }
                   4395:       return 0;
                   4396: 
                   4397:     default:
                   4398:       return 0;
                   4399:     }
                   4400: }
                   4401: 
                   4402: /* Rewrite a compare insn INSN which uses the biv described by BL
                   4403:    so that it doesn't use that biv any more.
                   4404:    Instead it will use some reduced giv related to that biv.
                   4405: 
                   4406:    The preceding function is very parallel to this one.  */
                   4407: 
                   4408: static void
                   4409: eliminate_biv (insn, bl, loop_start)
                   4410:      rtx insn;
                   4411:      struct iv_class *bl;
                   4412:      rtx loop_start;
                   4413: {
                   4414:   rtx src = SET_SRC (PATTERN (insn));
                   4415:   enum rtx_code code = GET_CODE (src);
                   4416:   struct induction *v, *tv;
                   4417:   rtx arg;
                   4418:   int arg_operand;
                   4419:   /* Mode of this biv.  */
                   4420:   enum machine_mode mode = GET_MODE (SET_DEST (PATTERN (bl->biv->insn)));
                   4421: 
                   4422:   switch (code)
                   4423:     {
                   4424:       /* a test insn */
                   4425:     case REG:
                   4426:       /* Can replace with any giv
                   4427:         that has (MULT_VAL != 0) and (ADD_VAL == 0).  */
                   4428: 
                   4429:       for (v = bl->giv; v; v = v->family)
                   4430:        if (v->mult_val != const0_rtx && v->add_val == const0_rtx
                   4431:            && v->new_reg != 0
                   4432:            && GET_MODE (SET_DEST (PATTERN (v->insn))) == mode)
                   4433:          break;
                   4434:       if (v)
                   4435:        {
                   4436:          /* We can test the sign of that giv's reduced reg.  */
                   4437:          SET_SRC (PATTERN (insn)) = v->new_reg;
                   4438:          return;
                   4439:        }
                   4440: 
                   4441:       /* Look for a giv with (MULT_VAL != 0) and (ADD_VAL != 0);
                   4442:         replace test insn with a compare insn (cmp REDUCED_GIV ADD_VAL) */
                   4443: 
                   4444:       for (v = bl->giv; v; v = v->family)
                   4445:        if (v->mult_val != const0_rtx && v->new_reg != 0
                   4446:            && GET_MODE (SET_DEST (PATTERN (v->insn))) == mode)
                   4447:          break;
                   4448:       if (v)
                   4449:        {
                   4450:          /* Replace biv with the giv's reduced register.  */
                   4451:          SET_SRC (PATTERN (insn)) = gen_rtx (MINUS, GET_MODE (v->new_reg),
                   4452:                                              v->new_reg, v->add_val);
                   4453: 
                   4454: #if 0
                   4455:          /* add_val must be invariant, so don't bother storing in a register */
                   4456:          /* calculate the appropriate constant to compare against */
                   4457:          emit_insn_before (gen_rtx (SET, VOIDmode, compare_value,
                   4458:                                     v->add_val),
                   4459:                            loop_start);
                   4460: #endif
                   4461:          return;
                   4462:        }
                   4463:       abort ();
                   4464:       break;
                   4465: 
                   4466:       /* a compare insn */
                   4467:     case MINUS:
                   4468:       /* Figure out which operand is the biv.  */
                   4469:       if ((GET_CODE (XEXP (src, 0)) == REG)
                   4470:          && (REGNO (XEXP (src, 0)) == bl->regno))
                   4471:        {
                   4472:          arg = XEXP (src, 1);
                   4473:          arg_operand = 1;
                   4474:        }
                   4475:       else
                   4476:        {
                   4477:          arg = XEXP (src, 0);
                   4478:          arg_operand = 0;
                   4479:        }
                   4480: 
                   4481:       if (GET_CODE (arg) == CONST_INT)
                   4482:        {
                   4483:          /* Can replace with any giv that has constant mult_val and add_val.
                   4484:             Make sure it was strength reduced by checking new_reg != 0.  */
                   4485: 
                   4486:          for (v = bl->giv; v; v = v->family)
                   4487:            if (GET_CODE (v->mult_val) == CONST_INT
                   4488:                && GET_CODE (v->add_val) == CONST_INT
                   4489:                && v->new_reg
                   4490:                && GET_MODE (SET_DEST (PATTERN (v->insn))) == mode)
                   4491:              break;
                   4492:          if (v)
                   4493:            {
                   4494:              /* Replace biv with the giv's reduced reg.  */
                   4495:              XEXP (src, 1-arg_operand) = v->new_reg;
                   4496:              /* Calculate the appropriate constant to compare against.  */
                   4497:              XEXP (src, arg_operand) = gen_rtx (CONST_INT, VOIDmode,
                   4498:                                         (INTVAL (arg) * INTVAL (v->mult_val)
                   4499:                                                 + INTVAL (v->add_val)));
                   4500:              return;
                   4501:            }
                   4502: 
                   4503:          /* Look for giv with constant mult_val and nonconst add_val.
                   4504:             Insert add insn before loop to calculate new compare value.  */
                   4505: 
                   4506:          for (v = bl->giv; v; v = v->family)
                   4507:            if (GET_CODE (v->mult_val) == CONST_INT
                   4508:                && v->new_reg
                   4509:                && GET_MODE (SET_DEST (PATTERN (v->insn))) == mode)
                   4510:              break;
                   4511:          if (v)
                   4512:            {
                   4513:              rtx compare_value = gen_reg_rtx (mode);
                   4514: 
                   4515:              /* Replace biv with giv's reduced register.  */
                   4516:              XEXP (src, 1-arg_operand) = v->new_reg;
                   4517: 
                   4518:              /* At start of loop, compute value to compare against.  */
                   4519:              emit_insn_before (gen_rtx (SET, VOIDmode, compare_value,
                   4520:                                  gen_rtx (PLUS, mode, v->add_val,
                   4521:                                     gen_rtx (CONST_INT, VOIDmode,
                   4522:                                        INTVAL (arg) * INTVAL (v->mult_val)))),
                   4523:                                loop_start);
                   4524:              XEXP (src, arg_operand) = compare_value;
                   4525:              return;
                   4526:            }
                   4527:          abort ();
                   4528:        }
                   4529:       else if (GET_CODE (arg) == REG || GET_CODE (arg) == MEM)
                   4530:        {
                   4531:          if (invariant_p (arg))
                   4532:            {
                   4533:              /* Look for giv with constant mult_val and nonconst add_val.
                   4534:                 Insert add-insn before loop to compute new compare value.  */
                   4535: 
                   4536:              for (v = bl->giv; v; v = v->family)
                   4537:                if (GET_CODE (v->mult_val) == CONST_INT
                   4538:                    && v->new_reg
                   4539:                    && GET_MODE (SET_DEST (PATTERN (v->insn))) == mode)
                   4540:                  break;
                   4541:              if (v)
                   4542:                {
                   4543:                  rtx compare_value = gen_reg_rtx (mode);
                   4544: 
                   4545:                  /* Replace biv with giv's reduced register.  */
                   4546:                  XEXP (src, 1-arg_operand) = v->new_reg;
                   4547: 
                   4548:                  /* Calculate the appropriate constant to compare against.  */
1.1.1.10  root     4549:                  emit_insn_before (gen_iv_mult (mode, arg, v->mult_val,
1.1.1.8   root     4550:                                                 compare_value),
                   4551:                                    loop_start);
                   4552:                  emit_insn_before (gen_rtx (SET, VOIDmode, compare_value,
                   4553:                                             gen_rtx (PLUS, mode, v->add_val,
                   4554:                                                      compare_value)),
                   4555:                                    loop_start);
                   4556:                  XEXP (src, arg_operand) = compare_value;
                   4557:                  return;
                   4558:                }
                   4559:            }
                   4560: 
                   4561:          /* Otherwise the reg compared with had better be a biv.  */
                   4562:          if (GET_CODE (arg) != REG
                   4563:              || induct_var[REGNO (arg)] != BASIC_INDUCT)
                   4564:            abort ();
                   4565: 
                   4566:          /* Look for a pair of givs, one for each biv,
                   4567:             with identical coefficients.  */
                   4568:          for (v = bl->giv; v; v = v->family)
                   4569:            {
                   4570:              if (!v->new_reg
                   4571:                  && GET_MODE (SET_DEST (PATTERN (v->insn))) == mode)
                   4572:                continue;
                   4573:              for (tv = class_struct[REGNO (arg)]->giv; tv; tv = tv->family)
                   4574:                if ((tv->new_reg != 0)
                   4575:                    && rtx_equal_p (tv->mult_val, v->mult_val)
                   4576:                    && rtx_equal_p (tv->mult_val, v->mult_val)
                   4577:                    && GET_MODE (SET_DEST (PATTERN (tv->insn))) == mode)
                   4578:                  break;
                   4579:              if (tv)
                   4580:                break;
                   4581:            }
                   4582:          if (v)
                   4583:            {
                   4584:              /* Replace biv with its giv's reduced reg.  */
                   4585:              XEXP (src, 1-arg_operand) = v->new_reg;
                   4586:              /* Replace other operand with the other giv's reduced reg.  */
                   4587:              XEXP (src, arg_operand) = tv->new_reg;
                   4588:              return;
                   4589:            }
                   4590:        }
                   4591:       abort ();
                   4592: 
                   4593:     default:
                   4594:       abort ();
                   4595:     }
                   4596: }
                   4597: 
                   4598: /* Try to calculate the final value of the biv,
                   4599:    the value it will have at the end of the loop.
                   4600:    If we can do it, return that value.  */
                   4601: 
1.1.1.10  root     4602: /* ??? One case that should be simple to handle
                   4603:    is when the biv is incremented by an invariant
                   4604:    exactly once each time around the loop,
                   4605:    and when the number of iterations can be determined
                   4606:    (as the value of some invariant).
                   4607:    Then the final value would be BIV + (INCREMENT * NUM_ITERATIONS).
                   4608: 
                   4609:    Once that case is handled, it would become desirable to detect empty
                   4610:    loops and delete them, since this optimization could make empty loops.  */
                   4611: 
1.1.1.8   root     4612: static rtx
                   4613: final_biv_value (bl, loop_end)
                   4614:      struct iv_class *bl;
                   4615:      rtx loop_end;
                   4616: {
                   4617:   /* wimpy, but guaranteed to work */
                   4618:   return 0;
                   4619: }
1.1.1.11! root     4620: 
        !          4621: /* Return nonzero if the last use of reg REGNO
        !          4622:    is in an insn following INSN in the same basic block.  */
        !          4623: 
        !          4624: static int
        !          4625: last_use_this_basic_block (regno, insn)
        !          4626:      int regno;
        !          4627:      rtx insn;
        !          4628: {
        !          4629:   rtx n;
        !          4630:   for (n = insn;
        !          4631:        n && GET_CODE (n) != CODE_LABEL && GET_CODE (n) != JUMP_INSN;
        !          4632:        n = NEXT_INSN (n))
        !          4633:     {
        !          4634:       if (regno_last_uid[regno] == INSN_UID (n))
        !          4635:        return 1;
        !          4636:     }
        !          4637:   return 0;
        !          4638: }

unix.superglobalmegacorp.com

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