Subversion Repositories tendra.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 7u83 1
/*
7 7u83 2
 * Copyright (c) 2002-2006 The TenDRA Project <http://www.tendra.org/>.
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions are met:
7
 *
8
 * 1. Redistributions of source code must retain the above copyright notice,
9
 *    this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright notice,
11
 *    this list of conditions and the following disclaimer in the documentation
12
 *    and/or other materials provided with the distribution.
13
 * 3. Neither the name of The TenDRA Project nor the names of its contributors
14
 *    may be used to endorse or promote products derived from this software
15
 *    without specific, prior written permission.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
18
 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
19
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
21
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22
 * EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
 *
29
 * $Id$
30
 */
31
/*
2 7u83 32
    		 Crown Copyright (c) 1997
33
 
34
    This TenDRA(r) Computer Program is subject to Copyright
35
    owned by the United Kingdom Secretary of State for Defence
36
    acting through the Defence Evaluation and Research Agency
37
    (DERA).  It is made available to Recipients with a
38
    royalty-free licence for its use, reproduction, transfer
39
    to other parties and amendment for any purpose not excluding
40
    product development provided that any such use et cetera
41
    shall be deemed to be acceptance of the following conditions:-
42
 
43
        (1) Its Recipients shall ensure that this Notice is
44
        reproduced upon any copies or amended versions of it;
45
 
46
        (2) Any amended version of it shall be clearly marked to
47
        show both the nature of and the organisation responsible
48
        for the relevant amendment or amendments;
49
 
50
        (3) Its onward transfer from a recipient to another
51
        party shall be deemed to be that party's acceptance of
52
        these conditions;
53
 
54
        (4) DERA gives no warranty or assurance as to its
55
        quality or suitability for any purpose and DERA accepts
56
        no liability whatsoever in relation to any use to which
57
        it may be put.
58
*/
59
 
60
 
61
/**********************************************************************
62
$Author: pwe $
63
$Date: 1998/03/11 11:03:24 $
64
$Revision: 1.4 $
65
$Log: inline.c,v $
66
 * Revision 1.4  1998/03/11  11:03:24  pwe
67
 * DWARF optimisation info
68
 *
69
 * Revision 1.3  1998/02/18  11:22:11  pwe
70
 * test corrections
71
 *
72
 * Revision 1.2  1998/01/20  17:14:23  release
73
 * Parameter named 'formal' confused SCO cc.
74
 *
75
 * Revision 1.1.1.1  1998/01/17  15:55:47  release
76
 * First version to be checked into rolling release.
77
 *
78
 * Revision 1.5  1997/10/23  09:24:25  pwe
79
 * extra diags
80
 *
81
 * Revision 1.4  1997/08/23  13:24:09  pwe
82
 * no invert order, and NEWDIAGS inlining
83
 *
84
Revision 1.3  1997/03/20 17:05:12  currie
85
Dwarf2 diags
86
 
87
Revision 1.2  1997/02/18 12:56:28  currie
88
NEW DIAG STRUCTURE
89
 
90
Revision 1.1  1995/04/06 10:44:05  currie
91
Initial revision
92
 
93
***********************************************************************/
94
 
95
#include "config.h"
96
#include "common_types.h"
97
#include "exp.h"
98
#include "expmacs.h"
99
#include "check.h"
100
#include "tags.h"
101
#include "shapemacs.h"
102
#include "me_fns.h"
103
#include "externs.h"
104
#include "flags.h"
105
#ifdef NEWDIAGS
106
#include "dg_globs.h"
107
#include "dg_aux.h"
108
#endif
109
 
110
#include "inline.h"
111
 
112
/* PROCEDURES */
113
 
7 7u83 114
static exp
115
last_action(exp e)
2 7u83 116
{
7 7u83 117
	if (e == nilexp) {
118
		return e;
119
	}
2 7u83 120
 
7 7u83 121
	if (name(e) == ident_tag || name(e) == seq_tag) {
122
		return last_action(bro(son(e)));
123
	}
2 7u83 124
 
7 7u83 125
	return e;
2 7u83 126
}
127
 
