Subversion Repositories tendra.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 7u83 1
/*
2
    		 Crown Copyright (c) 1997
3
 
4
    This TenDRA(r) Computer Program is subject to Copyright
5
    owned by the United Kingdom Secretary of State for Defence
6
    acting through the Defence Evaluation and Research Agency
7
    (DERA).  It is made available to Recipients with a
8
    royalty-free licence for its use, reproduction, transfer
9
    to other parties and amendment for any purpose not excluding
10
    product development provided that any such use et cetera
11
    shall be deemed to be acceptance of the following conditions:-
12
 
13
        (1) Its Recipients shall ensure that this Notice is
14
        reproduced upon any copies or amended versions of it;
15
 
16
        (2) Any amended version of it shall be clearly marked to
17
        show both the nature of and the organisation responsible
18
        for the relevant amendment or amendments;
19
 
20
        (3) Its onward transfer from a recipient to another
21
        party shall be deemed to be that party's acceptance of
22
        these conditions;
23
 
24
        (4) DERA gives no warranty or assurance as to its
25
        quality or suitability for any purpose and DERA accepts
26
        no liability whatsoever in relation to any use to which
27
        it may be put.
28
*/
29
 
30
 
31
/**********************************************************************
32
$Author: release $
33
$Date: 1998/01/17 15:56:06 $
34
$Revision: 1.1.1.1 $
35
$Log: regexps.c,v $
36
 * Revision 1.1.1.1  1998/01/17  15:56:06  release
37
 * First version to be checked into rolling release.
38
 *
39
 * Revision 1.7  1996/01/25  17:07:21  currie
40
 * Alias with bit-fields
41
 *
42
 * Revision 1.6  1996/01/08  17:05:33  currie
43
 * current_env in depends_on
44
 *
45
 * Revision 1.5  1995/10/20  10:48:03  currie
46
 * avs -slow + attempts to cheat buggy scheduler
47
 *
48
 * Revision 1.4  1995/09/12  10:59:41  currie
49
 * gcc pedanttry
50
 *
51
 * Revision 1.3  1995/09/04  10:11:57  currie
52
 * e changes !
53
 *
54
 * Revision 1.2  1995/08/16  16:07:08  currie
55
 * Shortened some .h names
56
 *
57
 * Revision 1.1  1995/04/13  09:08:06  currie
58
 * Initial revision
59
 *
60
***********************************************************************/
61
 
62
/* regexps.c
63
 
64
For trivial 'peephole' optimisations
65
 
66
*/
67
 
68
 
69
 
70
#include "config.h"
71
#include "expmacs.h"
72
#include "addrtypes.h"
73
#include "tags.h"
74
#include "move.h"
75
#include "bitsmacs.h"
76
#include "maxminmacs.h"
77
#include "shapemacs.h"
78
#include "common_types.h"
79
#include "extratags.h"
80
#include "check.h"
81
#include "basicread.h"
82
#include "regexps.h"
83
 
84
regpeep regexps[48];		/* [0:31] fix pt - [32:47] floating pt */
85
 
86
bool sim_exp PROTO_S ((exp a, exp b));
87
 
88
bool eq_sze
89
    PROTO_N ( (as, bs) )
90
    PROTO_T ( shape as X shape bs )
91
{
92
  if (is_floating(name(as))) return(name(as)==name(bs));
93
  if (is_floating(name(bs))) return 0;
94
  return (shape_size(as) == shape_size(bs) && shape_align(as)==shape_align(bs));
95
}
96
 
97
bool sim_explist
98
    PROTO_N ( (al, bl) )
99
    PROTO_T ( exp al X exp bl )
100
{
101
  if (al == nilexp && bl == nilexp)
102
    return (1);
103
  if (al == nilexp || bl == nilexp)
104
    return (0);
105
  if (!sim_exp (al, bl))
106
    return (0);
107
  if (last (al) && last (bl))
108
    return (1);
109
  if (last (al) || last (bl))
110
    return (0);
111
  return (sim_explist (bro (al), bro (bl)));
112
}
113
 
114
bool sim_exp
115
    PROTO_N ( (a,b) )
116
    PROTO_T ( exp a X exp b )
117
{	/* basically eq_exp except equal shapes
118
				   requirement  is weakened to equal sizes
119
				   and alignments */
120
  if (name (a) == name (b)) {
121
    if (name (a) == name_tag)
122
      return (son (a) == son (b) && no (a) == no (b) &&
123
	  eq_sze (sh (a), sh (b)));
124
    if (name(a)==maxlike_tag || name(a)==minlike_tag || name(a)==abslike_tag) {
125
    	return (props(son(a))==props(son(b)) &&
126
		shape_size(sh(a))==shape_size(sh(b)) &&
127
    			sim_explist(son(son(a)),son(son(b)) ) );
128
    }
129
    if (!is_a (name (a)) || !eq_sze (sh (a), sh (b)))
130
      return (0);
131
    if (name(a) == float_tag) return eq_exp(son(a), son(b));
132
    return (no (a) == no (b) &&
133
	sim_explist (son (a), son (b)));
134
  };
135
  return (0);
136
}
137
 
