Pristine Ack-5.5
[Ack-5.5.git] / util / ego / il / il_aux.c
1 /* $Id: il_aux.c,v 1.7 1994/06/24 10:26:07 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
7 /*  I N L I N E   S U B S T I T U T I O N
8  *
9  *  I L _ A U X . C
10  */
11
12 #include <stdio.h>
13 #include <em_spec.h>
14 #include <em_mnem.h>
15 #include <em_pseu.h>
16 #include "../share/types.h"
17 #include "il.h"
18 #include "../share/debug.h"
19 #include "../share/get.h"
20 #include "../share/put.h"
21 #include "../share/alloc.h"
22 #include "../share/global.h"
23 #include "../share/lset.h"
24 #include "../share/map.h"
25 #include "il_aux.h"
26
27
28 int tsize(type)
29         int type;
30 {
31         /* Determine the size of a variable of the
32          *  given type.
33          */
34
35         switch(type) {
36                 case SINGLE:    return ws;
37                 case DOUBLE:    return 2*ws;
38                 case POINTER:   return ps;
39                 default:        assert(FALSE);
40         }
41         /* NOTREACHED */
42 }
43
44
45
46 line_p duplicate(lnp)
47         line_p lnp;
48 {
49         /* Make a duplicate of an EM instruction.
50          * Pseudos may not be passed as argument.
51          */
52
53         line_p l;
54
55         l = newline(TYPE(lnp));
56         l->l_instr = INSTR(lnp);
57         switch(TYPE(l)) {
58                 case OPNO:
59                         break;
60                 case OPSHORT:
61                         SHORT(l) = SHORT(lnp);
62                         break;
63                 case OPOFFSET:
64                         OFFSET(l) = OFFSET(lnp);
65                         break;
66                 case OPINSTRLAB:
67                         INSTRLAB(l) = INSTRLAB(lnp);
68                         break;
69                 case OPOBJECT:
70                         OBJ(l) = OBJ(lnp);
71                         break;
72                 case OPPROC:
73                         PROC(l) = PROC(lnp);
74                         break;
75                 default:
76                         assert(FALSE); /* cannot copy pseudo */
77         }
78         return l;
79 }
80
81
82
83
84 line_p copy_expr(l1)
85         line_p l1;
86 {
87         /* copy the expression */
88
89         line_p head, tail, l, lnp;
90
91         head = (line_p) 0;
92         for (lnp = l1; lnp != (line_p) 0; lnp = lnp->l_next) {
93                 l = duplicate(lnp);
94                 if (head == (line_p) 0) {
95                         head = tail = l;
96                         PREV(l) = (line_p) 0;
97                 } else {
98                         tail->l_next = l;
99                         PREV(l) = tail;
100                         tail = l;
101                 }
102         }
103         return head;
104 }
105
106
107
108 rem_call(c)
109         call_p c;
110 {
111         actual_p act, nexta;
112         call_p   nc,nextc;
113         line_p   l,   nextl;
114
115         for (act = c->cl_actuals; act != (actual_p) 0; act = nexta) {
116                 nexta = act->ac_next;
117                 for (l = act->ac_exp; l != (line_p) 0; l = nextl) {
118                         nextl = l->l_next;
119                         oldline(l);
120                 }
121                 oldactual(act);
122         }
123         nc = c->cl_car;
124         oldcall(c);
125         for (; nc != (call_p) 0; nc = nextc) {
126                 /* Take care of nested calls */
127                 nextc = nc->cl_cdr;
128                 rem_call(nc);
129         }
130 }
131
132
133
134 /* rem_graph */
135
136 STATIC short remlines(l)
137         line_p l;
138 {
139
140         register line_p lnp;
141         line_p next;
142
143         for (lnp = l; lnp != (line_p) 0; lnp = next) {
144                 next = lnp->l_next;
145                 oldline(lnp);
146         }
147 }
148
149
150
151 remunit(kind,p,l)
152         short    kind;
153         proc_p   p;
154         line_p   l;
155 {
156         register bblock_p b;
157         bblock_p next;
158         Lindex   pi;
159
160         if (kind == LDATA) {
161                 remlines(l);
162                 return;
163         }
164         for (b = p->p_start; b != (bblock_p) 0; b = next) {
165                 next = b->b_next;
166                 remlines(b->b_start);
167                 Ldeleteset(b->b_loops);
168                 Ldeleteset(b->b_succ);
169                 Ldeleteset(b->b_pred);
170                 oldbblock(b);
171         }
172         for (pi = Lfirst(p->p_loops); pi != (Lindex) 0;
173                                          pi = Lnext(pi,p->p_loops)) {
174                 oldloop(Lelem(pi));
175         }
176         Ldeleteset(p->p_loops);
177         oldmap(lmap,llength);
178         oldmap(lbmap,llength);
179         oldmap(bmap,blength);
180         oldmap(lpmap,lplength);
181 }
182 remcc(head)
183         calcnt_p head;
184 {
185         calcnt_p cc, next;
186
187         for (cc = head; cc != (calcnt_p) 0; cc = next) {
188                 next = cc->cc_next;
189                 oldcalcnt(cc);
190         }
191 }
192
193
194 /* Extra I/O routines */
195
196 call_p getcall(cf)
197         FILE *cf;
198 {
199         /* read a call from the call-file */
200
201         call_p c;
202         proc_p voided;
203         actual_p act,*app;
204         short n,m;
205
206         curinp = cf;
207         c = newcall();
208         n = getshort(); /* void nesting level */
209         if (feof(curinp)) return (call_p) 0;
210         c->cl_caller = pmap[getshort()];
211         c->cl_id     = getshort();
212         c->cl_proc   = pmap[getshort()];
213         c->cl_looplevel = getbyte();
214         c->cl_flags = getbyte();
215         c->cl_ratio  = getshort();
216         app = &c->cl_actuals;
217         n = getshort();
218         while(n--) {
219                 act = newactual();
220                 m = getshort();
221                 act->ac_size = getoff();
222                 act->ac_inl = getbyte();
223                 act->ac_exp = getlines(cf,m,&voided);
224                 *app = act;
225                 app = &act->ac_next;
226         }
227         *app = (actual_p) 0;
228         return c;
229 }
230
231
232
233 line_p get_text(lf,p_out)
234         FILE *lf;
235         proc_p *p_out;
236 {
237         /* Read the EM text of one unit
238          * If it is a procedure, set p_out to
239          * the proc. just read. Else set p_out
240          * to 0.
241          */
242
243         line_p dumhead, l, lprev;
244         loop_p *oldlpmap = lpmap;
245         line_p *oldlmap = lmap;
246         short oldllength = llength;
247         short oldlastlabid = lastlabid;
248
249         curinp = lf;
250         *p_out = (proc_p) 0;
251         dumhead = newline(OPNO);
252         /* The list of instructions is preceeded by a dummy
253          * line, to simplify list manipulation
254          */
255         dumhead->l_instr = op_nop; /* just for fun */
256         lprev = dumhead;
257         for (;;) {
258                 l = read_line(p_out);
259                 if (feof(curinp)) return (line_p) 0;
260                 lprev->l_next = l;
261                 PREV(l) = lprev;
262                 if (INSTR(l) == ps_end) break;
263                 if (INSTR(l) == ps_mes) {
264                         message(l);
265                 }
266                 lprev = l;
267         }
268         /* The tables that map labels to instructions
269          * and labels to basic blocks are not used.
270          */
271         if (*p_out != (proc_p) 0) {
272                 oldmap(lmap,llength);
273                 oldmap(lbmap,llength);
274                 lmap = oldlmap;
275                 lpmap = oldlpmap;
276         }
277         llength = oldllength;
278         lastlabid = oldlastlabid;
279         return dumhead;
280 }
281
282
283
284 calcnt_p getcc(ccf,p)
285         FILE *ccf;
286         proc_p p;
287 {
288         /* Get call-count info of procedure p */
289
290         calcnt_p head,cc,*ccp;
291         short i;
292
293         fseek(ccf,p->p_extend->px_il.p_ccaddr,0);
294         curinp = ccf;
295         head = (calcnt_p) 0;
296         ccp = &head;
297         for (i = getshort(); i != (short) 0; i--) {
298                 cc = *ccp = newcalcnt();
299                 cc->cc_proc = pmap[getshort()];
300                 cc->cc_count = getshort();
301                 ccp = &cc->cc_next;
302         }
303         return head;
304 }
305
306
307 /* The following routines are only used by the Inline Substitution phase */
308
309
310 STATIC putactuals(alist,cfile)
311         actual_p alist;
312         FILE     *cfile;
313 {
314         /* output a list of actual parameters */
315
316         actual_p a,next;
317         line_p l;
318         int count;
319
320         count = 0;
321         for (a = alist; a != (actual_p) 0; a = a->ac_next) count++;
322         outshort(count); /* number of actuals */
323         for (a = alist; a != (actual_p) 0; a = next) {
324                 next = a->ac_next;
325                 count = 0;
326                 for (l = a->ac_exp; l != (line_p) 0; l= l->l_next) count++;
327                 outshort(count); /* length of actual */
328                 outoff(a->ac_size);
329                 outbyte(a->ac_inl);
330                 count = putlines(a->ac_exp,cfile);
331                 oldactual(a);
332         }
333 }
334
335
336
337 putcall(c,cfile,level)
338         call_p c;
339         FILE   *cfile;
340         short  level;
341 {
342         /* output a call */
343
344         call_p nc,nextc;
345
346
347         curoutp = cfile;
348         outshort(level);  /* nesting level */
349         outshort(c->cl_caller->p_id);   /* calling proc */
350         outshort(c->cl_id);
351         outshort(c->cl_proc->p_id);     /* called proc */
352         outbyte(c->cl_looplevel);
353         outbyte(c->cl_flags);
354         outshort(c->cl_ratio);
355         putactuals(c->cl_actuals,cfile);
356         nc = c->cl_car;
357         oldcall(c);
358         for (; nc != (call_p) 0; nc = nextc) {
359                 /* take care of nested calls */
360                 nextc = nc->cl_cdr;
361                 putcall(nc,cfile,level+1);
362         }
363 }
364
365 long putcc(head,ccf)
366         calcnt_p head;
367         FILE     *ccf;
368 {
369         /* Write call-count information to file ccf.
370          * Return the disk address of the info written.
371          */
372
373         calcnt_p cc;
374         long addr;
375         short cnt;
376
377         addr = ftell(ccf);
378         curoutp = ccf;
379         cnt = 0;
380         for (cc = head; cc != (calcnt_p) 0;cc = cc->cc_next) cnt++;
381         outshort(cnt);
382         for (cc = head; cc != (calcnt_p) 0; cc = cc->cc_next) {
383                 outproc(cc->cc_proc);
384                 outshort(cc->cc_count);
385         }
386         return addr;
387 }