7 7u83 128
 
129
static void
130
change_last_shapes(exp e, shape sha)
2 7u83 131
{
7 7u83 132
	if (e == nilexp) {
133
		return;
134
	}
2 7u83 135
 
7 7u83 136
	if (name(e) == ident_tag || name(e) == seq_tag) {
137
		sh(e) = sha;
138
		change_last_shapes(bro(son(e)), sha);
139
	}
2 7u83 140
 
7 7u83 141
	return;
2 7u83 142
}
143
 
7 7u83 144
 
145
/* replaces a formal paramter by an actual parameter */
146
static void
147
replace_pars(exp actual, exp formal_par)
2 7u83 148
{
7 7u83 149
	exp def;
150
	if (!last(actual)) {
151
		replace_pars(bro(actual), bro(son(formal_par)));
152
	}
2 7u83 153
 
7 7u83 154
	clearparam(formal_par);
155
	def = son(formal_par);
156
	if (no(formal_par) == 1 && shape_size(sh(pt(formal_par))) == 8) {
157
		setvis(formal_par);
158
	}
159
	replace(def, actual, formal_par);
2 7u83 160
 
7 7u83 161
	retcell(def);
162
	return;
2 7u83 163
}
164
 
7 7u83 165
 
166
/* inlines the procedure application e */
167
void
168
inline_exp(exp e)
2 7u83 169
{
7 7u83 170
	exp fn = son(e);	/* the name_tag for the function */
171
	exp pars = bro(fn);	/* the first actual parameter */
172
	exp body = son(son(son(fn)));	/* the proc_tag exp */
173
	exp bc, t, q;
174
	exp lab;
175
	exp var;		/* the destination to which the result is to be
176
				   assigned */
177
	exp new_var = nilexp;
178
	exp new_dec;		/* a new variable declaration if we make one */
179
	shape sha = sh(e);	/* the shape delivered by the application */
180
	exp cond_alt;
181
	exp res;
182
	exp last_act;
2 7u83 183
 
7 7u83 184
	if (name(sha) == tophd) {
185
		/* not returning a result, no ass needed */
186
		var = nilexp;
187
		cond_alt = f_make_top();
188
	} else {
189
		if (last(e) && name(bro(e)) == ass_tag &&
190
		    name(son(bro(e))) == name_tag) {
191
			/* the result of the application is being assigned to
192
			   a name_tag */
193
			var = son(bro(e));	/* the destination of the ass */
194
			cond_alt = f_make_top();	/* the result is being
195
							   assigned in the body
196
							   - no need for a
197
							   delivered result */
198
			e = bro(e); /* NOTE e CHANGED to ass_tag */
2 7u83 199
#ifdef NEWDIAGS
7 7u83 200
			if (diagnose) {
201
				/* bro(son(e)) is now the call */
202
				dg_whole_comp(e, bro(son(e)));
203
				dgf(e) = dgf(bro(son(e)));
204
			}
2 7u83 205
#endif
7 7u83 206
		} else {
207
			new_dec = me_start_clearvar(sha, sha);
208
			/* make a new variable to assign to at each res_tag */
209
			setinlined(new_dec);	/* mark the declaration */
210
			new_var = me_obtain(new_dec);
211
			var = new_var;	/* the destination of assignments
212
					   new_var is killed at end */
213
			cond_alt = f_contents(sha, copy(new_var));
214
			/* delivers the contents of the variable - hence the
215
			 * value */
216
		}
217
	}
2 7u83 218
 
7 7u83 219
	lab = me_b3(sh(cond_alt), me_shint(sha, 0), cond_alt, labst_tag);
220
	/* the labst for the new cond_tag we are making up */
221
	name(son(lab)) = clear_tag;
2 7u83 222
 
7 7u83 223
	t = fn;	  /* start t so that its bro is the first actual parameter */
224
	q = body; /* start q so that its son is the first formal parameter */
2 7u83 225
 
7 7u83 226
	while (!last(t)) {
227
		/* check actual and formal shapes */
228
		if (name(q) != ident_tag || !isparam(q)) {
229
			return;  /* no inline if more actuals than formals */
230
		}
231
		if (shape_size(sh(bro(t))) != shape_size(sh(son(q)))) {
232
			return;	/* no inlining if shapes do not match. */
233
		}
234
		t = bro(t);		/* next actual */
235
		q = bro(son(q));	/* next formal */
236
	}
2 7u83 237
 
7 7u83 238
	if (name(q) == ident_tag && isparam(q)) {
239
		return;  /* no inline if more formals than actuals */
240
	}
2 7u83 241
 
242
#ifdef NEWDIAGS
7 7u83 243
	doing_inlining = 1;
2 7u83 244
#endif
7 7u83 245
	bc = copy_res(body, var, lab);
246
	/* copy the body, making res_tag into assignment to var and
2 7u83 247
	   jump to lab */
248
#ifdef NEWDIAGS
7 7u83 249
	doing_inlining = 0;
2 7u83 250
#endif
7 7u83 251
	bc = hold(bc);
2 7u83 252
 
7 7u83 253
	/* if there are any parameters */
254
	if (!last(fn)) {
255
		/* replace formals by actuals */
256
		replace_pars(pars, son(bc));
257
	}
2 7u83 258
 
7 7u83 259
	IGNORE check(son(bc), son(bc));	/* check the result (proc_tag ?)*/
260
	res = son(bc); /* remove the proc_tag */
261
	retcell(bc);	/* and retcell it */
2 7u83 262
 
7 7u83 263
	last_act = last_action(res);
264
	if (no(son(lab)) == 1 && name(last_act) == goto_tag &&
265
	    pt(last_act) == lab) {
266
		/* there is only one (final) goto replacement for return */
267
		if (name(res) == goto_tag) {
268
			res = (name(sha) == tophd) ? f_make_top() :
269
				f_make_value(sha);
270
		} else {
271
			change_last_shapes(res, sh(bro(son(lab))));
2 7u83 272
#ifdef NEWDIAGS
7 7u83 273
			if (diagnose) {
274
				dg_whole_comp(last_act, bro(son(lab)));
275
			}
2 7u83 276
#endif
7 7u83 277
			replace(last_act, bro(son(lab)), res);
278
		}
279
	} else {
280
		res = me_b3(sh(lab), res, lab, cond_tag);
281
	}
282
	/* make up the cond out of the substituted exp and lab */
2 7u83 283
 
7 7u83 284
	if (var != nilexp) {
285
		kill_exp(var, var);
286
	}
2 7u83 287
 
7 7u83 288
	if (new_var != nilexp) { /* we made up a new variable */
289
		SET(new_dec);
290
		if (no(new_dec) != 1) {
291
			/* complete the variable def */
292
			res = me_complete_id(new_dec, res);
293
		} else {
294
			exp r = f_make_top();
2 7u83 295
#ifdef NEWDIAGS
7 7u83 296
			if (diagnose) {
297
				dgf(r) = dgf(bro(son(lab)));
298
			}
2 7u83 299
#endif
7 7u83 300
			replace(bro(son(lab)), r, r);
301
		}
302
	}
2 7u83 303
 
304
 
305
#ifdef NEWDIAGS
7 7u83 306
	if (diagnose) {
307
		dg_complete_inline(e, res);
308
	}
2 7u83 309
#endif
7 7u83 310
	replace(e, res, nilexp); /* replace the call by the inlined stuff */
311
	kill_exp(fn, fn);	 /* kill off the function name_tag */
2 7u83 312
 
7 7u83 313
	return;
2 7u83 314
}