Subversion Repositories tendra.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
6 7u83 1
/*
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
/*
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
/* 80x86/inlinechoice.c */
62
 
63
/**********************************************************************
64
$Author: release $
65
$Date: 1998/01/17 15:55:51 $
66
$Revision: 1.1.1.1 $
67
$Log: inlinechoice.c,v $
68
 * Revision 1.1.1.1  1998/01/17  15:55:51  release
69
 * First version to be checked into rolling release.
70
 *
71
 * Revision 1.8  1996/12/04  17:58:36  pwe
72
 * correct to allow inlining at >1 location
73
 *
74
 * Revision 1.7  1995/09/28  12:45:17  pwe
75
 * tidy for tcc
76
 *
77
 * Revision 1.6  1995/08/04  08:29:20  pwe
78
 * 4.0 general procs implemented
79
 *
80
 * Revision 1.5  1995/02/22  13:34:31  pwe
81
 * no inline if application shape differs from return shape of proc
82
 *
83
 * Revision 1.4  1995/01/30  12:56:15  pwe
84
 * Ownership -> PWE, tidy banners
85
 *
86
**********************************************************************/
87
 
88
 
89
#include "config.h"
90
#include "common_types.h"
91
#include "installglob.h"
92
#include "exp.h"
93
#include "expmacs.h"
94
#include "tags.h"
95
#include "flags.h"
96
#include "shapemacs.h"
97
#include "inl_norm.h"
98
 
99
#define crit_inline	300
100
#define crit_decs	5
101
#define crit_decsatapp	5
102
#define apply_cost      3
103
 
104
static int complexity(exp e, int count, int newdecs);
105
static last_new_decs = -999;
106
 
107
/*
108
    APPLY COMPLEXITY TO A LIST OF EXPRESSIONS
109
*/
110
 
111
int sbl
112
(exp e, int count, int newdecs)
113
{
114
    int c = complexity(e, count, newdecs);
115
    if (c < 0) return(c);
116
    if (last(e)) return(c);
117
    return(sbl(bro(e), c, newdecs));
118
}
119
 
120
 
121
/*
122
    FIND THE COMPLEXITY OF AN EXPRESSION
123
 
124
    This routine examines the structure of e to see if its complexity
125
    (roughly the number of nodes) is greater than count.  As soon as the
126
    complexity exceeds this value it stops.  It returns the difference
127
    between count and the calculated complexity.
128
*/
129
 
130
static int complexity
131
(exp e, int count, int newdecs)
132
{
133
    unsigned char n = name(e);
134
 
135
    last_new_decs = newdecs;
136
 
137
    if (count < 0)
138
      return(-1);
139
    if (newdecs > crit_decs)
140
      return(-2);
141
    if (son(e) == nilexp)
142
      return(count);
143
 
144
    switch (n) {
145
 
146
	case apply_tag: {
147
	    if (newdecs > crit_decsatapp)
148
	      return(-3);
149
	    return(sbl(son(e), (count - apply_cost),
150
			 (newdecs + 1)));
151
	}
152
 
153
	case rep_tag: {
154
	    return(complexity(bro(son(e)), (count - 1),
155
		     (newdecs + 1)
156
				));
157
	}
158
 
159
	case res_tag: {
160
	    return(complexity(son(e), (count + 1),
161
				  newdecs));
162
	}
163
 
164
	case ident_tag: {
165
	    return(sbl(son(e), (count - 1),
166
			   (newdecs + 1)));
167
	}
168
 
169
	case top_tag:
170
	case clear_tag:
171
	case val_tag: {
172
	    return(count);
173
	}
174
 
175
	case case_tag: {
176
	    return(complexity(son(e), (count - 1),
177
				  newdecs));
178
	}
179
 
180
	case name_tag:
181
	case string_tag:
182
	case env_offset_tag: {
183
	    return(count - 1);
184
	}
185
 
186
	case labst_tag: {
187
	    return(complexity(bro(son(e)), count, newdecs));
188
	}
189
 
190
	case solve_tag:
191
	case seq_tag:
192
	case cond_tag: {
193
	    return(sbl(son(e), count, newdecs));
194
	}
195
 
196
	default : {
197
	    return(sbl(son(e), (count - 1), newdecs));
198
	}
199
    }
200
    /* NOT REACHED */
201
}
202
 
203
 
