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
    		 Crown Copyright (c) 1997
3
 
4
    This TenDRA(r) Computer Program is subject to Copyright
5
    owned by the United Kingdom Secretary of State for Defence
6
    acting through the Defence Evaluation and Research Agency
7
    (DERA).  It is made available to Recipients with a
8
    royalty-free licence for its use, reproduction, transfer
9
    to other parties and amendment for any purpose not excluding
10
    product development provided that any such use et cetera
11
    shall be deemed to be acceptance of the following conditions:-
12
 
13
	(1) Its Recipients shall ensure that this Notice is
14
	reproduced upon any copies or amended versions of it;
15
 
16
	(2) Any amended version of it shall be clearly marked to
17
	show both the nature of and the organisation responsible
18
	for the relevant amendment or amendments;
19
 
20
	(3) Its onward transfer from a recipient to another
21
	party shall be deemed to be that party's acceptance of
22
	these conditions;
23
 
24
	(4) DERA gives no warranty or assurance as to its
25
	quality or suitability for any purpose and DERA accepts
26
	no liability whatsoever in relation to any use to which
27
	it may be put.
28
*/
29
 
30
 
31
/*
32
$Log: weights.c,v $
33
 * Revision 1.1.1.1  1998/01/17  15:56:03  release
34
 * First version to be checked into rolling release.
35
 *
36
 * Revision 1.2  1995/12/18  13:12:46  wfs
37
 * Put hppatrans uder cvs control. Major Changes made since last release
38
 * include:
39
 * (i) PIC code generation.
40
 * (ii) Profiling.
41
 * (iii) Dynamic Initialization.
42
 * (iv) Debugging of Exception Handling and Diagnostics.
43
 *
44
 * Revision 5.0  1995/08/25  13:42:58  wfs
45
 * Preperation for August 25 Glue release
46
 *
47
 * Revision 3.4  1995/08/25  10:41:19  wfs
48
 * A few refinements necessary for 3.1 and 4.0 compatability.
49
 *
50
 * Revision 3.4  1995/08/25  10:41:19  wfs
51
 * A few refinements necessary for 3.1 and 4.0 compatability.
52
 *
53
 * Revision 3.1  95/04/10  16:28:41  16:28:41  wfs (William Simmonds)
54
 * Apr95 tape version.
55
 * 
56
 * Revision 3.0  95/03/30  11:19:16  11:19:16  wfs (William Simmonds)
57
 * Mar95 tape version with CRCR95_178 bug fix.
58
 * 
59
 * Revision 2.0  95/03/15  15:29:06  15:29:06  wfs (William Simmonds)
60
 * spec 3.1 changes implemented, tests outstanding.
61
 * 
62
 * Revision 1.1  95/01/11  13:19:42  13:19:42  wfs (William Simmonds)
63
 * Initial revision
64
 * 
65
*/
66
 
67
 
68
#define HPPATRANS_CODE
69
/******************************************************************
70
		weights.c
71
 
72
	The main procedure here is weightsv which determines
73
the allocation of s regs. It considers which of those tags not already
74
allocated to a t reg by scan, are best put in an s register. The same
75
conditions as for t regs apply as to the suitability of the tags for registers.
76
Weights estimates the usage of each tag and hence the amount that would
77
be saved if it were held in an s reg. Thus it computes break points for
78
register allocation for later use by reg_alloc.
79
	The type weights consists of two arrays of integers. In the first
80
array each integer corresponds to a fixpnt reg and the second arrays'
81
integers correspond to floating point regs.
82
	At the end of a call of weights on an ident exp the props field
83
of the ident may still contain inreg_bits or infreg_bits, set by scan, to
84
indicate that a t reg should be used. Otherwise number of ident is set up to
85
represent the break point for allocation. A similar process occurs for
86
proc parameters which have the break value in the forweights field
87
of the parapair of the corresponding procrec. This value has three
88
meanings:
89
	1) The ident (or parameter) defines a fixpnt value and number
90
of ident (forweights of parpair) is an integer brk with the interpretation
91
that if there are at least brk fixpt s registers unallocated at this point then
92
one will be used for this tag (parameter).
93
	2) As 1 but for floating point values.
94
	3) number of ident = 100 in which case allocate value on the
95
stack, (this is obviously always available for parameters).
96
 
97
******************************************************************/
98
 
