Pristine Ack-5.5
[Ack-5.5.git] / util / ego / cs / cs_vnm.c
1 /* $Id: cs_vnm.c,v 1.7 1994/06/24 10:22:52 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 /* V A L U E N U M B E R I N G   M E T H O D */
8
9 #include <em_mnem.h>
10 #include "../share/types.h"
11 #include "../share/global.h"
12 #include "../share/debug.h"
13 #include "../share/aux.h"
14 #include "cs.h"
15 #include "cs_alloc.h"
16 #include "cs_aux.h"
17 #include "cs_entity.h"
18 #include "cs_avail.h"
19 #include "cs_stack.h"
20 #include "cs_kill.h"
21 #include "cs_partit.h"
22 #include "cs_getent.h"
23
24 STATIC push_entity(enp, lfirst)
25         entity_p enp;
26         line_p lfirst;
27 {
28         /* Build token and Push it. */
29
30         struct token tk;
31
32         tk.tk_vn = enp->en_vn;
33         tk.tk_size = enp->en_size;
34         tk.tk_lfirst = lfirst;
35         Push(&tk);
36 }
37
38 STATIC put_expensive_load(bp, lnp, lfirst, enp)
39         bblock_p bp;
40         line_p lnp, lfirst;
41         entity_p enp;
42 {
43         struct avail av;
44         occur_p ocp;
45
46         av.av_instr = INSTR(lnp);
47         av.av_size = enp->en_size;
48         av.av_operand = enp->en_vn;
49
50         ocp = newoccur(lfirst, lnp, bp);
51
52         av_enter(&av, ocp, EXPENSIVE_LOAD);
53 }
54
55 STATIC put_aar(bp, lnp, lfirst, enp)
56         bblock_p bp;
57         line_p lnp, lfirst;
58         entity_p enp;
59 {
60         /* Enp points to an ENARRELEM. We do as if its address was computed. */
61
62         struct avail av;
63         occur_p ocp;
64
65         assert(enp->en_kind == ENARRELEM);
66         av.av_instr = op_aar;
67         av.av_size = ps;
68         av.av_ofirst = enp->en_arbase;
69         av.av_osecond = enp->en_index;
70         av.av_othird = enp->en_adesc;
71
72         ocp = newoccur(lfirst, lnp, bp);
73
74         av_enter(&av, ocp, TERNAIR_OP);
75 }
76
77 STATIC push_avail(avp, lfirst)
78         avail_p avp;
79         line_p lfirst;
80 {
81         struct token tk;
82
83         tk.tk_vn = avp->av_result;
84         tk.tk_size = avp->av_size;
85         tk.tk_lfirst = lfirst;
86         Push(&tk);
87 }
88
89 STATIC push_unair_op(bp, lnp, tkp1)
90         bblock_p bp;
91         line_p lnp;
92         token_p tkp1;
93 {
94         struct avail av;
95         occur_p ocp;
96
97         av.av_instr = INSTR(lnp);
98         av.av_size = avsize(lnp);
99         av.av_operand = tkp1->tk_vn;
100
101         ocp = newoccur(tkp1->tk_lfirst, lnp, bp);
102
103         push_avail(av_enter(&av, ocp, UNAIR_OP), tkp1->tk_lfirst);
104 }
105
106 STATIC push_binair_op(bp, lnp, tkp1, tkp2)
107         bblock_p bp;
108         line_p lnp;
109         token_p tkp1, tkp2;
110 {
111         struct avail av;
112         occur_p ocp;
113
114         av.av_instr = INSTR(lnp);
115         av.av_size = avsize(lnp);
116         av.av_oleft = tkp1->tk_vn;
117         av.av_oright = tkp2->tk_vn;
118
119         ocp = newoccur(tkp1->tk_lfirst, lnp, bp);
120
121         push_avail(av_enter(&av, ocp, BINAIR_OP), tkp1->tk_lfirst);
122 }
123
124 STATIC push_ternair_op(bp, lnp, tkp1, tkp2, tkp3)
125         bblock_p bp;
126         line_p lnp;
127         token_p tkp1, tkp2, tkp3;
128 {
129         struct avail av;
130         occur_p ocp;
131
132         av.av_instr = INSTR(lnp);
133         av.av_size = avsize(lnp);
134         av.av_ofirst = tkp1->tk_vn;
135         av.av_osecond = tkp2->tk_vn;
136         av.av_othird = tkp3->tk_vn;
137
138         ocp = newoccur(tkp1->tk_lfirst, lnp, bp);
139
140         push_avail(av_enter(&av, ocp, TERNAIR_OP), tkp1->tk_lfirst);
141 }
142
143 STATIC fiddle_stack(lnp)
144         line_p lnp;
145 {
146         /* The instruction in lnp does something to the valuenumber-stack. */
147
148         struct token dummy;
149         offset size;
150
151         /* Partly initialize dummy. */
152         dummy.tk_lfirst = lnp;
153
154         switch (INSTR(lnp)) {
155                 default:
156                         assert(FALSE);
157                         break;
158                 case op_lor:
159                         dummy.tk_vn = newvalnum(); dummy.tk_size = ps;
160                         Push(&dummy);
161                         break;
162                 case op_asp:
163                         if ((size = off_set(lnp)) > 0) {
164                                 Pop(&dummy, size);
165                         } else {
166                                 dummy.tk_vn = newvalnum();
167                                 dummy.tk_size = size;
168                                 Push(&dummy);
169                         }
170                         break;
171                 case op_dup:
172                         Dup(lnp);
173                         break;
174                 case op_ass:
175                 case op_dus:
176                 case op_exg:
177                 case op_los:
178                         /* Don't waste effort. */
179                         clr_stack();
180                         break;
181                 case op_sig:
182                         Pop(&dummy, (offset) ps);
183                         break;
184                 case op_lfr:
185                         dummy.tk_vn = newvalnum();
186                         dummy.tk_size = off_set(lnp);
187                         Push(&dummy);
188                         break;
189                 case op_beq:
190                 case op_bge:
191                 case op_bgt:
192                 case op_bne:
193                 case op_ble:
194                 case op_blt:
195                         Pop(&dummy, (offset) ws);
196                         Pop(&dummy, (offset) ws);
197                         break;
198                 case op_bra:
199                 case op_csa:/* ??? */
200                 case op_csb:/* ??? */
201                 case op_gto:/* ??? */
202                 case op_ret:/* ??? */
203                 case op_rtt:/* ??? */
204                         break;
205                 case op_zeq:
206                 case op_zge:
207                 case op_zgt:
208                 case op_zne:
209                 case op_zle:
210                 case op_zlt:
211                 case op_trp:
212                         Pop(&dummy, (offset) ws);
213                         break;
214                 case op_rck:
215                         Pop(&dummy, (offset) ps);
216                         break;
217         }
218 }
219
220 STATIC proc_p find_proc(vn)
221         valnum vn;
222 {
223         /* Find the procedure-identifier with valuenumber vn. */
224
225         entity_p enp;
226
227         enp = find_entity(vn);
228
229         if (enp != (entity_p) 0 && enp->en_kind == ENPROC)
230                 return enp->en_pro;
231
232         return (proc_p) 0;
233 }
234
235 STATIC side_effects(lnp)
236         line_p lnp;
237 {
238         /* Lnp contains a cai or cal instruction. We try to find the callee
239          * and see what side-effects it has.
240          */
241         struct token tk;
242         proc_p pp;
243
244         if (INSTR(lnp) == op_cai) {
245                 Pop(&tk, (offset) ps);
246                 pp = find_proc(tk.tk_vn);
247         } else {
248                 assert(INSTR(lnp) == op_cal);
249                 pp = PROC(lnp);
250         }
251         if (pp != (proc_p) 0) {
252                 kill_call(pp);
253         } else {
254                 kill_much();
255         }
256 }
257
258 hopeless(instr)
259         int instr;
260 {
261         /* The effect of `instr' is too difficult to
262          * compute. We assume worst case behaviour.
263          */
264         switch (instr) {
265                 default:
266                         assert(FALSE);
267                         break;
268                 case op_mon:
269                 case op_str:
270                 case op_nop:    /* for volatiles */
271                         /* We can't even trust "static" entities. */
272                         kill_all();
273                         clr_stack();
274                         break;
275                 case op_blm:
276                 case op_bls:
277                 case op_sts:
278                         kill_much();
279                         clr_stack();
280                         break;
281         }
282 }
283
284 vnm(bp)
285         bblock_p bp;
286 {
287         register line_p lnp;
288         register entity_p rep;
289         line_p lfirst;
290         struct token tk, tk1, tk2, tk3;
291
292         for (lnp = bp->b_start; lnp != (line_p) 0; lnp = lnp->l_next) {
293
294                 rep = getentity(lnp, &lfirst);
295                 switch (instrgroup(lnp)) {
296                         case SIMPLE_LOAD:       
297                                 push_entity(rep, lfirst);
298                                 break;
299                         case LOAD_ARRAY:
300                                 put_aar(bp, lnp, lfirst, rep);
301                                 /* Fall through ... */
302                         case EXPENSIVE_LOAD:
303                                 push_entity(rep, lfirst);
304                                 put_expensive_load(bp, lnp, lfirst, rep);
305                                 break;
306                         case STORE_DIRECT:
307                                 kill_direct(rep);
308                                 Pop(&tk, rep->en_size);
309                                 rep->en_vn = tk.tk_vn;
310                                 break;
311                         case STORE_ARRAY:
312                                 put_aar(bp, lnp, lfirst, rep);
313                                 /* Fall through ... */
314                         case STORE_INDIR:
315                                 kill_indir(rep);
316                                 Pop(&tk, rep->en_size);
317                                 rep->en_vn = tk.tk_vn;
318                                 break;
319                         case UNAIR_OP:
320                                 Pop(&tk1, op11size(lnp));
321                                 push_unair_op(bp, lnp, &tk1);
322                                 break;
323                         case BINAIR_OP:
324                                 Pop(&tk2, op22size(lnp));
325                                 Pop(&tk1, op12size(lnp));
326                                 push_binair_op(bp, lnp, &tk1, &tk2);
327                                 break;
328                         case TERNAIR_OP:
329                                 Pop(&tk3, op33size(lnp));
330                                 Pop(&tk2, op23size(lnp));
331                                 Pop(&tk1, op13size(lnp));
332                                 push_ternair_op(bp, lnp, &tk1, &tk2, &tk3);
333                                 break;
334                         case KILL_ENTITY:
335                                 kill_direct(rep);
336                                 break;
337                         case SIDE_EFFECTS:
338                                 side_effects(lnp);
339                                 break;
340                         case FIDDLE_STACK:
341                                 fiddle_stack(lnp);
342                                 break;
343                         case IGNORE:
344                                 break;
345                         case HOPELESS:
346                                 hopeless(INSTR(lnp));
347                                 break;
348                         case BBLOCK_END:
349                                 fiddle_stack(lnp);
350                                 break;
351                         default:
352                                 assert(FALSE);
353                                 break;
354                 }
355         }
356 }