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