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
/*
2
    Copyright (c) 1993 Open Software Foundation, Inc.
3
 
4
 
5
    All Rights Reserved
6
 
7
 
8
    Permission to use, copy, modify, and distribute this software
9
    and its documentation for any purpose and without fee is hereby
10
    granted, provided that the above copyright notice appears in all
11
    copies and that both the copyright notice and this permission
12
    notice appear in supporting documentation.
13
 
14
 
15
    OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING
16
    ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
17
    PARTICULAR PURPOSE.
18
 
19
 
20
    IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
21
    CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
22
    LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
23
    NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
24
    WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
25
*/
26
 
27
/*
28
    		 Crown Copyright (c) 1997
29
 
30
    This TenDRA(r) Computer Program is subject to Copyright
31
    owned by the United Kingdom Secretary of State for Defence
32
    acting through the Defence Evaluation and Research Agency
33
    (DERA).  It is made available to Recipients with a
34
    royalty-free licence for its use, reproduction, transfer
35
    to other parties and amendment for any purpose not excluding
36
    product development provided that any such use et cetera
37
    shall be deemed to be acceptance of the following conditions:-
38
 
39
        (1) Its Recipients shall ensure that this Notice is
40
        reproduced upon any copies or amended versions of it;
41
 
42
        (2) Any amended version of it shall be clearly marked to
43
        show both the nature of and the organisation responsible
44
        for the relevant amendment or amendments;
45
 
46
        (3) Its onward transfer from a recipient to another
47
        party shall be deemed to be that party's acceptance of
48
        these conditions;
49
 
50
        (4) DERA gives no warranty or assurance as to its
51
        quality or suitability for any purpose and DERA accepts
52
        no liability whatsoever in relation to any use to which
53
        it may be put.
54
*/
55
 
56
 
57
 
58
/**********************************************************************
59
$Author: release $
60
$Date: 1998/02/04 15:49:11 $
61
$Revision: 1.2 $
62
$Log: tempdecs.c,v $
63
 * Revision 1.2  1998/02/04  15:49:11  release
64
 * Added OSF copyright message.
65
 *
66
 * Revision 1.1.1.1  1998/01/17  15:55:58  release
67
 * First version to be checked into rolling release.
68
 *
69
 * Revision 1.2  1996/10/04  16:04:47  pwe
70
 * add banners and mod for PWE ownership
71
 *
72
**********************************************************************/
73
 
74
 
75
#include "config.h"
76
#include "tags.h"
77
#include "common_types.h"
78
#include "exp.h"
79
#include "const.h"
80
#include "expmacs.h"
81
#include "bitsmacs.h"
82
#include "regable.h"
83
#include "tempdecs.h"
84
#include "regmacs.h"
85
#include "myassert.h"
86
 
87
/* to go in a switch as in case CASE_APPLYLIKE: */
88
#define	CASE_APPLYLIKE	apply_tag: case round_tag:case apply_general_tag
89
 
90
 
91
bool tempdecopt;	/* flag to allow this optimisation, set in main() */
92
static int nouses;
93
static bool useinpar;
94
static int param_uses PROTO_S ((exp));
95
static int locate_param PROTO_S ((exp));
96
 
