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