Subversion Repositories tendra.SVN

Rev

Go to most recent revision | Details | 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:01 $
61
$Revision: 1.2 $
62
$Log: needscan.c,v $
63
 * Revision 1.2  1998/02/04  15:49:01  release
64
 * Added OSF copyright message.
65
 *
66
 * Revision 1.1.1.1  1998/01/17  15:55:57  release
67
 * First version to be checked into rolling release.
68
 *
69
 * Revision 1.4  1996/10/14  17:31:56  pwe
70
 * include called callees in env_size
71
 *
72
 * Revision 1.3  1996/10/14  15:53:31  pwe
73
 * preserve regresult during postlude
74
 *
75
 * Revision 1.2  1996/10/04  16:03:03  pwe
76
 * add banners and mod for PWE ownership
77
 *
78
**********************************************************************/
79
 
80
 
81
/******************************************************************
82
 
83
		needs_scan.c
84
 
85
	Defines the scan through a program which reorganises it so that all
86
arguments of operations are suitable for later code-production. The procedure
87
scan evaluates the register requirements of an exp. The exps are produced
88
from the decoding process and the various exp -> exp transformations  in
89
the proc independent (common to other  translators)
90
 
91
******************************************************************/
92
#include "config.h"
93
#include "memtdf.h"
94
#include "codegen.h"
95
 
96
#include "myassert.h"
97
#include "comment.h"
98
 
99
 
100
#include "common_types.h"
101
#include "exptypes.h"
102
#include "exp.h"
103
#include "expmacs.h"
104
#include "tags.h"
105
#include "localtypes.h"
106
#include "procrectypes.h"
107
#include "bitsmacs.h"
108
#include "maxminmacs.h"
109
#include "regable.h"
110
#include "tempdecs.h"
111
#include "shapemacs.h"
112
#include "const.h"
113
#include "flpt.h"
114
#include "install_fns.h"
115
#include "externs.h"
116
 
117
#include "flags.h"
118
 
119
#include "machine.h"
120
#include "translat.h"
121
#include "check.h"
122
#include "makecode.h"
123
#include "needscan.h"
124
#include "me_fns.h"
125
#include "stack.h"
126
#include "error.h"
127
#include "dynamic_init.h"
128
/*
129
 * Will an ident exp be in memory?
130
 * We have to guess at this stage for non globals.
131
 */
132
#define INMEMIDENT(ident_exp)	(isvis(ident_exp) || isglob(ident_exp))
133
 
134
/*
135
 * Will evaluating exp 'e' cause last instruction to be a load from store?
136
 * Always false if generating diagnostics, we dont want to rearrange in
137
 * this case as it makes debugging less obvious.
138
 * This is not exact, register contents tracking may find a copy in reg.
139
 */
140
#define LOADFROMSTORE(e) \
141
	( \
142
	!diagnose \
143
	&& \
144
	( \
145
	  (name(e) == cont_tag && (name(son(e)) != name_tag || INMEMIDENT(son(son(e))))) \
146
	  || \
147
	  (name(e) == name_tag && isglob(son(e))) /* load of TOC entry */ \
148
	) \
149
	)
150
int maxfix, maxfloat;		/* the maximum number of t-regs */
151
bool tail_call;
152
bool gen_call;
153
long callee_size;
154
long max_callees;
155
long no_of_returns;
156
int end_param;
157
 
158
/* The following are used for allocating param regs to t-regs */
159
static int freefixed;
160
static int freefloat;
161
 
162
 
163
static int stparam, fixparam, floatparam;
164
 
165
 
166
extern bool do_tlrecursion;
167
 
168
static bool nonevis = 1;
169
static bool rep_tag_scanned;
170
 
171
int scan_cond PROTO_S ((exp *,exp));
172
needs scan PROTO_S ((exp *, exp ** ));
173
static void number_caller_parameter PROTO_S ((exp));
174
static void number_callee_parameter PROTO_S ((exp));
175
 
176
/* declaration of scan.
177
   needs is defined in procrectypes.h.
178
   This is a structure which has two integers giving
179
   the number of fixed and floating point registers required to contain live values
180
   in the expression parameters. A further field prop is used for various
181
   flags about certain forms of exp (mainly idents and procs). The maxargs
182
   field gives the maximum size in bits for the parameters of all the procs
183
   called in the exp. The needs of a proc body are preserved in the needs field
184
   of the procrec (see procrectypes.h).
185
   */
186
 
187
 
188
/***************************************************************
189
		cca
190
 
191
This procedure effectively inserts a new declaration into an exp. This
192
is used to stop a procedure requiring more than the available number of
193
registers.
194
****************************************************************/
195
 
196
static void cca PROTO_N ((to,x)) PROTO_T (exp * *to X exp * x)
197
{
198
  if (name((**to))==diagnose_tag)
199
  {
200
    *to = &son((**to));
201
  }
202
  if (x == (*to))
203
  {
204
    exp def = *(x);
205
 
206
    /* replace by  Let tg = def In tg Ni */
207
    exp id = getexp(sh(def), bro(def), last(def), def, nilexp,
208
		    0, 1, ident_tag);
209
    exp tg = getexp(sh(def), id, 1, id, nilexp,
210
		    0, 0, name_tag);
211
 
212
    pt(id) = tg;		/* use of tag */
213
    bro(def) = tg;		/* bro(def) is body of Let = tg */
214
    clearlast(def);
215
    *(x) = id;			/* replace pointer to x by Let */
216
    return;
217
  }
218
  else
219
  {				/* replace by Let tg = def In ato/def = tg Ni */
220
    exp def = *(x);
221
    exp ato = *(*to);
222
    exp id = getexp(sh(ato), bro(ato), last(ato), def, nilexp,
223
		    0, 1, ident_tag);
224
    exp tg = getexp(sh(def), bro(def), last(def), id, nilexp,
225
		    0, 0, name_tag);
226
 
227
    pt(id) = tg;		/* use of tg */
228
    bro(def) = ato;		/* ato is body of Let */
229
    clearlast(def);
230
    bro(ato) = id;		/* its father is Let */
231
    setlast(ato);
232
    *(*to) = id;		/* replace pointer to 'to' by Let */
233
    *(x) = tg;			/* replace use of x by tg */
234
    *to = &bro(def);		/* later replacement to same 'to' will be at
235
				 * body of Let */
236
    return;
237
  }
238
}
239
 
240
/* General useful needs */
241
static needs onefix = { 1, 0, 0, 0 };			/* needs one fix pt reg */
242
static needs twofix = { 2, 0, 0, 0 };			/* needs 2 fix pt regs */
243
static needs onefloat = { 0, 1, 0, 0 };			/* needs 1 flt pt regs */
244
static needs zeroneeds = { 0, 0, 0, 0 };		/* has no needs */
245
 
246
 
247
static needs shapeneeds PROTO_N ((s)) PROTO_T (shape s)
248
{				/* this gives the needs for manipulating a
249
				 * value of shape s */
250
  if (is_floating(name(s)))
251
  {
252
    return onefloat;
253
  }
254
  else
255
  {
256
    if (valregable(s))
257
    {
258
      return onefix;
259
    }
260
    else
261
    {				/* if the shape does not fit into a reg, needs
262
				 * two fixed regs for moving ... */
263
      return twofix;
264
    }
265
  }
266
}
267
 
268
 
269
static bool complex PROTO_N ((e)) PROTO_T (exp e)
270
{				/* these are basically the expressions which
271
				 * cannot be accessed by a simple load or
272
				 * store instruction */
273
  if (name(e) == name_tag ||
274
      (
275
       name(e) == cont_tag && 
276
       name(son(e)) == name_tag 
277
       && isvar(son(son(e)))
278
       ) || 
279
      name(e) == val_tag || 
280
      name(e) == real_tag
281
      )
282
  {
283
    return 0;
284
  }
285
  else
286
  {
287
    return 1;
288
  }
289
}
290
 
291
 
292
needs commutative_scan PROTO_N ((e,at)) PROTO_T (exp * e X exp * *at)
293
{
294
  /*
295
   * does the scan on commutative and associative operations and may perform
296
   * various transformations allowed by these properties
297
   */
298
  needs a1;
299
  needs a2;
300
  exp dad = *(e);
301
  exp *br = &son(*e);
302
  exp prev;
303
  bool dont_commute;
304
 
305
  ASSERT(father(son(*e)) == *e);
306
 
307
  /* scan the first operand - won't be a val_tag */
308
  a1 = scan(br, at);
309
 
310
  /* 
311
   * if first operand is a proc, or ends with a load instruction,
312
   * it is not worth doing a commute to a later position
313
   */
314
  dont_commute = (a1.fixneeds >= maxfix || (a1.propsneeds & hasproccall))
315
		 || LOADFROMSTORE(*br);
316
 
317
  do
318
  {
319
    exp *prevbr;
320
 
321
    prevbr = br;
322
    prev = *(br);
323
    br = &bro(prev);
324
    a2 = scan(br, at);
325
    /* scan the next operand ... */
326
    if (name(*(br)) != val_tag)
327
    {
328
      prop pc;
329
      bool all_treg_needs;
330
 
331
      a1.floatneeds = max(a1.floatneeds, a2.floatneeds);
332
      pc = a2.propsneeds & hasproccall;
333
      all_treg_needs = (a2.fixneeds >= maxfix || pc != 0);
334
 
335
      if ( !dont_commute
336
	   &&
337
	   (all_treg_needs || LOADFROMSTORE(*br))
338
	   &&
339
	   (a1.fixneeds < maxfix && (a1.propsneeds & hasproccall) == 0)
340
	 )
341
      {
342
	/*
343
	 * ...its evaluation will call a proc, or ends with a load instruction,
344
	 * so put it first
345
	 */
346
 
347
	exp op1 = son(dad);
348
	exp cop = *(br);
349
	bool lcop = last(cop);
350
 
351
	bro(prev) = bro(cop);
352
	if (lcop)
353
	  setlast(prev);
354
	bro(cop) = op1;
355
	clearlast(cop);
356
	son(dad) = cop;
357
	br = (prev == op1) ? &bro(cop) : prevbr;
358
	dont_commute = 1;
359
	a1.fixneeds = max(a2.fixneeds, a1.fixneeds + 1);
360
	a1.propsneeds |= a2.propsneeds;
361
	a1.maxargs = max(a1.maxargs, a2.maxargs);
362
      }
363
      else if (all_treg_needs)
364
      {				/* ... its evaluation would disturb
365
				 * accumulated result, so replace it by a
366
				 * newly declared tag */
367
	cca(at, br);
368
	a1.fixneeds = max(a1.fixneeds, 2);
369
	a1.propsneeds = a1.propsneeds | morefix | (pc << 1);
370
	a1.maxargs = max(a1.maxargs, a2.maxargs);
371
      }
372
      else
373
      {
374
	/*
375
	 * ... its evaluation  will not disturb the accumulated result
376
	 */
377
	a1.fixneeds = max(a1.fixneeds, a2.fixneeds + 1);
378
	a1.propsneeds = a1.propsneeds | a2.propsneeds;
379
      }
380
    }
381
  } while (!last(*(br)));
382
 
383
  return a1;
384
}
385
 
386
 