97
bool APPLYLIKE PROTO_N ((e)) PROTO_T (exp e)
98
{
99
  if(name(e)==apply_tag )
100
    return 1;
101
  if(name(e)==apply_general_tag)
102
    return 1;
103
  if(name(e)==round_tag)
104
    if(name(sh(e))==ulonghd||architecture!=POWERPC_CODE)
105
      return 1;
106
  return 0;
107
}
108
/* RETURNS_R_RESULT returns 1 if the exp returns R_RESULT when evaluated */
109
bool RETURNS_R_RESULT PROTO_N ((e)) PROTO_T (exp e )
110
{
111
  if(name(e)==apply_tag && valregable(sh(e)))
112
  {
113
    return 1;
114
  }
115
  if(name(e)==apply_general_tag && valregable(sh(e)))
116
  {
117
    return 1;
118
  }
119
  if(name(e)==round_tag)
120
  {
121
    if(name(sh(e))==ulonghd||architecture!=POWERPC_CODE)
122
      return 1;
123
  }
124
  return 0;
125
}
126
/* RETURNS_FR_RESULT returns 1 if the exp returns FR_RESULT when evaluated */
127
bool RETURNS_FR_RESULT PROTO_N ((e)) PROTO_T (exp e)
128
{
129
  if(name(e)==apply_tag && is_floating(name(sh(e))))
130
  {
131
    return 1;
132
  }
133
  if(name(e)==apply_general_tag && is_floating(name(sh(e))))
134
  {
135
    return 1;
136
  }
137
  return 0;
138
}
139
 
140
 
141
int trace_uses PROTO_N ((e,id)) PROTO_T (exp e X exp id)
142
{
143
  /*
144
   * reduces nouses for each non-assignment use of id encountered in e; sets
145
   * useinpar if use in actual parameter (or function) posn terminates with 0 on
146
   * applications or jumps terminates with 2 on assignment to id otherwise
147
   * delivers 1
148
   * 0 is returned if trace_uses runs into a dead end 
149
   * 2 is returned if trace_uses runs into another assignment
150
   * 1 is returned if still searching ok so as soon as 0 or 2 is returned 
151
   * the recursion ends quickly
152
   */
153
 
154
  if(APPLYLIKE(e))
155
  {
156
    /* u is nouses before we start to scan the parameters */
157
    int u = nouses;
158
    int p = 1;
159
    exp l = son(e);
160
 
161
    while (p == 1)
162
    {
163
      p = trace_uses(l, id);
164
      if (u != nouses || p == 2)
165
      {
166
	/* We found a use of the ident or we found an assignment to it */
167
	useinpar = 1;
168
      }
169
 
170
      if (p == 0)
171
	nouses = u;
172
      if (last(l))
173
	break;
174
      l = bro(l);
175
    }
176
    return 0;
177
  }
178
 
179
  switch (name(e))
180
  {
181
   case caller_name_tag:
182
   case env_offset_tag:
183
   case general_env_offset_tag:
184
    /* Don't want to look at sons of these tags */
185
    return 1;
186
   case name_tag:
187
    {
188
      nouses -= (son(e) == id);
189
      return (1);
190
    }
191
 
192
   case ident_tag:
193
    {
194
      exp f = son(e);
195
      exp s = bro(f);
196
      int a;
197
 
198
      if ((props(e) & defer_bit) != 0)
199
      {
200
	exp t = f;
201
 
202
	f = s;
203
	s = t;
204
      }
205
      a = trace_uses(f, id);
206
      if (a != 1)
207
	return a;
208
      return trace_uses(s, id);
209
    }
210
   case case_tag:
211
    {
212
      trace_uses(son(e), id);
213
      return 0;
214
    }
215
 
216
  case labst_tag:
217
    return 0;
218
 
219
   case cond_tag:
220
    {
221
      int el;
222
 
223
      /* Cond tags are not treated like the default since we know 
224
	 that the first argument will be coded first */
225
      el = trace_uses(son(e),id);
226
      if (el != 1)
227
      {
228
	return el;
229
      }
230
      return 0;
231
    }
232
   case seq_tag:
233
    {
234
      exp s = son(son(e));
235
 
236
      for (;;)
237
      {
238
	int el = trace_uses(s, id);
239
 
240
	if (el != 1)
241
	  return el;
242
	if (last(s))
243
	  return trace_uses(bro(son(e)), id);
244
	s = bro(s);
245
      }
246
    }
247
 
248
   case ass_tag:
249
    {
250
      if (isvar(id) && name(son(e)) == name_tag && son(son(e)) == id)
251
      {
252
	trace_uses(bro(son(e)), id);
253
	return 2;
254
      }
255
      else if (APPLYLIKE(bro(son(e))))
256
      {
257
	return trace_uses(bro(son(e)), id);
258
      }
259
      /* else cont to next case */
260
    }
261
   default:
262
    {
263
      exp s = son(e);
264
      int nu = nouses;
265
      int bad_arguments = 0; 
266
      /* A bad argument is one which contains an assignment or something to stop flow */
267
      int good_arguments = 0;
268
      /* A good_argument is one which contains one or more uses of id, but doesn't have
269
	 any assignments or things to stop flow */
270
      int ret_value = 0;
271
 
272
      if(s==nilexp)
273
      {
274
	/*no arguments */
275
	return 1;
276
      }
277
      for (;;)
278
      {
279
	int monitor_uses;
280
	int el; 
281
	monitor_uses = nouses;
282
	el = trace_uses(s, id);
283
	if (el==1  && nouses < monitor_uses)
284
	{
285
	  /* argument with uses of ident*/
286
	  good_arguments ++;
287
	}
288
	if (el != 1)
289
	{	
290
	  /* An argument corrupts the flow */
291
	  bad_arguments++;
292
	  ret_value = el;
293
	}
294
	if (last(s))
295
	  break;
296
	s = bro(s);
297
      }
298
      if (bad_arguments==0)
299
      {
300
	return 1;
301
	/* No problems */
302
      }
303
 
304
      if (bad_arguments==1 && good_arguments==0)
305
      {
306
	/* one bad one */
307
	/* all the rest don't use it */
308
	return ret_value;
309
      }
310
      nouses = nu;
311
      return ret_value;
312
    }
313
  }
314
}
315
 
