Subversion Repositories tendra.SVN

Rev

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

Rev 5 Rev 6
Line -... Line 1...
-
 
1
/*
-
 
2
 * Copyright (c) 2002-2006 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 83... Line 113...
83
  test a declaration to see that the identifier is only used as an
113
  test a declaration to see that the identifier is only used as an
84
  applied procedure.
114
  applied procedure.
85
 *********************************************************************/
115
 *********************************************************************/
86
 
116
 
87
 
117
 
88
int apply_only
118
int
89
    PROTO_N ( (e) )
-
 
90
    PROTO_T ( exp e )
119
apply_only(exp e)
91
{
120
{
92
  exp t = pt (e);
121
	exp t = pt(e);
93
  int ao = 1;
122
	int ao = 1;
94
  exp f;
123
	exp f;
95
  while (ao && t != nilexp) {
124
	while (ao && t != nilexp) {
96
#ifdef NEWDIAGS
125
#ifdef NEWDIAGS
97
    if (isdiaginfo(t))
126
		if (isdiaginfo(t)) {
98
      t = pt (t);
127
			t = pt(t);
99
    else {
128
		} else {
100
      f = father(t);
129
			f = father(t);
101
      if (name (f) == apply_tag && son(f) == t)
130
			if (name(f) == apply_tag && son(f) == t) {
102
        t = pt (t);
131
				t = pt(t);
103
      else
132
			} else {
104
        ao = 0;
133
				ao = 0;
105
    };
134
			}
-
 
135
		}
106
#else
136
#else
107
    f = father(t);
137
		f = father(t);
108
    if (name (f) == apply_tag && son(f) == t)
138
		if (name(f) == apply_tag && son(f) == t) {
109
      t = pt (t);
139
			t = pt(t);
110
    else
140
		} else {
111
      ao = 0;
141
			ao = 0;
-
 
142
		}
112
#endif
143
#endif
113
  };
144
	}
114
  return (ao);
145
	return(ao);
115
}
146
}
116
 
147
 
117
 
148
 
-
 
149
void
118
void normalised_inlining
150
normalised_inlining(void)
119
    PROTO_Z ()
-
 
