Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – tendra.SVN – Blame – /branches/tendra5/src/installers/power/common/weights.c – Rev 2

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:13 $
61
$Revision: 1.2 $
62
$Log: weights.c,v $
63
 * Revision 1.2  1998/02/04  15:49:13  release
64
 * Added OSF copyright message.
65
 *
66
 * Revision 1.1.1.1  1998/01/17  15:55:58  release
67
 * First version to be checked into rolling release.
68
 *
69
 * Revision 1.2  1996/10/04  16:05:06  pwe
70
 * add banners and mod for PWE ownership
71
 *
72
**********************************************************************/
73
 
74
 
75
/******************************************************************
76
		weights.c
77
 
78
	The main procedure here is weightsv which determines
79
the allocation of s regs. It considers which of those tags not already
80
allocated to a t reg by scan, are best put in an s register. The same
81
conditions as for t regs apply as to the suitability of the tags for registers.
82
Weights estimates the usage of each tag and hence the amount that would
83
be saved if it were held in an s reg. Thus it computes break points for
84
register allocation for later use by reg_alloc.
85
	The type weights consists of two arrays of integers. In the first
86
array each integer corresponds to a fixpnt reg and the second arrays'
87
integers correspond to floating point regs.
88
	At the end of a call of weights on an ident exp the props field
89
of the ident may still contain inreg_bits or infreg_bits, set by scan, to
90
indicate that a t reg should be used. Otherwise number of ident is set up to
91
represent the break point for allocation. A similar process occurs for
92
proc parameters which have the break value in the forweights field
93
of the parapair of the corresponding procrec. This value has three
94
meanings:
95
	1) The ident (or parameter) defines a fixpnt value and number
96
of ident (forweights of parpair) is an integer brk with the interpretation
97
that if there are at least brk fixpt s registers unallocated at this point then
98
one will be used for this tag (parameter).
99
	2) As 1 but for floating point values.
100
	3) number of ident = 100 in which case allocate value on the
101
stack, (this is obviously always available for parameters).
102
 
103
******************************************************************/
104
 
105
#include "config.h"
106
#include "memtdf.h"
107
 
108
#include "exptypes.h"
109
#include "exp.h"
110
#include "expmacs.h"
111
#include "tags.h"
112
#include "localtypes.h"
113
#include "procrectypes.h"
114
#include "procrecs.h"
115
#include "bitsmacs.h"
116
#include "maxminmacs.h"
117
#include "regable.h"
118
#include "shapemacs.h"
119
#include "myassert.h"
120
#include "weights.h"
121
 
122
 
123
 
124
static CONST weights zeroweights =
125
{
126
  { 0.0	/* , ... */ },
127
  { 0.0	/* , ... */ }
128
};
129
 
130
 
131
weights weightsv PROTO_S ((double, exp));
132
 
133
 
134
weights add_weights PROTO_N ((w1,w2)) PROTO_T (weights * w1 X weights * w2)
135
{
136
  /* sum of weights */
137
  weights r;
138
  long i;
139
 
140
  for (i = 0; i < wfixno; ++i)
141
  {
142
    (r.fix)[i] = (w1->fix)[i] + (w2->fix)[i];
143
  }
144
  for (i = 0; i < wfloatno; ++i)
145
  {
146
    (r.floating)[i] = (w1->floating)[i] + (w2->floating)[i];
147
  }
148
  return (r);
149
}
150
 
151
 