138
void clear_all
139
    PROTO_Z ()
140
{	/* forget all register - exp associations */
141
  int   i;
142
  for (i = 0; i < 48; i++) {
143
    regexps[i].keptexp = nilexp;
144
    setregalt (regexps[i].inans, 0);
145
  }
146
}
147
 
148
 
149
void clear_reg
150
    PROTO_N ( (i) )
151
    PROTO_T ( int i )
152
{	/* forget reg i - exp association */
153
  i = abs (i);
154
  if (i >= 0 && i < 48) {
155
    regexps[i].keptexp = nilexp;
156
    setregalt (regexps[i].inans, 0);
157
  }
158
}
159
 
160
 
161
ans iskept
162
    PROTO_N ( (e) )
163
    PROTO_T ( exp e )
164
{		/* find if e has already been evaluated
165
				   into a register */
166
  int   i;
167
  ans nilans;
168
  ans aa;
169
  setregalt (nilans, 0);
170
  aa = nilans;
171
  for (i = 0; i < 48; i++) {
172
    exp ke = regexps[i].keptexp;
173
    bool isc = regexps[i].iscont;
174
    if (ke != nilexp) {		/* there is an accociation with reg i */
175
      if (
176
	  ((!isc && sim_exp (ke, e)) ||
177
	    (name (e) == cont_tag && isc  &&
178
	      eq_sze (sh (ke), sh (e))
179
	      && sim_exp (ke, son (e))  && al1(sh(son(e))) == al1(sh(ke)) )
180
	  )
181
	) {
182
	aa = (regexps[i].inans);
183
	switch (aa.discrim) {
184
	  case notinreg:
185
	    {
186
	      if (!aa.val.instoreans.adval) {
187
				/* the expression is given indirectly - it
188
				   may have also been loaded into a
189
				   register */
190
		continue;
191
	      }
192
	      /* else ... */
193
	    }
194
	  default:
195
	    return aa;
196
	}
197
      }
198
      else
199
	if (name (ke) == cont_tag && !isc) {
200
	  ans aq;
201
	  aq = regexps[i].inans;
202
	  if (aq.discrim == notinreg) {
203
	    instore is;
204
	    is = insalt (aq);
205
	    if (!is.adval && is.b.offset == 0 && is.b.base > 0 && is.b.base < 31
206
		&& sim_exp (son (ke), e)) {
207
				/* the contents of req expression is here
208
				   as a reg-offset */
209
	      is.adval = 1;
210
	      setinsalt (aq, is);
211
	      return aq;
212
	    }
213
	  }
214
	}
215
	else
216
	  if (name (ke) == reff_tag && !isc) {
217
	    ans aq;
218
	    aq = regexps[i].inans;
219
	    if (aq.discrim == notinreg) {
220
	      instore is;
221
	      is = insalt (aq);
222
	      if (is.adval && is.b.offset == (no (ke) / 8)
223
		  && is.b.base > 0 && is.b.base < 31
224
		  && sim_exp (son (ke), e)) {
225
				/* a ref select of req expression is here
226
				   as a reg-offset */
227
		is.adval = 1;
228
		is.b.offset = 0;
229
		setinsalt (aq, is);
230
		return aq;
231
	      }
232
	    }
233
	  }
234
    }
235
  }
236
  return aa;
237
}
238
 
239
void keepexp
240
    PROTO_N ( (e, loc) )
241
    PROTO_T ( exp e X ans loc )
242
{	/* set up exp - address association */
243
  int   pos;
244
  switch (loc.discrim) {
245
    case insomereg:
246
    case insomefreg: {
247
	failer ("Keep ? reg");
248
      }
249
    case inreg:
250
      {
251
	pos = regalt (loc);
252
	break;
253
      }
254
    case infreg:
255
      {
256
	pos = fregalt (loc).fr + 32;
257
	break;
258
      }
259
    case notinreg:
260
      {
261
	pos = insalt (loc).b.base;
262
	if (pos < 0 || pos > 30)
263
	  return;
264
      }
265
 
266
  };
267
  if (pos==2 || pos == 32) return;
268
  regexps[pos].keptexp = e;
269
  regexps[pos].inans = loc;
270
  regexps[pos].iscont = 0;
271
}
272
 
273
void keepcont
274
    PROTO_N ( (e, reg) )
275
    PROTO_T ( exp e X int reg )
276
{/* set up cont(e)-reg association */
277
  freg fr;
278
  int   z = abs (reg);
279
  if (z==2|| z==32) return;
280
  if (z > 31) {
281
    fr.dble = (reg < 0);
282
    fr.fr = z - 32;
283
    setfregalt (regexps[z].inans, fr);
284
  }
285
  else {
286
    instore is;
287
    is.b.base = reg;
288
    is.b.offset = 0;
289
    is.adval = 1;
290
    setinsalt (regexps[z].inans, is);
291
  }
292
 
293
  regexps[z].keptexp = e;
294
 
295
  regexps[z].iscont = 1;
296
 
297
}
298
 
