Subversion Repositories tendra.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 7u83 1
/*
7 7u83 2
 * Copyright (c) 2002-2005 The TenDRA Project <http://www.tendra.org/>.
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions are met:
7
 *
8
 * 1. Redistributions of source code must retain the above copyright notice,
9
 *    this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright notice,
11
 *    this list of conditions and the following disclaimer in the documentation
12
 *    and/or other materials provided with the distribution.
13
 * 3. Neither the name of The TenDRA Project nor the names of its contributors
14
 *    may be used to endorse or promote products derived from this software
15
 *    without specific, prior written permission.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
18
 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
19
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
21
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22
 * EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
 *
29
 * $Id$
30
 */
31
/*
2 7u83 32
    Copyright (c) 1993 Open Software Foundation, Inc.
33
 
34
 
35
    All Rights Reserved
36
 
37
 
38
    Permission to use, copy, modify, and distribute this software
39
    and its documentation for any purpose and without fee is hereby
40
    granted, provided that the above copyright notice appears in all
41
    copies and that both the copyright notice and this permission
42
    notice appear in supporting documentation.
43
 
44
 
45
    OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING
46
    ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
47
    PARTICULAR PURPOSE.
48
 
49
 
50
    IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
51
    CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
52
    LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
53
    NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
54
    WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
55
*/
56
 
57
/*
58
    		 Crown Copyright (c) 1997
7 7u83 59
 
2 7u83 60
    This TenDRA(r) Computer Program is subject to Copyright
61
    owned by the United Kingdom Secretary of State for Defence
62
    acting through the Defence Evaluation and Research Agency
63
    (DERA).  It is made available to Recipients with a
64
    royalty-free licence for its use, reproduction, transfer
65
    to other parties and amendment for any purpose not excluding
66
    product development provided that any such use et cetera
67
    shall be deemed to be acceptance of the following conditions:-
7 7u83 68
 
2 7u83 69
        (1) Its Recipients shall ensure that this Notice is
70
        reproduced upon any copies or amended versions of it;
7 7u83 71
 
2 7u83 72
        (2) Any amended version of it shall be clearly marked to
73
        show both the nature of and the organisation responsible
74
        for the relevant amendment or amendments;
7 7u83 75
 
2 7u83 76
        (3) Its onward transfer from a recipient to another
77
        party shall be deemed to be that party's acceptance of
78
        these conditions;
7 7u83 79
 
2 7u83 80
        (4) DERA gives no warranty or assurance as to its
81
        quality or suitability for any purpose and DERA accepts
82
        no liability whatsoever in relation to any use to which
83
        it may be put.
84
*/
85
 
86
 
87
 
88
/**********************************************************************
89
$Author: release $
90
$Date: 1998/02/04 15:49:13 $
91
$Revision: 1.2 $
92
$Log: weights.c,v $
93
 * Revision 1.2  1998/02/04  15:49:13  release
94
 * Added OSF copyright message.
95
 *
96
 * Revision 1.1.1.1  1998/01/17  15:55:58  release
97
 * First version to be checked into rolling release.
98
 *
99
 * Revision 1.2  1996/10/04  16:05:06  pwe
100
 * add banners and mod for PWE ownership
101
 *
102
**********************************************************************/
103
 
104
 
105
/******************************************************************
106
		weights.c
107
 
108
	The main procedure here is weightsv which determines
109
the allocation of s regs. It considers which of those tags not already
110
allocated to a t reg by scan, are best put in an s register. The same
111
conditions as for t regs apply as to the suitability of the tags for registers.
112
Weights estimates the usage of each tag and hence the amount that would
113
be saved if it were held in an s reg. Thus it computes break points for
114
register allocation for later use by reg_alloc.
115
	The type weights consists of two arrays of integers. In the first
116
array each integer corresponds to a fixpnt reg and the second arrays'
117
integers correspond to floating point regs.
118
	At the end of a call of weights on an ident exp the props field
119
of the ident may still contain inreg_bits or infreg_bits, set by scan, to
120
indicate that a t reg should be used. Otherwise number of ident is set up to
121
represent the break point for allocation. A similar process occurs for
122
proc parameters which have the break value in the forweights field
123
of the parapair of the corresponding procrec. This value has three
124
meanings:
125
	1) The ident (or parameter) defines a fixpnt value and number
126
of ident (forweights of parpair) is an integer brk with the interpretation
127
that if there are at least brk fixpt s registers unallocated at this point then
128
one will be used for this tag (parameter).
129
	2) As 1 but for floating point values.
130
	3) number of ident = 100 in which case allocate value on the
131
stack, (this is obviously always available for parameters).
132
 
133
******************************************************************/
134
 
