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
    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:07 $
61
$Revision: 1.2 $
62
$Log: regalloc.c,v $
63
 * Revision 1.2  1998/02/04  15:49:07  release
64
 * Added OSF copyright message.
65
 *
66
 * Revision 1.1.1.1  1998/01/17  15:55:57  release
67
 * First version to be checked into rolling release.
68
 *
69
 * Revision 1.2  1996/10/04  16:04:01  pwe
70
 * add banners and mod for PWE ownership
71
 *
72
**********************************************************************/
73
 
74
 
75
/****************************************************************
76
		regalloc.c
77
 
78
	The main procedure defined here is reg_alloc which
79
allocates registers and stack space for a proc exp. After the application of
80
weights to the body reg_alloc re-codes the number field of each ident within it.
81
Paralloc in paralloc.c does the corresponding work for the parameters.
82
	At the end of reg_alloc:-
83
1) props of ident contains inreg_bits or infreg_bits and number = 0
84
then the value will be in a t reg to be chosen in make_code
85
2) if props contains the reg bits then number of ident is fixpt s reg
86
or floatpnt s reg (divided by 2)
87
3) value is on the stack and:
88
number of ident = (word displacement in locals)*64 + R_SP
89
 
90
*****************************************************************/
91
#include "config.h"
92
#include "memtdf.h"
93
#include "codegen.h"
94
 
95
#include "myassert.h"
96
#include "maxminmacs.h"
97
#include "comment.h"
98
 
99
#include "regalloc.h"
100
 
101
 
102
 
103
#define ALIGNNEXT(bitposn, bitalign)	(((bitposn)+(bitalign)-1) & ~((bitalign)-1))
104
 
105
 
106
spacereq zerospace = {0, 0, 0, 0x0};
107
 
108
/*****************************************************************
109
	maxspace
110
 
111
Procedure to find the total spacereq of two spacereqs. The bit
112
representations of the s regs used are simply 'or'ed so that the
113
resulting dump fields contain all the regs of the parameters.
114
The largest of the two stack sizes is returned as the stack of the result.
115
 
116
*****************************************************************/
117
 
118
spacereq maxspace PROTO_N ((a,b)) PROTO_T (spacereq a X spacereq b)
119
{
120
  a.fixdump |= b.fixdump;
121
  a.fltdump |= b.fltdump;
122
  a.stack = max(a.stack, b.stack);
123
  a.obtain = nilexp;
124
  return a;
125
}
126
 
127
/* maxspace2 is used by seq tags and ident_tags since the result of these tags
128
   could be the result of one of the brothers */
129
spacereq maxspace2 PROTO_N ((a,b)) PROTO_T (spacereq a X spacereq b)
130
{
131
  a.fixdump |= b.fixdump;
132
  a.fltdump |= b.fltdump;
133
  a.stack = max(a.stack, b.stack);
134
  a.obtain = b.obtain;
135
  return a;
136
} 
137
 
138
/******************************************************************
139
	reg_alloc
140
 
141
Delivers a spacereq which gives the local stack bit requirement in the
142
stack field and the s regs used as bit positions in the fixdump and
143
fltdump fields for fixed and float regs.
144
 
145
******************************************************************/
146
 
147
spacereq regalloc PROTO_N ((e,freefixed,freefloat,stack)) PROTO_T (exp e X int freefixed X int freefloat X long stack)
148
/*
149
 * e is a proc body.
150
 * freefixed and freefloat are the number of fixed and floating s regs
151
 * available. These are initialised at the outer level but may be reduced
152
 * by usage in paralloc.
153
 */