299
void keepreg
300
    PROTO_N ( (e, reg) )
301
    PROTO_T ( exp e X int reg )
302
{	/* set up e-reg association */
303
  freg fr;
304
  int   z = abs (reg);
305
  if (z==2 || z==32) return;
306
  if (z > 31) {
307
    fr.dble = (reg < 0);
308
    fr.fr = z - 32;
309
    setfregalt (regexps[z].inans, fr);
310
  }
311
  else {
312
    instore is;
313
    is.b.base = reg;
314
    is.b.offset = 0;
315
    is.adval = 1;
316
    setinsalt (regexps[z].inans, is);
317
  }
318
 
319
  regexps[z].keptexp = e;
320
  regexps[z].iscont = 0;
321
}
322
 
323
static bool couldeffect PROTO_S ((exp e, exp z, int count));
324
 
325
static bool couldbe
326
    PROTO_N ( (e, lhs, count) )
327
    PROTO_T ( exp e X exp lhs X int count )
328
{ /* could e be lhs? */
329
  int   ne = name (e);
330
  exp s = son (e);
331
 
332
  if (ne == name_tag) {
333
    if (lhs != 0 && s == son (lhs)) {
334
	return 1;
335
    }
336
    if (isvar (s)) {
337
      return (lhs == 0 && (isvis (s) || isglob(s)));
338
    }
339
    if (name (s) == proc_tag)
340
      return (lhs == 0);
341
    if (son (s) == nilexp)
342
      return 1;
343
    if (count > 5) return 1; /* pathological */
344
    return couldbe (son (s), lhs, count+1);
345
  }
346
  if (ne == cont_tag) {
347
    if (lhs != 0 && name (s) == name_tag && son (s) != nilexp) {
348
      return (son (s) == son (lhs) || isvis (son (lhs)) || isvis (son (s)));
349
    }
350
    return 1;
351
  }
352
  if (ne == reff_tag || ne == field_tag) {
353
    return couldbe (s, lhs, count);
354
  }
355
  if (ne == addptr_tag || ne == subptr_tag) {
356
    return (couldbe (s, lhs, count) || couldeffect (bro (s), lhs, count));
357
  }
358
 
359
  return 1;
360
 
361
}
362
 
363
static bool couldeffect
364
    PROTO_N ( (e, z, count) )
365
    PROTO_T ( exp e X exp z X int count )
366
{
367
				/* could alteration to z effect e? */
368
  int   ne = name (e);
369
  if (ne == cont_tag) {
370
    return couldbe (son (e), z, count);
371
  }
372
  if (ne == name_tag) {
373
    if (isvar (son (e)))
374
      return (z == 0 && isvis (son (e)));
375
    if (name (son (e)) == proc_tag)
376
      return 0;
377
    if (son (son (e)) == nilexp)
378
      return 1 /* could it happen? */ ;
379
    if (count > 5) return 1; /* pathological */
380
    return couldeffect (son (son (e)), z, count+1);
381
 
382
  }
383
  if (ne < plus_tag || ne == contvol_tag)
384
    return 1;
385
 
386
  e = son (e);
387
 
388
  while (e != nilexp) {
389
    if (couldeffect (e, z, count))
390
      return 1;
391
    if (last (e))
392
      return 0;
393
    e = bro (e);
394
  }
395
  return 0;
396
}
397
 
398
bool dependson
399
    PROTO_N ( (e, isc, z) )
400
    PROTO_T ( exp e X bool isc X exp z )
401
{/* does e depend on z */
402
  if (e == nilexp) {
403
    return 0;
404
  }
405
  for (;;) {
406
    if (name (z) == reff_tag || name (z) == addptr_tag ||
407
	name (z) == subptr_tag) {
408
      z = son (z);
409
    }
410
 
411
   if (name (z) != name_tag) {
412
    if (name (z) != cont_tag)
413
      return 1;
414
    z = 0;
415
    break;
416
   }
417
 
418
    if (isvar (son (z)))
419
      break;
420
    if (name (son (z)) == proc_tag) {
421
      z = 0;
422
      break;
423
    }
424
    if (son (son (z)) == nilexp)
425
      return 1;			/* can it happen? */
426
    z = son (son (z));
427
  }
428
 
429
  /* z is now unambiguous variable name or 0 meaning some contents */
430
 
431
  return ((isc) ? couldbe (e, z, 0) : couldeffect (e, z, 0));
432
}
433
 
434
 
435
 
436
 
437
 
438
void clear_dep_reg
439
    PROTO_N ( (lhs) )
440
    PROTO_T ( exp lhs )
441
{	/* remove association of any register
442
				   which depends on lhs */
443
  int   i;
444
  for (i = 0; i < 48; i++) {
445
    if (dependson (regexps[i].keptexp, regexps[i].iscont, lhs)) {
446
      regexps[i].keptexp = nilexp;
447
      setregalt (regexps[i].inans, 0);
448
    }
449
  }
450
}