316
 
317
void after_a PROTO_N ((a,id)) PROTO_T (exp a X exp id)
318
{
319
  /* apply trace_uses to dynamic successors of a */
320
  exp dad;
321
  exp l;
322
 
323
tailrecurse:
324
  dad = father(a);
325
  if (nouses == 0)
326
    return;
327
  if (name(dad) == cond_tag || name(dad) == rep_tag
328
      || name(dad) == solve_tag || name(dad) == labst_tag
329
      || name(dad) == case_tag || name(dad) == goto_tag
330
      || name(dad) == test_tag || APPLYLIKE(dad))
331
  {
332
    /* dont try too hard ! */
333
    while (APPLYLIKE(dad) && dad != id)
334
      dad = father(dad);
335
    if (APPLYLIKE(dad))
336
    {
337
      useinpar = 1;
338
    }
339
    return;
340
  }
341
 
342
 
343
  for (l = a; !last(l); l = bro(l))
344
  {
345
    int u = trace_uses(bro(l), id);
346
 
347
    if (u != 1 || nouses == 0)
348
      return;
349
  }
350
  a = dad;
351
  if (dad != id)
352
    goto tailrecurse;
353
}
354
bool simple_seq PROTO_N ((e,id)) PROTO_T (exp e X exp id)
355
{
356
#if 0
357
  exp dad = father(e);
358
 
359
  for (;;)
360
  {
361
    if (dad == id)
362
      return 1;
363
    if (name(dad) == seq_tag || name(dad) == 0
364
	|| name(dad) == ident_tag)
365
    {
366
      dad = father(dad);
367
    }
368
    else
369
      return 0;
370
  }
371
#else
372
  return 1;
373
#endif
374
}
375
 