154
{
155
  int n = name(e);
156
  exp s = son(e);
157
  spacereq def;
158
 
159
  switch(n)
160
  {
161
   case ident_tag:
162
    {
163
      int ffix = freefixed;
164
      int ffloat = freefloat;
165
      long st = stack;
166
      bool caller_in_postlude = (name(s)==caller_name_tag);
167
      spacereq body;
168
 
169
      FULLCOMMENT4("regalloc ident_tag:	vis=%d	freefixed,freefloat,stack = %d %d %ld", isvis(e)!=0, freefixed, freefloat, stack);
170
 
171
      ASSERT(freefixed >= 0);
172
      ASSERT(freefloat >= 0);
173
 
174
      if (props(e) & defer_bit)
175
      {
176
	/* the tag declared is transparent to code production */
177
	def = zerospace;
178
      }
179
      else if (
180
	       !isvar(e) && !isparam(e)
181
	       && name(s) == name_tag
182
	       && !isvar(son(s))
183
	       && !isvis(son(s))
184
	       && !isparam(son(s))
185
	       && (props(son(s)) & inreg_bits)
186
	       )
187
      {
188
	/*
189
	 * dont take space for this constant dec,
190
	 * initialiser is another simple constant ident
191
	 * (eg from double nested loop optimisation)
192
	 */
193
	props(e) |= defer_bit;
194
	def = zerospace;
195
      }
196
      else
197
      {
198
	ash a;
199
	a = ashof(sh(s));
200
 
201
	if (name(s) == compound_tag || 
202
	    name(s) == nof_tag || 
203
	    name(s) == concatnof_tag )
204
	{
205
	  /*
206
	   * elements of tuples are done separately so evaluate above dec
207
	   * using stack space
208
	   * stack - bit address for current allocation
209
	   * st - bit address for next allocation
210
	   */
211
 
212
	  ASSERT((stack&31)==0);	/* we expect stack to be word aligned */
213
 
214
	  st = ALIGNNEXT(stack, a.ashalign);
215
	  st = ALIGNNEXT(st+a.ashsize, 32);	/* maintain word alignment */
216
 
217
	  ASSERT(st-stack>=a.ashsize);
218
	  ASSERT((st&31)==0);
219
 
220
	  def = regalloc (s, freefixed, freefloat, st);
221
	}
222
	else
223
	{
224
	  def = regalloc(s, freefixed, freefloat, stack);
225
	}
226
 
227
	FULLCOMMENT4("regalloc ident_tag:	props=%#x fixregable=%d no(e)=%d ffix=%d", props(e), fixregable(e), no(e), ffix);
228
 
229
	if ((props(e) & inreg_bits) == 0 && 
230
	    fixregable(e) && no(e) < ffix
231
	    && !caller_in_postlude)
232
	{
233
	  /* suitable for s reg, no(e) has been set up by weights */
234
	  props(e) |= inreg_bits;
235
	  no(e) = SREG_TO_REALREG(ffix);	/* will be in s reg */
236
	  def.fixdump |= RMASK(no(e));
237
	  ffix--;
238
	  FULLCOMMENT1("regalloc suitable for s reg:	no(e)=%ld", no(e));
239
	  ASSERT(ffix >= 0);
240
	  ASSERT(IS_SREG(no(e)));
241
	  ASSERT(a.ashsize <= 32);
242
	}
243
	else if ((props(e) & infreg_bits) == 0 && 
244
		 floatregable(e) && no(e) < ffloat
245
		 && !caller_in_postlude)
246
	{
247
	  /* suitable for float s reg , no(e) has been set up by weights */
248
	  props(e) |= infreg_bits;
249
	  no(e) = SFREG_TO_REALFREG(ffloat);	/* will be in s reg */
250
	  def.fltdump |= RMASK(no(e));
251
	  ffloat--;
252
	  FULLCOMMENT1("regalloc suitable for s freg:	no(e)=%ld", no(e));
253
	  ASSERT(ffloat >= 0);
254
	  ASSERT(IS_FLT_SREG(no(e)));
255
	  ASSERT(a.ashsize <= 64);
256
	}
257
	else if ((props(e) & inanyreg) == 0)
258
	{
259
	  /*
260
	   * not suitable for reg allocation
261
	   */
262
	  if (name(son(e)) == val_tag && !isvar(e) && !isenvoff(e))
263
	  {
264
	    /*
265
	     * must have been forced by const optimisation
266
	     * - replace uses by the value
267
	     */
268
	    exp t = pt(e);
269
 
270
	    for (; t != nilexp;)
271
	    {
272
	      exp p = pt(t);
273
 
274
	      setname(t, val_tag);
275
	      son(t) = nilexp;
276
	      no(t) = no(son(e));
277
	      props(t) = 0;
278
	      pt(t) = nilexp;
279
	      t = p;
280
	    }
281
	    pt(e) = nilexp;
282
 
283
	    FULLCOMMENT("regalloc heavily used const: no spare regs - replace use by value");
284
	    props(e) |= defer_bit;
285
	    def = zerospace;
286
	  }
287
	  else if (name(son(e)) == name_tag && !isvar(e) && !isenvoff(e))
288
	  {
289
	    /* must have been forced  - defer it */
290
	    FULLCOMMENT("regalloc heavily used address: no spare regs - replace use by value");
291
	    props(e) |= defer_bit;
292
	    def = zerospace;
293
	  }
294
	  else if (isparam(e) || caller_in_postlude)
295
	  {
296
	    /* Caller parameters and callee parameters are
297
	       calculated in make_ident_tag_code
298
	       Caller parameters identified in postludes are
299
	       also done in make_ident_tag_code
300
 
301
	       It is essential that caller parameters identified
302
	       in postludes are not allocated into s-regs
303
	       */
304
	    no(e) = 0;
305
	  }
306
	  else
307
	  {
308
	    /*
309
	     * allocate on stack
310
	     * stack - bit address for current allocation
311
	     * st - bit address for next allocation
312
	     */
313
 
314
	    ASSERT((stack&31)==0);	/* we expect stack to be word aligned */
315
 
316
	    stack = ALIGNNEXT(stack, a.ashalign);
317
	    st = ALIGNNEXT(stack+a.ashsize, 32);	/* maintain word alignment */
318
 
319
	    ASSERT(st-stack>=a.ashsize);
320
	    ASSERT((stack&31)==0);
321
 
322
	    def.stack = max(def.stack, st);
323
	    no(e) = (stack<<3) + R_FP;		/* no() decoded by boff() */
324
	    ASSERT((stack&7)==0);			/* must be byte aligned */
325
	    FULLCOMMENT3("regalloc allocate on stack:	stack,st=%ld,%ld	no(e)=%ld", stack,st,no(e));
326
	  }
327
	}
328
	else 
329
	{
330
	  FULLCOMMENT1("regalloc no(e)==%d:/* allocation of stack like regs in make_code */", no(e));
331
	}
332
      }
333
      body = regalloc(bro(s), ffix, ffloat, st);
334
 
335
      FULLCOMMENT3("regalloc return:	ffix,ffloat,st = %d %d %ld", ffix, ffloat, st);
336
      return maxspace2(def, body);
337
    }
338
 
339
   case case_tag:
340
    {
341
      /* We do not wish to recurse down the bro(son(e)) */
342
      def = regalloc(s, freefixed, freefloat, stack);
343
      def.obtain = nilexp;/* A case returns nothing */
344
      return def;
345
    }
346
   case cont_tag:
347
    if (name(s)==name_tag &&
348
	name(son(s))==ident_tag &&
349
	isvar(son(s)) &&
350
	(
351
	(((props(son(s)) & inreg_bits)!=0) && IS_SREG(no(son(s))))  ||
352
	  (((props(son(s)) & infreg_bits)!=0) && IS_FLT_SREG(no(son(s))))
353
	 )
354
	)
355
    {
356
      def = zerospace;
357
      def.stack = stack;
358
      def.obtain = son(s);
359
      return def;
360
    }
361
    else
362
    {
363
      goto label_default;
364
    }
365
   case name_tag:
366
    {
367
      def = zerospace;
368
      def.stack = stack;
369
 
370
      if( name(s)==ident_tag &&
371
	 !isvar(s) &&
372
	 (
373
	 (((props(s) & inreg_bits)!=0) && IS_SREG(no(s))) ||
374
	 (((props(s) & infreg_bits)!=0) && IS_FLT_SREG(no(s)))
375
	  )
376
	 )
377
      {
378
	/* This could be the last one */
379
	def.obtain = s;
380
      }
381
      return def;
382
    }
383
   case env_offset_tag:
384
   case general_env_offset_tag:
385
   case caller_name_tag:
386
    {
387
      /* We do not wish to recurse down these tags */
388
      def = zerospace;
389
      def.stack = stack;
390
      def.obtain = nilexp;
391
      return def;
392
    }
393
   case seq_tag:
394
    {      
395
      def = regalloc(s, freefixed, freefloat, stack);
396
      s = bro(s);
397
      def = maxspace2(def,regalloc(s, freefixed, freefloat, stack));
398
      return def;	
399
    }
400
   label_default:
401
   default:
402
    {
403
      if(s == nilexp)
404
      {
405
	def = zerospace;
406
	def.stack = stack;
407
	def.obtain = nilexp;
408
	return def;
409
      }
410
      else
411
      {
412
	def = regalloc(s, freefixed, freefloat, stack);
413
	if (def.obtain == s)
414
	{
415
	  if (props(def.obtain)&inreg_bits !=0)
416
	  {
417
	    freefixed--;
418
	  }
419
	  else
420
	  {
421
	    freefloat--;
422
	  }
423
	}
424
 
425
	while (!last(s))
426
	{
427
	  s = bro(s);
428
	  def = maxspace(def, regalloc(s, freefixed, freefloat, stack));
429
	  if (def.obtain==s)
430
	  {
431
	    if (props(def.obtain)&inreg_bits !=0)
432
	    {
433
	      freefixed--;
434
	    }
435
	    else
436
	    {
437
	      freefloat--;
438
	    }
439
	  }
440
	}
441
	return def;	
442
      }
443
    }
444
  }
445
}