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