387
needs non_commutative_scan PROTO_N ((e,at)) PROTO_T (exp * e X exp * *at)
388
{
389
  /*
390
   * scan non-commutative fix pt operation
391
   */
392
  needs l;
393
  needs r;
394
  prop pc;
395
  exp *arg = &son(*e);
396
 
397
  l = scan(arg, at);
398
  /* scan 1st operand */
399
  arg = &bro(*arg);
400
  r = scan(arg, at);
401
  /* scan second operand ... */
402
  l.floatneeds = max(l.floatneeds, r.floatneeds);
403
  pc = r.propsneeds & hasproccall;
404
  if (r.fixneeds < maxfix && pc == 0)
405
  {				/* ...it fits into registers */
406
    l.fixneeds = max(l.fixneeds, r.fixneeds + 1);
407
    l.propsneeds = l.propsneeds | r.propsneeds;
408
  }
409
  else
410
  {				/* ...it requires new declaration of second
411
				 * operand */
412
    cca(at, arg);
413
    l.fixneeds = max(l.fixneeds, 1);
414
    l.propsneeds = l.propsneeds | morefix | (pc << 1);
415
    l.maxargs = max(l.maxargs, r.maxargs);
416
  }
417
  return l;
418
}
419
 
420
static needs fpop PROTO_N ((e,at)) PROTO_T (exp * e X exp * *at)
421
{
422
  /* scans diadic floating point operation  */
423
  needs l;
424
  needs r;
425
  exp op = *(e);
426
  prop pcr, pcl;
427
  exp *arg = &son(op);
428
 
429
  l = scan(arg, at);
430
  arg = &bro(*arg);
431
  r = scan(arg, at);
432
  l.fixneeds = max(l.fixneeds, r.fixneeds);
433
  pcr = r.propsneeds & hasproccall;
434
  pcl = l.propsneeds & hasproccall;
435
 
436
  if (r.floatneeds <= l.floatneeds && r.floatneeds < maxfloat && pcr == 0)
437
  {
438
    l.floatneeds = max(2, max(l.floatneeds, r.floatneeds + 1));
439
    l.propsneeds = l.propsneeds | r.propsneeds;
440
    ClearRev(op);
441
  }
442
  else if (pcl == 0 && l.floatneeds <= r.floatneeds && l.floatneeds < maxfloat)
443
  {
444
    l.floatneeds = max(2, max(r.floatneeds, l.floatneeds + 1));
445
    l.propsneeds = l.propsneeds | r.propsneeds;
446
    SetRev(op);
447
  }
448
  else if (r.floatneeds < maxfloat && pcr == 0)
449
  {
450
    l.floatneeds = max(2, max(l.floatneeds, r.floatneeds + 1));
451
    l.propsneeds = l.propsneeds | r.propsneeds;
452
    ClearRev(op);
453
  }
454
  else
455
  {
456
    cca(at, arg);
457
    ClearRev(op);
458
    l.floatneeds = max(l.floatneeds, 2);
459
    l.propsneeds = l.propsneeds | morefloat | (pcr << 1);
460
    l.maxargs = max(l.maxargs, r.maxargs);
461
  }
462
  return l;
463
}
464
/**********************************************************************
465
	maxneeds
466
 
467
Calculates a needs value. Each element of which is the maximum of the
468
corresponding elements in the two parameter needs
469
**********************************************************************/
470
 
471
static needs maxneeds PROTO_N ((a,b)) PROTO_T (needs a X needs b)
472
{
473
  needs an;
474
 
475
  an.fixneeds = max(a.fixneeds, b.fixneeds);
476
  an.floatneeds = max(a.floatneeds, b.floatneeds);
477
  an.maxargs = max(a.maxargs, b.maxargs);
478
  an.propsneeds = a.propsneeds | b.propsneeds;
479
  return an;
480
}
481
 
482
 
483
/**********************************************************************
484
	maxsequence
485
 
486
**********************************************************************/
487
 
488
static needs maxtup PROTO_N ((e,at)) PROTO_T (exp e X exp ** at)
489
{				/* calculates the needs of a tuple of
490
				 * expressions; any new declarations required
491
				 * by a component expression will replace the
492
				 * component expression */
493
  exp *stat = &son(e);
494
  needs an;
495
 
496
  an = zeroneeds;
497
  if(*stat==nilexp )
498
  {
499
    return an;
500
  }
501
  while (an = maxneeds(an, scan(stat, at)), !last(*stat))
502
  {
503
    stat = &bro(*stat);
504
  }
505
  return an;
506
}
507
 
508
 
509
static bool unchanged PROTO_N ((usedname,ident)) PROTO_T (exp usedname X exp ident)
510
{
511
  /*
512
   * finds if usedname is only used in cont operation or as result of ident
513
   * i.e. value of name is unchanged over its scope
514
   */
515
  exp uses = pt(usedname);
516
 
517
  while (uses != nilexp)
518
  {
519
    if (intnl_to(ident, uses))
520
    {
521
      if (!last(uses) || name(bro(uses)) != cont_tag)
522
      {
523
	exp z = uses;
524
 
525
	while (z != ident)
526
	{
527
	  if (!last(z) ||
528
	      (name(bro(z)) != seq_tag && name(bro(z)) != ident_tag))
529
	  {
530
	    return 0;
531
	  }
532
	  z = bro(z);
533
	}
534
      }
535
    }
536
    uses = pt(uses);
537
  }
538
  return 1;
539
}
540
 
541
 
542
static exp *ptr_position PROTO_N ((e)) PROTO_T (exp e)
543
{
544
  exp *a;
545
  exp dad = father(e);
546
 
547
  if (son(dad) == e)
548
  {
549
    a = &son(dad);
550
  }
551
  else
552
  {
553
    exp sib = son(dad);
554
 
555
    while (bro(sib) != e)
556
    {
557
      sib = bro(sib);
558
    }
559
    a = &bro(sib);
560
  }
561
  return a;
562
}
563
 
564
 
565
 
566
/*
567
 * The POWER convention for delivering a struct from a procedure is is have an
568
 * extra pointer parameter in the proc; this means that there always must be
569
 * space in the calling work-space for the result struct whether or not the
570
 * value is used e.g. as in f(x); or f(x).a etc. This proc is part of the
571
 * mechanism to determine whether it is necessary to insert a dummy
572
 * declaration to ensure that this space exists.
573
 */
574
static bool chase PROTO_N ((sel,e)) PROTO_T (exp sel X exp * e)
575
{
576
  /* distribute selection throughout compound expressions */
577
  bool b = 0;
578
  exp *one;
579
 
580
  switch (name(*e))
581
  {
582
  case ident_tag:
583
  case seq_tag:
584
  case rep_tag:
585
  case labst_tag:
586
    {
587
      b = chase(sel, &bro(son(*e)));
588
      break;
589
    }
590
  case solve_tag:
591
  case cond_tag:
592
    {
593
      one = &son(*e);
594
      for (;;)
595
      {
596
	b |= chase(sel, one);
597
	if (last(*one))
598
	  break;
599
	one = &bro(*one);
600
      }
601
      break;
602
    }
603
  case field_tag:
604
    {
605
      if (chase(*e, &son(*e)))
606
      {
607
	/* inner field has been distributed */
608
	exp stare = *e;
609
	exp ss = son(stare);
610
 
611
	if (!last(stare))
612
	  clearlast(ss);
613
	bro(ss) = bro(stare);
614
	sh(ss) = sh(stare);
615
	*e = ss;
616
	return chase(sel, e);
617
      }				/* ... continue to default */
618
    }
619
  default:
620
    {
621
      if (son(sel) != *e)
622
      {				/* only change if not outer */
623
	exp stare = *e;
624
	exp newsel = getexp(sh(sel), bro(stare), last(stare), stare, nilexp,
625
			    props(sel), no(sel), name(sel));
626
 
627
	*e = newsel;
628
	bro(stare) = newsel;
629
	setlast(stare);
630
	b = 1;
631
      }
632
    }
633
  }
634
  if (b)
635
    sh(*e) = sh(sel);
636
  return b;
637
}
638
 
639
 
640
 
641
/********************************************************************
642
		scan
643
 
644
	This procedure works out register requirements of an exp. At each
645
call the fix field of the needs is the number of fixpnt registers required to contain live values to evaluate this expression. This never exceeds maxfix
646
because if it would have, a new declaration is introduced in the exp tree (similarly for floating regs and maxfloat). In these cases the prop field will
647
contain the bits morefix (or morefloat).
648
	Scan also works out various things concerned with proc calls.
649
The maxargs field contains the max size in bits of the space required for the
650
parameters of all the procedures called in the exp. An exp proc call
651
produces a hasproccall bit in the prop field, if this is transformed as part of
652
the definition of a new declaration the bit is replaced by a usesproccall. The
653
distinction is only used in unfolding nested proc calls; POWER requires this to
654
be done statically. The condition that a proc exp is a leaf (i.e no proc calls)
655
is that its prop contains neither bit.
656
	If an ident exp is suitable, scan marks the props of ident with
657
either inreg or infreg bits to indicate that a t reg may be used for this tag.
658
 
659
	A thorough understanding of needs along with other procedures
660
that do switch(name(exp)) requires a knowledge of the meaning of the fields
661
of the exp in each case.
662
 
663
********************************************************************/
664
 
665
 
