Subversion Repositories tendra.SVN

Rev

Rev 2 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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