1 /* $Id: ud_defs.c,v 1.6 1994/06/24 10:33:32 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".
7 /* U S E - D E F I N I T I O N A N A L Y S I S
13 #include "../share/types.h"
15 #include "../share/debug.h"
16 #include "../share/global.h"
17 #include "../share/lset.h"
18 #include "../share/cset.h"
19 #include "../share/map.h"
20 #include "../share/locals.h"
22 #include "../share/alloc.h"
23 #include "../share/aux.h"
25 short nrdefs; /* total number of definitions */
26 short nrexpldefs; /* number of explicit definitions */
30 STATIC cset all_globl_defs, all_indir_defs;
31 /* auxiliary sets, used by gen_sets */
37 /* See if instruction l does an explicit definition */
62 /* See if instruction l does an implicit definition */
86 /* Make a map of all explicit definitions
88 * Determine the set of explicit definitions
89 * of variable v (i.e. vardefs[v]), for all
91 * For every basic block b, compute CHGVARS(b),
92 * i.e. the set of variables changed in b by an
93 * explicit definition.
101 /* first count the number of definitions */
102 for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) {
103 for (l = b->b_start; l != (line_p) 0 ; l = l->l_next) {
104 if (does_expl_def(l)) {
106 if (!found) continue; /* no ud for this var */
112 /* now allocate the defs table and the vardefs table*/
113 defs = (line_p *) newmap(nrexpldefs);
114 vardefs = (cset *) newmap(nrvars);
115 for (i = 1; i <= nrvars; i++) {
116 vardefs[i] = Cempty_set(nrexpldefs);
119 for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) {
120 CHGVARS(b) =Cempty_set(nrvars);
121 for (l = b->b_start; l != (line_p) 0 ; l = l->l_next) {
122 if (does_expl_def(l)) {
124 if (!found) continue;
125 assert (v <= nrvars);
128 Cadd(cnt,&vardefs[v]);
137 STATIC init_gen(nrdefs)
140 /* Initializing routine of gen_sets. Compute the set
141 * of all implicit definitions to global variables
142 * (all_globl_defs) and the set of all implicit
143 * definition generated by an indirect assignment
144 * through a pointer (all_indir_defs).
149 all_globl_defs = Cempty_set(nrdefs);
150 all_indir_defs = Cempty_set(nrdefs);
151 for (v = 1; v <= nrglobals; v++) {
152 Cadd(IMPLICIT_DEF(GLOB_TO_VARNR(v)), &all_globl_defs);
153 Cadd(IMPLICIT_DEF(GLOB_TO_VARNR(v)), &all_indir_defs);
155 for (v = 1; v <= nrlocals; v++) {
156 if (!IS_REGVAR(locals[v])) {
157 Cadd(IMPLICIT_DEF(LOC_TO_VARNR(v)), &all_indir_defs);
166 Cdeleteset(all_globl_defs);
167 Cdeleteset(all_indir_defs);
172 STATIC bool same_target(l,defnr)
176 /* See if l defines the same variable as def */
181 if (IS_IMPL_DEF(defnr)) {
182 /* An implicitly generated definition */
183 v = IMPL_VAR(TO_IMPLICIT(defnr));
185 return TYPE(l) == OPOBJECT &&
186 OBJ(l)->o_globnr == TO_GLOBAL(v);
188 return TYPE(l) != OPOBJECT &&
189 locals[TO_LOCAL(v)]->lc_off == off_set(l);
192 /* explicit definition */
193 def = defs[TO_EXPLICIT(defnr)];
194 if (TYPE(l) == OPOBJECT) {
195 return TYPE(def) == OPOBJECT && OBJ(def) == OBJ(l);
197 return TYPE(def) != OPOBJECT && off_set(def) == off_set(l);
203 STATIC rem_prev_defs(l,gen_p)
207 /* Remove all definitions in gen that define the
208 * same variable as l.
215 for (i = Cfirst(gen); i != (Cindex) 0; i = next) {
217 if (same_target(l,Celem(i))) {
218 Cremove(Celem(i),gen_p);
226 STATIC impl_globl_defs(p,gen_p)
230 /* Add all definitions of global variables
231 * that are generated implicitly by a call
232 * to p to the set gen_p.
237 cset ext = p->p_change->c_ext;
239 for (i = Cfirst(ext); i != (Cindex) 0; i = Cnext(i,ext)) {
240 if (( v = omap[Celem(i)]->o_globnr) != (short) 0) {
241 /* the global variable v, for which we do
242 * maintain ud-info is changed by p, so a
243 * definition of v is generated implicitly.
245 Cadd(IMPLICIT_DEF(GLOB_TO_VARNR(v)),gen_p);
252 STATIC impl_gen_defs(l,gen_p)
256 /* Add all definitions generated implicitly by instruction l
257 * to gen_p. l may be a call or some kind of indirect
267 impl_globl_defs(p,gen_p);
268 if (!CHANGE_INDIR(p)) return;
271 /* else fall through ... */
273 /* Indirect subroutine call or call to
274 * a subroutine whose body is not available.
275 * Assume worst case; all global
276 * variables are changed and
277 * the called proc. does a store-
280 Cjoin(all_globl_defs,gen_p);
282 /* default: indir. assignment */
284 Cjoin(all_indir_defs,gen_p);
293 /* Compute for every basic block b of p the
294 * set GEN(b) of definitions in b (explicit as
295 * well as implicit) that reach the end of b.
302 init_gen(nrdefs); /* compute all_globl_defs and all_indir_defs */
303 for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) {
304 GEN(b) = Cempty_set(nrdefs);
305 for (l = b->b_start; l != (line_p) 0; l = l->l_next) {
306 if (does_impl_def(l)) {
307 impl_gen_defs(l,&GEN(b));
308 /* add definitions implicitly
309 * generated by subroutine call
310 * or indir. pointer assignment.
313 if (does_expl_def(l)) {
314 if (defnr <= nrdefs && defs[defnr] == l) {
315 rem_prev_defs(l,&GEN(b));
316 /* previous defs. of same var
317 * don't reach the end of b.
319 Cadd(EXPL_TO_DEFNR(defnr),&GEN(b));
326 clean_gen(); /* clean up */
332 STATIC killed_defs(v,b)
336 /* Put all definitions of v occurring outside b
337 * in KILL(b). In fact, we also put explicit
338 * definitions occurring in b, but not reaching the
339 * end of b, in KILL(b). This causes no harm.
345 for (i = Cfirst(vardefs[v]); i != (Cindex) 0; i = Cnext(i,vardefs[v])) {
346 d = Celem(i); /* d is an explicit definition of v */
347 if (!Cis_elem(EXPL_TO_DEFNR(d),GEN(b))) {
348 Cadd(EXPL_TO_DEFNR(d),&KILL(b));
351 /* Also add implicit definition of v to KILL(b) */
352 Cadd(IMPLICIT_DEF(v),&KILL(b));
361 /* For every basic block b of p compute the set
362 * KILL(b) of definitions outside b that define
363 * variables redefined by b.
364 * KILL(b) contains explicit as well as implicit
372 for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) {
373 KILL(b) = Cempty_set(nrdefs);
374 for (i = Cfirst(CHGVARS(b)); i != (Cindex) 0;
375 i = Cnext(i,CHGVARS(b))) {
376 v = Celem(i); /* v is a variable changed in b */