135
#include "config.h"
136
#include "memtdf.h"
137
 
138
#include "exptypes.h"
139
#include "exp.h"
140
#include "expmacs.h"
141
#include "tags.h"
142
#include "localtypes.h"
143
#include "procrectypes.h"
144
#include "procrecs.h"
145
#include "bitsmacs.h"
146
#include "maxminmacs.h"
147
#include "regable.h"
148
#include "shapemacs.h"
149
#include "myassert.h"
150
#include "weights.h"
151
 
152
 
153
 
154
static CONST weights zeroweights =
155
{
156
  { 0.0	/* , ... */ },
157
  { 0.0	/* , ... */ }
158
};
159
 
160
 
7 7u83 161
weights weightsv(double, exp);
2 7u83 162
 
163
 
7 7u83 164
weights add_weights(weights * w1, weights * w2)
2 7u83 165
{
166
  /* sum of weights */
167
  weights r;
168
  long i;
169
 
170
  for (i = 0; i < wfixno; ++i)
171
  {
7 7u83 172
   (r.fix)[i] = (w1->fix)[i] + (w2->fix)[i];
2 7u83 173
  }
174
  for (i = 0; i < wfloatno; ++i)
175
  {
7 7u83 176
   (r.floating)[i] = (w1->floating)[i] + (w2->floating)[i];
2 7u83 177
  }
7 7u83 178
  return(r);
2 7u83 179
}
180
 
181
 
7 7u83 182
wp max_weights(double loc, weights * ws, bool fix)
2 7u83 183
{
184
  /*
185
   * loc is the usage count of a tag, ws is the weights computed for the scope
186
   * of the tag and fix distinguishes between fix and float. This computes the
187
   * weights for the declaration and a break point for register allocation
188
   * which gives the number of available regs for which it is worthwhile to
189
   * allocate this tag into a reg ("regged"). This proc is the source of all
190
   * non-zero weights. NB loc may be negative since using a s-reg will involve
191
   * a dump and restore.
192
   */
193
  long bk = wfixno + 1;
194
  long i;
195
  float *w = (ws->fix);		/* w[i] = greatest usage of (i+1) inner fixed tags  */
196
  wp res;
7 7u83 197
  float *pw = & (((res.wp_weights).fix)[0]);
2 7u83 198
 
199
  if (fix)
200
  {
201
    for (i = 0; i < wfixno; ++i)
202
    {
203
      if (i == 0)
204
      {
205
	if (loc > w[i])
206
	{
207
	  /* this tag has higher usage than any inner one ... */
208
	  pw[i] = loc;
209
	  bk = i;		/* ... so it's regged in pref to others */
210
	}
211
	else
212
	  pw[i] = w[i];
213
      }
214
      else
215
      {
216
	if ((loc + w[i - 1]) > w[i])
217
	{
218
 
219
	  /*
220
	   * this tag and i inner ones have higher usage than any other (i+1)
221
	   * inner ones ...
222
	   */
223
	  pw[i] = loc + w[i - 1];
224
	  if (i < bk)
225
	    bk = i;
226
 
227
	  /*
228
	   * ... so it and i inner ones are regged in preference to any other
229
	   * (i+1) inner ones
230
	   */
231
	}
232
	else
233
	  pw[i] = w[i];
234
      }
235
    }
236
 
237
    res.fix_break = bk;
238
  }
239
  else
240
  {
241
    for (i = 0; i < wfixno; ++i)
242
    {
243
      pw[i] = w[i];
244
    }
245
  }
246
 
247
  res.fix_break = bk;
248
 
249
  bk = wfloatno + 1;
250
  w = (ws->floating);
7 7u83 251
  pw = & (((res.wp_weights).floating)[0]);
2 7u83 252
  if (!fix)
253
  {				/* same algorithm for float regs as fixed regs */
254
    for (i = 0; i < wfloatno; ++i)
255
    {
256
      if (i == 0)
257
      {
258
	if (loc > w[i])
259
	{
260
	  pw[i] = loc;
261
	  bk = i;
262
	}
263
	else
264
	  pw[i] = w[i];
265
      }
266
      else
267
      {
268
	if ((loc + w[i - 1]) > w[i])
269
	{
270
	  pw[i] = loc + w[i - 1];
271
	  if (i < bk)
272
	    bk = i;
273
	}
274
	else
275
	  pw[i] = w[i];
276
      }
277
    }
278
  }
279
  else
280
  {
281
    for (i = 0; i < wfloatno; ++i)
282
    {
283
      pw[i] = w[i];
284
    }
285
  }
286
 
287
  res.float_break = bk;
288
  return res;
289
}
290
 