666
needs scan PROTO_N ((e,at)) PROTO_T (exp * e X exp * *at)
667
{
668
  /*
669
   * e is the expression to be scanned, at is the place to put any new decs .
670
   * NB order of recursive calls with same at is critical
671
   */
672
  exp ste = *(e);
673
  int nstare = name(ste);
674
  static long exp_num = 0;		/* count of exps we evaluate */
675
 
676
  exp_num++;
677
  ASSERT(*e != nilexp);
678
 
679
 
680
  switch (nstare)
681
  {
682
   case 0:
683
    {/* zero_tag */
684
      return zeroneeds;
685
    };
686
 
687
   case compound_tag:
688
   case nof_tag:
689
   case concatnof_tag:
690
   case ncopies_tag:
691
    {
692
      needs nl;
693
      bool cantdo;
694
      exp dad;
695
 
696
      if(nstare==nof_tag && son(ste)==nilexp)
697
	return zeroneeds;
698
 
699
      if (name(ste) == ncopies_tag && name(son(ste)) != name_tag
700
	  && name(son(ste)) != val_tag)
701
      {
702
	nl = scan(&son(*e), at);
703
	cca(at, &son(*e));
704
      }
705
      else
706
      {
707
	nl = maxtup(*(e), at);
708
      }
709
      ste = *e;
710
      dad = father(ste);
711
      if (name(dad) == compound_tag || 
712
	  name(dad) == nof_tag || 
713
	  name(dad) == concatnof_tag)
714
      {
715
	cantdo = 0;
716
      }
717
      else if (last(ste))
718
      {
719
	if (name(bro(ste)) == ass_tag)
720
	{
721
	  exp a = son(bro(ste));
722
 
723
	  cantdo = (name(a) != name_tag || !isvar(son(a)));
724
	}
725
	else
726
	{
727
	  cantdo = 1;
728
	}
729
      }
730
      else if (last(bro(ste)))
731
      {
732
	cantdo = (name(bro(bro(ste))) != ident_tag);
733
      }
734
      else
735
      {
736
	cantdo = 1;
737
      }
738
 
739
 
740
      if (cantdo)
741
      {
742
	/* can only deal with tuples in simple assignment or identity */
743
	int prps = (nl.propsneeds & hasproccall) << 1;
744
 
745
	cca(at, ptr_position(ste));
746
	nl = shapeneeds(sh(*(e)));
747
	nl.propsneeds |= morefix;
748
	nl.propsneeds |= prps;
749
      }
750
 
751
      nl.fixneeds = max(nl.fixneeds,2);
752
 
753
      return nl;
754
    };
755
 
756
  case cond_tag:
757
    {
758
      if (scan_cond(e, nilexp) !=0) 
759
      {
760
	return scan(e, at);
761
      }                   /* Else goto next case */
762
    }
763
    /*FALLTHROUGH*/
764
   case rep_tag:
765
   case solve_tag:
766
    {
767
      exp *stat;
768
      exp *statat;
769
      needs an;
770
 
771
      stat = &son(*e);
772
      statat = stat;
773
      an = zeroneeds;
774
      rep_tag_scanned=0;
775
      /* 
776
       * Simply scan each argument
777
       * The arguments are effectively independent pieces
778
       * of code for these constructions 
779
       */
780
      /***********************************************************/
781
      /*    _        _________                                   */
782
      /*   |_|----->|        _|                                  */
783
      /*  /         |    _  |_|                                  */
784
      /* e          |___|_|___|                                  */
785
      /*               / |                                       */
786
      /*              /  |                                       */
787
      /*          stat(1)|       stat(2)       stat(3)           */
788
      /*             ____v____  /  _________  /  _________       */ 
789
      /*            |        _|/  |        _|/  |        _|      */
790
      /*            |    _  |_|-->|    _  |_|-->|    _  |_|-->   */
791
      /*            |___|_|___|   |___|_|___|   |___|_|___|      */
792
      /*                                                         */
793
      /***********************************************************/
794
      while (an = maxneeds(an, scan(stat, &statat)), !last(*(stat)))
795
      {
796
	stat = &bro(*stat);
797
	statat = stat;
798
      }
799
      if(name(*e)==rep_tag)
800
      {
801
	if (rep_tag_scanned==0)
802
	{
803
	  setinnermost(*e);
804
	}
805
	else
806
	{
807
	  clearinnermost(*e);
808
	}
809
      }
810
      rep_tag_scanned=1;
811
      if ((an.propsneeds & usesproccall) != 0)
812
      {
813
	an.propsneeds |= hasproccall;
814
      }
815
      return an;
816
    }
817
 
818
  case labst_tag:
819
    {
820
      exp *stat;
821
      exp *statat;
822
      needs an;
823
      int expn = exp_num;
824
 
825
      ASSERT(!last(son(*e)));
826
      ASSERT(last(bro(son(*e))));
827
 
828
      /****************************************/
829
      /*    _     _________                   */
830
      /*   |_|-->| labst   |                  */
831
      /*  /      |    _    |                  */
832
      /* e       |___|_|___|   stat           */
833
      /*              |       /               */
834
      /*          ____v____  /  ________      */
835
      /*         | clear  _|/  |       _|     */
836
      /*         |       |_|-->|      |_|     */
837
      /*         |_________|   |________|     */
838
      /*                                      */
839
      /****************************************/
840
      stat = &bro(son(*e));
841
      statat = stat;
842
      an = scan(stat, &statat);
843
 
844
      if ((an.propsneeds & usesproccall) != 0)
845
      {
846
	an.propsneeds |= hasproccall;
847
      }
848
 
849
      /*
850
       * ptno(son()) is set to exp number so that make_code can estimate
851
       * distances of conditional branches, which is limited on POWER.
852
       */
853
      ptno(son(*e)) = expn;
854
 
855
      return an;
856
    }
857
 
858
 
859
/*********************************************************************
860
  ident_tag
861
 
862
shape of exp is body,
863
son is def, brother of son is body,
864
ptr of ident exp is chain of uses
865
*********************************************************************/
866
   case ident_tag:
867
    {
868
      needs bdy;
869
      needs defneeds;
870
      exp stare = *(e);
871
      exp *arg;
872
      exp t = pt(stare), s;
873
      bool fxregble;
874
      bool flregble;
875
      bool old_nonevis = nonevis;
876
      bool uses_R_RESULT;
877
      bool uses_FR_RESULT;
878
#if 0
879
      /* We can't do this because of env_offset not appearing in the list of uses */
880
      if (pt(stare) == nilexp)
881
      {
882
	/* no uses, should have caonly flag set (not already set for params) */
883
	setcaonly(stare);
884
      }
885
#endif 
886
      if (isvar(stare) && (!iscaonly(stare) || all_variables_visible))
887
      {
888
	setvis(stare);
889
      }
890
 
891
      if (isparam(stare))
892
      {
893
	if (name(son(stare))!=formal_callee_tag)
894
	{
895
	  number_caller_parameter(stare);
896
	}
897
	else
898
	{
899
	  number_callee_parameter(stare);
900
	}
901
      }
902
 
903
      nonevis &= !isvis(stare);
904
 
905
      /* Scan the body of the ident */
906
      arg = &bro(son(stare));
907
      bdy = scan(arg, &arg);
908
      /* Scan the def of the ident */
909
      arg = &son(stare);
910
      defneeds = scan(arg, &arg);
911
      ASSERT(stare == *e);
912
 
913
      nonevis = old_nonevis;
914
      t = son(stare);
915
      s = bro(t);
916
      fxregble = fixregable(stare);
917
      flregble = floatregable(stare);
918
      uses_R_RESULT = (bdy.propsneeds & uses_R_RESULT_bit)!=0;
919
      uses_FR_RESULT = (bdy.propsneeds & uses_FR_RESULT_bit)!=0;
920
/*****************************************************************************/
921
      if (name(son(stare))==caller_name_tag)
922
      {
923
	/*
924
	 * IDENT is a caller in postlude 
925
	 */
926
	no(stare) = R_NO_REG;
927
	/* At present all callers in postludes are only allowed on the stack*/
928
	/* This is because of the problems created by nested postludes */
929
      }
930
/*****************************************************************************/
931
      else if (isparam(stare) && name(son(stare))==formal_callee_tag)
932
      {
933
	/*
934
	 * IDENT is a callee parameter
935
	 */
936
	no(stare) = R_NO_REG;
937
      }
938
/*****************************************************************************/
939
      else if (isparam(stare) && name(son(stare))!=formal_callee_tag)
940
      {
941
	/*
942
	 * IDENT is a caller parameter
943
	 */
944
	if (do_profile)
945
	{
946
	  /* mcount is called after the last param is dealt with */
947
	  /* So we must put all params on the stack or in s-regs */
948
	  bdy.propsneeds |= hasproccall;  
949
	}
950
	no(stare)=R_NO_REG;
951
      }
952
/*****************************************************************************/
953
      else
954
      {
955
	/*
956
	 * IDENT is a normal ident
957
	 */
958
	ASSERT(!isparam(*e));
959
 
960
 
961
	if (!isvis(*e) && 
962
	    (bdy.propsneeds & anyproccall)==0 &&
963
	    (
964
	     (uses_R_RESULT==0 && fxregble) || 
965
	     (uses_FR_RESULT==0 && flregble)
966
	     ) &&
967
	    (
968
	     name(t) == apply_tag || /* Let a := f()*/
969
	     (name(s) == seq_tag && name(bro(son(s))) == res_tag &&
970
	      name(son(bro(son(s)))) == cont_tag && isvar(stare) &&
971
	      name(son(son(bro(son(s))))) == name_tag &&
972
	      son(son(son(bro(son(s))))) == stare
973
	      )			/* Let a := ..; return cont a */
974
	     )
975
	    )
976
	{	
977
	  /* Ident suitable for res reg */
978
	  if (fxregble)
979
	  {
980
	    props(stare) |= inreg_bits;
981
	    no(stare) = R_RESULT;
982
	    bdy.propsneeds |= uses_R_RESULT_bit;
983
	  }
984
	  else
985
	  {
986
	    props(stare) |= infreg_bits;
987
	    no(stare) = FR_RESULT;
988
	    bdy.propsneeds |= uses_FR_RESULT_bit;
989
	  }
990
	}
991
 
992
#if 1
993
	else if (!isvar(*e) && !isparam(*e) &&
994
		 ((name(t) == reff_tag && name(son(t)) == cont_tag &&
995
		   name(son(son(t))) == name_tag && isvar(son(son(son(t))))
996
		   && !isvis(son(son(son(t)))) && !isglob(son(son(son(t))))
997
		   && unchanged(son(son(son(t))), stare)
998
	  /*
999
	   * reff cont variable-not assigned to in scope
1000
	   */
1001
		   ) ||
1002
		  (name(t) == cont_tag && name(son(t)) == name_tag &&
1003
		   isvar(son(son(t))) && !isvis(son(son(t))) && !isglob(son(son(t)))
1004
		   && unchanged(son(son(t)), stare)
1005
	  /*
1006
	   * cont variable - not assigned to in scope
1007
	   */
1008
		   )
1009
		  )
1010
	  )
1011
	{
1012
	  props(stare) |= defer_bit;
1013
	  /* dont take space for this dec */
1014
	}
1015
#endif
1016
#if 0	/* dont undo large const in loop optimisation */
1017
	else if (!isvar(stare) &&
1018
		 (isusereg(stare) == 0)
1019
		 && (name(t) == name_tag || name(t) == val_tag))
1020
	{
1021
	  props(stare) |= defer_bit;
1022
	  /* dont take space for this dec */
1023
	}
1024
#endif
1025
#if 1
1026
	else if (!isvar(stare)
1027
		 && name(t) == name_tag
1028
		 && !isvar(son(t))
1029
		 && !isvis(son(t))
1030
		 && (props(son(t)) & inanyreg)
1031
		)
1032
	{
1033
	  /*
1034
	   * dont take space for this constant dec,
1035
	   * initialiser is another simple constant ident
1036
	   * (eg from double nested loop optimisation)
1037
	   */
1038
	  props(stare) |= defer_bit;
1039
	}
1040
#endif
1041
	/* All the parameters have been scanned at this point so
1042
	   maxfix gives the total no of free t-regs */
1043
	else if (fxregble &&
1044
		 bdy.fixneeds < maxfix && 
1045
		 (bdy.propsneeds & morefix) == 0 && 
1046
		 ((bdy.propsneeds & anyproccall)==0
1047
#if 0
1048
		  ||
1049
		  tempdec(stare, ((bdy.propsneeds & morefix)==0) && bdy.fixneeds<2)
1050
#endif
1051
		  )
1052
		 )
1053
	{
1054
	  if ( (props(stare) & notparreg) ==0)
1055
	  {
1056
	    no(stare) = R_NO_REG;
1057
	    props(stare) |= inreg_bits;
1058
	    if (uses_R_RESULT==1)
1059
	    {
1060
	      props(stare) |= notresreg;
1061
	    }
1062
	    bdy.fixneeds += 1;
1063
	  }
1064
	}
1065
	else if (flregble &&
1066
		 bdy.floatneeds < maxfloat && 
1067
		 (bdy.propsneeds & morefloat) == 0 && 
1068
		 ((bdy.propsneeds & anyproccall)==0
1069
#if 0
1070
		  ||
1071
		  tempdec(stare, ((bdy.propsneeds & morefloat) == 0 &&
1072
				     bdy.floatneeds < 1))
1073
#endif
1074
		  )
1075
		 )
1076
	{
1077
	  if ( (props(stare) & notparreg) == 0)
1078
	  {
1079
	    /* Ident suitable for float t-reg */
1080
	    no(stare) = FR_NO_REG;
1081
	    props(stare) |= infreg_bits;
1082
	    if (uses_FR_RESULT==1)
1083
	    {
1084
	      props(stare) |= notresreg;
1085
	    }
1086
	    bdy.floatneeds += 1;
1087
	  }
1088
	}
1089
	else
1090
	{
1091
	  /*
1092
	   * allocate either on stack or saved reg, decided later by
1093
	   * regalloc()
1094
	   */
1095
	  no(stare) = R_NO_REG;
1096
	}
1097
      }
1098
      bdy = maxneeds(bdy, defneeds);
1099
      if ((bdy.propsneeds & usesproccall) != 0)
1100
      {
1101
	bdy.propsneeds |= hasproccall;
1102
      }
1103
      return bdy;
1104
    }
1105
 
1106
/*********************************************************************
1107
	sequence
1108
 
1109
shape of exp is shape of end of sequence
1110
son is sequence holder, son of this is list of voided statements.
1111
*********************************************************************/
1112
 
1113
  case seq_tag:
1114
    {
1115
      exp *arg = &bro(son(*e));
1116
      needs an;
1117
      exp *stat;
1118
      exp * atsc = &son(son(*e));
1119
      for(;;) 
1120
      {
1121
	exp sc = *atsc;
1122
	if (name(sc) == cond_tag && name(sh(son(sc)))==bothd
1123
	    && name(bro(son(bro(son(sc))))) == top_tag) 
1124
	{
1125
	  /* sc is cond(... goto | make_top); can replace
1126
	     make_top by next exp in sequence */
1127
	  exp lbst = bro(son(sc));
1128
	  exp mkt = bro(son(lbst));
1129
	  exp ne = (last(sc))? bro(son(*e)): bro(sc);
1130
	  exp bne = bro(ne);
1131
	  bool lne = last(ne);
1132
	  if (name(ne) != cond_tag) 
1133
	  { 
1134
	    /* only worthwhile eliding if ne is a cond */
1135
	    if (last(sc)) break;
1136
	    atsc = &bro(sc);
1137
	    continue;
1138
	  }
1139
	  sh(sc) = sh(ne);
1140
	  bro(ne) = lbst; setlast(ne);
1141
	  bro(son(lbst)) = ne;
1142
	  /* sc is now cond( ... goto | next cond exp) */
1143
	  if (!last(sc)) 
1144
	  { /* not last in seq - swallow next*/
1145
	    bro(sc) = bne; 
1146
	    if (lne) { setlast(sc); } else { clearlast(sc);}
1147
	    no(son(*e))--; /* one less statement */
1148
	  }
1149
	  else if (no(son(*e)) != 1) 
1150
	  { /* last but not only - replace by
1151
	       make_top and put cond in res posn */
1152
	    bro(mkt) = bro(sc); setlast(mkt);
1153
	    *atsc = mkt;
1154
	    bro(sc) = bne; 
1155
	    if (lne) { setlast(sc); } else { clearlast(sc);}
1156
	    *arg = sc;
1157
	    sc = mkt;
1158
	  }
1159
	  else 
1160
	  { /* whole sequence can be replace by cond */
1161
	    bro(sc) = bro(*e);
1162
	    if (last(*e)) { setlast(sc); } else {clearlast(sc); }
1163
	    *e = sc;
1164
	    return scan(e, at);
1165
	  }
1166
 
1167
	}
1168
	if (last(sc)) break;
1169
	atsc = &bro(sc);
1170
      }
1171
      an = scan(arg, &arg);
1172
      stat = &son(son(*e));
1173
 
1174
      arg = stat;
1175
      for (;;)
1176
      {
1177
	needs stneeds;
1178
 
1179
	stneeds = scan(stat, &arg);
1180
	/* initial statements voided */
1181
	an = maxneeds(an, stneeds);
1182
	if (last(*(stat)))
1183
	{
1184
	  if ((an.propsneeds & usesproccall) != 0)
1185
	  {
1186
	    an.propsneeds |= hasproccall;
1187
	  }
1188
	  return an;
1189
	}
1190
	stat = &bro(*stat);
1191
	arg = stat;
1192
      }
1193
 
1194
    };
1195
 
1196
/********************************************************************
1197
	goto
1198
 
1199
shape is bottom
1200
son is exp for value jumped with
1201
ptr is labelled exp
1202
*********************************************************************/
1203
 
1204
   case goto_tag:
1205
    /* By popular request the  infamous trap_tag */
1206
   case trap_tag:
1207
    {
1208
      return zeroneeds;
1209
    };
1210
   case ass_tag:
1211
   case assvol_tag:
1212
    {
1213
      exp *lhs = &son(*e);
1214
      exp *rhs = &bro(*lhs);
1215
      needs nr;
1216
      ash a;
1217
 
1218
      nr = scan(rhs, at);
1219
      /* scan source */
1220
 
1221
      a = ashof(sh(*(rhs)));
1222
      if (!valregable(sh(*rhs)))
1223
      {
1224
	/* complicated memory move */
1225
	if (!(a.ashsize <= 32 && a.ashsize == a.ashalign))
1226
	  nr.fixneeds += 2;	/* memory block copy */
1227
      }
1228
 
1229
      if (name(*(lhs)) == name_tag &&
1230
	  ((isvar(son(*(lhs))) && !isglob(son(*(lhs)))) ||
1231
	   ((nr.propsneeds & (hasproccall | morefix)) == 0
1232
	    && nr.fixneeds+1 < maxfix
1233
	    )
1234
	   )
1235
	)
1236
      {	
1237
	/* simple destination */
1238
	if (isvar(son(*(lhs))) && isglob(son(*(lhs))))
1239
	  nr.fixneeds += 1;		/* for TOC access */
1240
	return nr;
1241
      }
1242
      else
1243
      {
1244
	needs nl;
1245
	prop prps = (nr.propsneeds & hasproccall) << 1;
1246
 
1247
	nl = scan(lhs, at);
1248
	/* scan destination */
1249
	if (APPLYLIKE(*(rhs)) && 
1250
	    nstare == ass_tag &&
1251
	    (nl.propsneeds & (anyproccall|uses_R_RESULT_bit|uses_FR_RESULT_bit))==0
1252
	    )
1253
	{
1254
	  /*
1255
	   * source is proc call, so assign result reg directly
1256
	   */
1257
	  ;
1258
	}
1259
	else if (nr.fixneeds >= maxfix || prps != 0)
1260
	{
1261
	  /*
1262
	   * source and destination regs overlap, so identify source
1263
	   */
1264
	  cca(at, rhs);
1265
	  nl = shapeneeds(sh(*(rhs)));
1266
	  nl.propsneeds |= morefix;
1267
	  nl.propsneeds &= ~(prps >> 1);
1268
	  nl.propsneeds |= prps;
1269
	}
1270
	nr.fixneeds += 1;
1271
	return maxneeds(nl, nr);
1272
      }
1273
    };
1274
   case untidy_return_tag:
1275
   case res_tag:
1276
    {
1277
      needs x;
1278
      shape s;
1279
      exp *arg = &son(*e);
1280
      s = sh(*(arg));
1281
      props(*e) = 0;		/* clear possibility of tlrecirsion; may be
1282
				 * set later */
1283
      no_of_returns++;
1284
      x = scan(arg, at);	/* scan result exp ... */
1285
 
1286
      if (shape_size(s) != 0)
1287
      {			
1288
	/* ...not a void result */
1289
	x.propsneeds |= has_result_bit;
1290
 
1291
	if (is_floating(name(s)))
1292
	{		
1293
	  /* ... floating pt result */
1294
	  x.propsneeds |= realresult_bit;
1295
	  if (name(s) != shrealhd)
1296
	  {
1297
	    x.propsneeds |= longrealresult_bit;
1298
	  }
1299
	}
1300
	else
1301
	{
1302
	  if (!valregable(s))
1303
	  {	
1304
	    ASSERT(redo_structfns==0);
1305
	    x.propsneeds |= long_result_bit;
1306
	  }
1307
	}
1308
      }
1309
 
1310
#if 0				/* +++ if we can avoid leaf proc conflict */
1311
      if ((x.propsneeds & (long_result_bit | anyproccall | uses_res_reg_bit)) == 0)
1312
      {
1313
	r = son(*(e));
1314
	if (name(r) == ident_tag && isvar(r) &&
1315
	    name(ss = bro(son(r))) == seq_tag &&
1316
	    name(t = bro(son(ss))) == cont_tag &&
1317
	    name(son(t)) == name_tag && son(son(t)) == r)
1318
	{
1319
 
1320
	  /*
1321
	   * result is tag allocated into result reg - see ident_tag:
1322
	   */
1323
	  if ((props(r) & inreg_bits) != 0)
1324
	  {
1325
	    x.fixneeds--;
1326
	  }
1327
	  else if ((props(r) & infreg_bits) != 0)
1328
	  {
1329
	    x.floatneeds--;
1330
	  }
1331
	  else
1332
	  {
1333
	    props(r) |= (is_floating(name(s))) ? infreg_bits : inreg_bits;
1334
	  }
1335
	  x.propsneeds |= uses_res_reg_bit;
1336
	  no(r) = R_USE_RES_REG;/* identification  uses result reg in body */
1337
	}
1338
      }
1339
#endif
1340
      return x;
1341
    };
1342
 
1343
  case apply_tag:
1344
    {
1345
      exp application = *(e);
1346
      exp fn = son(application);
1347
      exp *par = &bro(fn);
1348
      exp *fnexp = &son(*e);
1349
      int parsize = 0;
1350
      needs nds;
1351
      bool regresult = reg_result(sh(application));
1352
      int i;
1353
 
1354
 
1355
 
1356
      nds = scan(fnexp, at);
1357
      /* scan the function exp ... */
1358
      if ((nds.propsneeds & hasproccall) != 0)
1359
      {
1360
	/* .... it must be identified */
1361
	cca(at, fnexp);
1362
	nds.propsneeds &= ~hasproccall;
1363
	nds.propsneeds |= usesproccall;
1364
	fn = son(application);
1365
	par = &bro(fn);
1366
      }
1367
 
1368
 
1369
      for (i = 1; !last(fn); ++i)
1370
      {				/* scan parameters in turn ... */
1371
	needs onepar;
1372
	shape shpar = sh(*par);
1373
	int par_regs_used;
1374
	int move_to_stack_regs;
1375
 
1376
	par_regs_used = (parsize >> 5);
1377
 
1378
	if (par_regs_used >= (end_param-R_FIRST_PARAM+1))
1379
	{
1380
	  par_regs_used = (end_param-R_FIRST_PARAM+1);
1381
	  move_to_stack_regs = 1;	/* can no longer move to param reg, need spare */
1382
	}
1383
	else
1384
	{
1385
	  move_to_stack_regs = 0;
1386
	}
1387
 
1388
	onepar = scan(par, at);
1389
 
1390
	FULLCOMMENT4("scan: apply_tag: i=%d parn=%d pars=%d mover=%d",
1391
		i, onepar.fixneeds, par_regs_used, move_to_stack_regs);
1392
 
1393
	if (((i != 1 || regresult) && (onepar.propsneeds & hasproccall) != 0))
1394
	{
1395
	  /* if it isn't the first parameter, and it calls a proc, identify it */
1396
	  FULLCOMMENT("scan apply_tag: cca bring forward apply");
1397
	  cca(at, par);
1398
	  nds.propsneeds |= usesproccall;
1399
	  nds = maxneeds(shapeneeds(sh(*(par))), nds);
1400
	  nds.maxargs = max(nds.maxargs, onepar.maxargs);
1401
	}
1402
	else if ((i != 1 && (onepar.propsneeds & hasproccall) != 0) ||
1403
		 onepar.fixneeds >= 6 /* +++ remove safety net */ ||
1404
		 onepar.fixneeds + move_to_stack_regs + par_regs_used > maxfix)
1405
	{
1406
	  /* requires to many regs to evaluate, identify it */
1407
	  FULLCOMMENT("scan apply_tag: cca, param has too large fixneeds");
1408
	  cca(at, par);
1409
	  nds.propsneeds |= morefix;
1410
	  nds = maxneeds(shapeneeds(sh(*(par))), nds);
1411
	  nds.maxargs = max(nds.maxargs, onepar.maxargs);
1412
	}
1413
	else
1414
	{
1415
	  nds = maxneeds(onepar, nds);
1416
	}
1417
	parsize = ALIGNNEXT(parsize, shape_align(shpar));
1418
	parsize = ALIGNNEXT(parsize + shape_size(shpar), 32);
1419
 
1420
	if (last(*(par)))
1421
	{
1422
	  break;
1423
	};
1424
	par = &bro(*par);
1425
      }
1426
 
1427
      if (!regresult && name(father(application)) != ass_tag)
1428
      {
1429
	/* find space for non reg result */
1430
	FULLCOMMENT("scan apply_tag: cca space for non reg result");
1431
	cca(at, ptr_position(application));
1432
	nds.propsneeds |= usesproccall;
1433
      }
1434
      else
1435
      {
1436
	nds.propsneeds |= hasproccall;
1437
      }
1438
      nds.maxargs = max(nds.maxargs, parsize);
1439
      return nds;
1440
    };
1441
 
1442
  case null_tag:
1443
    {
1444
      /* many int optimisations keyed off val_tag so represent null as val_tag */
1445
      name(*e) = val_tag;
1446
      no(*e) = 0;		/* null represented as 0 */
1447
      return shapeneeds(sh(*e));
1448
    }
1449
 
1450
  case val_tag:
1451
    {
1452
      exp s = sh(*e);
1453
 
1454
      if (name(s) == offsethd && al2(s) >= 8)
1455
      {
1456
	/* express disps in bytes */
1457
	no(*e) = no(*e) >> 3;
1458
      }
1459
      /* ... and continue */
1460
    }
1461
 
1462
   case name_tag:
1463
   case real_tag:
1464
   case string_tag:
1465
   case env_offset_tag:
1466
   case current_env_tag:
1467
   case make_lv_tag:
1468
   case last_local_tag:
1469
    {
1470
      return shapeneeds(sh(*(e)));
1471
    };
1472
 
1473
    case clear_tag:
1474
    case top_tag:
1475
    case prof_tag:
1476
    case local_free_all_tag:
1477
    {
1478
      return zeroneeds;
1479
    };
1480
 
1481
   case neg_tag:
1482
   case case_tag:
1483
   case not_tag:
1484
   case offset_negate_tag:
1485
   case diagnose_tag:
1486
   case goto_lv_tag:  
1487
   case alloca_tag:
1488
    {
1489
      return scan(&son(*e), at);
1490
    }
1491
   case abs_tag:
1492
    if (architecture!=RS6000_CODE)
1493
    {
1494
      /* We cant use abs instruction so we convert */
1495
      shape int_shpe = sh(*e);
1496
      exp arg = son(*e);
1497
      exp id = me_startid(int_shpe,arg,0);
1498
      exp LABST__TAG;
1499
      exp CLEAR__TAG;
1500
      exp SEQ__TAG;
1501
      exp TEST__TAG;
1502
      exp VAL__TAG;
1503
      exp NEG__TAG;
1504
      exp COND__TAG;
1505
      exp ZERO__TAG;
1506
      exp ABS__TAG;
1507
      ABS__TAG = *e;
1508
 
1509
      CLEAR__TAG = getexp (f_top, nilexp, 0, nilexp, nilexp,0, 0, clear_tag);
1510
      LABST__TAG = me_b3(int_shpe,CLEAR__TAG,me_obtain(id),labst_tag);
1511
 
1512
      VAL__TAG = me_shint(int_shpe,0);
1513
      TEST__TAG = me_q1(no_nat_option,f_less_than,&LABST__TAG,
1514
			me_obtain(id),VAL__TAG,test_tag);
1515
      NEG__TAG = me_u3(int_shpe,me_obtain(id),neg_tag);
1516
      pt(NEG__TAG) = pt(ABS__TAG);
1517
      props(NEG__TAG)=props(ABS__TAG);
1518
 
1519
      ZERO__TAG = me_u3(f_top,TEST__TAG,0);
1520
      SEQ__TAG = me_b3(int_shpe,ZERO__TAG,NEG__TAG,seq_tag);
1521
      COND__TAG = me_b3(int_shpe,SEQ__TAG,LABST__TAG,cond_tag);
1522
      id = me_complete_id(id,COND__TAG);
1523
      if (last(*e))
1524
      {
1525
	setlast(id);
1526
      }
1527
      else
1528
      {
1529
	clearlast(id);
1530
      }
1531
      bro(id) = bro(*e);
1532
      *e = id;
1533
      return scan(e,at);
1534
    }
1535
 
1536
 
1537
 
1538
   case fneg_tag:
1539
   case fabs_tag:
1540
   case chfl_tag:
1541
    {
1542
      needs nds;
1543
 
1544
      nds = scan(&son(*e), at);
1545
      return nds;
1546
    }
1547
   case bitf_to_int_tag:
1548
   case int_to_bitf_tag:
1549
    {
1550
      exp *arg = &son(*e);
1551
 
1552
      return scan(arg, at);
1553
    }
1554
 
1555
  case round_tag:
1556
    {
1557
      needs s;
1558
      exp *arg = &son(*e);
1559
      shape sres = sh(*e);
1560
      if(shape_size(sres) !=32)
1561
      {
1562
	exp ch = getexp(sres,bro(*e),last(*e),*e,pt(*e),props(*e),0,chvar_tag);
1563
	bro(*e)=ch;setlast(*e);
1564
	sh(*e)=slongsh;
1565
	*e=ch;
1566
	return scan(e,at);
1567
      }
1568
      s = scan(arg,at);
1569
      s.fixneeds = max(s.fixneeds,1);
1570
      s.floatneeds = max(s.floatneeds,2);
1571
      return s;
1572
    };
1573
   case shl_tag:
1574
   case shr_tag:
1575
   case long_jump_tag:
1576
    {
1577
      exp *lhs = &son(*e);
1578
      exp *rhs = &bro(*lhs);
1579
      needs nr;
1580
      needs nl;
1581
      prop prps;
1582
 
1583
      nr = scan(rhs, at);
1584
      nl = scan(lhs, at);
1585
      rhs = &bro(*lhs);
1586
      prps = (nr.propsneeds & hasproccall) << 1;
1587
      if (nr.fixneeds >= maxfix || prps != 0)
1588
      {
1589
 
1590
	/*
1591
	 * if reg requirements overlap, identify second operand
1592
	 */
1593
	cca(at, rhs);
1594
	nl = shapeneeds(sh(*(rhs)));
1595
	nl.propsneeds |= morefix;
1596
	nl.propsneeds &= ~(prps >> 1);
1597
	nl.propsneeds |= prps;
1598
      }
1599
      nr.fixneeds += 1;
1600
      return maxneeds(nl, nr);
1601
 
1602
    };
1603
 
1604
 
1605
  case test_tag:
1606
    {
1607
      exp stare = *(e);
1608
      exp l = son(stare);
1609
      exp r = bro(l);
1610
 
1611
      if (!last(stare) && name(bro(stare)) == test_tag &&
1612
	  no(stare) == no(bro(stare)) &&
1613
	  props(stare) == props(bro(stare)) &&
1614
	  eq_exp(l, son(bro(stare))) && eq_exp(r, bro(son(bro(stare))))
1615
	)
1616
      {				/* same test following in seq list - remove
1617
				 * second test */
1618
	if (last(bro(stare)))
1619
	  setlast(stare);
1620
	bro(stare) = bro(bro(stare));
1621
      }
1622
 
1623
      if (last(stare) && name(bro(stare)) == 0	/* seq holder */
1624
	  && name(bro(bro(stare))) == test_tag &&
1625
	  name(bro(bro(bro(stare)))) == seq_tag &&
1626
	  no(stare) == no(bro(bro(stare))) &&
1627
	  props(stare) == props(bro(bro(stare))) &&
1628
	  eq_exp(l, son(bro(bro(stare))))
1629
	  && eq_exp(r, bro(son(bro(bro(stare)))))
1630
	)
1631
      {				/* same test following in seq res - void
1632
				 * second test */
1633
	setname(bro(bro(stare)), top_tag);
1634
	son(bro(bro(stare))) = nilexp;
1635
	pt(bro(bro(stare))) = nilexp;
1636
      }
1637
 
1638
      /*
1639
       * commute tests if
1640
       * a) lhs a const (to support convention of const on rhs); or
1641
       * b) rhs is a load from mem, move to lhs in hope of reducing
1642
       *    load-use delays
1643
       */
1644
      if (
1645
	   (
1646
	    test_number(stare)==TEST_NE||test_number(stare)==TEST_EQ||
1647
	    !is_floating(name(sh(l)))
1648
	    )
1649
	   &&
1650
	   (
1651
	     (name(l) == val_tag)
1652
	     ||
1653
	     (LOADFROMSTORE(r) && !LOADFROMSTORE(l))
1654
	   )
1655
	 )
1656
      {
1657
	/* commute */
1658
	bro(l) = stare;
1659
	setlast(l);
1660
	bro(r) = l;
1661
	clearlast(r);
1662
	son(stare) = r;
1663
	r = l;
1664
	l = son(stare);
1665
	settest_number(stare,cbranch(test_number(stare)));
1666
      }
1667
 
1668
      if (is_floating(name(sh(l))))
1669
      {
1670
	return fpop(e, at);
1671
      }
1672
      else if (name(r) == val_tag && no(r) == 1 
1673
	       && (test_number(stare) == TEST_GE || 
1674
		   test_number(stare) == TEST_LT)
1675
	       )
1676
      {
1677
	/* The only reason for this optimisation is that it increases
1678
	   the chance of using the Record bit */
1679
	no(r) = 0;
1680
	if (test_number(stare) == TEST_GE)
1681
	{
1682
	  /* Branch >=1 is same as >0 */
1683
	  settest_number(stare,TEST_GT);
1684
	}
1685
	else
1686
	{
1687
	  /* Branch <1 is same as <= 0 */
1688
	  settest_number(stare,TEST_LE);
1689
	}
1690
      }
1691
      return non_commutative_scan(e, at);
1692
    }
1693
   case movecont_tag:
1694
    {
1695
     exp * d  = &son(*e);
1696
     exp * s  = &bro(*d);
1697
     exp * sz = &bro(*s);
1698
     needs nd;
1699
     needs ns;
1700
     needs nsz;
1701
     prop prps ;
1702
     nd  = scan(d, at);
1703
     ns  = scan (s, at);
1704
     nsz = scan(sz, at);
1705
     prps = (ns.propsneeds & hasproccall) << 1;
1706
     if (ns.fixneeds >= maxfix || prps != 0) {
1707
       /* if reg requirements overlap, identify
1708
	  second operand */
1709
       cca (at, s);
1710
       ns = shapeneeds (sh (* (s)));
1711
       ns.propsneeds |= morefix;
1712
       ns.propsneeds &= ~(prps >> 1);
1713
       ns.propsneeds |= prps;
1714
     }
1715
     nd.fixneeds += 1;
1716
     nd = maxneeds (nd, ns);
1717
     prps= (nsz.propsneeds & hasproccall) << 1;
1718
     if (nd.fixneeds +nsz.fixneeds >= maxfix || prps != 0) {
1719
       /* if reg requirements overlap, identify
1720
	  last operand */
1721
       cca (at, sz);
1722
       nsz = shapeneeds (sh (* (sz)));
1723
       nsz.propsneeds |= morefix;
1724
       nsz.propsneeds &= ~(prps >> 1);
1725
       nsz.propsneeds |= prps;
1726
     }                
1727
     nd.fixneeds+=1;
1728
     nd = maxneeds(nd,nsz);
1729
     if (nd.fixneeds < 4) nd.fixneeds = 3;
1730
     return nd;
1731
   }
1732
 
1733
 
1734
 
1735
   case plus_tag:
1736
    {				/* replace any operands which are neg(..) by -
1737
				 * if poss */
1738
      exp sum = *(e);
1739
      exp list = son(sum);
1740
      bool someneg = 0;
1741
      bool allneg = 1;
1742
 
1743
      /* check BUGP13 [corruption by extract_consts()] is fixed */
1744
      /* check father set correctly */
1745
      ASSERT(father(son(sum))==sum);
1746
 
1747
      for (; optop(sum);)
1748
      {
1749
	if (name(list) == neg_tag)
1750
	  someneg = 1;
1751
	else
1752
	  allneg = 0;
1753
	if (last(list))
1754
	  break;
1755
	list = bro(list);
1756
      }
1757
 
1758
      if (someneg)
1759
      {				/* there are some neg() operands */
1760
	if (allneg)
1761
	{
1762
	  /* transform -..-... to -(..+.. +...) */
1763
	  exp x;
1764
 
1765
	  /*
1766
	   * Build a new list form operand of neg_tags, which will
1767
	   * become plus_tag operands.
1768
	   */
1769
	  x = son(sum);
1770
	  list = son(x);
1771
	  for (;;)
1772
	  {
1773
	    /*
1774
	     * 'x' moves along neg_tag's lists
1775
	     * 'list' moves along sons of neg_tag's lists, building a new list
1776
	     * eventually new list is made son of plus_tag
1777
	     */
1778
 
1779
	    ASSERT(list == son(x));
1780
 
1781
	    bro(list) = son(bro(x));
1782
	    if (!last(x))
1783
	    {
1784
	      clearlast(list);
1785
	      list = bro(list);
1786
	      x = bro(x);
1787
	    }
1788
	    else
1789
	    {
1790
 
1791
	      setlast(list);
1792
	      bro(list) = sum;		/* set father to be */
1793
	      son(sum) = son(son(sum)); /* set new sons of plus_tag */
1794
	      break;
1795
	    }
1796
	  }
1797
 
1798
	  /*
1799
	   * create new neg_tag to replace plus_tag,
1800
	   * old plus_tag being the operand of the new neg_tag.
1801
	   */
1802
	  x = getexp(sh(sum), bro(sum), last(sum), sum, nilexp,
1803
		     0, 0, neg_tag);
1804
 
1805
	  setlast(sum);
1806
 
1807
	  /* set father of sum, new neg_tag exp */
1808
	  bro(sum) = x;
1809
 
1810
	  /* check father of sum is correct */
1811
	  ASSERT(father(son(sum))==sum);
1812
 
1813
	  *(e) = x;
1814
	}			/* end allneg */
1815
	else
1816
	{
1817
	  /* transform to  ((..(..+..) - ..) -..) */
1818
	  int n = 0;
1819
	  exp brosum = bro(sum);
1820
	  bool lastsum = last(sum);
1821
	  exp x = son(sum);
1822
	  exp newsum = sum;
1823
 
1824
	  list = nilexp;
1825
	  for (;;)
1826
	  {
1827
	    exp nxt = bro(x);
1828
	    bool final = last(x);
1829
 
1830
	    if (name(x) == neg_tag)
1831
	    {
1832
	      bro(son(x)) = list;
1833
	      list = son(x);
1834
	    }
1835
	    else
1836
	    {
1837
	      bro(x) = newsum;
1838
	      newsum = x;
1839
	      if ((n++) == 0)
1840
		setlast(newsum);
1841
	      else
1842
		clearlast(newsum);
1843
	    }
1844
	    if (final)
1845
	      break;
1846
	    x = nxt;
1847
	  }
1848
 
1849
	  if (n > 1)
1850
	  {
1851
	    son(sum) = newsum;
1852
	    newsum = sum;	/* use existing exp for add operations */
1853
	  }
1854
	  for (;;)
1855
	  {			/* introduce - operations */
1856
	    exp nxt = bro(list);
1857
 
1858
	    bro(newsum) = list;
1859
	    clearlast(newsum);
1860
	    x = getexp(sh(sum), nilexp, 0, newsum, nilexp, 0, 0, minus_tag);
1861
 
1862
	    bro(list) = x;
1863
	    setlast(list);
1864
	    newsum = x;
1865
	    if ((list = nxt) == nilexp)
1866
	      break;
1867
	  }
1868
	  bro(newsum) = brosum;
1869
	  if (lastsum)
1870
	  {
1871
	    setlast(newsum);
1872
	  }
1873
	  else
1874
	  {
1875
	    clearlast(newsum);
1876
	  }
1877
	  *(e) = newsum;
1878
	}			/* end else allneg */
1879
 
1880
	/* check father set correctly */
1881
	ASSERT(father(son(*e))==*e);
1882
 
1883
	return scan(e, at);
1884
 
1885
      }				/* end someneg - else continue to next case */
1886
    }
1887
   case addptr_tag:
1888
    {
1889
      exp p = son(*e);
1890
      exp d = bro(p);
1891
      int fal = frame_al_of_ptr(sh(p));    	
1892
      if (fal!=0 && i_reckon_its_a_general_proc(fal)) 
1893
      {	
1894
	int oal = frame_al1_of_offset(sh(d));
1895
/*	if( ((oal-1)&oal) != 0) 
1896
	{
1897
	  fail("can't cope with mixed frame offsets yet");
1898
	}*/
1899
	if ( !l_or_cees(oal)) 
1900
	{
1901
	  /* callers are referenced through R_TP */
1902
	  /* to get this we use locptr to access through R_FP(current_env)*/
1903
	  exp ne = getexp(sh(p), d, 0, p, nilexp, 0, 0,locptr_tag);
1904
	  bro(p) = ne; setlast(p);
1905
	  son(*e) = ne;
1906
	}
1907
      }
1908
      /* ... and continue */  	  
1909
    }
1910
 
1911
 
1912
   case local_free_tag:
1913
   case mult_tag:
1914
   case and_tag:
1915
   case or_tag:
1916
   case xor_tag:
1917
    {
1918
      return commutative_scan(e, at);
1919
    };
1920
   case reff_tag:
1921
   case offset_pad_tag:
1922
   case chvar_tag:
1923
   case locptr_tag:
1924
    {
1925
      exp *arg = &son(*e);
1926
 
1927
      return maxneeds(scan(arg, at),
1928
		      shapeneeds(sh(*(e))));
1929
    };
1930
 
1931
  case float_tag:
1932
    {
1933
      needs nds;
1934
      exp *arg = &son(*e);
1935
 
1936
      nds = maxneeds(scan(arg, at), shapeneeds(sh(*(e))));
1937
      if (name(sh(son(*(e)))) == ulonghd)
1938
      {
1939
	if (nds.floatneeds < 2)
1940
	  nds.floatneeds = 2;
1941
      }
1942
      return nds;
1943
    }
1944
   case cont_tag:
1945
   case contvol_tag:
1946
    {
1947
      exp *arg = &son(*e);
1948
      needs nds;
1949
 
1950
      nds = maxneeds(scan(arg, at), shapeneeds(sh(*(e))));
1951
      nds.fixneeds = max(nds.fixneeds, 2);
1952
      return nds;
1953
    };
1954
   case offset_mult_tag: case offset_div_tag: {
1955
     exp op1 = son(*e);
1956
     exp op2 = bro(op1);
1957
     shape s = sh(op2);
1958
     if (name(op2)==val_tag  && name(s)==offsethd 
1959
	 && al2(s) >= 8) {
1960
       int n = no(op2)/8;
1961
       if (n == 1) {
1962
	 /* offset is one  byte */
1963
	 bro(op1) = bro(*e);
1964
	 if (last(*e)) { setlast(op1); } else {clearlast(op1); }
1965
	 *e = op1;
1966
	 return( scan(e, at));
1967
       }
1968
       else 
1969
	 if ( name(*e) == offset_mult_tag && n > 1 && (n&(n-1))== 0)
1970
	   if( name(op1) == and_tag 
1971
	      && name(son(op1))== shr_tag &&
1972
	      name(bro(son(op1)))==val_tag ) {
1973
	     exp shexp = son(op1);
1974
	     exp ac = bro(shexp);
1975
	     exp shop1 = son(shexp);
1976
	     exp shop2 = bro(shop1);
1977
	     int na = no(ac);
1978
	     if ((na&(na+1))==0 && name(shop2)==val_tag) {
1979
	       int pn = 0;
1980
	       int ns = no(shop2);
1981
	       int i = n;
1982
	       while (i>1) { i >>= 1; pn++; }
1983
 
1984
	       if (ns > pn) 
1985
	       {
1986
		 /* can do transform:
1987
		    (((shop1>>ns) & na) * n) =>
1988
		    shop1>>(ns-pn) & (na*n)
1989
		      */
1990
		 no(shop2) = ns-pn;
1991
		 no(ac) = na*n;
1992
		 bro(op1) = bro(*e);
1993
		 if (last(*e)) 
1994
		 {
1995
		   setlast(op1); 
1996
		 } 
1997
		 else 
1998
		 {
1999
		   clearlast(op1);
2000
		 }   
2001
		 *e = op1;
2002
		 return( scan(e, at));
2003
	       }
2004
	     }
2005
	   }
2006
	   else 
2007
	   { 
2008
	     /* will do this by literal shift */
2009
	     no(op2) = n;
2010
	     return scan(&son(*e), at);
2011
	   } 
2012
     }
2013
     return non_commutative_scan (e, at);
2014
 
2015
   }
2016
 
2017
 
2018
   case div0_tag:
2019
   case div1_tag:
2020
   case div2_tag:
2021
   case rem0_tag:
2022
   case mod_tag:
2023
   case rem2_tag:
2024
   case minus_tag:
2025
   case subptr_tag:
2026
   case minptr_tag:
2027
   case offset_div_by_int_tag:
2028
   case max_tag:
2029
   case min_tag:
2030
   case offset_max_tag:
2031
   case component_tag:
2032
   case make_stack_limit_tag:
2033
    {
2034
      return non_commutative_scan(e, at);
2035
    };
2036
   case offset_add_tag:
2037
    {
2038
      exp l = son(*e);
2039
      exp r = bro(l);
2040
      if (name(l) == val_tag) 
2041
      {
2042
	sh(l) = sh(r);   /* both offsets will be treated the same */
2043
	son(*e) = r; clearlast(r);
2044
	bro(r) = l; setlast(l); bro(l) = *e;
2045
	/* ... and put val last */
2046
      }
2047
      else
2048
      {	
2049
	if (al2(sh(l))>=8 && al2(sh(r)) <8) 
2050
	{
2051
	  return non_commutative_scan(e, at);
2052
	}
2053
      }
2054
 
2055
      setname(*e, plus_tag);
2056
 
2057
      return commutative_scan(e,at);
2058
    }
2059
   case offset_subtract_tag: {
2060
	exp l = son(*e);
2061
	exp r = bro(l);
2062
	if (name(r)==val_tag) {
2063
		sh(r) = sh(l);   /* both offsets will be treated the same */
2064
	}
2065
	else		
2066
	if ( al2(sh(r))>=8 && al2(sh(l)) <8) {
2067
	        return non_commutative_scan (e, at);
2068
	}
2069
 
2070
	setname(*e, minus_tag);
2071
	return non_commutative_scan (e, at);
2072
    }
2073
 
2074
  case fdiv_tag:
2075
  case fplus_tag:
2076
  case fminus_tag:
2077
  case fmult_tag:
2078
    {
2079
      exp op = *(e);
2080
      exp a2 = bro(son(op));
2081
 
2082
      if (!last(a2))
2083
      {				/* + and * can have >2 parameters - make them
2084
				 * diadic - can do better a+exp => let x = exp
2085
				 * in a+x */
2086
	exp opn = getexp(sh(op), op, 0, a2, nilexp, 0, 0, name(op));
2087
 
2088
	/* dont need to transfer error treatment - nans */
2089
	exp nd = getexp(sh(op), bro(op), last(op), opn, nilexp, 0, 1,
2090
			ident_tag);
2091
	exp id = getexp(sh(op), op, 1, nd, nilexp, 0, 0, name_tag);
2092
 
2093
	pt(nd) = id;
2094
	bro(son(op)) = id;
2095
	setlast(op);
2096
	bro(op) = nd;
2097
	while (!last(a2))
2098
	  a2 = bro(a2);
2099
	bro(a2) = opn;
2100
	*(e) = nd;
2101
	return scan(e, at);
2102
      }
2103
      return fpop(e, at);
2104
    };
2105
   case field_tag:
2106
    {
2107
      needs str;
2108
      exp *arg = &son(*e);
2109
 
2110
      if (chase(*e, arg))
2111
      {				/* field has been distributed */
2112
	exp stare = *e;
2113
	exp ss = son(stare);
2114
 
2115
	if (!last(stare))
2116
	  clearlast(ss);
2117
	bro(ss) = bro(stare);
2118
	sh(ss) = sh(stare);
2119
	*e = ss;
2120
	return (scan(e, at));
2121
      }
2122
      str = scan(arg, at);
2123
      return maxneeds(str, shapeneeds(sh(*(e))));
2124
    };
2125
 
2126
/*********************************************************************
2127
	load_proc
2128
 
2129
 
2130
number is number of proc (useful for indexing)
2131
*********************************************************************/
2132
   case proc_tag:
2133
   case general_proc_tag:
2134
    {
2135
      exp *bexp;
2136
      exp *bat;
2137
      needs body;
2138
 
2139
      exp_num = 0;
2140
      callee_size = 0;
2141
      max_callees = -1;
2142
      no_of_returns = 0;
2143
      maxfix = maxfix_tregs;
2144
      maxfloat = MAXFLT_TREGS;
2145
      stparam = 0;
2146
      fixparam = R_FIRST_PARAM;
2147
      floatparam = FR_FIRST_PARAM;
2148
 
2149
      /* Parameter allocation t-regs */
2150
      freefixed = PROC_TREGS;
2151
      freefloat = PROC_FLT_TREGS;
2152
 
2153
      if (name(*e)==general_proc_tag)
2154
      {
2155
	end_param = GENERAL_PROC_PARAM_REGS + R_FIRST_PARAM - 1;
2156
      }
2157
      else
2158
      {
2159
	end_param = PROC_PARAM_REGS + R_FIRST_PARAM - 1;
2160
      }
2161
 
2162
      nonevis = 1;
2163
      gen_call = 0;
2164
      tail_call = 0;
2165
      bexp = &son(*e);
2166
      bat = bexp;
2167
      body = scan(bexp, &bat);
2168
#ifdef DO_DYNAMIC_INITIALISATION
2169
      if (proc_is_main(*e))
2170
      {
2171
        /* we need a call to __main */
2172
        body.propsneeds |= usesproccall;
2173
      }
2174
#endif
2175
      return body;
2176
    }
2177
/********************************************************************
2178
 |  TDF SPECIFICATION 4.0 ADDITIONS       |
2179
 ******************************************
2180
 The new tags introduced for the move from spec 3.0 to spec 4.0 are
2181
 general_proc
2182
 apply_general
2183
 make_callee_list
2184
 make_dynamic_callee
2185
 tail_call
2186
 same_callees
2187
 untidy_return
2188
 set_stack_limit
2189
 env_size
2190
 general_env_offset
2191
 caller_name
2192
 formal_callee
2193
 caller
2194
********************************************************************/
2195
   case apply_general_tag: 
2196
    {
2197
      exp application = *(e);
2198
      exp *fn = &son (application);
2199
      exp cers = bro(*fn);
2200
      exp *cerl = &son(cers);
2201
      long stpar = 0;
2202
      needs nds;
2203
      needs plnds;
2204
      int i;
2205
 
2206
      gen_call = 1;
2207
 
2208
      /* scan the function */
2209
      nds = scan(fn, at);
2210
 
2211
      if ((nds.propsneeds & hasproccall) != 0) 
2212
      {
2213
	/* .... it must be identified */
2214
	cca (at, fn);
2215
	nds.propsneeds &= ~hasproccall;
2216
	nds.propsneeds |= usesproccall;
2217
	fn = &son(application);
2218
      }
2219
      /* scan the callers */
2220
      for(i=0; i<no(cers); i++) 
2221
      {
2222
	needs onepar;
2223
	shape shonepar = sh(*cerl);
2224
	exp * par = (name(*cerl)==caller_tag)?&son(*cerl):cerl;
2225
	int n = ALIGNNEXT(stpar, shape_align(shonepar));  
2226
	onepar = scan(par,at);
2227
	if ((i != 0 && (onepar.propsneeds & hasproccall) != 0) ||
2228
	    onepar.fixneeds+(stpar>>5) > maxfix) 
2229
	{
2230
	  /* +++ if we go over a certain number of param regs
2231
	     they are forced to be on the stack so stpar>>5 
2232
	     is not the best estimate ,but sufficient*/
2233
	  /* stpar>>5 is the no of param regs used so far */
2234
	  /* if it isn't the first parameter, and it
2235
	     calls a proc, identify it */
2236
	  /* it is ok for first param to have a proccall since we have
2237
	     no loaded parameters to corrupt */
2238
	  cca (at, par);
2239
	  nds.propsneeds |= usesproccall;
2240
	  nds = maxneeds (shapeneeds (sh (* (par))), nds);
2241
	  nds.maxargs = max (nds.maxargs, onepar.maxargs);
2242
	}
2243
	else 
2244
	{
2245
	  nds = maxneeds (onepar, nds);
2246
	}
2247
	if (name(*cerl)==caller_tag) 
2248
	{
2249
	  /* for caller_tag's we record where it will live */
2250
	  no(*cerl) = n; 
2251
	  clear_coded_caller(*cerl);
2252
	}
2253
	n = n + shape_size(shonepar);
2254
	stpar = ALIGNNEXT(n,32);
2255
	cerl = &bro(*cerl);
2256
      }
2257
      nds.maxargs = max (nds.maxargs, stpar);
2258
      /* scan the callees */
2259
      nds = maxneeds(scan(&bro(bro(son(application))), at), nds);
2260
      /* scan the postlude */
2261
      plnds = scan(&bro(bro(bro(son(application)))), at);
2262
      if(plnds.propsneeds & anyproccall)
2263
      {
2264
	props(application)=1;
2265
	if (is_floating(name(sh(application))) || valregable(sh(application))) 
2266
	{
2267
	  cca(at, ptr_position(application));
2268
	  plnds.propsneeds |= usesproccall;
2269
	}
2270
      }
2271
      else
2272
      {
2273
	props(application)=0;
2274
	if (is_floating(name(sh(application))) || valregable(sh(application))) 
2275
	{
2276
	  cca(at, ptr_position(application));
2277
	}
2278
      }
2279
      nds = maxneeds(nds, plnds);
2280
      nds.propsneeds |= hasproccall;
2281
      return nds;
2282
    }
2283
/********************************************************************/ 
2284
   case make_callee_list_tag:
2285
    {
2286
      exp cees = *e;
2287
      exp *par = &son(cees);
2288
      needs nds;
2289
      long stpar = 0;
2290
      int i;
2291
      nds = zeroneeds;
2292
      for ( i=0;i<no(cees);i++)
2293
      {
2294
	/* scan each callee and identify if necessary */
2295
	needs onepar;
2296
	shape shonepar = sh(*par);
2297
	int n = ALIGNNEXT(stpar,shape_align(shonepar));
2298
	onepar = scan(par,at);
2299
	if((onepar.propsneeds & hasproccall)!=0 || onepar.fixneeds+1>maxfix)
2300
	{
2301
	  /* if it calls a proc identify it */
2302
	  cca(at,par);
2303
	  nds.propsneeds |=usesproccall;
2304
	  nds = maxneeds(shapeneeds(sh(*par)),nds);
2305
	  nds.maxargs = max(nds.maxargs,onepar.maxargs);
2306
	}
2307
	else
2308
	{
2309
	  nds = maxneeds(onepar,nds);
2310
	}
2311
	n += shape_size(shonepar);
2312
	stpar = ALIGNNEXT(n,32);
2313
	par = &bro(*par);
2314
      }
2315
      no(cees)=stpar; /* The total no of bits needed for callees */
2316
      max_callees = max (max_callees, stpar);
2317
      return nds;
2318
    }
2319
 
2320
/********************************************************************/ 
2321
   case make_dynamic_callee_tag:
2322
    {
2323
      exp cees = *e;
2324
      exp *ptr = &son(cees);
2325
      needs ndsp;
2326
      needs nds;
2327
      nds = zeroneeds;
2328
      ndsp = scan(ptr, at);
2329
      if (((ndsp.propsneeds & hasproccall) != 0) ||
2330
	  ndsp.fixneeds+1 > maxfix) 
2331
      {
2332
	cca (at, ptr);
2333
	nds.propsneeds |= usesproccall;
2334
	nds = maxneeds (shapeneeds (sh (* (ptr))), nds);
2335
	nds.maxargs =  max(nds.maxargs, ndsp.maxargs);
2336
      }
2337
      else 
2338
      {
2339
	nds = ndsp;
2340
      }
2341
      ndsp = scan(&bro(son(*e)), at);
2342
      if (((ndsp.propsneeds & hasproccall) != 0) ||
2343
	  ndsp.fixneeds+2 > maxfix) 
2344
      {
2345
	cca (at, &bro(son(cees)));
2346
	nds.propsneeds |= usesproccall;
2347
	nds = maxneeds (shapeneeds (sh (bro(son(*e)))), nds);
2348
	nds.maxargs = max (nds.maxargs, ndsp.maxargs);
2349
      }
2350
      else 
2351
      {
2352
	nds = maxneeds (ndsp, nds);
2353
      }
2354
      if (nds.fixneeds<5) nds.fixneeds = 5;
2355
      return nds;
2356
    }
2357
/********************************************************************/
2358
   case tail_call_tag:
2359
    {
2360
      needs ndsp;
2361
      needs nds;
2362
      exp *fn = &son(*e);
2363
      ndsp = scan(fn,at);
2364
      tail_call = 1;
2365
      if(((ndsp.propsneeds & hasproccall)!=0)|| ndsp.fixneeds+1>maxfix)
2366
      {
2367
	cca(at,fn);
2368
	nds.propsneeds |= usesproccall;
2369
	nds = maxneeds ( shapeneeds(sh(*fn)),nds);
2370
	nds.maxargs = max (nds.maxargs,ndsp.maxargs);
2371
      }
2372
      else
2373
      {
2374
	nds = ndsp;
2375
      }
2376
      gen_call = 1;
2377
      ndsp = scan(&bro(son(*e)),at);
2378
      nds = maxneeds(nds,ndsp);
2379
      return nds;
2380
    }
2381
/********************************************************************/
2382
   case same_callees_tag:
2383
    {
2384
      needs nds;
2385
      nds = zeroneeds;
2386
      nds.fixneeds = 4;
2387
      max_callees = max (max_callees, callee_size);
2388
      return nds;
2389
    }
2390
/********************************************************************/
2391
   case env_size_tag:
2392
   case set_stack_limit_tag:
2393
   case return_to_label_tag:
2394
    {
2395
      exp *arg = &son(*e);
2396
      return scan(arg,at);
2397
    }
2398
/********************************************************************/
2399
   case general_env_offset_tag:
2400
   case caller_name_tag:
2401
    {
2402
      return shapeneeds(sh(*e));
2403
    }
2404
/********************************************************************/
2405
   case formal_callee_tag:
2406
    {
2407
      return zeroneeds;
2408
    }
2409
/********************************************************************/
2410
   case caller_tag:
2411
    {
2412
      fail("Shouldn't be scanning a caller_tag");
2413
      return zeroneeds;
2414
    }
2415
/********************************************************************/
2416
   default:
2417
    {
2418
      FULLCOMMENT1("scan: bad nstare=%d", nstare);
2419
      fail("case not covered in needs scan");
2420
      return zeroneeds;
2421
    }
2422
  }
2423
}
2424
int scan_cond PROTO_N ((e, outer_id)) PROTO_T (exp * e X exp outer_id)
2425
{
2426
  exp ste = *e;
2427
  exp first = son (ste);
2428
  exp labst = bro (first);
2429
  exp second = bro (son (labst));
2430
 
2431
  ASSERT(name(ste)==cond_tag);
2432
 
2433
  if (name(second)==top_tag && name(sh(first))==bothd && no(son(labst))==1
2434
      && name(first)==seq_tag && name(bro(son(first))) == goto_tag){
2435
    /* cond is { ... test(L); ? ; goto X | L:make_top}
2436
       if ? empty can replace by seq { ... not-test(X); make_top }
2437
       */
2438
    exp l = son(son(first));
2439
    while(!last(l)) { l = bro(l); }
2440
    while(name(l)==seq_tag) { l = bro(son(l)); }
2441
    if (name(l)==test_tag && pt(l)==labst) {
2442
      settest_number(l, notbranch[test_number(l)]);
2443
      pt(l) = pt(bro(son(first)));
2444
      bro(son(first)) = second;
2445
      bro(second) = first; setlast(second);
2446
      bro(first) = bro(ste); 
2447
      if(last(ste)) { setlast(first);} else { clearlast(first); }
2448
      *e = first;
2449
      return 1;
2450
    }
2451
    else return 0;
2452
  }
2453
 
2454
 
2455
  if (name (first) == seq_tag && name (second) == cond_tag 
2456
      && no(son(labst)) == 1 
2457
      && name (son (son (first))) == test_tag 
2458
      && pt (son (son (first))) == labst
2459
      && name (son (second)) == seq_tag
2460
      && name (son (son (son (second)))) == test_tag) {
2461
    /* cond is ( seq (test to L;....| 
2462
       L:cond(seq(test;...),...) ) ..... */
2463
    exp test1 = son (son (first));
2464
    exp test2 = son (son (son (second)));
2465
    exp op11 = son(test1);
2466
    exp op21 = bro(op11);
2467
    exp op12 = son(test2);
2468
    exp op22 = bro(op12);
2469
    bool c1 = complex (op11);
2470
    bool c2 = complex (op21);
2471
 
2472
    if (c1 && eq_exp (op11, op12)) {
2473
      /* ....if first operands of tests are
2474
	 same, identify them */
2475
      exp newid = getexp (sh (ste), bro (ste), last (ste), op11, nilexp,
2476
			  0, 2, ident_tag);
2477
      exp tg1 = getexp (sh (op11), op21, 0, newid, nilexp, 0, 0, name_tag);
2478
      exp tg2 = getexp (sh (op12), op22, 0, newid, nilexp, 0, 0, name_tag);
2479
 
2480
      pt (newid) = tg1;
2481
      pt (tg1) = tg2;	/* uses of newid */
2482
      bro (op11) = ste; clearlast (op11);/* body of newid */
2483
      /* forget son test2 = son test1 */
2484
      bro (ste) = newid;
2485
      setlast (ste);	/* father body = newid */
2486
      son (test1) = tg1;
2487
      son (test2) = tg2;	/* relace 1st operands of test */
2488
      if (!complex(op21) ) { 
2489
	/* if the second operand of 1st test is simple, then identification
2490
	   could go in a t-teg (!!!NB overloading of inlined flag!!!).... */
2491
	setinlined(newid); 
2492
      }
2493
      kill_exp(op12, op12);
2494
      * (e) = newid;
2495
      if( scan_cond (&bro(son(labst)), newid) == 2 && complex(op22)) {
2496
	/* ... however a further use of identification means that 
2497
	   the second operand of the second test must also be simple */
2498
	clearinlined(newid);
2499
      }
2500
      return 1;
2501
    }
2502
    else
2503
      if (c2 && eq_exp (op21, op22)) {
2504
	/* ....if second operands of tests are
2505
	   same, identify them */
2506
 
2507
	exp newid = getexp (sh (ste), bro (ste), last (ste), op21,
2508
			    nilexp, 0, 2, ident_tag);
2509
	exp tg1 = getexp (sh (op21), test1, 1,
2510
			  newid, nilexp, 0, 0, name_tag);
2511
	exp tg2 = getexp (sh (op22), test2, 1, newid, nilexp,
2512
			  0, 0, name_tag);
2513
 
2514
	pt (newid) = tg1;
2515
	pt (tg1) = tg2;	/* uses of newid */
2516
	bro (op21) = ste; clearlast (op21);
2517
	/* body of newid */
2518
	/* forget bro son test2 = bro son test1 */
2519
	bro (ste) = newid;
2520
	setlast (ste);	/* father body = newid */
2521
	bro (op11) = tg1;
2522
	bro (op12) = tg2;
2523
	if (!complex(op11) ) { setinlined(newid); }
2524
	kill_exp(op22, op22);
2525
	/* relace 2nd operands of test */
2526
	* (e) = newid;
2527
	if (scan_cond (&bro(son(labst)), newid) == 2 && complex(op12) ) { 
2528
	  clearinlined(newid); 
2529
	}
2530
	return 1;
2531
      }
2532
      else
2533
	if (name (op12) != name_tag
2534
	    && name (op11) == name_tag 
2535
	    && son (op11) == outer_id
2536
	    && eq_exp (son (outer_id), op12)
2537
	    ) {		/* 1st param of test1 is already identified with
2538
			   1st param of  test2 */
2539
	  exp tg = getexp (sh (op12), op22, 0, outer_id,
2540
			   pt (outer_id), 0, 0, name_tag);
2541
	  pt (outer_id) = tg;
2542
	  no (outer_id) += 1;
2543
	  if (complex(op21) ){ clearinlined(outer_id); }
2544
	  /* update usage of ident */
2545
	  son (test2) = tg;
2546
	  kill_exp(op12, op12);
2547
	  if (scan_cond (&bro(son(labst)), outer_id) == 2 && complex(op22)) {
2548
	    clearinlined(outer_id);
2549
	  }
2550
	  return 2;
2551
	}
2552
  }			
2553
  return 0;
2554
}
2555
static void number_caller_parameter PROTO_N ((param_id)) PROTO_T (exp param_id)
2556
{
2557
  exp init_exp = son(param_id);
2558
  shape param_shape = sh(init_exp);
2559
  long par_size = shape_size(param_shape);
2560
  long par_stack_location = ALIGNNEXT(stparam,32);
2561
 
2562
  ASSERT(name(init_exp)==clear_tag);
2563
 
2564
  if(is_floating(name(param_shape)))
2565
  {
2566
    if(floatparam <= FR_LAST_PARAM )
2567
    {
2568
      props(init_exp) = floatparam;
2569
      floatparam++;
2570
    }
2571
    else
2572
    {
2573
      props(init_exp) = 0;/*passed by stack */
2574
    }
2575
  }
2576
  else
2577
  {
2578
    if (fixparam <= end_param)
2579
    {
2580
      props(init_exp) = fixparam;
2581
    }
2582
    else
2583
    {
2584
      props(init_exp) = 0;/*passed by stack*/
2585
    }
2586
  }
2587
  no(init_exp) = par_stack_location;
2588
  stparam = ALIGNNEXT(par_stack_location + par_size, 32);
2589
  fixparam = R_FIRST_PARAM + (stparam / 32);
2590
  return;
2591
}
2592
 
2593
 
2594
static void number_callee_parameter PROTO_N ((callee_id)) PROTO_T (exp callee_id)
2595
{
2596
  exp def = son(callee_id);
2597
  shape callee_shape = sh(def);
2598
  long size_of_callee = shape_size(callee_shape);
2599
  long alignment_of_callee = shape_align(callee_shape);
2600
  long n = ALIGNNEXT( callee_size , alignment_of_callee);
2601
 
2602
  no(def) = n;
2603
  callee_size = ALIGNNEXT ( n + size_of_callee , 32 );
2604
  return;
2605
}