152
wp max_weights PROTO_N ((loc,ws,fix)) PROTO_T (double loc X weights * ws X bool fix)
153
{
154
  /*
155
   * loc is the usage count of a tag, ws is the weights computed for the scope
156
   * of the tag and fix distinguishes between fix and float. This computes the
157
   * weights for the declaration and a break point for register allocation
158
   * which gives the number of available regs for which it is worthwhile to
159
   * allocate this tag into a reg ("regged"). This proc is the source of all
160
   * non-zero weights. NB loc may be negative since using a s-reg will involve
161
   * a dump and restore.
162
   */
163
  long bk = wfixno + 1;
164
  long i;
165
  float *w = (ws->fix);		/* w[i] = greatest usage of (i+1) inner fixed tags  */
166
  wp res;
167
  float *pw = &(((res.wp_weights).fix)[0]);
168
 
169
  if (fix)
170
  {
171
    for (i = 0; i < wfixno; ++i)
172
    {
173
      if (i == 0)
174
      {
175
	if (loc > w[i])
176
	{
177
	  /* this tag has higher usage than any inner one ... */
178
	  pw[i] = loc;
179
	  bk = i;		/* ... so it's regged in pref to others */
180
	}
181
	else
182
	  pw[i] = w[i];
183
      }
184
      else
185
      {
186
	if ((loc + w[i - 1]) > w[i])
187
	{
188
 
189
	  /*
190
	   * this tag and i inner ones have higher usage than any other (i+1)
191
	   * inner ones ...
192
	   */
193
	  pw[i] = loc + w[i - 1];
194
	  if (i < bk)
195
	    bk = i;
196
 
197
	  /*
198
	   * ... so it and i inner ones are regged in preference to any other
199
	   * (i+1) inner ones
200
	   */
201
	}
202
	else
203
	  pw[i] = w[i];
204
      }
205
    }
206
 
207
    res.fix_break = bk;
208
  }
209
  else
210
  {
211
    for (i = 0; i < wfixno; ++i)
212
    {
213
      pw[i] = w[i];
214
    }
215
  }
216
 
217
  res.fix_break = bk;
218
 
219
  bk = wfloatno + 1;
220
  w = (ws->floating);
221
  pw = &(((res.wp_weights).floating)[0]);
222
  if (!fix)
223
  {				/* same algorithm for float regs as fixed regs */
224
    for (i = 0; i < wfloatno; ++i)
225
    {
226
      if (i == 0)
227
      {
228
	if (loc > w[i])
229
	{
230
	  pw[i] = loc;
231
	  bk = i;
232
	}
233
	else
234
	  pw[i] = w[i];
235
      }
236
      else
237
      {
238
	if ((loc + w[i - 1]) > w[i])
239
	{
240
	  pw[i] = loc + w[i - 1];
241
	  if (i < bk)
242
	    bk = i;
243
	}
244
	else
245
	  pw[i] = w[i];
246
      }
247
    }
248
  }
249
  else
250
  {
251
    for (i = 0; i < wfloatno; ++i)
252
    {
253
      pw[i] = w[i];
254
    }
255
  }
256
 
257
  res.float_break = bk;
258
  return res;
259
}
260
 
261
weights mult_weights PROTO_N ((m,ws)) PROTO_T (double m X weights * ws)
262
{
263
  /*
264
   * multiply weights by scalar - non overflowing
265
   */
266
  weights res;
267
  float *r = &(res.fix)[0];
268
  float *w = ws->fix;
269
  long i;
270
 
271
  for (i = 0; i < wfixno; ++i)
272
  {
273
    r[i] = w[i] * m;
274
  }
275
 
276
  r = &(res.floating)[0];
277
  w = ws->floating;
278
  for (i = 0; i < wfloatno; ++i)
279
  {
280
    r[i] = w[i] * m;
281
  }
282
  return (res);
283
}
284
 
285
weights add_wlist PROTO_N ((scale,re)) PROTO_T (double scale X exp re)
286
{				/* sum of  weights of list re */
287
  weights w, w1;
288
  exp r = re;
289
 
290
  if (r == nilexp)
291
  {
292
    return zeroweights;
293
  }
294
  else if (last(r))
295
  {
296
    return (weightsv(scale, r));
297
  }
298
  else
299
  {
300
    w = weightsv(scale, r);
301
    do
302
    {
303
      r = bro(r);
304
      w1 = weightsv(scale, r);
305
      w = add_weights(&w, &w1);
306
    } while (!last(r));
307
    return w;
308
  }
309
}
310
 
311
 
312
 
