1 /* $Id: sr_iv.c,v 1.6 1994/06/24 10:32:21 ceriel Exp $ */
3 * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
4 * See the copyright notice in the ACK home directory, in the file "Copyright".
6 /* S T R E N G T H R E D U C T I O N
15 #include "../share/types.h"
17 #include "../share/lset.h"
18 #include "../share/cset.h"
19 #include "../share/debug.h"
20 #include "../share/global.h"
21 #include "../share/alloc.h"
22 #include "../share/aux.h"
29 STATIC lset ivvars; /* set of induction variables */
31 STATIC short nature(lnp)
34 /* Auxiliary routine used by inc_or_dec, is_add and plus_or_min.
35 * Determine if lnp had INCREMENT/DECREMENT-nature (1),
36 * ADD-nature (2), SUBTRACT-nature (3)
37 * or Buddha-nature (0).
42 assert(lnp != (line_p) 0);
43 size_ok = (TYPE(lnp) == OPSHORT && SHORT(lnp) == ws);
50 return (size_ok? 2:0);
53 return (size_ok? 3:0);
60 #define is_add(l) (nature(l) == 2)
61 #define plus_or_min(l) (nature(l) > 1)
62 #define inc_or_dec(l) (nature(l) == 1)
65 STATIC bool is_same(l,lnp)
68 /* lnp is a STL x , where x is a candidate
69 * induction variable. See if l is a LOL x
70 * (with the same x as the store-instruction)
73 assert(INSTR(lnp) == op_stl);
74 return l != (line_p) 0 && INSTR(l) == op_lol &&
75 off_set(l) == off_set(lnp);
83 /* Record the fact that we've found a new induction variable.
84 * lnp points to the last instruction of the code that
85 * increments the induction variable, i.e. a STL, DEL or INL.
91 i->iv_off = (TYPE(lnp) == OPSHORT ? (offset) SHORT(lnp) : OFFSET(lnp));
92 i->iv_incr = lnp; /* last instruction of increment code */
93 i->iv_step = step; /* step value */
119 STATIC try_patterns(lnp)
122 /* lnp is a STL x; try to recognize
123 * one of the patterns:
124 * 'LOAD const; LOAD x; ADD; STORE x'
125 * or 'LOAD x; LOAD const; ADD or SUBTRACT;
127 * or 'LOAD x; INCREMENT/DECREMENT; STORE x'
132 l = PREV(lnp); /* instruction before lnp*/
133 if (l == (line_p) 0) return; /* no match possible */
136 if (is_same(l2,lnp)) {
137 /* e.g. LOL iv ; INC ; STL iv */
143 if(is_same(l2,lnp) && is_const(PREV(l2))) {
144 ivar(lnp,SHORT(PREV(l2)));
148 if (plus_or_min(l)) {
149 if (is_const(l2) && is_same(PREV(l2),lnp)) {
150 ivar(lnp,sign(l) * SHORT(l2));
156 induc_vars(loop,ivar_out, vars_out)
158 lset *ivar_out, *vars_out;
160 /* Construct the set of induction variables. We use several
161 * global variables computed by 'candidates'.
168 ivvars = Lempty_set();
169 candidates(loop, &cand_iv, &vars);
170 /* Find the set of all variables that are assigned precisely
171 * once within the loop, within a firm block.
172 * Also find all remaining local variables that are changed
175 if (Lnrelems(cand_iv) > 0) {
176 for (i = Lfirst(cand_iv); i != (Lindex) 0; i = Lnext(i,cand_iv)) {
177 lnp = (line_p) Lelem(i);
178 if (INSTR(lnp) == op_inl || INSTR(lnp) == op_del) {
185 Ljoin(cand_iv, &vars);