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