Pristine Ack-5.5
[Ack-5.5.git] / util / ego / share / aux.c
1 /* $Id: aux.c,v 1.6 1994/06/24 10:29:26 ceriel Exp $ */
2 /*
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".
5  */
6 /*  S H A R E D   F I L E
7  *
8  *  A U X I L I A R Y   R O U T I N E S
9  *
10  */
11
12 #include <em_mes.h>
13 #include <em_pseu.h>
14 #include "types.h"
15 #include "debug.h"
16 #include "global.h"
17 #include "alloc.h"
18 #include "aux.h"
19 #include "map.h"
20 #include "lset.h"
21
22 offset off_set(lnp)
23         line_p lnp;
24 {
25         switch(lnp->l_optype) {
26                 case OPSHORT:
27                         return (offset) SHORT(lnp);
28                 case OPOFFSET:
29                         return OFFSET(lnp);
30                 default:
31                         assert(FALSE);
32         }
33         /* NOTREACHED */
34 }
35
36
37
38
39 offset aoff(ap,n)
40         register arg_p ap;
41 {
42         while (n>0) {
43                 if (ap != (arg_p) 0)
44                         ap = ap->a_next;
45                 n--;
46         }
47         if (ap == (arg_p) 0)
48                 error("too few parameters");
49         if (ap->a_type != ARGOFF)
50                 error("offset expected");
51         return(ap->a_a.a_offset);
52 }
53
54
55 offset tmplocal(p,size)
56         proc_p p;
57         offset   size;
58 {
59         /* Allocate a new local variable in the stack frame of p */
60
61         p->p_localbytes +=  size;
62         return -(p->p_localbytes);
63 }
64
65
66
67
68 line_p int_line(off)
69         offset off;
70 {
71         /* Allocate a line struct of type OPSHORT or OPOFFSET,
72          * whichever one fits best.
73          */
74
75         line_p lnp;
76
77         if ((short) off == off) {
78                 /* fits in a short */
79                 lnp = newline(OPSHORT);
80                 SHORT(lnp) = (short) off;
81         } else {
82                 lnp = newline(OPOFFSET);
83                 OFFSET(lnp) = off;
84         }
85         return lnp;
86 }
87
88
89
90 line_p reg_mes(tmp,size,typ,score)
91         offset tmp;
92         short  size;
93         int    typ,score;
94 {
95         /* Generate a register message */
96
97         line_p l;
98         arg_p a;
99
100 #define NEXTARG(a,val) a->a_next = newarg(ARGOFF); a = a->a_next; \
101                         a->a_a.a_offset = val
102         l = newline(OPLIST);
103         l->l_instr = ps_mes;
104         a = ARG(l) = newarg(ARGOFF);
105         a->a_a.a_offset = ms_reg;
106         NEXTARG(a,tmp);
107         NEXTARG(a,size);
108         NEXTARG(a,typ);
109         NEXTARG(a,score);
110         return l;
111 }
112
113
114 bool dom(b1,b2)
115         bblock_p b1,b2;
116 {
117         /* See if b1 dominates b2. Note that a block always
118          * dominates itself.
119          */
120
121         register bblock_p b;
122
123         for (b = b2; b != (bblock_p) 0; b = b->b_idom) {
124                 /* See if b1 is a (not necessarily proper) ancestor
125                  * of b2 in the immediate dominator tree.
126                  */
127                 if (b == b1) return TRUE;
128         }
129         return FALSE;
130 }
131
132
133 bblock_p common_dom(a,b)
134         bblock_p a,b;
135 {
136         /* find a basic block that dominates a as well as b;
137          * note that a basic block also dominates itself.
138          */
139
140         assert (a != (bblock_p) 0);
141         assert (b != (bblock_p) 0);
142         if (dom(a,b)) {
143                 return a;
144         } else {
145                 if (dom(b,a)) {
146                         return b;
147                 } else {
148                         return common_dom(a->b_idom,b->b_idom);
149                 }
150         }
151 }
152
153 #define R       time_space_ratio
154
155 short add_timespace(time,space)
156         short time,space;
157 {
158         /* Add together a time and space, using the time_space_ratio
159          * parameter that may be set by the user, indicating the need
160          * to optimize for time, space or something in between.
161          */
162
163         return (R * time + (100 - R) * space) / 100;
164 }
165
166
167
168 rm_line(l,b)
169         line_p l;
170         bblock_p b;
171 {
172         if (b->b_start == l) {
173                 b->b_start = l->l_next;
174         } else {
175                 PREV(l)->l_next = l->l_next;
176         }
177         if (l->l_next != (line_p) 0) {
178                 PREV(l->l_next) = PREV(l);
179         }
180         oldline(l);
181 }
182
183
184
185
186 appnd_line(l1,l2)
187         line_p l1,l2;
188 {
189         /* Put l1 after l2 */
190
191         PREV(l1) = l2;
192         l1->l_next = l2->l_next;
193         l2->l_next = l1;
194         if (l1->l_next != (line_p) 0) {
195                 PREV(l1->l_next) = l1;
196         }
197 }
198
199
200
201 line_p last_instr(b)
202         bblock_p b;
203 {
204         /* Determine the last line of a list */
205
206         register line_p l = b->b_start;
207
208         if (l == (line_p) 0) return (line_p) 0;
209         while (l->l_next != (line_p) 0) l = l->l_next;
210         return l;
211 }
212
213
214
215
216 line_p find_mesreg(off)
217         offset off;
218 {
219         /* Find the register message for the local with the given offset */
220
221         Lindex li;
222         line_p l;
223
224         for (li = Lfirst(mesregs); li != (Lindex) 0; li = Lnext(li,mesregs)) {
225                 l = (line_p) Lelem(li);
226                 if (aoff(ARG(l),1) == off) return l;
227         }
228         return (line_p) 0;
229 }
230
231
232 bool is_regvar(off)
233         offset off;
234 {
235         return find_mesreg(off) != (line_p) 0;
236 }
237
238
239
240 offset regv_arg(off,n)
241         offset off;
242         int n;
243 {
244         /* fetch the n'th argument of the register message of the
245          * local variable at offset off;
246          */
247
248         line_p x = find_mesreg(off);
249         assert (x != (line_p) 0);
250         return aoff(ARG(x),n);
251 }