376
int tempdec PROTO_N ((e,enoughs)) PROTO_T (exp e X bool enoughs)
377
{
378
  /*
379
   * e is a local declaration; 'enoughs' is a misnomer to say whether there
380
   * are t-regs available delivers 1 if e can be allocated into t-reg or par
381
   * reg
382
   */
383
  exp p;
384
 
385
  if (!tempdecopt)
386
    return 0;
387
 
388
  nouses = 0;
389
  useinpar = 0;
390
 
391
  if (isvar(e))
392
  {
393
    for (p = pt(e); p != nilexp; p = pt(p))
394
    {
395
      /* find no of uses which are not assignments to id ... */
396
      if (!last(p) && last(bro(p))
397
	  && name(bro(bro(p))) == ass_tag)
398
      {
399
	if (!simple_seq(bro(bro(p)), e))
400
	  return 0;
401
	continue;
402
      }
403
      nouses++;
404
    }
405
  }
406
  else
407
    nouses = no(e);
408
 
409
  /*
410
   * trace simple successors to assignmnts or init to id to find if all uses
411
   * occur before unpredictable change of control (or another assignment to
412
   * id)
413
   */
414
 
415
  if (name(son(e)) != clear_tag || isparam(e))
416
  {
417
    after_a(son(e), e);
418
  }
419
 
420
  if (isvar(e))
421
  {
422
    for (p = pt(e); p != nilexp; p = pt(p))
423
    {
424
      if (!last(p) && last(bro(p))
425
	  && name(bro(bro(p))) == ass_tag)
426
      {
427
	after_a(bro(bro(p)), e);
428
      }
429
    }
430
  }
431
 
432
  if (nouses == 0 && (enoughs || !useinpar))
433
  {
434
    if (useinpar)
435
    {
436
      /* See if it can be allocated into a parameter register */
437
      props(e) |= notparreg;
438
      if (isparam(e))
439
      {
440
	return param_uses(e);
441
      }
442
      else 
443
	return 100;
444
    }
445
    return 100;
446
  }
447
  return 0;
448
}
449
static int param_uses PROTO_N ((id)) PROTO_T (exp id)
450
{
451
  exp p;
452
  ASSERT(isparam(id));
453
  ASSERT(useinpar);
454
  ASSERT(nouses==0);
455
  /* We found all the uses of the ident and we found one of them in a parameter list */
456
 
457
  for(p=pt(id) ; p!=nilexp;p = pt(p))
458
  {
459
    if (APPLYLIKE(father(p)))
460
    {
461
      return locate_param(p);
462
    }
463
  }
464
  /* not a simple use in a parameter list */
465
  return 100;
466
}
467
static int locate_param PROTO_N ((e)) PROTO_T (exp e)
468
{
469
  exp f = father(e);
470
  bool is_float = is_floating(name(sh(e)));
471
  exp par;
472
 
473
 
474
  ASSERT(APPLYLIKE(f));
475
  switch (name(f))
476
  {
477
   case apply_general_tag:
478
    par =  son(bro(son(f))); 
479
    break;
480
   case apply_tag:
481
    par = bro(son(f));
482
    break;
483
   case round_tag:
484
    par = son(f);
485
    break;
486
   default:
487
    return 0;
488
  }
489
  {
490
    int fxparam = R_FIRST_PARAM;
491
    int flparam = FR_FIRST_PARAM;
492
    int stparam = 0;
493
 
494
    for(;;)
495
    {
496
      int par_size = shape_size(sh(par));
497
 
498
      if (par==e)
499
      {
500
	/* We have found it */
501
	if (is_float)
502
	{
503
	  if (flparam>FR_LAST_PARAM)
504
	    return 0;
505
	  else
506
	    return flparam;
507
	}
508
	else
509
	{
510
	  if(fxparam>end_param)
511
	    return 0;
512
	  else
513
	    return fxparam;
514
	}
515
      }
516
      stparam = ALIGNNEXT(stparam + par_size,32);
517
      fxparam = (stparam/32) + R_FIRST_PARAM;
518
      if (is_floating(name(sh(par))))
519
      {
520
	flparam++;
521
      }
522
      if(last(par))
523
	break;
524
      par = bro(par);
525
    }
526
    return 0;
527
  }
528
}  
529
 
530
 
531
 
532
 
533
 
534