99
 
100
#include "config.h"
101
#include "exptypes.h"
102
#include "expmacs.h"
103
#include "codetypes.h"
104
#include "installtypes.h"
105
#include "const.h"
106
#include "exp.h"
107
#include "tags.h"
108
#include "common_types.h"
109
#include "proctypes.h"
110
#include "procrec.h"
111
#include "bitsmacs.h"
112
#include "maxminmacs.h"
113
#include "regable.h"
114
#include "comment.h"
115
#include "shapemacs.h"
116
#include "special.h"
117
#include "weights.h"
118
 
119
 
120
 
121
weights zeroweights =
122
{{
123
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
124
},
125
{
126
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
127
}
128
};
129
 
130
/* NB scale, throughout,  should be a float but mips cc V2.10 compiles calls and
131
		proc body inconsistently !! */
132
 
133
weights weightsv PROTO_S ( ( double, exp ) ) ;
134
 
135
weights add_weights 
136
    PROTO_N ( ( w1, w2 ) )
137
    PROTO_T ( weights * w1 X weights * w2 )
138
{
139
  /* sum of weights */
140
  weights r;
141
  long i;
142
 
143
  for (i = 0; i < wfixno; ++i)
144
  {
145
    (r.fix)[i] = (w1->fix)[i] + (w2->fix)[i];
146
  };
147
  for (i = 0; i < wfloatno; ++i)
148
  {
149
    (r.floating)[i] = (w1->floating)[i] + (w2->floating)[i];
150
  };
151
  return (r);
152
}
153
 
154
wp max_weights 
155
    PROTO_N ( ( loc, ws, fix ) )
156
    PROTO_T ( double loc X weights * ws X bool fix )
157
{
158
 
159
  /*
160
   * loc is the usage count of a tag, ws is the weights computed for the scope
161
   * of the tag and fix distinguishes between fix and float. This computes the
162
   * weights for the declaration and a break point for register allocation
163
   * which gives the number of available regs for which it is worthwhile to
164
   * allocate this tag into a reg ("regged"). This proc is the source of all
165
   * non-zero weights. NB loc may be negative since using a s-reg will involve
166
   * a dump and restore
167
   */
168
  long bk = wfixno + 1;
169
  long i;
170
  float *w = (ws->fix);
171
  /* w[i] = greatest usage of (i+1) inner fixed tags  */
172
  wp res;
173
  float *pw = &(((res.wp_weights).fix)[0]);
174
 
175
  if (fix)
176
  {
177
    for (i = 0; i < wfixno; ++i)
178
    {
179
      if (i == 0)
180
      {
181
	if (loc > w[i])
182
	{
183
	  /* this tag has higher usage than any inner one ... */
184
	  pw[i] = loc;
185
	  bk = i;		/* ... so it's regged in pref to others */
186
	}
187
	else
188
	  pw[i] = w[i];
189
      }
190
      else
191
      {
192
	if ((loc + w[i - 1]) > w[i])
193
	{
194
 
195
	  /*
196
	   * this tag and i inner ones have higher usage than any other (i+1)
197
	   * inner ones ...
198
	   */
199
	  pw[i] = loc + w[i - 1];
200
	  if (i < bk)
201
	    bk = i;
202
 
203
	  /*
204
	   * ... so it and i inner ones are regged in preference to any other
205
	   * (i+1) inner ones
206
	   */
207
	}
208
	else
209
	  pw[i] = w[i];
210
      };
211
    };
212
 
213
    res.fix_break = bk;
214
  }
215
  else
216
  {
217
    for (i = 0; i < wfixno; ++i)
218
    {
219
      pw[i] = w[i];
220
    }
221
  }
222
 
223
#if NO_SREG
224
  res.fix_break = wfixno + 1;
225
#else
226
  res.fix_break = bk;
227
#endif
228
 
229
  bk = wfloatno + 1;
230
  w = (ws->floating);
231
  pw = &(((res.wp_weights).floating)[0]);
232
  if (!fix)
233
  {				/* same algorithm for float regs as fixed regs */
234
    for (i = 0; i < wfloatno; ++i)
235
    {
236
      if (i == 0)
237
      {
238
	if (loc > w[i])
239
	{
240
	  pw[i] = loc;
241
	  bk = i;
242
	}
243
	else
244
	  pw[i] = w[i];
245
      }
246
      else
247
      {
248
	if ((loc + w[i - 1]) > w[i])
249
	{
250
	  pw[i] = loc + w[i - 1];
251
	  if (i < bk)
252
	    bk = i;
253
	}
254
	else
255
	  pw[i] = w[i];
256
      };
257
    };
258
  }
259
  else
260
  {
261
    for (i = 0; i < wfloatno; ++i)
262
    {
263
      pw[i] = w[i];
264
    }
265
  }
266
 
267
  res.float_break = bk;
268
  return res;
269
}
270
 
