Subversion Repositories tendra.SVN

Rev

Details | 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
$Log: tempdecs.c,v $
33
 * Revision 1.1.1.1  1998/01/17  15:56:03  release
34
 * First version to be checked into rolling release.
35
 *
36
 * Revision 1.2  1995/12/18  13:12:40  wfs
37
 * Put hppatrans uder cvs control. Major Changes made since last release
38
 * include:
39
 * (i) PIC code generation.
40
 * (ii) Profiling.
41
 * (iii) Dynamic Initialization.
42
 * (iv) Debugging of Exception Handling and Diagnostics.
43
 *
44
 * Revision 5.2  1995/10/20  14:14:22  wfs
45
 * #included "muldvrem.h" for gcc compilation.
46
 *
47
 * Revision 5.1  1995/09/07  15:44:58  wfs
48
 * Fixed bug in "APPLYLIKE".
49
 *
50
 * Revision 5.0  1995/08/25  13:42:58  wfs
51
 * Preperation for August 25 Glue release
52
 *
53
 * Revision 3.4  1995/08/25  10:34:20  wfs
54
 * Refinement of "APPLYLIKE" required for 3.1 and 4.0 compatability
55
 *
56
 * Revision 3.4  1995/08/25  10:34:20  wfs
57
 * Refinement of "APPLYLIKE" required for 3.1 and 4.0 compatability
58
 *
59
 * Revision 3.1  95/04/10  16:28:30  16:28:30  wfs (William Simmonds)
60
 * Apr95 tape version.
61
 * 
62
 * Revision 3.0  95/03/30  11:19:06  11:19:06  wfs (William Simmonds)
63
 * Mar95 tape version with CRCR95_178 bug fix.
64
 * 
65
 * Revision 2.0  95/03/15  15:28:59  15:28:59  wfs (William Simmonds)
66
 * spec 3.1 changes implemented, tests outstanding.
67
 * 
68
 * Revision 1.1  95/01/11  13:19:10  13:19:10  wfs (William Simmonds)
69
 * Initial revision
70
 * 
71
*/
72
 
73
 
74
#define HPPATRANS_CODE
75
/* tempdec.c - is the value in the declaration required over proc calls ?
76
    if it isn't, declaration can be allocated in t-reg, rather than
77
    s-reg.
78
 
79
*/
80
 
81
 
82
#include "config.h"
83
#include "tags.h"
84
#include "common_types.h"
85
#include "exp.h"
86
#include "const.h"
87
#include "expmacs.h"
88
#include "bitsmacs.h"
89
#include "muldvrem.h"
90
#include "tempdecs.h"
91
 
92
 
93
/*
94
    IS THE EXPRESSION e A PROCEDURE APPLICATION?
95
*/
96
 
97
#define APPLYLIKE( e ) ( name(e)==apply_tag || name(e)==apply_general_tag ||\
98
			 name(e)==tail_call_tag || is_muldivrem_call(e) )
99
 
100
 
101
/*
102
    FLAG : APPLY TEMPDEF OPTIMISATION?
103
*/
104
 
105
bool tempdecopt ;     /* flag to allow this optimisation, set in main () */
106
 
107
 
108
/*
109
    VARIABLES SET BY TRACE_USES
110
*/
111
 
112
static int nouses ;
113
static bool useinpar ;
114
 
115
 
116
/*
117
    Reduces nouses for each non-assignment use of id encountered in e,
118
    sets useinpar if use in actual parameter (or function) position,
119
    terminates with 0 on applications or jumps, terminates with 2 on
120
    assignment to id, otherwise delivers 1.
121
*/
122
 
123
int trace_uses 
124
    PROTO_N ( ( e, id ) )
125
    PROTO_T ( exp e X exp id )