7 7u83 291
weights mult_weights(double m, weights * ws)
2 7u83 292
{
293
  /*
294
   * multiply weights by scalar - non overflowing
295
   */
296
  weights res;
7 7u83 297
  float *r = & (res.fix)[0];
2 7u83 298
  float *w = ws->fix;
299
  long i;
300
 
301
  for (i = 0; i < wfixno; ++i)
302
  {
7 7u83 303
    r[i] = w[i]* m;
2 7u83 304
  }
305
 
7 7u83 306
  r = & (res.floating)[0];
2 7u83 307
  w = ws->floating;
308
  for (i = 0; i < wfloatno; ++i)
309
  {
7 7u83 310
    r[i] = w[i]* m;
2 7u83 311
  }
7 7u83 312
  return(res);
2 7u83 313
}
314
 
7 7u83 315
weights add_wlist(double scale, exp re)
2 7u83 316
{				/* sum of  weights of list re */
317
  weights w, w1;
318
  exp r = re;
319
 
320
  if (r == nilexp)
321
  {
322
    return zeroweights;
323
  }
324
  else if (last(r))
325
  {
7 7u83 326
    return(weightsv(scale, r));
2 7u83 327
  }
328
  else
329
  {
330
    w = weightsv(scale, r);
331
    do
332
    {
333
      r = bro(r);
334
      w1 = weightsv(scale, r);
335
      w = add_weights(&w, &w1);
336
    } while (!last(r));
337
    return w;
338
  }
339
}
340
 
341
 
342
 
