2 |
7u83 |
1 |
/*
|
|
|
2 |
Crown Copyright (c) 1997
|
|
|
3 |
|
|
|
4 |
This TenDRA(r) Computer Program is subject to Copyright
|
|
|
5 |
owned by the United Kingdom Secretary of State for Defence
|
|
|
6 |
acting through the Defence Evaluation and Research Agency
|
|
|
7 |
(DERA). It is made available to Recipients with a
|
|
|
8 |
royalty-free licence for its use, reproduction, transfer
|
|
|
9 |
to other parties and amendment for any purpose not excluding
|
|
|
10 |
product development provided that any such use et cetera
|
|
|
11 |
shall be deemed to be acceptance of the following conditions:-
|
|
|
12 |
|
|
|
13 |
(1) Its Recipients shall ensure that this Notice is
|
|
|
14 |
reproduced upon any copies or amended versions of it;
|
|
|
15 |
|
|
|
16 |
(2) Any amended version of it shall be clearly marked to
|
|
|
17 |
show both the nature of and the organisation responsible
|
|
|
18 |
for the relevant amendment or amendments;
|
|
|
19 |
|
|
|
20 |
(3) Its onward transfer from a recipient to another
|
|
|
21 |
party shall be deemed to be that party's acceptance of
|
|
|
22 |
these conditions;
|
|
|
23 |
|
|
|
24 |
(4) DERA gives no warranty or assurance as to its
|
|
|
25 |
quality or suitability for any purpose and DERA accepts
|
|
|
26 |
no liability whatsoever in relation to any use to which
|
|
|
27 |
it may be put.
|
|
|
28 |
*/
|
|
|
29 |
|
|
|
30 |
|
|
|
31 |
/**********************************************************************
|
|
|
32 |
$Author: pwe $
|
|
|
33 |
$Date: 1998/03/11 11:03:24 $
|
|
|
34 |
$Revision: 1.4 $
|
|
|
35 |
$Log: inline.c,v $
|
|
|
36 |
* Revision 1.4 1998/03/11 11:03:24 pwe
|
|
|
37 |
* DWARF optimisation info
|
|
|
38 |
*
|
|
|
39 |
* Revision 1.3 1998/02/18 11:22:11 pwe
|
|
|
40 |
* test corrections
|
|
|
41 |
*
|
|
|
42 |
* Revision 1.2 1998/01/20 17:14:23 release
|
|
|
43 |
* Parameter named 'formal' confused SCO cc.
|
|
|
44 |
*
|
|
|
45 |
* Revision 1.1.1.1 1998/01/17 15:55:47 release
|
|
|
46 |
* First version to be checked into rolling release.
|
|
|
47 |
*
|
|
|
48 |
* Revision 1.5 1997/10/23 09:24:25 pwe
|
|
|
49 |
* extra diags
|
|
|
50 |
*
|
|
|
51 |
* Revision 1.4 1997/08/23 13:24:09 pwe
|
|
|
52 |
* no invert order, and NEWDIAGS inlining
|
|
|
53 |
*
|
|
|
54 |
Revision 1.3 1997/03/20 17:05:12 currie
|
|
|
55 |
Dwarf2 diags
|
|
|
56 |
|
|
|
57 |
Revision 1.2 1997/02/18 12:56:28 currie
|
|
|
58 |
NEW DIAG STRUCTURE
|
|
|
59 |
|
|
|
60 |
Revision 1.1 1995/04/06 10:44:05 currie
|
|
|
61 |
Initial revision
|
|
|
62 |
|
|
|
63 |
***********************************************************************/
|
|
|
64 |
|
|
|
65 |
|
|
|
66 |
|
|
|
67 |
|
|
|
68 |
#include "config.h"
|
|
|
69 |
#include "common_types.h"
|
|
|
70 |
#include "exp.h"
|
|
|
71 |
#include "expmacs.h"
|
|
|
72 |
#include "check.h"
|
|
|
73 |
#include "tags.h"
|
|
|
74 |
#include "shapemacs.h"
|
|
|
75 |
#include "me_fns.h"
|
|
|
76 |
#include "externs.h"
|
|
|
77 |
#include "flags.h"
|
|
|
78 |
#ifdef NEWDIAGS
|
|
|
79 |
#include "dg_globs.h"
|
|
|
80 |
#include "dg_aux.h"
|
|
|
81 |
#endif
|
|
|
82 |
|
|
|
83 |
#include "inline.h"
|
|
|
84 |
|
|
|
85 |
/* PROCEDURES */
|
|
|
86 |
|
|
|
87 |
static exp last_action
|
|
|
88 |
PROTO_N ( (e) )
|
|
|
89 |
PROTO_T ( exp e )
|
|
|
90 |
{
|
|
|
91 |
if (e == nilexp)
|
|
|
92 |
return e;
|
|
|
93 |
|
|
|
94 |
if (name(e) == ident_tag || name(e) == seq_tag) {
|
|
|
95 |
return last_action(bro(son(e)));
|
|
|
96 |
}
|
|
|
97 |
|
|
|
98 |
return e;
|
|
|
99 |
}
|
|
|
100 |
|
|
|
101 |
static void change_last_shapes
|
|
|
102 |
PROTO_N ( (e, sha) )
|
|
|
103 |
PROTO_T ( exp e X shape sha )
|
|
|
104 |
{
|
|
|
105 |
if (e == nilexp)
|
|
|
106 |
return;
|
|
|
107 |
|
|
|
108 |
if (name(e) == ident_tag || name(e) == seq_tag) {
|
|
|
109 |
sh(e) = sha;
|
|
|
110 |
change_last_shapes(bro(son(e)), sha);
|
|
|
111 |
}
|
|
|
112 |
|
|
|
113 |
return;
|
|
|
114 |
}
|
|
|
115 |
|
|
|
116 |
/* replaces a formal paramter by an actual parameter */
|
|
|
117 |
static void replace_pars
|
|
|
118 |
PROTO_N ( (actual, formal_par) )
|
|
|
119 |
PROTO_T ( exp actual X exp formal_par )
|
|
|
120 |
{
|
|
|
121 |
exp def;
|
|
|
122 |
if (!last(actual))
|
|
|
123 |
replace_pars(bro(actual), bro(son(formal_par)));
|
|
|
124 |
|
|
|
125 |
clearparam(formal_par);
|
|
|
126 |
def = son(formal_par);
|
|
|
127 |
if (no(formal_par) == 1 &&
|
|
|
128 |
shape_size(sh(pt(formal_par))) == 8)
|
|
|
129 |
setvis(formal_par);
|
|
|
130 |
replace(def, actual, formal_par);
|
|
|
131 |
|
|
|
132 |
retcell(def);
|
|
|
133 |
return;
|
|
|
134 |
}
|
|
|
135 |
|
|
|
136 |
/* inlines the procedure application e */
|
|
|
137 |
void inline_exp
|
|
|
138 |
PROTO_N ( (e) )
|
|
|
139 |
PROTO_T ( exp e )
|
|
|
140 |
{
|
|
|
141 |
exp fn = son(e); /* the name_tag for the function */
|
|
|
142 |
exp pars = bro(fn); /* the first actual parameter */
|
|
|
143 |
exp body = son(son(son(fn))); /* the proc_tag exp */
|
|
|
144 |
exp bc, t, q;
|
|
|
145 |
exp lab;
|
|
|
146 |
exp var; /* the destination to which the result is to
|
|
|
147 |
be assigned */
|
|
|
148 |
exp new_var = nilexp;
|
|
|
149 |
exp new_dec; /* a new variable declaration if we make one */
|
|
|
150 |
shape sha = sh(e); /* the shape delivered by the application */
|
|
|
151 |
exp cond_alt;
|
|
|
152 |
exp res;
|
|
|
153 |
exp last_act;
|
|
|
154 |
|
|
|
155 |
if (name(sha) == tophd) { /* not returning a result, no ass needed */
|
|
|
156 |
var = nilexp;
|
|
|
157 |
cond_alt = f_make_top();
|
|
|
158 |
}
|
|
|
159 |
else {
|
|
|
160 |
if (last(e) && name(bro(e)) == ass_tag &&
|
|
|
161 |
name(son(bro(e))) == name_tag) {
|
|
|
162 |
/* the result of the application is being assigned to
|
|
|
163 |
a name_tag */
|
|
|
164 |
var = son(bro(e));/* the destination of the ass */
|
|
|
165 |
cond_alt = f_make_top(); /* the result is being assigned in the
|
|
|
166 |
body - no need for a delivered result */
|
|
|
167 |
e = bro(e); /* NOTE e CHANGED to ass_tag */
|
|
|
168 |
#ifdef NEWDIAGS
|
|
|
169 |
if (diagnose) { /* bro(son(e)) is now the call */
|
|
|
170 |
dg_whole_comp (e, bro(son(e)));
|
|
|
171 |
dgf(e) = dgf(bro(son(e)));
|
|
|
172 |
}
|
|
|
173 |
#endif
|
|
|
174 |
}
|
|
|
175 |
else {
|
|
|
176 |
new_dec = me_start_clearvar(sha, sha);
|
|
|
177 |
/* make a new variable to assign to at each res_tag */
|
|
|
178 |
setinlined(new_dec); /* mark the declaration */
|
|
|
179 |
new_var = me_obtain(new_dec);
|
|
|
180 |
var = new_var; /* the destination of assignments
|
|
|
181 |
new_var is killed at end */
|
|
|
182 |
cond_alt = f_contents(sha, copy(new_var));
|
|
|
183 |
/* delivers the contents of the variable - hence the value */
|
|
|
184 |
};
|
|
|
185 |
};
|
|
|
186 |
|
|
|
187 |
lab = me_b3(sh(cond_alt), me_shint(sha, 0), cond_alt, labst_tag);
|
|
|
188 |
/* the labst for the new cond_tag we are making up */
|
|
|
189 |
name(son(lab)) = clear_tag;
|
|
|
190 |
|
|
|
191 |
t = fn; /* start t so that its bro is the first actual parameter */
|
|
|
192 |
q = body; /* start q so that its son is the first formal parameter */
|
|
|
193 |
|
|
|
194 |
while (!last(t)) /* check actual and formal shapes */
|
|
|
195 |
{
|
|
|
196 |
if (name(q) != ident_tag || !isparam(q))
|
|
|
197 |
return; /* no inline if more actuals than formals */
|
|
|
198 |
if (shape_size(sh(bro(t))) != shape_size(sh(son(q))))
|
|
|
199 |
return; /* no inlining if shapes do not match. */
|
|
|
200 |
t = bro(t); /* next actual */
|
|
|
201 |
q = bro(son(q)); /* next formal */
|
|
|
202 |
};
|
|
|
203 |
|
|
|
204 |
if (name(q) == ident_tag && isparam(q))
|
|
|
205 |
return; /* no inline if more formals than actuals */
|
|
|
206 |
|
|
|
207 |
#ifdef NEWDIAGS
|
|
|
208 |
doing_inlining = 1;
|
|
|
209 |
#endif
|
|
|
210 |
bc = copy_res(body, var, lab);
|
|
|
211 |
/* copy the body, making res_tag into assignment to var and
|
|
|
212 |
jump to lab */
|
|
|
213 |
#ifdef NEWDIAGS
|
|
|
214 |
doing_inlining = 0;
|
|
|
215 |
#endif
|
|
|
216 |
bc = hold(bc);
|
|
|
217 |
|
|
|
218 |
if (!last(fn)) { /* if there are any parameters */
|
|
|
219 |
replace_pars(pars, son(bc)); /* replace formals by actuals */
|
|
|
220 |
}
|
|
|
221 |
|
|
|
222 |
IGNORE check(son(bc), son(bc)); /* check the result (proc_tag ?)*/
|
|
|
223 |
res = son(bc); /* remove the proc_tag */
|
|
|
224 |
retcell(bc); /* and retcell it */
|
|
|
225 |
|
|
|
226 |
last_act = last_action(res);
|
|
|
227 |
if (no(son(lab)) == 1 && name(last_act) == goto_tag &&
|
|
|
228 |
pt(last_act) == lab) {
|
|
|
229 |
/* there is only one (final) goto replacement for return */
|
|
|
230 |
if (name(res) == goto_tag) {
|
|
|
231 |
res = (name(sha)==tophd)?f_make_top():f_make_value(sha);
|
|
|
232 |
}
|
|
|
233 |
else {
|
|
|
234 |
change_last_shapes(res, sh(bro(son(lab))));
|
|
|
235 |
#ifdef NEWDIAGS
|
|
|
236 |
if (diagnose)
|
|
|
237 |
dg_whole_comp (last_act, bro(son(lab)));
|
|
|
238 |
#endif
|
|
|
239 |
replace(last_act, bro(son(lab)), res);
|
|
|
240 |
}
|
|
|
241 |
}
|
|
|
242 |
else
|
|
|
243 |
res = me_b3(sh(lab), res, lab, cond_tag);
|
|
|
244 |
/* make up the cond out of the substituted exp and lab */
|
|
|
245 |
|
|
|
246 |
if (var != nilexp)
|
|
|
247 |
kill_exp(var, var);
|
|
|
248 |
|
|
|
249 |
if (new_var != nilexp) { /* we made up a new variable */
|
|
|
250 |
SET(new_dec);
|
|
|
251 |
if (no(new_dec) != 1) {
|
|
|
252 |
res = me_complete_id(new_dec, res); /* complete the variable def */
|
|
|
253 |
}
|
|
|
254 |
else {
|
|
|
255 |
exp r = f_make_top();
|
|
|
256 |
#ifdef NEWDIAGS
|
|
|
257 |
if (diagnose)
|
|
|
258 |
dgf(r) = dgf(bro(son(lab)));
|
|
|
259 |
#endif
|
|
|
260 |
replace(bro(son(lab)), r, r);
|
|
|
261 |
}
|
|
|
262 |
};
|
|
|
263 |
|
|
|
264 |
|
|
|
265 |
#ifdef NEWDIAGS
|
|
|
266 |
if (diagnose)
|
|
|
267 |
dg_complete_inline (e, res);
|
|
|
268 |
#endif
|
|
|
269 |
replace(e, res, nilexp); /* replace the call by the inlined stuff */
|
|
|
270 |
kill_exp(fn, fn); /* kill off the function name_tag */
|
|
|
271 |
|
|
|
272 |
return;
|
|
|
273 |
}
|