126
{
127
    if ( APPLYLIKE ( e ) ) {
128
	int u = nouses ;
129
	int p = 1 ;
130
	exp l = son ( e ) ;
131
 
132
	while ( p == 1 ) {
133
	    p = trace_uses ( l, id ) ;
134
	    if ( u != nouses || p == 2 ) useinpar = 1 ;
135
	    if ( p == 0 ) nouses = u ;
136
	    if ( last ( l ) ) break ;
137
	    l = bro ( l ) ;
138
	}
139
	return ( 0 ) ;
140
    }
141
 
142
    switch ( name ( e ) ) {
143
 
144
	case env_offset_tag:
145
	case name_tag : {
146
	    nouses -= ( son ( e ) == id ? 1 : 0 ) ;
147
	    return ( 1 ) ;
148
	}
149
 
150
	case ident_tag : {
151
	    exp f = son ( e ) ;
152
	    exp s = bro ( f ) ;
153
	    int a ;
154
 
155
	    if ( ( props ( e ) & defer_bit ) != 0 ) {
156
		exp t = f ;
157
		f = s ;
158
		s = t ;
159
	    }
160
	    a = trace_uses ( f, id ) ;
161
	    if ( a != 1 ) return ( a ) ;
162
	    return ( trace_uses ( s, id ) ) ;
163
	}
164
 
165
	case case_tag : {
166
	    trace_uses ( son ( e ), id ) ;
167
	    return ( 0 ) ;
168
	}
169
 
170
	case labst_tag : {
171
	    return ( 0 ) ;
172
	}
173
 
174
	case seq_tag : {
175
	    exp s = son ( son ( e ) ) ;
176
	    for ( ; ; ) {
177
		int el = trace_uses ( s, id ) ;
178
		if ( el != 1 ) return ( el ) ;
179
		if ( last ( s ) ) {
180
		    return ( trace_uses ( bro ( son ( e ) ), id ) ) ;
181
		}
182
		s = bro ( s ) ;
183
	    }
184
	    /* NOT REACHED */
185
	    break ;
186
	}
187
 
188
	case test_tag: case goto_lv_tag:{
189
		int nu = nouses;
190
		if (trace_uses(son(e),id) != 1 || 
191
				trace_uses(bro(son(e)), id) !=1 ){
192
			nouses = nu;
193
		}
194
		return 0;
195
	}
196
 
197
	case ass_tag : {
198
	    if ( isvar ( id ) && name ( son ( e ) ) == name_tag &&
199
		 son ( son ( e ) ) == id ) {
200
		trace_uses ( bro ( son ( e ) ), id ) ;
201
		return ( 2 ) ;
202
	    } else if ( APPLYLIKE ( bro ( son ( e ) ) ) ) {
203
		return ( trace_uses ( bro ( son ( e ) ), id ) ) ;
204
	    }
205
	    /* Fall through */
206
	}
207
 
208
	default : {
209
	    exp s = son ( e ) ;
210
	    int nu = nouses ;	 /* s list can be done in any order ... */
211
 
212
	    if ( s == nilexp ) return ( 1 ) ;
213
	    for ( ; ; ) {
214
		int el = trace_uses ( s, id ) ;
215
 
216
		if ( el != 1 ) {
217
		    /* ... so reset nouses if any terminate */
218
		    nouses = nu ;
219
		    return el ;
220
		}
221
		if ( last ( s ) ) return ( 1 ) ;
222
		s = bro ( s ) ;
223
	    }
224
	    /* NOT REACHED */
225
	    break ;
226
	}
227
    }
228
    /* NOT REACHED */
229
    return ( 0 ) ;
230
}
231
 
232
 
233
/*
234
    APPLY TRACE_USES TO DYNAMIC SUCCESSORS OF a
235
*/
236
 
237
void after_a 
238
    PROTO_N ( ( a, id ) )
239
    PROTO_T ( exp a X exp id )
