1 /* $Id: ud_const.c,v 1.6 1994/06/24 10:33:20 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 /* C O N S T A N T P R O P A G A T I O N */
11 #include "../share/types.h"
13 #include "../share/debug.h"
14 #include "../share/global.h"
15 #include "../share/alloc.h"
16 #include "../share/lset.h"
17 #include "../share/cset.h"
18 #include "../share/def.h"
19 #include "../share/aux.h"
20 #include "../share/locals.h"
26 #define IS_REG(v) (locals[TO_LOCAL(v)]->lc_flags & LCF_REG)
27 #define CALLS_UNKNOWN(p) (p->p_flags1 & (byte) PF_CALUNKNOWN)
33 /* See if 'l' is a use of a variable */
50 bool value_known(def,val_out)
54 /* See if the value stored by definition 'def'
55 * is known statically (i.e. is a constant).
76 /* fall through ... */
80 if (l == (line_p) 0) return FALSE;
84 if (SHORT(l) >= sz1) {
97 /* fall through ... */
112 bool affected(use,v,l)
116 /* See if the variable referenced by 'use' may be
117 * changed by instruction l, which is either a cal, cai or
118 * an indirect assignment.
121 if (INSTR(l) == op_cal &&
122 TYPE(use) == OPOBJECT &&
123 BODY_KNOWN(PROC(l)) &&
124 !CALLS_UNKNOWN(PROC(l)) &&
125 !CHANGE_INDIR(PROC(l))) {
126 return Cis_elem(OBJ(use)->o_id,PROC(l)->p_change->c_ext);
128 return TYPE(use) == OPOBJECT || !IS_REG(v);
134 STATIC search_backwards(use,v,found,def)
139 /* Search backwards in the current basic block,
140 * starting at 'use', trying to find a definition
141 * of the variable referenced by 'use', whose variable
142 * number is v. If the definition found is an
143 * implicit one, return 0 as def.
148 for (l = PREV(use); l != (line_p) 0; l = PREV(l)) {
149 if (does_expl_def(l) && same_var(use,l)) {
154 if (does_impl_def(l) && affected(use,v,l)) {
166 STATIC short outer_def(vdefs,in)
169 /* See if there is a unique definition of variable
170 * v reaching the beginning of block b.
171 * 'vdefs' is vardefs[v], 'in' is IN(b).
177 for (i = Cfirst(vdefs); i != (Cindex) 0; i = Cnext(i,vdefs)) {
179 if (Cis_elem(EXPL_TO_DEFNR(n),in)) {
180 if (defnr != 0) return 0;
181 /* If there was already a def., there's no unique one */
191 line_p unique_def(use,b,defnr_out)
196 /* See if there is one unique explicit definition
197 * of the variable used by 'use', that reaches 'use'.
202 line_p def = (line_p) 0;
205 var_nr(use,&v,&found);
207 /* We do maintain ud-info for this variable.
208 * See if there is a previous explicit definition
209 * in the current basic block.
211 search_backwards(use,v,&found,&def);
212 if (!found && !Cis_elem(IMPLICIT_DEF(v),IN(b))) {
213 /* See if there is a unique explicit definition
214 * outside the current block, reaching the
215 * beginning of the current block.
217 *defnr_out = outer_def(vardefs[v],IN(b));
218 def = (*defnr_out == 0 ? (line_p) 0 : defs[*defnr_out]);
231 /* Perform the substitutions required for constant folding */