120
{
151
{
121
  int proc_count = 0;
152
  int proc_count = 0;
122
  dec * my_def;
153
  dec *my_def;
123
  dec ** to_dec;
154
  dec **to_dec;
124
  exp def;
155
  exp def;
125
  int i;
156
  int i;
126
  int j;
157
  int j;
127
  char * consider;
158
  char *consider;
128
  int * order;
159
  int *order;
129
  char * uses;
160
  char *uses;
130
  int changed;
161
  int changed;
131
  int low;
162
  int low;
132
  int high;
163
  int high;
133
  int no_inlined =0;
164
  int no_inlined =0;
134
 
165
 
135
  if (!do_inlining)
166
  if (!do_inlining) {
136
    return;
167
    return;
-
 
168
  }
137
 
169
 
138
  /* count the defined procedures */
170
  /* count the defined procedures */
139
 
171
 
140
  my_def = top_def;
172
  my_def = top_def;
141
  while (my_def != (dec *) 0) {
173
  while (my_def != (dec *)0) {
142
    exp crt_exp = my_def -> dec_u.dec_val.dec_exp;
174
    exp crt_exp = my_def -> dec_u.dec_val.dec_exp;
143
 
175
 
144
    def = son(crt_exp);
176
    def = son(crt_exp);
145
    if (def != nilexp && !isvar (crt_exp) && name (def) == proc_tag &&
177
    if (def != nilexp && !isvar(crt_exp) && name(def) == proc_tag &&
146
        !isrecursive(def) && apply_only (crt_exp) && !proc_has_setjmp(def) &&
178
        !isrecursive(def) && apply_only(crt_exp) && !proc_has_setjmp(def) &&
147
        !proc_uses_crt_env(def) &&
179
        !proc_uses_crt_env(def) && !proc_has_alloca(def) && !proc_has_lv(def)) {
148
	!proc_has_alloca(def) &&
-
 
149
	!proc_has_lv(def)) {
-
 
150
      proc_count++;
180
      proc_count++;
151
    }
181
    }
152
    my_def = my_def -> def_next;
182
    my_def = my_def->def_next;
153
  }
183
  }
154
 
184
 
155
  /* allocate
185
  /* allocate
156
     a matrix, uses, to hold uses[i, j] - i calls j
186
     a matrix, uses, to hold uses[i, j] - i calls j
157
     a vector, to_dec, to hold dec* (number -> dec)
187
     a vector, to_dec, to hold dec* (number -> dec)
158
     a vector, consider, 1 if still considering.
188
     a vector, consider, 1 if still considering.
159
     a vector, order, of the procedure numbers (+1) ordered
189
     a vector, order, of the procedure numbers (+1) ordered
160
  */
190
  */
161
 
191
 
162
  uses = (char*)xcalloc(proc_count * proc_count, sizeof(char));
192
  uses = (char *)xcalloc(proc_count * proc_count, sizeof(char));
163
  to_dec = (dec**)xcalloc(proc_count, sizeof(dec*));
193
  to_dec = (dec **)xcalloc(proc_count, sizeof(dec *));
164
  consider = (char*)xcalloc(proc_count, sizeof(char));
194
  consider = (char *)xcalloc(proc_count, sizeof(char));
165
    /* assumes calloc clears consider */
195
    /* assumes calloc clears consider */
166
  order = (int*)xcalloc(proc_count, sizeof(int));
196
  order = (int *)xcalloc(proc_count, sizeof(int));
167
    /* assumes calloc clears order */
197
    /* assumes calloc clears order */
168
 
198
 
169
 
199
 
170
  /* form the to_dec vector and set index in each proc dec.
200
  /* form the to_dec vector and set index in each proc dec.
171
     set consider vector */
201
     set consider vector */
172
 
202
 
173
  my_def = top_def;
203
  my_def = top_def;
174
  i = 0;
204
  i = 0;
175
  while (my_def != (dec *) 0) {
205
  while (my_def != (dec *)0) {
176
    exp crt_exp = my_def -> dec_u.dec_val.dec_exp;
206
    exp crt_exp = my_def->dec_u.dec_val.dec_exp;
177
 
207
 
178
    def = son(crt_exp);
208
    def = son(crt_exp);
179
    if (def != nilexp && !isvar (crt_exp) && name (def) == proc_tag &&
209
    if (def != nilexp && !isvar(crt_exp) && name(def) == proc_tag &&
180
        !isrecursive(def) && apply_only (crt_exp) && !proc_has_setjmp(def) &&
210
        !isrecursive(def) && apply_only(crt_exp) && !proc_has_setjmp(def) &&
181
        !proc_uses_crt_env(def) &&
211
        !proc_uses_crt_env(def) && !proc_has_alloca(def) && !proc_has_lv(def)) {
182
	!proc_has_alloca(def) &&
-
 
183
	!proc_has_lv(def)) {
-
 
184
      to_dec[i] = my_def;
212
      to_dec[i] = my_def;
185
      my_def -> dec_u.dec_val.index = i;
213
      my_def -> dec_u.dec_val.index = i;
186
      consider[i] = 1;
214
      consider[i] = 1;
187
      i++;
215
      i++;
188
    }
216
    }
189
    my_def = my_def -> def_next;
217
    my_def = my_def->def_next;
190
  }
218
  }
191
 
219
 
192
  /* form uses matrix: uses[i, j] implies i calls j */
220
  /* form uses matrix: uses[i, j] implies i calls j */
193
 
221
 
194
  for (i = 0; i < proc_count; i++) {
222
  for (i = 0; i < proc_count; i++) {
195
    exp crt_exp = to_dec[i] -> dec_u.dec_val.dec_exp;
223
    exp crt_exp = to_dec[i]->dec_u.dec_val.dec_exp;
196
 
224
 
197
    if (no(crt_exp) == 0 || son(crt_exp) == nilexp) {
225
    if (no(crt_exp) == 0 || son(crt_exp) == nilexp) {
198
      consider[i] = 0;
226
      consider[i] = 0;
199
    }
-
 
200
    else {
227
    } else {
201
      exp t = pt(crt_exp);
228
      exp t = pt(crt_exp);
202
 
229
 
203
      while (t != nilexp) {
230
      while (t != nilexp) {
204
	exp k = t;
231
	exp k = t;
205
#ifdef NEWDIAGS
232
#ifdef NEWDIAGS
206
	if (isdiaginfo(t)) {
233
	if (isdiaginfo(t)) {
207
	  t = pt (t);
234
	  t = pt(t);
208
	  continue;
235
	  continue;
209
	}
236
	}
210
#endif
237
#endif
211
	while (k != nilexp && name(k) != hold_tag && name(k) != 102
238
	while (k != nilexp && name(k) != hold_tag && name(k) != 102 &&
212
	       && name(k) != proc_tag && name(k) != general_proc_tag)
239
	       name(k) != proc_tag && name(k) != general_proc_tag) {
213
	  k = bro(k);
240
	  k = bro(k);
-
 
241
	}
214
	if (k != nilexp && name(k) == proc_tag) {
242
	if (k != nilexp && name(k) == proc_tag) {
215
	  int up = brog(bro(k)) -> dec_u.dec_val.index;
243
	  int up = brog(bro(k))->dec_u.dec_val.index;
216
	  if (up >=0 && up< proc_count) {
244
	  if (up >=0 && up< proc_count) {
217
	  	uses[proc_count *up + i] = 1;
245
	  	uses[proc_count *up + i] = 1;
218
	  }
246
	  }
219
	}
247
	}
220
	t = pt(t);
248
	t = pt(t);
221
      }
249
      }
222
    }
250
    }
223
  }
251
  }
224
 
252
 
225
  /* form the order list from uses */
253
  /* form the order list from uses */
226
 
254
 
227
  low = 0;
255
  low = 0;
228
  high = proc_count-1;
256
  high = proc_count - 1;
229
  changed = 1;
257
  changed = 1;
230
  while (changed) {
258
  while (changed) {
231
    changed = 0;
259
    changed = 0;
232
 
260
 
233
    for (i = 0; i < proc_count; i++) {
261
    for (i = 0; i < proc_count; i++) {
234
      if (consider[i]) {
262
      if (consider[i]) {
235
        int good = 1;
263
        int good = 1;
236
        for (j = 0; good && j < proc_count; j++) {
264
        for (j = 0; good && j < proc_count; j++) {
237
	  if (consider[j] && uses[i*proc_count+j] == 1)
265
	  if (consider[j] && uses[i * proc_count + j] == 1)
238
	    good = 0;
266
	    good = 0;
239
        }
267
        }
240
	if (good) {
268
	if (good) {
241
	  consider[i] = 0;
269
	  consider[i] = 0;
242
	  order[low++] = i+1;
270
	  order[low++] = i + 1;
243
	  changed = 1;
271
	  changed = 1;
244
	}
272
	}
245
      }
273
      }
246
    }
274
    }
247
 
275
 
248
    for (i = 0; i < proc_count; i++) {
276
    for (i = 0; i < proc_count; i++) {
249
      if (consider[i]) {
277
      if (consider[i]) {
250
        int good = 1;
278
        int good = 1;
251
        for (j = 0; good && j < proc_count; j++) {
279
        for (j = 0; good && j < proc_count; j++) {
252
	  if (consider[j] && uses[j*proc_count+i] == 1)
280
	  if (consider[j] && uses[j * proc_count + i] == 1)
253
	    good = 0;
281
	    good = 0;
254
        }
282
        }
255
	if (good) {
283
	if (good) {
256
	  consider[i] = 0;
284
	  consider[i] = 0;
257
	  order[high--] = i+1;
285
	  order[high--] = i + 1;
258
	  changed = 1;
286
	  changed = 1;
259
	}
287
	}
260
      }
288
      }
261
    }
289
    }
262
  }
290
  }
263
 
291
 
264
  /* permit inlining of static recursive functions */
292
  /* permit inlining of static recursive functions */
265
 
293
 
266
  for (i = 0; i < proc_count; i++) {
294
  for (i = 0; i < proc_count; i++) {
267
    if (consider[i]) {
295
    if (consider[i]) {
268
      order[low++] = i+1;
296
      order[low++] = i + 1;
269
    }
297
    }
270
  }
298
  }
271
 
299
 
272
  /* try to inline in given order */
300
  /* try to inline in given order */
273
 
301
 
Line 278... Line 306...
278
      exp k;
306
      exp k;
279
      int total_uses;
307
      int total_uses;
280
      int crt_uses;
308
      int crt_uses;
281
      int this_changed = 1;
309
      int this_changed = 1;
282
      my_def = to_dec[order[i] - 1];
310
      my_def = to_dec[order[i] - 1];
283
      crt_exp = my_def -> dec_u.dec_val.dec_exp;
311
      crt_exp = my_def->dec_u.dec_val.dec_exp;
284
      def = son(crt_exp);
312
      def = son(crt_exp);
285
      total_uses = no(crt_exp);
313
      total_uses = no(crt_exp);
286
#ifdef NEWDIAGS
314
#ifdef NEWDIAGS
287
      if (diagnose)
315
      if (diagnose) {
288
	start_diag_inlining (def, my_def->dec_u.dec_val.diag_info);
316
	start_diag_inlining(def, my_def->dec_u.dec_val.diag_info);
-
 
317
      }
289
#endif
318
#endif
290
 
319
 
291
      while (this_changed) {
320
      while (this_changed) {
292
        this_changed = 0;
321
        this_changed = 0;
293
	t = pt(crt_exp);
322
	t = pt(crt_exp);
294
	crt_uses = no(crt_exp);
323
	crt_uses = no(crt_exp);
295
        while (t!=nilexp) {
324
        while (t != nilexp) {
296
      	  exp nextt = pt(t);
325
      	  exp nextt = pt(t);
297
	  exp dad;
326
	  exp dad;
298
#ifdef NEWDIAGS
327
#ifdef NEWDIAGS
299
	  if (isdiaginfo(t)) {
328
	  if (isdiaginfo(t)) {
300
	    t = pt (t);
329
	    t = pt(t);
301
	    continue;
330
	    continue;
302
	  }
331
	  }
303
#endif
332
#endif
304
	  dad = father(t);
333
	  dad = father(t);
305
	  if (istoinline(dad)) {
334
	  if (istoinline(dad)) {
306
	    inline_exp(dad);
335
	    inline_exp(dad);
307
 
336
 
308
	    k = t;
337
	    k = t;
309
	    while (k != nilexp && name(k) != hold_tag && name(k) != proc_tag)
338
	    while (k != nilexp && name(k) != hold_tag && name(k) != proc_tag) {
310
	      k = bro(k);
339
	      k = bro(k);
-
 
340
	    }
311
	    if (print_inlines)
341
	    if (print_inlines) {
312
	      IGNORE fprintf(stderr, "%s inlined in %s\n",
342
	      IGNORE fprintf(stderr, "%s inlined in %s\n",
313
	      		my_def -> dec_u.dec_val.dec_id,
343
			     my_def->dec_u.dec_val.dec_id,
314
			brog(bro(k)) -> dec_u.dec_val.dec_id);
344
			     brog(bro(k))->dec_u.dec_val.dec_id);
-
 
345
	    }
315
 
346
 
316
	    this_changed = 1;
347
	    this_changed = 1;
317
	    break;
348
	    break;
318
	  }
-
 
319
	  else
-
 
320
	  if (no_inlined > 10000) {
349
	  } else if (no_inlined > 10000) {
321
               break; /* pathological expansion in AVS */
350
	    break; /* pathological expansion in AVS */
322
          }
351
          } else {
323
	  else {
-
 
324
	    int ch = inlinechoice(t, def, total_uses);
352
	    int ch = inlinechoice(t, def, total_uses);
325
	    if (ch == 0)
353
	    if (ch == 0) {
326
	      break;
354
	      break;
-
 
355
	    }
327
	    if (ch == 2) {
356
	    if (ch == 2) {
328
	      inline_exp(dad);
357
	      inline_exp(dad);
329
	      no_inlined++;
358
	      no_inlined++;
330
 
359
 
331
	      k = t;
360
	      k = t;
332
	      while (k != nilexp && name(k) != hold_tag && name(k) != proc_tag)
361
	      while (k != nilexp && name(k) != hold_tag &&
-
 
362
		     name(k) != proc_tag) {
333
	        k = bro(k);
363
	        k = bro(k);
-
 
364
	      }
334
	      if (print_inlines)
365
	      if (print_inlines) {
335
	        IGNORE fprintf(stderr, "%s inlined in %s\n",
366
	        IGNORE fprintf(stderr, "%s inlined in %s\n",
336
	      		my_def -> dec_u.dec_val.dec_id,
367
			       my_def->dec_u.dec_val.dec_id,
337
			brog(bro(k)) -> dec_u.dec_val.dec_id);
368
			       brog(bro(k))->dec_u.dec_val.dec_id);
-
 
369
	      }
338
 
370
 
339
	      this_changed = 1;
371
	      this_changed = 1;
340
	      break;
372
	      break;
341
	    }
373
	    }
342
	  };
374
	  }
343
	  t = nextt;
375
	  t = nextt;
344
        }
376
        }
345
	if (crt_uses <= no(crt_exp))
377
	if (crt_uses <= no(crt_exp)) {
346
	  break;
378
	  break;
-
 
379
	}
347
      }
380
      }
348
#ifdef NEWDIAGS
381
#ifdef NEWDIAGS
349
      if (diagnose)
382
      if (diagnose) {
350
	end_diag_inlining (def, my_def->dec_u.dec_val.diag_info);
383
	end_diag_inlining(def, my_def->dec_u.dec_val.diag_info);
-
 
384
      }
351
#endif
385
#endif
352
    }
386
    }
353
  }
387
  }
354
 
388
 
355
  xfree((void*)to_dec);
389
  xfree((void *)to_dec);
356
  xfree((void*)uses);
390
  xfree((void *)uses);
357
  xfree((void*)consider);
391
  xfree((void *)consider);
358
  xfree((void*)order);
392
  xfree((void *)order);
359
 
393
 
360
  return;
394
  return;
361
}
395
}