343
/*****************************************************************
344
	weightsv
345
 
346
This procedure estimates the usage of tags and parameters to help
347
determine whether they can advantageously be placed in s registers.
348
The parameter scale allows more importance to be placed on usage
349
inside 'for' loops for example. The procedure reg_alloc in reg_alloc.c
350
finally determines the actual choice of s reg and recodes the number
351
field of an ident.
352
 
353
******************************************************************/
7 7u83 354
weights weightsv(double scale, exp e)
2 7u83 355
{
356
 
357
tailrecurse:
358
 
359
  switch (name(e))
360
  {
361
  case name_tag:
362
    {
363
      exp s = son(e);
364
 
365
      if (name(s) == ident_tag && !isglob(s))
366
      {
367
	/*
368
	 * 64-bit & 32-bit float load same speed on POWER,
369
	 * so don't differentiate, eg by adding sacle*2.0
370
	 */
371
	fno(s) += scale;
372
      }
373
      /* usage of tag stored in number of son of load_name (decl) */
374
      return zeroweights;
375
    }
376
 
377
  case ident_tag:
378
    {
7 7u83 379
      if (son(e)!= nilexp)
2 7u83 380
      {
381
	weights wdef;
382
	bool wdef_set;
383
	weights wbody;
384
	long noe = no(e) /* set by scan */ ;
385
 
386
#if 1
387
	if (isparam(e))
388
	{
389
	  /* initialising is a use */
390
	  fno(e) = scale;
391
	  wdef_set = 0;
392
	}
393
	else
394
#endif
395
	if (name(son(e)) == clear_tag || props(e) & defer_bit)
396
	{
397
	  fno(e) = 0.0;
398
	  wdef_set = 0;
399
	}
400
	else
401
	{
402
	  /*
403
	   * 64-bit & 32-bit float load same speed on POWER,
404
	   * so don't differentiate, eg by adding sacle*2.0
405
	   */
406
	  ASSERT(!isparam(e));
407
	  fno(e) = scale;
408
	  wdef = weightsv(scale, son(e));
409
	  wdef_set = 1;
410
	}
411
	/* weights for initialisation of dec */
412
 
413
	wbody = weightsv(scale, bro(son(e)));
414
	/* weights of body of scan */
415
 
416
	if (props(e) & defer_bit)
417
	{			/* declaration will be treated transparently
418
				 * in code production */
419
	  exp t = son(e);
420
	  exp s;
421
 
422
	  if (name(t) == val_tag || name(t) == real_tag)
423
	  {
424
	    return wbody;
425
	  }
426
 
7 7u83 427
	  while (name(t)!= name_tag)
2 7u83 428
	  {
429
	    t = son(t);
430
	  }
431
 
432
	  s = son(t);
433
	  if (name(s) == ident_tag && !isglob(t))
434
	  {
435
	    fno(s) += fno(e);
436
	  }
437
	  /* usage of tag stored in number of son of load_name (decl) */
438
 
439
	  return wbody;
440
	}			/* end deferred */
441
 
442
	if ((props(e) & inreg_bits) == 0 && fixregable(e))
443
	{
444
	  wp p;
445
 
446
	  /*
447
	   * Usage decreased by 1.5 because of dump and restore of s-reg.
448
	   * Dump and restore do not create load delay slots hence 1.5, not 2.0.
449
	   */
450
	  p = max_weights(fno(e) - 1.5 * scale, &wbody, 1);
451
 
452
	  no(e) = p.fix_break;
453
 
454
	  if (wdef_set)
455
	    return add_weights(&wdef, &p.wp_weights);
456
	  else
457
	    return p.wp_weights;
458
	}
459
	else if ((props(e) & infreg_bits) == 0 && floatregable(e))
460
	{
461
	  wp p;
462
 
463
	  /*
464
	   * Usage decreased by 1.5 because of dump and restore of double s-reg.
465
	   * 64-bit & 32-bit float load same speed on POWER, so don't differentiate.
466
	   * Dump and restore do not create load delay slots hence 1.5, not 2.0.
467
	   */
468
	  p = max_weights(fno(e) - 1.5 * scale, &wbody, 0);
469
 
470
	  no(e) = p.float_break;
471
 
472
	  if (wdef_set)
473
	    return add_weights(&wdef, &p.wp_weights);
474
	  else
475
	    return p.wp_weights;
476
	}
477
	else
478
	{
479
	  no(e) = noe /* restore to value given by scan */ ;
480
 
481
	  if (wdef_set)
482
	    return add_weights(&wdef, &wbody);
483
	  else
484
	    return wbody;
485
	}
486
      }
487
      else
488
      {
489
	return zeroweights;
490
      }
491
    }
492
  case rep_tag:
493
    {
494
      e = bro(son(e));
495
      goto tailrecurse;
496
    }
497
 
498
  case case_tag:
499
    {
500
      e = son(e);
501
      goto tailrecurse;
502
    }
503
 
504
  case labst_tag:
505
    {
506
      scale = fno(e);
507
      e = bro(son(e));
508
      goto tailrecurse;
509
    }
510
 
511
   case val_tag:
512
   case env_offset_tag:
513
   case general_env_offset_tag:
514
   case caller_name_tag:
515
    {
516
      return zeroweights;
517
    }
518
 
519
  case ncopies_tag:
520
    {
7 7u83 521
      scale = no(e)* scale;
2 7u83 522
      e = son(e);
523
      goto tailrecurse;
524
    }
525
 
526
 
527
 
528
 
529
  default:
530
    {
531
      if (son(e) == nilexp)
532
      {
533
	return zeroweights;
534
      }
535
      if (last(son(e)))
536
      {
537
	e = son(e);
538
	goto tailrecurse;
539
      }
7 7u83 540
      return(add_wlist(scale, son(e)));
2 7u83 541
    }
542
  }
543
}