1 /* $Id: locals.c,v 1.10 1994/06/24 10:30:18 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".
27 extern short nrglobals;
30 local_p *locals; /* dynamic array */
32 STATIC localvar(off,size,locs,reg,score)
39 /* process a reference to a local variable.
40 * A local is characterized by a (offset,size) pair.
41 * We first collect all locals in a list, sorted
42 * by offset. Later we will construct a table
46 local_p lc, x, *prevp;
49 for (lc = *locs; lc != (local_p) 0; lc = lc->lc_next) {
50 if (lc->lc_off == off && lc->lc_size == size) {
52 REGVAR(lc); /* register variable */
55 return; /* local already present */
57 if (lc->lc_off > off) break;
60 /* the local was not seen before; create an entry
63 x = *prevp = newlocal();
75 STATIC check_message(l,locs)
79 /* See if l is a register message */
84 if (aoff(arg,0) == ms_reg && arg->a_next != (arg_p) 0) {
85 localvar(aoff(arg,1), (short) aoff(arg,2), locs, TRUE,
93 STATIC check_local_use(l,locs)
116 check_message(l,locs);
117 /* fall through .. */
121 if (l->l_next && INSTR(l->l_next) == op_nop) {
125 localvar(off_set(l),sz,locs,FALSE,(offset) 0);
132 /* Make a table of local variables.
133 * This table is used to associate a
134 * unique number with a local. If two
135 * locals overlap (e.g. LDL 4 and LDL 2)
136 * none of them is considered any further,
137 * i.e. we don't compute ud-info for them.
140 local_p prev = 0, next, lc;
141 local_p locallist = (local_p) 0;
143 offset x, ill_zone = 0;
147 /* first make a list of all locals used */
148 for (b = p->p_start; b != (bblock_p) 0; b = b->b_next) {
149 for (l = b->b_start; l != (line_p) 0; l = l->l_next) {
150 check_local_use(l,&locallist);
153 /* Now remove overlapping locals, count useful ones on the fly */
154 for (lc = locallist; lc != (local_p) 0; lc = lc->lc_next) {
155 if (ill_zone != 0 && lc->lc_off < ill_zone) {
156 /* this local overlaps with a previous one */
158 if (!IS_BADLC(prev)) {
165 x = lc->lc_off + lc->lc_size;
166 if (ill_zone == 0 || x > ill_zone) {
171 /* Now we know how many local variables there are */
173 locals = (local_p *) newmap(cnt);
175 for (lc = locallist; lc != (local_p) 0; lc = next) {
181 lc->lc_next = (local_p) 0;
184 assert (cnt == nrlocals+1);
189 find_local(off,nr_out,found_out)
194 /* Try to find the local variable at the given
195 * offset. Return its local-number.
200 for (v = 1; v <= nrlocals; v++) {
201 if (locals[v]->lc_off > off) break;
202 if (locals[v]->lc_off == off) {
214 var_nr(l,nr_out,found_out)
219 /* Determine the number of the variable referenced
220 * by EM instruction l.
228 /* global variable */
229 if (OBJ(l)->o_globnr == 0) {
230 /* We don't maintain ud-info for this var */
233 *nr_out = GLOB_TO_VARNR(OBJ(l)->o_globnr);
238 off = (offset) SHORT(l);
246 /* Its's a local variable */
247 find_local(off,&nr,found_out);
249 *nr_out = LOC_TO_VARNR(nr);