313
/*****************************************************************
314
	weightsv
315
 
316
This procedure estimates the usage of tags and parameters to help
317
determine whether they can advantageously be placed in s registers.
318
The parameter scale allows more importance to be placed on usage
319
inside 'for' loops for example. The procedure reg_alloc in reg_alloc.c
320
finally determines the actual choice of s reg and recodes the number
321
field of an ident.
322
 
323
******************************************************************/
324
weights weightsv PROTO_N ((scale,e)) PROTO_T (double scale X exp e)
325
{
326
 
327
tailrecurse:
328
 
329
  switch (name(e))
330
  {
331
  case name_tag:
332
    {
333
      exp s = son(e);
334
 
335
      if (name(s) == ident_tag && !isglob(s))
336
      {
337
	/*
338
	 * 64-bit & 32-bit float load same speed on POWER,
339
	 * so don't differentiate, eg by adding sacle*2.0
340
	 */
341
	fno(s) += scale;
342
      }
343
      /* usage of tag stored in number of son of load_name (decl) */
344
      return zeroweights;
345
    }
346
 
347
  case ident_tag:
348
    {
349
      if (son(e) != nilexp)
350
      {
351
	weights wdef;
352
	bool wdef_set;
353
	weights wbody;
354
	long noe = no(e) /* set by scan */ ;
355
 
356
#if 1
357
	if (isparam(e))
358
	{
359
	  /* initialising is a use */
360
	  fno(e) = scale;
361
	  wdef_set = 0;
362
	}
363
	else
364
#endif
365
	if (name(son(e)) == clear_tag || props(e) & defer_bit)
366
	{
367
	  fno(e) = 0.0;
368
	  wdef_set = 0;
369
	}
370
	else
371
	{
372
	  /*
373
	   * 64-bit & 32-bit float load same speed on POWER,
374
	   * so don't differentiate, eg by adding sacle*2.0
375
	   */
376
	  ASSERT(!isparam(e));
377
	  fno(e) = scale;
378
	  wdef = weightsv(scale, son(e));
379
	  wdef_set = 1;
380
	}
381
	/* weights for initialisation of dec */
382
 
383
	wbody = weightsv(scale, bro(son(e)));
384
	/* weights of body of scan */
385
 
386
	if (props(e) & defer_bit)
387
	{			/* declaration will be treated transparently
388
				 * in code production */
389
	  exp t = son(e);
390
	  exp s;
391
 
392
	  if (name(t) == val_tag || name(t) == real_tag)
393
	  {
394
	    return wbody;
395
	  }
396
 
397
	  while (name(t) != name_tag)
398
	  {
399
	    t = son(t);
400
	  }
401
 
402
	  s = son(t);
403
	  if (name(s) == ident_tag && !isglob(t))
404
	  {
405
	    fno(s) += fno(e);
406
	  }
407
	  /* usage of tag stored in number of son of load_name (decl) */
408
 
409
	  return wbody;
410
	}			/* end deferred */
411
 
412
	if ((props(e) & inreg_bits) == 0 && fixregable(e))
413
	{
414
	  wp p;
415
 
416
	  /*
417
	   * Usage decreased by 1.5 because of dump and restore of s-reg.
418
	   * Dump and restore do not create load delay slots hence 1.5, not 2.0.
419
	   */
420
	  p = max_weights(fno(e) - 1.5 * scale, &wbody, 1);
421
 
422
	  no(e) = p.fix_break;
423
 
424
	  if (wdef_set)
425
	    return add_weights(&wdef, &p.wp_weights);
426
	  else
427
	    return p.wp_weights;
428
	}
429
	else if ((props(e) & infreg_bits) == 0 && floatregable(e))
430
	{
431
	  wp p;
432
 
433
	  /*
434
	   * Usage decreased by 1.5 because of dump and restore of double s-reg.
435
	   * 64-bit & 32-bit float load same speed on POWER, so don't differentiate.
436
	   * Dump and restore do not create load delay slots hence 1.5, not 2.0.
437
	   */
438
	  p = max_weights(fno(e) - 1.5 * scale, &wbody, 0);
439
 
440
	  no(e) = p.float_break;
441
 
442
	  if (wdef_set)
443
	    return add_weights(&wdef, &p.wp_weights);
444
	  else
445
	    return p.wp_weights;
446
	}
447
	else
448
	{
449
	  no(e) = noe /* restore to value given by scan */ ;
450
 
451
	  if (wdef_set)
452
	    return add_weights(&wdef, &wbody);
453
	  else
454
	    return wbody;
455
	}
456
      }
457
      else
458
      {
459
	return zeroweights;
460
      }
461
    }
462
  case rep_tag:
463
    {
464
      e = bro(son(e));
465
      goto tailrecurse;
466
    }
467
 
468
  case case_tag:
469
    {
470
      e = son(e);
471
      goto tailrecurse;
472
    }
473
 
474
  case labst_tag:
475
    {
476
      scale = fno(e);
477
      e = bro(son(e));
478
      goto tailrecurse;
479
    }
480
 
481
   case val_tag:
482
   case env_offset_tag:
483
   case general_env_offset_tag:
484
   case caller_name_tag:
485
    {
486
      return zeroweights;
487
    }
488
 
489
  case ncopies_tag:
490
    {
491
      scale = no(e) * scale;
492
      e = son(e);
493
      goto tailrecurse;
494
    }
495
 
496
 
497
 
498
 
499
  default:
500
    {
501
      if (son(e) == nilexp)
502
      {
503
	return zeroweights;
504
      }
505
      if (last(son(e)))
506
      {
507
	e = son(e);
508
	goto tailrecurse;
509
      }
510
      return (add_wlist(scale, son(e)));
511
    }
512
  }
513
}