1 /* $Id: lv.c,v 1.10 1994/06/24 10:26:28 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 /* L I V E V A R I A B L E S A N A L Y S I S */
15 #include "../share/types.h"
17 #include "../share/debug.h"
18 #include "../share/global.h"
19 #include "../share/lset.h"
20 #include "../share/cset.h"
21 #include "../share/def.h"
22 #include "../share/files.h"
23 #include "../share/alloc.h"
24 #include "../share/map.h"
25 #include "../share/get.h"
26 #include "../share/put.h"
27 #include "../share/aux.h"
28 #include "../share/init_glob.h"
29 #include "../share/locals.h"
30 #include "../share/go.h"
31 #include "../share/parser.h"
33 #define newlvbx() (bext_p) newstruct(bext_lv)
34 #define oldlvbx(x) oldstruct(bext_lv,x)
41 STATIC bool mesgflag = FALSE; /* Suppress generation of live/dead info */
48 for (p = &locals[1]; p <= &locals[nrlocals]; p++) {
51 oldmap(locals,nrlocals);
56 STATIC bool is_dir_use(l)
59 /* See if l is a direct use of some variable
60 * (i.e. not through a pointer). A LIL is a
61 * direct use of some pointer variable
62 * (and an indirect use of some other variable).
63 * A SIL is also a direct use.
64 * A LOI, however, is not an direct use of a variable.
65 * An an increment/decrement instruction is regarded
66 * as a use here, and not as a definition, as the
67 * variable is first used and than defined.
90 STATIC bool is_indir_use(l)
93 /* See if instruction l uses some variable(s) indirectly,
94 * i.e. through a pointer or via a procedure call.
118 STATIC bool is_def(l)
121 /* See if l does a direct definition */
141 /* Compute DEF(b) and USE(b), for every basic block b
142 * of procedure p. DEF(b) contains the variables that
143 * are certain to be defined (assigned) in b
144 * before being used. USE(b) contains the variables
145 * that may be used in b, before being defined.
146 * (Note that uncertainty arises in the presence of
147 * pointers and procedure calls).
148 * We compute these sets, by scanning the text of
149 * the basic block from beginning till end.
158 all_ind_uses = Cempty_set(nrvars);
159 for (v = 1; v < nrlocals; v++) {
160 if (!IS_REGVAR(locals[v])) {
161 Cadd(LOC_TO_VARNR(v),&all_ind_uses);
164 for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) {
165 USE(b) = Cempty_set(nrvars);
166 DEF(b) = Cempty_set(nrvars);
167 for (l = b->b_start; l != (line_p) 0; l = l->l_next) {
169 /* An direct definition (i.e. not
170 * through a pointer).
173 if (found && !Cis_elem(v,USE(b))) {
174 /* We do maintain live-dead info
175 * for this variable, and it was
176 * not used earlier in b.
183 if (found && !Cis_elem(v,DEF(b))) {
187 if (is_indir_use(l)) {
188 /* Add variable that may be used
191 Cjoin(all_ind_uses,&USE(b));
196 Cdeleteset(all_ind_uses);
201 STATIC unite_ins(bbset,setp)
205 /* Take the union of L_IN(b), for all b in bbset,
206 * and put the result in setp.
212 for (i = Lfirst(bbset); i != (Lindex) 0; i = Lnext(i,bbset)) {
213 Cjoin(L_IN((bblock_p) Lelem(i)), setp);
222 /* Solve the data flow equations for Live Variables,
223 * for procedure p. These equations are:
224 * (1) IN[b] = OUT[b] - DEF[b] + USE[b]
225 * (2) OUT(b) = IN(s1) + ... + IN(sn) ;
226 * where SUCC(b) = {s1, ... , sn}
230 cset newout = Cempty_set(nrvars);
233 for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) {
234 L_IN(b) = Cempty_set(nrvars);
235 Ccopy_set(USE(b), &L_IN(b));
236 L_OUT(b) = Cempty_set(nrvars);
240 for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) {
241 unite_ins(b->b_succ,&newout);
242 if (!Cequal(newout,L_OUT(b))) {
244 Ccopy_set(newout, &L_OUT(b));
245 Ccopy_set(newout, &L_IN(b));
246 Csubtract(DEF(b), &L_IN(b));
247 Cjoin(USE(b), &L_IN(b));
255 STATIC live_variables_analysis(p)
259 nrvars = nrglobals + nrlocals;
265 STATIC init_live_dead(b)
268 /* For every register variable, see if it is
269 * live or dead at the end of b.
275 for (v = 1; v <= nrlocals; v++) {
277 if (IS_REGVAR(loc) && Cis_elem(LOC_TO_VARNR(v),L_OUT(b))) {
287 STATIC line_p make_mesg(mesg,loc)
291 /* Create a line for a message stating that
292 * local variable loc is live/dead. This message
293 * looks like: "mes ms_ego,ego_live,off,size" or
294 * "mes ms_ego,ego_dead,off,size".
297 line_p l = newline(OPLIST);
301 ap = ARG(l) = newarg(ARGOFF);
302 ap->a_a.a_offset = ms_ego;
303 ap = ap->a_next = newarg(ARGOFF);
304 ap->a_a.a_offset = mesg;
305 ap = ap->a_next = newarg(ARGOFF);
306 ap->a_a.a_offset = loc->lc_off;
307 ap = ap->a_next = newarg(ARGOFF);
308 ap->a_a.a_offset = loc->lc_size;
315 STATIC block_entry(b,prev)
320 bool was_live, is_live;
322 /* Generate a live/dead message for every register variable that
323 * was live at the end of prev, but dead at the beginning of b,
324 * or v.v. If prev = 0 (i.e. begin of procedure), parameters were
325 * live, normal local variables were dead.
328 for (v = 1; v <= nrlocals; v++) {
330 if (IS_REGVAR(loc)) {
331 vn = LOC_TO_VARNR(v);
332 if (prev == (bblock_p) 0) {
333 was_live = loc->lc_off >= 0;
335 was_live = Cis_elem(vn,L_OUT(prev));
337 is_live = Cis_elem(vn,L_IN(b));
338 if (was_live != is_live) {
339 app_block(make_mesg((is_live?ego_live:ego_dead),loc),b);
347 STATIC app_block(l,b)
351 line_p x = b->b_start;
353 if (x != (line_p) 0 && INSTR(x) == ps_pro) {
354 /* start of procedure; append after pro pseudo ! */
355 if ((l->l_next = x->l_next) != (line_p) 0) {
361 if ((l->l_next = x) != (line_p) 0) {
365 PREV(l) = (line_p) 0;
371 STATIC definition(l,useless_out,v_out,mesgflag)
377 /* Process a definition. If the defined (register-) variable
378 * is live after 'l', then create a live-message and put
386 *useless_out = FALSE;
388 if (found && IS_LOCAL(v)) {
390 loc = locals[TO_LOCAL(v)];
391 if (IS_REGVAR(loc)) {
392 /* Tricky stuff here. Make sure that a variable
393 that is assigned to is alive, at least for
394 a very very short time. Otherwize, the
395 register allocation pass might think that it
396 is never alive, and (incorrectly) use the
397 same register for this variable as for
398 another variable, that is alive at this point.
399 If this variable is dead after the assignment,
400 the two messages (ego_live, ego_dead) are right
401 after each other. Luckily, this IS an interval.
404 appnd_line(make_mesg(ego_live,loc), l);
411 appnd_line(make_mesg(ego_dead, loc), l);
422 STATIC use(l,mesgflag)
426 /* Process a use. If the defined (register-) variable
427 * is dead after 'l', then create a dead-message and put
436 if (found && IS_LOCAL(v)) {
437 loc = locals[TO_LOCAL(v)];
438 if (IS_REGVAR(loc) && IS_DEAD(loc)) {
440 appnd_line(make_mesg(ego_dead,loc), l);
449 STATIC nothing() { } /* No action to be undertaken at level 0 of parser */
451 STATIC rem_code(l1,l2,b)
459 for (l = l1; l != l2; l = next) {
463 if (x == (line_p) 0) {
468 if (y != (line_p) 0) {
476 #define SIZE(v) ((offset) locals[TO_LOCAL(v)]->lc_size)
485 /* Create live/dead messages for every possible register
486 * variable of p. A dead-message is put after a "use" of
487 * such a variable, if the variable becomes dead just
488 * after the use (i.e. this was its last use).
489 * A live message is put after a "definition" of such
490 * a variable, if the variable becomes live just
491 * after the definition (which will usually be the case).
492 * We traverse every basic block b of p from the last
493 * instruction of b backwards to the beginning of b.
494 * Initially, all variables that are dead at the end
495 * of b are marked dead. All others are marked live.
496 * If we come accross a definition of a variable X that
497 * was marked live, we put a live-message after the
498 * definition and mark X dead.
499 * If we come accross a use of a variable X that
500 * was marked dead, we put a dead-message after the
501 * use and mark X live.
502 * So at any point, the mark of X tells whether X is
503 * live or dead immediately before (!) that point.
504 * We also generate a message at the start of a basic block
505 * for every variable that was live at the end of the (textually)
506 * previous block, but dead at the entry of this block, or v.v.
507 * On the fly, useless assignments are removed.
513 bblock_p prevb = (bblock_p) 0;
517 for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) {
518 block_entry(b,prevb); /* generate message at head of block */
523 for (l = last_instr(b); l != (line_p) 0; l = prev) {
524 /* traverse backwards! */
527 definition(l,&useless,&v,mesgflag);
528 if (useless && /* assignment to dead var. */
529 parse(prev,SIZE(v),&lnp,0,nothing)) {
530 /* The code "VAR := expression" can
531 * be removed. 'l' is the "STL VAR",
532 * lnp is the beginning of the EM code
533 * for the expression.
537 OUTVERBOSE("useless assignment ,proc %d,local %d", curproc->p_id,
538 (int) locals[TO_LOCAL(v)]->lc_off);
556 /* Allocate extended data structures for Use Definition analysis */
560 for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) {
561 b->b_extend = newlvbx();
569 /* Deallocate extended data structures for Use Definition analysis */
573 for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) {
577 Cdeleteset(L_OUT(b));
578 oldlvbx(b->b_extend);
596 if (IS_ENTERED_WITH_GTO(p)) return;
597 locals = (local_p *) 0;
599 live_variables_analysis(p);
601 /* generate live-dead messages for regvars */
612 go(argc,argv,init_globals,lv_optimize,no_action,lv_flags);
613 report("useless assignments deleted",Slv);