Subversion Repositories tendra.SVN

Rev

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

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