271
weights mult_weights 
272
    PROTO_N ( ( m, ws ) )
273
    PROTO_T ( double m X weights * ws )
274
{
275
 
276
  /*
277
   * multiply weights by scalar - non overflowing
278
   */
279
  weights res;
280
  float *r = &(res.fix)[0];
281
  float *w = ws->fix;
282
  long i;
283
 
284
  for (i = 0; i < wfixno; ++i)
285
  {
286
    r[i] = w[i] * m;
287
  };
288
 
289
  r = &(res.floating)[0];
290
  w = ws->floating;
291
  for (i = 0; i < wfloatno; ++i)
292
  {
293
    r[i] = w[i] * m;
294
  };
295
  return (res);
296
}
297
 
298
weights add_wlist 
299
    PROTO_N ( ( scale, re ) )
300
    PROTO_T ( double scale X exp re )
301
{				/* sum of  weights of list re */
302
  weights w, w1;
303
  exp r = re;
304
 
305
  if (r == nilexp)
306
  {
307
    return zeroweights;
308
  }
309
  else if (last(r))
310
  {
311
    return (weightsv(scale, r));
312
  }
313
  else
314
  {
315
    w = weightsv(scale, r);
316
    do
317
    {
318
      r = bro(r);
319
      w1 = weightsv(scale, r);
320
      w = add_weights(&w, &w1);
321
    } while (!last(r));
322
    return w;
323
  }
324
}
325
 
326
 
327
 
328
/*****************************************************************
329
	weightsv
330
 
331
This procedure estimates the usage of tags and parameters to help
332
determine whether they can advantageously be placed in s registers.
333
The parameter scale allows more importance to be placed on usage
334
inside 'for' loops for example. The procedure reg_alloc in reg_alloc.c
335
finally determines the actual choice of s reg and recodes the number
336
field of an ident.
337
 
338
******************************************************************/
339
weights weightsv 
340
    PROTO_N ( ( scale, e ) )
341
    PROTO_T ( double scale X exp e )