204
/* delivers 0 if no uses of this proc can be inlined.
205
   delivers 1 if this use cannot be inlined
206
   delivers 2 if this use can be inlined.
207
*/
208
int inlinechoice
209
(exp t, exp def, int total_uses)
210
{
211
  int res;
212
 
213
  exp apars;
214
  exp fpars;
215
 
216
  int newdecs = 0;
217
  int no_actuals;
218
  int max_complexity;
219
 
220
  int nparam;
221
  CONST  int CONST_BONUS_UNIT = 16;
222
  int const_param_bonus;
223
  int adjusted_max_complexity;
224
 
225
  shape shdef = pt(def) /* Oh, yes it is! */;
226
 
227
  if (!eq_shape(sh(father(t)), shdef)) {
228
     /* shape required by application is different from definition */
229
	return 1;
230
  }
231
 
232
  nparam = 0;
233
  const_param_bonus = 0;
234
 
235
 
236
  max_complexity = (crit_inline / total_uses);
237
 
238
#if issparc
239
  {
240
#define QQQ 2
241
    int i;
242
    if (total_uses >= (1 << QQQ))
243
    {
244
      for (i= total_uses >> QQQ; i>0; i >>=1)
245
      {
246
	max_complexity *= 3;
247
	max_complexity /= 2;
248
      }
249
    }
250
#undef QQQ
251
  }
252
#endif
253
 
254
  if (max_complexity < 15) {
255
    max_complexity = 15;
256
  } else if (max_complexity > 120) {
257
    max_complexity = 120;
258
  }
259
 
260
  apars = bro(t); /* only uses are applications */
261
  no_actuals = last(t);		/* if so then apars is apply_tag... */
262
  fpars = son(def);
263
 
264
  for (;;) {
265
     if (name(fpars)!=ident_tag || !isparam(fpars)) {
266
		 /* first beyond formals */
267
       if (!no_actuals)
268
	 newdecs = 10;
269
	 /* more actuals than formals, since last(apars)->break */
270
       break;
271
     }
272
     nparam++;
273
 
274
     switch (name(apars)) {
275
      case val_tag: case real_tag: case string_tag: case name_tag:
276
      	   break;
277
      case cont_tag: {
278
      	   if (name(son(apars)) ==name_tag && isvar(son(son(apars))) &&
279
      	        		!isvar(fpars))break;
280
      	   } /* ... else continue */
281
      default: newdecs++;
282
     }
283
     switch (name(apars))
284
     {
285
      case val_tag: {
286
	int n = no(apars);
287
	if (isbigval(apars))break;
288
 
289
	/* Simple constant param. Increase desire to
290
	   inline since a constant may cause further
291
	   optimisation, eg strength reduction (mul
292
	   to shift) or dead code savings */
293
 
294
#define IS_POW2(c)	((c)!= 0 && ((c) & ((c) - 1)) == 0)
295
 
296
	if (0) {
297
	  /* needs a register - poor */
298
	  const_param_bonus += CONST_BONUS_UNIT / 4;
299
	} else if (n == 0 || (n > 0 && IS_POW2(n))) {
300
	  /* very good */
301
	  const_param_bonus += CONST_BONUS_UNIT;
302
	} else {
303
	  /* less good */
304
	  const_param_bonus += CONST_BONUS_UNIT / 2;
305
	}
306
	break;
307
      }
308
 
309
#undef IS_POW2
310
 
311
      case real_tag:
312
	/* reals not that useful */
313
	const_param_bonus += CONST_BONUS_UNIT / 4;
314
	break;
315
 
316
      case string_tag:
317
       case name_tag:
318
	 break;
319
 
320
      case cont_tag:
321
	if (name(son(apars)) == name_tag &&
322
	    isvar(son(son(apars))) &&
323
	    !isvar(fpars)) {
324
	  break;
325
	}
326
	/* FALL THROUGH */
327
 
328
      default : {
329
	newdecs++;
330
	break;
331
      }
332
     }
333
     fpars = bro(son(fpars));
334
     if (last(apars))break;
335
     apars = bro(apars);
336
   }
337
 
338
  adjusted_max_complexity = max_complexity;
339
 
340
  /* increase to up to 3 times (average around 2) according
341
     to const params */
342
  if (nparam != 0) {
343
    adjusted_max_complexity +=
344
     (2 * max_complexity * const_param_bonus) /
345
	(CONST_BONUS_UNIT * nparam);
346
  }
347
 
348
  /* increase by number of instructions saved for call */
349
    adjusted_max_complexity += nparam - newdecs + 1;
350
 
351
  if ((complexity(fpars,  adjusted_max_complexity, newdecs)) >= 0)
352
    res = 2;
353
  else if (newdecs == 0)
354
    res = 0;
355
  else
356
    res = 1;
357
 
358
 
359
  return res;
360
 
361
}
362