Subversion Repositories tendra.SVN

Rev

Rev 5 | Details | Compare with Previous | Last modification | View Log | RSS feed

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