342
{
343
  unsigned char n;
344
 
345
  tailrecurse:
346
  n = name(e);
347
 
348
 
349
  switch (n)
350
  {
351
  case name_tag:
352
    {
353
      exp s = son(e);
354
 
355
      if (name(s) == ident_tag && !isglob(s))
356
      {
357
	if (is_floating(name(sh(e))) && name(sh(e)) != shrealhd)
358
	{
359
	  fno(s) += scale * 2.0;
360
	}
361
	else
362
	  fno(s) += scale;
363
      }
364
      /* usage of tag stored in number of son of load_name (decl) */
365
      return zeroweights;
366
    };
367
 
368
  case ident_tag:
369
    {
370
      if (son(e) != nilexp)
371
      {
372
	weights wdef;
373
	bool wdef_set;
374
	weights wbody;
375
	long noe = no(e) /* set by scan */ ;
376
 
377
#if 1
378
	if (isparam(e))
379
	{
380
	  /* initialising is a use */
381
	  fno(e) = scale;
382
	  wdef_set = 0;
383
	}
384
	else
385
#endif
386
	if (name(son(e)) == clear_tag || props(e) & defer_bit)
387
	{
388
	  wdef = zeroweights;
389
	  fno(e) = 0.0;
390
	  wdef_set = 0;
391
	}
392
	else
393
	{
394
	  /* maybe needs a store to initialise */
395
	  if (is_floating(name(sh(son(e)))) && name(sh(son(e))) != shrealhd)
396
	  {
397
	    fno(e) = scale * 2.0;
398
	  }
399
	  else
400
	    fno(e) = scale;
401
	  wdef = weightsv(scale, son(e));
402
	  wdef_set = 1;
403
	}
404
	/* weights for initialisation of dec */
405
 
406
	wbody = weightsv(scale, bro(son(e)));
407
	/* weights of body of scan */
408
 
409
	if (props(e) & defer_bit)
410
	{			/* declaration will be treated transparently
411
				 * in code production */
412
	  exp t = son(e);
413
	  exp s;
414
 
415
	  if ((name(t) == val_tag) || (name(t) == real_tag)) /* +++ string_tag too */
416
	  {
417
	    return wbody;
418
	  }
419
	  while (name(t) != name_tag)
420
	  {
421
	    t = son(t);
422
	  }
423
 
424
	  s = son(t);
425
	  if (name(s) == ident_tag && !isglob(t))
426
	  {
427
	    fno(s) += fno(e);
428
	  }
429
	  /* usage of tag stored in number of son of load_name (decl) */
430
 
431
	  return wbody;
432
	}			/* end deferred */
433
 
434
	if ((props(e) & inreg_bits) == 0 && fixregable(e))
435
	{
436
	  wp p;
437
 
438
	  p = max_weights(fno(e) - 2.0 * scale, &wbody, 1);
439
 
440
	  no(e) = p.fix_break;
441
	  if (wdef_set)
442
	    return add_weights(&wdef, &p.wp_weights);
443
	  else
444
	    return p.wp_weights;
445
	}
446
	else if ((props(e) & infreg_bits) == 0 && floatregable(e))
447
	{
448
	  wp p;
449
 
450
	  p = max_weights(fno(e) - 3.0 * scale, &wbody, 0);
451
 
452
	  /*
453
	   * usage decreased by 3 because of dump and restore of double s-reg
454
	   */
455
	  no(e) = p.float_break /* was noe */ ;
456
	  if (wdef_set)
457
	    return add_weights(&wdef, &p.wp_weights);
458
	  else
459
	    return p.wp_weights;
460
	}
461
	else
462
	{
463
	  no(e) = noe;
464
 
465
	  if (wdef_set)
466
	    return add_weights(&wdef, &wbody);
467
	  else
468
	    return wbody;
469
	}
470
      }
471
      else
472
	return zeroweights;
473
    };
474
  case rep_tag:
475
    {
476
      e = bro(son(e));
477
      goto tailrecurse;
478
    }
479
 
480
  case case_tag:
481
    {
482
      e = son(e);
483
      goto tailrecurse;
484
    };
485
 
486
  case labst_tag:
487
    {
488
      scale = fno(e) * scale;
489
      e = bro(son(e));
490
      goto tailrecurse;
491
    }
492
 
493
 
494
  case val_tag:
495
    {
496
      return zeroweights;
497
    };
498
 
499
  case ncopies_tag:
500
    {
501
      scale = no(e) * scale;
502
      e = son(e);
503
      goto tailrecurse;
504
    }
505
 
506
 
507
 
508
 
509
  default:
510
    {
511
      if (son(e) == nilexp || n == env_offset_tag
512
			   || n == general_env_offset_tag )
513
      {
514
	return zeroweights;
515
      }
516
      if (last(son(e)))
517
      {
518
	e = son(e);
519
	goto tailrecurse;
520
      }
521
      return (add_wlist(scale, son(e)));
522
    }
523
  }
524
}
525
 
526
 
527
 
528
 
529
 
530
 
531
 
532
 
533
 
534
 
535
 
536
 
537
 
538