240
{
241
    char n ;
242
    exp dad ;
243
    exp l ;
244
 
245
    tailrec : {
246
	dad = father ( a ) ;
247
	n = name ( dad ) ;
248
	if ( nouses == 0 ) return ;
249
	if ( n == cond_tag || n == rep_tag || n == solve_tag ||
250
	     n == labst_tag || n == case_tag || n == goto_tag ||
251
	     n == test_tag || n == goto_lv_tag || APPLYLIKE ( dad ) ) {
252
	    /* Don't try too hard! */
253
	    while ( APPLYLIKE ( dad ) && dad != id ) dad = father ( dad ) ;
254
	    if ( APPLYLIKE ( dad ) ) {
255
		useinpar = 1 ;
256
	    }
257
	    return ;
258
	}
259
 
260
	for ( l = a ; !last ( l ) ; l = bro ( l ) )
261
	{
262
	    int u = trace_uses ( bro ( l ), id ) ;
263
	    if ( u != 1 || nouses == 0 ) return ;
264
	}
265
	a = dad ;
266
    }
267
    if ( dad != id ) goto tailrec ;
268
    return ;
269
}
270
 
271
 
272
bool simple_seq 
273
    PROTO_N ( ( e, id ) )
274
    PROTO_T ( exp e X exp id )
275
{
276
    exp dad = father ( e ) ;
277
    for ( ; ; ) {
278
	if ( dad == id ) return ( 1 ) ;
279
	if ( name ( dad ) == seq_tag || name ( dad ) == 0 ||
280
	     name ( dad ) == ident_tag ) {
281
	    dad = father ( dad ) ;
282
	} else {
283
	    return ( 0 ) ;
284
	}
285
    }
286
    /* NOT REACHED */
287
}
288
 
289
 
290
bool tempdec 
291
    PROTO_N ( ( e, enoughs ) )
292
    PROTO_T ( exp e X bool enoughs )
293
{
294
    /*
295
 * e is a local declaration ; 'enoughs' is a misnomer to say whether there
296
 * are t-regs available delivers 1 if e can be allocated into t-reg or par
297
 * reg
298
 */
299
    exp p ;
300
    if ( !tempdecopt ) return ( 0 ) ;
301
 
302
    nouses = 0 ;
303
    useinpar = 0 ;
304
 
305
    if ( isvar ( e ) ) {
306
	for ( p = pt ( e ) ; p != nilexp ; p = pt ( p ) ) {
307
	    /* find no of uses which are not assignments to id ... */
308
	    if ( !last ( p ) && last ( bro ( p ) ) &&
309
		 name ( bro ( bro ( p ) ) ) == ass_tag ) {
310
		if ( !simple_seq ( bro ( bro ( p ) ), e ) ) return  ( 0 ) ;
311
		/* ... in simple sequence */
312
		continue ;
313
	    }
314
	    nouses++ ;
315
	}
316
    } else {
317
	nouses = no ( e ) ;
318
    }
319
 
320
    /*
321
 * trace simple successors to assignmnts or init to id to find if all uses
322
 * occur before unpredictable change of control ( or another assignment to
323
 * id )
324
 */
325
 
326
    if ( name ( son ( e ) ) != clear_tag || isparam ( e ) ) {
327
	after_a ( son ( e ), e ) ;
328
    }
329
 
330
    if ( isvar ( e ) ) {
331
	for ( p = pt ( e ) ; p != nilexp ; p = pt ( p ) ) {
332
	    if ( !last ( p ) && last ( bro ( p ) ) &&
333
		 name ( bro ( bro ( p ) ) ) == ass_tag ) {
334
		after_a ( bro ( bro ( p ) ), e ) ;
335
	    }
336
	}
337
    }
338
 
339
    if ( nouses == 0 && ( enoughs || !useinpar ) ) {
340
#if 0
341
	/* +++ temp circumvention, we need to calculate t-reg reqt better when
342
     some not allowed by props ( e ) |= notparreg */
343
	if ( useinpar ) return ( 0 ) ;
344
#else
345
	if ( useinpar ) props ( e ) |= notparreg ;     /* don't allocate this into par reg */
346
#endif
347
	return ( 1 ) ;
348
    }
349
    return ( 0 ) ;
350
}
351
 
352
 
353
 
354
 
355
 
356
 
357
 
358
 
359