Subversion Repositories tendra.SVN

Rev

Rev 2 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
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
}