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