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-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 116... Line 146...
116
#define false 0
146
#define false 0
117
#define true  1
147
#define true  1
118
#define MAXUSE 16
148
#define MAXUSE 16
119
#define VERYBIGUSAGE 100
149
#define VERYBIGUSAGE 100
120
#define MEMINC 64
150
#define MEMINC 64
121
#define nilmem ((memlist *)0)
151
#define nilmem	((memlist *)0)
122
 
152
 
123
/* IDENTITIES */
153
/* IDENTITIES */
124
 
154
 
125
static maxconst self_const = {
155
static maxconst self_const = {
126
  true, nilexp
156
  true, nilexp
Line 157... Line 187...
157
static int has_lj_dest;
187
static int has_lj_dest;
158
 
188
 
159
 
189
 
160
/* PROCEDURES */
190
/* PROCEDURES */
161
 
191
 
162
exp get_repeats PROTO_S ((void));
192
exp get_repeats(void);
163
 
193
 
164
static int find_glob
194
static int
165
    PROTO_N ( (e) )
-
 
166
    PROTO_T ( exp e )
195
find_glob(exp e)
167
{
196
{
168
  int i;
197
  int i;
169
  for ( i = 0; i < glob_index; i++)
198
  for (i = 0; i < glob_index; i++)
170
    if (glob_dest[i] == e)
199
    if (glob_dest[i] == e)
171
      return 1;
200
      return 1;
172
  return 0;
201
  return 0;
173
}
202
}
174
 
203
 
175
/************************************************************************
204
/************************************************************************
176
 *  ret_constlist returns the elements of a constants-list
205
 *  ret_constlist returns the elements of a constants-list
177
 ************************************************************************/
206
 ************************************************************************/
-
 
207
static void ret_constlist(exp head);
178
 
208
 
179
void ret_constlist
209
void
180
    PROTO_N ( (head) )
-
 
181
    PROTO_T ( exp head )
210
ret_constlist(exp head)
182
{
211
{
183
  if (head != nilexp) {
212
  if (head != nilexp) {
184
    exp limit = pt (head), t = son (head), n;
213
    exp limit = pt(head), t = son(head), n;
185
    retcell (head);
214
    retcell(head);
186
    while (t != limit) {
215
    while (t != limit) {
187
      n = bro (t);
216
      n = bro(t);
188
      retcell (t);
217
      retcell(t);
189
      t = n;
218
      t = n;
190
    }
219
    }
191
    retcell (t);
220
    retcell(t);
192
  }
221
  }
193
  return;
222
  return;
194
}
223
}
195
 
224
 
196
static maxconst max_const PROTO_S ( ( exp, exp, int ) ) ;
225
static maxconst max_const(exp, exp, int);
197
/* declaration - max_const and mc_list are mutually recursive */
226
/* declaration - max_const and mc_list are mutually recursive */
198
 
227
 
199
 
228
 
200
 
229
 
201
/************************************************************************
230
/************************************************************************
Line 211... Line 240...
211
 *                variables
240
 *                variables
212
 *        good    if this is true AND all the expressions in the list are
241
 *        good    if this is true AND all the expressions in the list are
213
 *                constant then the value self_const is returned.
242
 *                constant then the value self_const is returned.
214
 ************************************************************************/
243
 ************************************************************************/
215
 
244
 
216
static maxconst mc_list
245
static
217
    PROTO_N ( (whole, e, ass_ok, good) )
-
 
218
    PROTO_T ( exp whole X exp e X int ass_ok X int good )
246
maxconst mc_list(exp whole, exp e, int ass_ok, int good)
219
{
247
{
220
  exp t = e;
248
  exp t = e;
221
  int contin = true;
249
  int contin = true;
222
  maxconst mc, result;
250
  maxconst mc, result;
223
 
251
 
Line 225... Line 253...
225
  result.cont = nilexp;
253
  result.cont = nilexp;
226
 
254
 
227
  do {
255
  do {
228
    /* NB - t may be killed within max_const (offset_mult) */
256
    /* NB - t may be killed within max_const (offset_mult) */
229
    /* so remember next one in list */
257
    /* so remember next one in list */
230
    exp next_t = bro (t);
258
    exp next_t = bro(t);
231
    if (last (t))
259
    if (last(t)) {
232
      contin = false;
260
      contin = false;
-
 
261
    }
233
    mc = max_const (whole, t, ass_ok);
262
    mc = max_const(whole, t, ass_ok);
234
 
263
 
235
    if (mc.self) {
264
    if (mc.self) {
236
      /* the whole of t is constant */
265
      /* the whole of t is constant */
237
      /* make a list element */
266
      /* make a list element */
238
      exp w = getexp (f_bottom, nilexp, false, t, nilexp, cond_flag,
267
      exp w = getexp(f_bottom, nilexp, false, t, nilexp, cond_flag,
239
		       0, 0);
268
		       0, 0);
240
      if (result.cont == nilexp)/* first item - start a list */
269
      if (result.cont == nilexp) {/* first item - start a list */
241
	result.cont = getexp (f_bottom, nilexp, false, w, w, 0,  0, 0);
270
	result.cont = getexp(f_bottom, nilexp, false, w, w, 0,  0, 0);
242
      else {			/* add this to list */
271
      } else {			/* add this to list */
243
	bro (pt (result.cont)) = w;
272
	bro(pt(result.cont)) = w;
244
	pt (result.cont) = w;
273
	pt(result.cont) = w;
245
      }
274
      }
246
    } else {
275
    } else {
247
      result.self = false;	/* some part of e is not constant */
276
      result.self = false;	/* some part of e is not constant */
248
      if (mc.cont != nilexp) {	/* but t has constants in it */
277
      if (mc.cont != nilexp) {	/* but t has constants in it */
249
	if (result.cont != nilexp) {	/* add them to list */
278
	if (result.cont != nilexp) {	/* add them to list */
250
	  bro (pt (result.cont)) = son (mc.cont);
279
	  bro(pt(result.cont)) = son(mc.cont);
251
	  pt (result.cont) = pt (mc.cont);
280
	  pt(result.cont) = pt(mc.cont);
252
	  retcell (mc.cont);
281
	  retcell(mc.cont);
253
	} else			/* list was empty - start list */
282
	} else {		/* list was empty - start list */
254
	  result.cont = mc.cont;
283
	  result.cont = mc.cont;
-
 
284
	}
255
      }
285
      }
256
    }
286
    }
257
 
287
 
258
    t = next_t;
288
    t = next_t;
259
  }
-
 
260
  while (contin);
289
  } while (contin);
261
 
290
 
262
  if (result.self) {
291
  if (result.self) {
263
    ret_constlist (result.cont);
292
    ret_constlist(result.cont);
264
    return (self_const);
293
    return(self_const);
265
  }
294
  }
266
  return result;
295
  return result;
267
}
296
}
268
 
297
 
269
 
298
 
270
/************************************************************************
299
/************************************************************************
271
 *  intnl_to returns true if part is contained in whole
300
 *  intnl_to returns true if part is contained in whole
272
 ************************************************************************/
301
 ************************************************************************/
273
 
302
 
274
int intnl_to
303
int
275
    PROTO_N ( (whole, part) )
-
 
276
    PROTO_T ( exp whole X exp part )
304
intnl_to(exp whole, exp part)
277
{
305
{
278
  exp q = part;
306
  exp q = part;
279
 
307
 
280
  while (q != whole && q != nilexp && name(q) != hold_tag
308
  while (q != whole && q != nilexp && name(q) != hold_tag &&
281
		&& name(q) != hold2_tag &&
-
 
282
	 (name (q) != ident_tag || !isglob (q)))
309
	 name(q) != hold2_tag && (name(q) != ident_tag || !isglob(q))) {
283
    q = father (q);
310
    q = father(q);
-
 
311
  }
284
 
312
 
285
  return q == whole;
313
  return q == whole;
286
}
314
}
287
 
315
 
288
/* heavily used idents are kept in lookup list */
316
/* heavily used idents are kept in lookup list */
289
 
317
 
290
static int not_assigned_to PROTO_S ( ( exp, exp ) ) ;
318
static int not_assigned_to(exp, exp);
291
 
319
 
292
static int not_ass2
320
static int
293
    PROTO_N ( (vardec, piece) )
-
 
294
    PROTO_T ( exp vardec X exp piece )
321
not_ass2(exp vardec, exp piece)
295
{
322
{
296
  /*
323
  /*
297
   * this replaces used_in with stronger test - see changes in assigns_alias
324
   * this replaces used_in with stronger test - see changes in assigns_alias
298
   */
325
   */
299
  exp t = pt (vardec);
326
  exp t = pt(vardec);
300
  exp q;
327
  exp q;
301
  exp upwards = t;
328
  exp upwards = t;
302
 
329
 
303
  do {				/* test each use of the identifier */
330
  do {				/* test each use of the identifier */
304
    q = t;
331
    q = t;
305
    while (q != nilexp && q != piece && q != vardec &&
332
    while (q != nilexp && q != piece && q != vardec &&
306
	   name (q) != rep_tag &&
-
 
307
	   (name (q) != ident_tag || !isglob (q))) {
333
	   name(q) != rep_tag && (name(q) != ident_tag || !isglob(q))) {
308
      upwards = q;
334
      upwards = q;
309
      q = bro (q);
335
      q = bro(q);
310
    }
336
    }
311
 
337
 
312
    if (q != nilexp && q != piece && name (q) == rep_tag) {
338
    if (q != nilexp && q != piece && name(q) == rep_tag) {
313
      /* q has got to a repeat, so */
339
      /* q has got to a repeat, so */
314
      /* scan up repeat_list structure for holder of piece */
340
      /* scan up repeat_list structure for holder of piece */
315
      exp h = pt (q), hp = pt (piece);
341
      exp h = pt(q), hp = pt(piece);
316
      while (h != nilexp && h != hp)
342
      while (h != nilexp && h != hp) {
317
	h = bro (h);
343
	h = bro(h);
-
 
344
      }
318
      if (h == hp) {
345
      if (h == hp) {
319
	/* q was within piece */
346
	/* q was within piece */
320
	q = piece;
347
	q = piece;
321
	upwards = son (q);
348
	upwards = son(q);
322
	while (!last (upwards))
349
	while (!last(upwards)) {
323
	  upwards = bro (upwards);
350
	  upwards = bro(upwards);
-
 
351
	}
324
      } else
352
      } else {
325
	q = nilexp;
353
	q = nilexp;
-
 
354
      }
326
    }
355
    }
327
    /* ascend from the use until we reach either vardec or piece */
356
    /* ascend from the use until we reach either vardec or piece */
328
    if (q == piece && last (upwards)) {	/* the use was in piece */
357
    if (q == piece && last (upwards)) {	/* the use was in piece */
329
      if (isreallyass(t))
358
      if (isreallyass(t)) {
330
        return false;
359
        return false;
-
 
360
      }
331
      if (!last (t) && last (bro (t)) &&
361
      if (!last(t) && last(bro(t)) &&
332
	  (name (bro (bro (t))) == ass_tag ||
-
 
333
	   name (bro (bro (t))) == assvol_tag))
362
	(name(bro(bro(t))) == ass_tag || name(bro(bro(t))) == assvol_tag)) {
334
	return false;		/* the use was an assignment */
363
	return false;		/* the use was an assignment */
335
      if (!last (t) && last (bro (t))
364
      }
336
	  && name (bro (bro (t))) == ident_tag) {
365
      if (!last(t) && last(bro(t)) && name(bro(bro(t))) == ident_tag) {
337
	/* use in declaration */
366
	/* use in declaration */
338
	if (!isvar (bro (bro (t))) &&
-
 
339
	    !not_assigned_to (bro (bro (t)), bro (t))) {
367
	if (!isvar(bro(bro(t))) && !not_assigned_to(bro(bro(t)), bro(t))) {
340
	  return false;
368
	  return false;
341
	}
369
	}
342
      } else {
370
      } else {
343
	exp dad = father (t);
371
	exp dad = father(t);
344
	if (name (dad) == addptr_tag && son (dad) == t) {
372
	if (name(dad) == addptr_tag && son(dad) == t) {
345
	  /* use in subscript .... */
373
	  /* use in subscript .... */
346
	  if (!last (dad) && last (bro (dad)) &&
374
	  if (!last(dad) && last(bro(dad)) &&
347
	       (name (bro (bro (dad))) == ass_tag ||
375
	     (name(bro(bro(dad))) == ass_tag ||
348
	         name (bro (bro (dad))) == assvol_tag))
376
	       name(bro(bro(dad))) == assvol_tag)) {
349
	    return false;		/* the use was an assignment */
377
	    return false;		/* the use was an assignment */
-
 
378
	  }
350
	  if (!last (dad) && last (bro (dad)) &&
379
	  if (!last(dad) && last(bro(dad)) &&
351
	      name (bro (bro (dad))) == ident_tag) {
380
	      name(bro(bro(dad))) == ident_tag) {
352
	    /* ... which is identified */
381
	    /* ... which is identified */
353
	    if (!isvar (bro (bro (dad))) &&
382
	    if (!isvar(bro(bro(dad))) &&
354
		!not_assigned_to (bro (bro (dad)), bro (dad))) {
383
		!not_assigned_to(bro(bro(dad)), bro(dad))) {
355
	      return false;
384
	      return false;
356
	    }
385
	    }
357
	  }
386
	  }
358
	}
387
	}
359
      }
388
      }
360
    }
389
    }
361
    t = pt (t);
390
    t = pt(t);
362
  } while (t != nilexp);
391
  } while (t != nilexp);
363
  return true;
392
  return true;
364
}
393
}
365
 
394
 
366
 
395
 
367
static int not_assigned_to
396
static int
368
    PROTO_N ( (vardec, body) )
-
 
369
    PROTO_T ( exp vardec X exp body )
397
not_assigned_to(exp vardec, exp body)
370
{
398
{
371
  if (no (vardec) > VERYBIGUSAGE)
399
  if (no(vardec) > VERYBIGUSAGE) {
372
    return false;
400
    return false;
-
 
401
  }
373
 
402
 
374
  if (no (vardec) > MAXUSE) {
403
  if (no(vardec) > MAXUSE) {
375
    /* when a variable is used many times the result from not_ass2 */
404
    /* when a variable is used many times the result from not_ass2 */
376
    /* is saved in an ordered list to avoid n-squared run-times    */
405
    /* is saved in an ordered list to avoid n-squared run-times    */
377
    memlist *ptr = mem;
406
    memlist *ptr = mem;
378
    /* is this declaration known? */
407
    /* is this declaration known? */
379
    /* NOTE: memory is cleared after each repeat is processed */
408
    /* NOTE: memory is cleared after each repeat is processed */
Line 381... Line 410...
381
    while (ptr != nilmem && (ptr->dec) != vardec)
410
    while (ptr != nilmem && (ptr->dec) != vardec)
382
      ptr = ptr->next;
411
      ptr = ptr->next;
383
    if (ptr == nilmem) {
412
    if (ptr == nilmem) {
384
      memlist **pp = &mem;
413
      memlist **pp = &mem;
385
      /* insert with heavier used decs first */
414
      /* insert with heavier used decs first */
386
      while (*pp != nilmem && no ((*pp)->dec) > no (vardec))
415
      while (*pp != nilmem && no((*pp) ->dec) > no(vardec)) {
387
	pp = &((*pp)->next);
416
	pp = & ((*pp) ->next);
-
 
417
      }
388
      if (fmem == nilmem) {
418
      if (fmem == nilmem) {
389
	/* add some cells onto the free list */
419
	/* add some cells onto the free list */
390
	memlist **fpp = &fmem;
420
	memlist **fpp = &fmem;
391
	int i;
421
	int i;
392
	*fpp = (memlist *) xcalloc (MEMINC, sizeof (memlist));
422
	*fpp = (memlist *)xcalloc(MEMINC, sizeof(memlist));
393
	for (i = 0; i < MEMINC; ++i) {
423
	for (i = 0; i < MEMINC; ++i) {
394
	  (*fpp)->next = (*fpp) + 1;
424
	 (*fpp) ->next = (*fpp) + 1;
395
	  fpp = &((*fpp)->next);
425
	  fpp = & ((*fpp) ->next);
396
	}
426
	}
397
	*fpp = nilmem;
427
	*fpp = nilmem;
398
      }
428
      }
399
      /* get a cell from the free list */
429
      /* get a cell from the free list */
400
      ptr = fmem;
430
      ptr = fmem;
401
      fmem = ptr->next;
431
      fmem = ptr->next;
402
      /* remember this vardec */
432
      /* remember this vardec */
403
      ptr->dec = vardec;
433
      ptr->dec = vardec;
404
      ptr->res = not_ass2 (vardec, body);
434
      ptr->res = not_ass2(vardec, body);
405
      /* put cell into mem list */
435
      /* put cell into mem list */
406
      ptr->next = *pp;
436
      ptr->next = *pp;
407
      *pp = ptr;
437
      *pp = ptr;
408
    }
438
    }
409
    return (ptr->res);
439
    return(ptr->res);
410
  } else
440
  } else {
411
    /* default case - identifier not heavily used */
441
    /* default case - identifier not heavily used */
412
    return (not_ass2 (vardec, body));
442
    return(not_ass2(vardec, body));
-
 
443
  }
413
}
444
}
414
 
445
 
415
 
446
 
416
 
447
 
417
/************************************************************************
448
/************************************************************************
Line 423... Line 454...
423
 *        e       the expression under consideration
454
 *        e       the expression under consideration
424
 *        ass_ok  all assignments in this region are to simple unaliassed
455
 *        ass_ok  all assignments in this region are to simple unaliassed
425
 *                variables
456
 *                variables
426
 ************************************************************************/
457
 ************************************************************************/
427
 
458
 
428
static maxconst max_const
459
static maxconst
429
    PROTO_N ( (whole, e, ass_ok) )
-
 
430
    PROTO_T ( exp whole X exp e X int ass_ok )
460
max_const(exp whole, exp e, int ass_ok)
431
{
461
{
432
  switch (name (e)) {
462
  switch (name(e)) {
433
  case labst_tag:
463
  case labst_tag:
434
    return mc_list (whole, bro (son (e)), ass_ok, false);
464
    return mc_list(whole, bro(son(e)), ass_ok, false);
435
 
465
 
436
  case contvol_tag:
466
  case contvol_tag:
437
  case case_tag:
467
  case case_tag:
438
  case goto_tag:
468
  case goto_tag:
439
  case apply_general_tag:
469
  case apply_general_tag:
Line 442... Line 472...
442
 
472
 
443
  case fdiv_tag: {
473
  case fdiv_tag: {
444
    maxconst mc;
474
    maxconst mc;
445
    maxconst mct;
475
    maxconst mct;
446
    mc = max_const(whole, bro(son(e)), ass_ok);
476
    mc = max_const(whole, bro(son(e)), ass_ok);
447
    mct = mc_list (whole, son (e), ass_ok, optop(e));
477
    mct = mc_list(whole, son(e), ass_ok, optop(e));
448
    if (mct.self)
478
    if (mct.self) {
449
      return mct;
479
      return mct;
-
 
480
    }
450
 
481
 
451
    if (mc.self && !strict_fl_div && optop(e)) {
482
    if (mc.self && !strict_fl_div && optop(e)) {
452
      flpt f = new_flpt();
483
      flpt f = new_flpt();
453
      exp funit;
484
      exp funit;
454
      exp temp1;
485
      exp temp1;
455
      exp temp2;
486
      exp temp2;
456
      flt_copy (flptnos[fone_no], &flptnos[f]);
487
      flt_copy(flptnos[fone_no], &flptnos[f]);
457
      funit = getexp(sh(e), nilexp, 0, nilexp, nilexp,
488
      funit = getexp(sh(e), nilexp, 0, nilexp, nilexp, 0, f, real_tag);
458
			0, f, real_tag);
-
 
459
      temp1 = me_b3(sh(e), funit, bro(son(e)), fdiv_tag);
489
      temp1 = me_b3(sh(e), funit, bro(son(e)), fdiv_tag);
460
      temp2 = me_b3(sh(e), son(e), temp1, fmult_tag);
490
      temp2 = me_b3(sh(e), son(e), temp1, fmult_tag);
461
 
491
 
462
#ifdef NEWDIAGS
492
#ifdef NEWDIAGS
463
      dgf(temp2) = dgf(e);
493
      dgf(temp2) = dgf(e);
464
#endif
494
#endif
465
      replace(e, temp2, temp2);
495
      replace(e, temp2, temp2);
466
      return max_const(whole, temp2, ass_ok);
496
      return max_const(whole, temp2, ass_ok);
467
    }
-
 
468
    else
497
    } else {
469
      return mct;
498
      return mct;
-
 
499
    }
470
  };
500
  }
471
 
501
 
472
 
502
 
473
  case cond_tag:{
503
  case cond_tag: {
474
      prop old_cond_flag = cond_flag;
504
      prop old_cond_flag = cond_flag;
475
      maxconst mc;
505
      maxconst mc;
476
      if (cond_flag == 0)
506
      if (cond_flag == 0) {
477
	cond_flag = 1;
507
	cond_flag = 1;
-
 
508
      }
478
      mc = mc_list (whole, son (e), ass_ok, false);
509
      mc = mc_list(whole, son(e), ass_ok, false);
479
      cond_flag = old_cond_flag;
510
      cond_flag = old_cond_flag;
480
      return mc;
511
      return mc;
481
    }
512
  }
482
 
513
 
483
  case test_tag:{
514
  case test_tag:{
484
      maxconst mc;
515
      maxconst mc;
485
      mc = mc_list (whole, son (e), ass_ok, false);
516
      mc = mc_list(whole, son(e), ass_ok, false);
486
      if (cond_flag == 1)
517
      if (cond_flag == 1) {
487
	cond_flag = 2;
518
	cond_flag = 2;
-
 
519
      }
488
      return mc;
520
      return mc;
489
    }
521
  }
490
 
522
 
491
  case val_tag:
523
  case val_tag:
492
  case proc_tag:
524
  case proc_tag:
493
  case env_offset_tag:
525
  case env_offset_tag:
494
  case general_env_offset_tag:
526
  case general_env_offset_tag:
495
    return self_const;
527
    return self_const;
496
 
528
 
497
  case name_tag:
529
  case name_tag:
498
    if (intnl_to (whole, son (e)))
530
    if (intnl_to(whole, son(e))) {
499
      return no_consts;		/* internal const - may change */
531
      return no_consts;		/* internal const - may change */
500
    else
532
    } else {
501
      return self_const;	/* external constant */
533
      return self_const;	/* external constant */
-
 
534
    }
502
 
535
 
503
  case cont_tag:
536
  case cont_tag:
504
    if ((name (son (e)) == name_tag) && isvar (son (son (e)))) {
537
    if ((name(son(e)) == name_tag) && isvar(son(son(e)))) {
505
      /* so e is extracting the contents of a variable */
538
      /* so e is extracting the contents of a variable */
506
      exp var = son (son (e));
539
      exp var = son(son(e));
507
 
540
 
508
      if (!intnl_to (whole, var) && (not_assigned_to (var, whole))
541
      if (!intnl_to(whole, var) && (not_assigned_to(var, whole))
509
	  && ass_ok) {
542
	  && ass_ok) {
510
	/*
543
	/*
511
	 * variable declared external to whole, and NEVER assigned to in
544
	 * variable declared external to whole, and NEVER assigned to in
512
	 * whole
545
	 * whole
513
	 */
546
	 */
514
	if (iscaonly(var))
547
	if (iscaonly(var)) {
-
 
548
	  return self_const;
-
 
549
	}
-
 
550
	if (isglob(var) && !find_glob(var)) {
515
	  return self_const;
551
	  return self_const;
516
	if (isglob(var) && !find_glob(var))
-
 
517
	  return self_const;
-
 
518
	return no_consts;
-
 
519
	}
552
	}
520
      else
-
 
521
	return no_consts;
553
	return no_consts;
-
 
554
      } else {
-
 
555
	return no_consts;
-
 
556
      }
522
    } else
557
    } else {
523
      return mc_list (whole, son (e), ass_ok, ass_ok);
558
      return mc_list(whole, son(e), ass_ok, ass_ok);
-
 
559
    }
524
 
560
 
525
  case plus_tag:
561
  case plus_tag:
526
  case and_tag:
562
  case and_tag:
527
  case or_tag:
563
  case or_tag:
528
  case xor_tag:
564
  case xor_tag:
529
  case mult_tag:{
565
  case mult_tag: {
530
      maxconst mc;
566
      maxconst mc;
531
 
567
 
532
      mc = mc_list (whole, son (e), ass_ok, optop(e));
568
      mc = mc_list(whole, son(e), ass_ok, optop(e));
533
 
569
 
534
      if (mc.cont != nilexp && pt (mc.cont) != son (mc.cont) && optop(e)) {
570
      if (mc.cont != nilexp && pt(mc.cont) != son(mc.cont) && optop(e)) {
535
	/* more than 1 item in list */
571
	/* more than 1 item in list */
536
	exp limit = pt (mc.cont), h = son (mc.cont), arg, this, last_h;
572
	exp limit = pt(mc.cont), h = son(mc.cont), arg, this, last_h;
537
	int arg_count = 0;
573
	int arg_count = 0;
538
	int tot_args = 1;
574
	int tot_args = 1;
539
	this = son(e);
575
	this = son(e);
540
	while(!last(this)) {
576
	while (!last(this)) {
541
	  this = bro(this);
577
	  this = bro(this);
542
	  ++tot_args;
578
	  ++tot_args;
543
	};
579
	}
544
 
580
 
545
	/* remember for which operator these are arguments */
581
	/* remember for which operator these are arguments */
546
	/* NB - some items may not be args of this operator */
582
	/* NB - some items may not be args of this operator */
547
	while (h != nilexp) {
583
	while (h != nilexp) {
548
	  this = son (h);
584
	  this = son(h);
549
	  arg = son (e);
585
	  arg = son(e);
550
	  while (arg != nilexp && arg != this)
586
	  while (arg != nilexp && arg != this) {
551
	    arg = (last (arg) ? nilexp : bro (arg));
587
	    arg = (last(arg)? nilexp : bro(arg));
-
 
588
	  }
552
	  if (arg != nilexp) {
589
	  if (arg != nilexp) {
553
	    /* it's an argument of this operator */
590
	    /* it's an argument of this operator */
554
	    ++arg_count;
591
	    ++arg_count;
555
	    pt (h) = e;
592
	    pt(h) = e;
556
	    last_h = h;
593
	    last_h = h;
557
	  }
594
	  }
558
	  h = (h == limit ? nilexp : bro (h));
595
	  h = (h == limit ? nilexp : bro(h));
559
	}
596
	}
560
	/* remove reference to operator if only 1 arg is const */
597
	/* remove reference to operator if only 1 arg is const */
561
	if (arg_count != tot_args && arg_count > 0) {
598
	if (arg_count != tot_args && arg_count > 0) {
562
	  SET(last_h);
599
	  SET(last_h);
563
	  pt (last_h) = nilexp;
600
	  pt(last_h) = nilexp;
564
	};
601
	}
565
      }
602
      }
566
      return mc;
603
      return mc;
567
    }
604
  }
568
 
605
 
569
  case addptr_tag:{
606
  case addptr_tag: {
570
      exp p = son (e);
607
      exp p = son(e);
571
      maxconst mc, mx;
608
      maxconst mc, mx;
572
 
609
 
573
      /* find the root pointer */
610
      /* find the root pointer */
574
      while (name (p) == addptr_tag)
611
      while (name(p) == addptr_tag) {
575
	p = son (p);
612
	p = son(p);
-
 
613
      }
576
 
614
 
577
      mc = max_const (whole, p, ass_ok);
615
      mc = max_const(whole, p, ass_ok);
578
      ret_constlist (mc.cont);
616
      ret_constlist(mc.cont);
579
 
617
 
580
      if (mc.self) {
618
      if (mc.self) {
581
	/* root pointer is constant in this context */
619
	/* root pointer is constant in this context */
582
	exp c_list = nilexp, v_list = nilexp, x, cph, *list;
620
	exp c_list = nilexp, v_list = nilexp, x, cph, *list;
583
 
621
 
584
	/* construct list of ALL constant parts */
622
	/* construct list of ALL constant parts */
585
	/* initial list element will hold const. ptr */
623
	/* initial list element will hold const. ptr */
586
	cph = getexp (f_bottom, nilexp, false, nilexp, nilexp,
624
	cph = getexp(f_bottom, nilexp, false, nilexp, nilexp,
587
		      0,  0, 0);
625
		      0,  0, 0);
588
	mc.self = false;	/* assume, for moment */
626
	mc.self = false;	/* assume, for moment */
589
	mc.cont = getexp (f_bottom, nilexp, false, cph, cph,
627
	mc.cont = getexp(f_bottom, nilexp, false, cph, cph,
590
			  0,  0, 0);
628
			  0,  0, 0);
591
 
629
 
592
	/* return up the chain, testing the offsets */
630
	/* return up the chain, testing the offsets */
593
	while (p != e) {
631
	while (p != e) {
594
	  mx = max_const (whole, bro (p), ass_ok);
632
	  mx = max_const(whole, bro(p), ass_ok);
595
	  p = bro (p);		/* p is now the offset */
633
	  p = bro(p);		/* p is now the offset */
596
 
634
 
597
	  /* add offset to appropriate list */
635
	  /* add offset to appropriate list */
598
	  list = (mx.self) ? &c_list : &v_list;
636
	  list = (mx.self)? &c_list : &v_list;
599
	  *list = getexp (nilexp, *list, 0, p, nilexp, 0,  0, 0);
637
	  *list = getexp(nilexp, *list, 0, p, nilexp, 0,  0, 0);
600
 
638
 
601
	  if (mx.cont != nilexp) {
639
	  if (mx.cont != nilexp) {
602
	    /* the offset is not constant, but PARTS of it are */
640
	    /* the offset is not constant, but PARTS of it are */
603
 
641
 
604
	    /* remove any "negate(name(...))" */
642
	    /* remove any "negate(name(...))" */
605
	    exp lim = pt (mx.cont), h = son (mx.cont);
643
	    exp lim = pt(mx.cont), h = son(mx.cont);
606
	    while (h != nilexp) {
644
	    while (h != nilexp) {
607
	      if (name (son (h)) == neg_tag &&
645
	      if (name(son(h)) == neg_tag && name(son(son(h))) == name_tag) {
608
		  name (son (son (h))) == name_tag)
-
 
609
		no (h) = -1;	/* set "done" flag */
646
		no(h) = -1;	/* set "done" flag */
-
 
647
	      }
610
	      h = (h == lim ? nilexp : bro (h));
648
	      h = (h == lim ? nilexp : bro(h));
611
	    }
649
	    }
612
 
650
 
613
	    /* add constant parts to mc */
651
	    /* add constant parts to mc */
614
	    bro (pt (mx.cont)) = son (mc.cont);
652
	    bro(pt(mx.cont)) = son(mc.cont);
615
	    son (mc.cont) = son (mx.cont);
653
	    son(mc.cont) = son(mx.cont);
616
	    retcell (mx.cont);
654
	    retcell(mx.cont);
617
	  }
655
	  }
618
	  p = bro (p);		/* p is now the next higher operation */
656
	  p = bro(p);		/* p is now the next higher operation */
619
	}
657
	}
620
 
658
 
621
	if (v_list == nilexp) {
659
	if (v_list == nilexp) {
622
	  /* whole addptr expression is constant */
660
	  /* whole addptr expression is constant */
623
	  /* return c_list elements */
661
	  /* return c_list elements */
624
	  while (c_list != nilexp) {
662
	  while (c_list != nilexp) {
625
	    x = c_list;
663
	    x = c_list;
626
	    c_list = bro (c_list);
664
	    c_list = bro(c_list);
627
	    retcell (x);
665
	    retcell(x);
628
	  }
666
	  }
629
 
667
 
630
	  ret_constlist (mc.cont);
668
	  ret_constlist(mc.cont);
631
 
669
 
632
	  return self_const;
670
	  return self_const;
633
	}
671
	}
634
	/* go down the chain of addptrs, rearranging offsets */
672
	/* go down the chain of addptrs, rearranging offsets */
635
	/* NB - assumes addptr is strictly diadic, so "last" */
673
	/* NB - assumes addptr is strictly diadic, so "last" */
636
	/* flags are already correct		       */
674
	/* flags are already correct		       */
637
 
675
 
638
	/* put non-constant offsets at the higher levels */
676
	/* put non-constant offsets at the higher levels */
639
	while (v_list != nilexp) {
677
	while (v_list != nilexp) {
640
	  /* put next offset in 2nd argument position */
678
	  /* put next offset in 2nd argument position */
641
	  x = son (p);
679
	  x = son(p);
642
	  bro (x) = son (v_list);
680
	  bro(x) = son(v_list);
643
	  bro (bro (x)) = p;
681
	  bro(bro(x)) = p;
644
	  p = x;		/* point to 1st argument */
682
	  p = x;		/* point to 1st argument */
645
	  /* traverse v_list, returning elements */
683
	  /* traverse v_list, returning elements */
646
	  x = v_list;
684
	  x = v_list;
647
	  v_list = bro (x);
685
	  v_list = bro(x);
648
	  retcell (x);
686
	  retcell(x);
649
	}
687
	}
650
 
688
 
651
	/* the rest is constant - add it to mc.cont */
689
	/* the rest is constant - add it to mc.cont */
652
	son (cph) = p;
690
	son(cph) = p;
653
 
691
 
654
	/* and put constant offsets at the lower levels */
692
	/* and put constant offsets at the lower levels */
655
	while (c_list != nilexp) {
693
	while (c_list != nilexp) {
656
	  /* put next offset in 2nd argument position */
694
	  /* put next offset in 2nd argument position */
657
	  x = son (p);
695
	  x = son(p);
658
	  bro (x) = son (c_list);
696
	  bro(x) = son(c_list);
659
	  bro (bro (x)) = p;
697
	  bro(bro(x)) = p;
660
	  p = x;		/* point to 1st argument */
698
	  p = x;		/* point to 1st argument */
661
	  /* traverse c_list, returning elements */
699
	  /* traverse c_list, returning elements */
662
	  x = c_list;
700
	  x = c_list;
663
	  c_list = bro (x);
701
	  c_list = bro(x);
664
	  retcell (x);
702
	  retcell(x);
665
	}
703
	}
666
 
704
 
667
	return mc;
705
	return mc;
668
      } else
706
      } else {
669
	return mc_list (whole, son (e), ass_ok, true);
707
	return mc_list(whole, son(e), ass_ok, true);
670
    }
708
      }
-
 
709
  }
671
 
710
 
672
  case offset_mult_tag:{
711
  case offset_mult_tag: {
673
      exp arg1 = son (e);
712
      exp arg1 = son(e);
674
      exp arg2 = bro (arg1);
713
      exp arg2 = bro(arg1);
675
      maxconst mc1, mc2;
714
      maxconst mc1, mc2;
676
      shape ofsh = sh (e);
715
      shape ofsh = sh(e);
677
      mc1 = max_const (whole, arg1, ass_ok);
716
      mc1 = max_const(whole, arg1, ass_ok);
678
      mc2 = max_const (whole, arg2, ass_ok);
717
      mc2 = max_const(whole, arg2, ass_ok);
679
      if (mc1.self && mc2.self)
718
      if (mc1.self && mc2.self) {
680
	return self_const;
719
	return self_const;
-
 
720
      }
681
      if (mc2.self && mc1.cont != nilexp) {
721
      if (mc2.self && mc1.cont != nilexp) {
682
	/**********************************************************
722
	/**********************************************************
683
         * the offset is const, and arg1 has some constant parts
723
         * the offset is const, and arg1 has some constant parts
684
         * so transform:
724
         * so transform:
685
         *   offset_mult((a*b),K)
725
         *   offset_mult((a*b),K)
Line 691... Line 731...
691
         *********************************************************/
731
         *********************************************************/
692
	exp klist = nilexp, nklist = nilexp;
732
	exp klist = nilexp, nklist = nilexp;
693
	exp *ref;
733
	exp *ref;
694
	exp m_res;
734
	exp m_res;
695
	int j;
735
	int j;
696
	ret_constlist (mc1.cont);
736
	ret_constlist(mc1.cont);
697
	if (name (arg1) == mult_tag) {
737
	if (name(arg1) == mult_tag) {
698
	  exp m_arg = son (arg1);
738
	  exp m_arg = son(arg1);
699
	  /* sort into const and varying args */
739
	  /* sort into const and varying args */
700
	  while (m_arg != nilexp) {
740
	  while (m_arg != nilexp) {
701
	    mc1 = max_const (whole, m_arg, ass_ok);
741
	    mc1 = max_const(whole, m_arg, ass_ok);
702
	    if (mc1.self) {
742
	    if (mc1.self) {
703
	      /* add to constant operand list */
743
	      /* add to constant operand list */
704
	      klist = getexp (nilexp, klist, false, m_arg, nilexp,
744
	      klist = getexp(nilexp, klist, false, m_arg, nilexp,
705
			      0,  0, 0);
745
			      0,  0, 0);
706
	    } else {
746
	    } else {
707
	      /* add to non-constant operand list */
747
	      /* add to non-constant operand list */
708
	      nklist = getexp (nilexp, nklist, false, m_arg, nilexp,
748
	      nklist = getexp(nilexp, nklist, false, m_arg, nilexp,
709
			       0,  0, 0);
749
			       0,  0, 0);
710
	      ret_constlist (mc1.cont);
750
	      ret_constlist(mc1.cont);
711
	    }
751
	    }
712
	    if (last (m_arg))
752
	    if (last(m_arg)) {
713
	      m_arg = nilexp;
753
	      m_arg = nilexp;
714
	    else
754
	    } else {
715
	      m_arg = bro (m_arg);
755
	      m_arg = bro(m_arg);
-
 
756
	    }
716
	  }
757
	  }
717
	  /* build offset_mult chain with const parts innermost */
758
	  /* build offset_mult chain with const parts innermost */
718
	  m_res = copy (arg2);
759
	  m_res = copy(arg2);
719
	  for (j = 0; j < 2; ++j) {
760
	  for (j = 0; j < 2; ++j) {
720
	    exp *list = (j == 0) ? &klist : &nklist;
761
	    exp *list = (j == 0)? &klist : &nklist;
721
	    /* use klist, and then nklist */
762
	    /* use klist, and then nklist */
722
	    while (*list != nilexp) {
763
	    while (*list != nilexp) {
723
	      exp z = *list;
764
	      exp z = *list;
724
	      exp a1 = copy (son (z));
765
	      exp a1 = copy(son(z));
725
	      exp offmul = getexp (ofsh, nilexp, false, a1, nilexp,
766
	      exp offmul = getexp(ofsh, nilexp, false, a1, nilexp,
726
				   0,  0, offset_mult_tag);
767
				   0,  0, offset_mult_tag);
727
	      setbro (a1, m_res);
768
	      setbro(a1, m_res);
728
	      clearlast (a1);
769
	      clearlast(a1);
729
	      setbro (m_res, offmul);
770
	      setbro(m_res, offmul);
730
	      setlast (m_res);
771
	      setlast(m_res);
731
	      m_res = hold_check(offmul);
772
	      m_res = hold_check(offmul);
732
	      *list = bro (z);
773
	      *list = bro(z);
733
	      retcell (z);
774
	      retcell(z);
734
	    }
775
	    }
735
	  }
776
	  }
736
	  /* insert m_res - kill left overs */
777
	  /* insert m_res - kill left overs */
737
	  ref = refto (father (e), e);
778
	  ref = refto(father(e), e);
738
	  if (last (*ref))
779
	  if (last(*ref)) {
739
	    setlast (m_res);
780
	    setlast(m_res);
740
	  else
781
	  } else {
741
	    clearlast (m_res);
782
	    clearlast(m_res);
-
 
783
	  }
742
	  bro (m_res) = bro (*ref);
784
	  bro(m_res) = bro(*ref);
743
	  *ref = m_res;
785
	  *ref = m_res;
744
	  kill_exp (e, e);
786
	  kill_exp(e, e);
745
	} else
787
	} else {
746
	  m_res = e;
788
	  m_res = e;
-
 
789
	}
747
	return mc_list (whole, son (m_res), ass_ok, true);
790
	return mc_list(whole, son(m_res), ass_ok, true);
748
      }
791
      }
749
      /* default action */
792
      /* default action */
750
      return mc_list (whole, son (e), ass_ok, true);
793
      return mc_list(whole, son(e), ass_ok, true);
751
    }
794
  }
752
 
795
 
753
  default:
796
  default:
754
    if (son (e) == nilexp)
797
    if (son(e) == nilexp) {
755
      return self_const;
798
      return self_const;
756
    else
799
    } else {
757
      return mc_list (whole, son (e), ass_ok, is_a (name (e)) && optop(e));
800
      return mc_list(whole, son(e), ass_ok, is_a(name(e)) && optop(e));
-
 
801
    }
758
  }
802
  }
759
}
803
}
760
 
804
 
761
 
805
 
762
/************************************************************************
806
/************************************************************************
Line 769... Line 813...
769
 *                NB where safe_eval has NOT been used,
813
 *                NB where safe_eval has NOT been used,
770
 *                   patn is son(kdec)
814
 *                   patn is son(kdec)
771
 *        list    list of constant expresion holders
815
 *        list    list of constant expresion holders
772
 *        limit   last constant holder in list
816
 *        limit   last constant holder in list
773
 ************************************************************************/
817
 ************************************************************************/
774
 
818
 
775
void do_this_k
-
 
776
    PROTO_N ( (kdec, patn, list, limit) )
819
void do_this_k(exp kdec, exp patn, exp list, exp limit);
-
 
820
 
-
 
821
void
777
    PROTO_T ( exp kdec X exp patn X exp list X exp limit )
822
do_this_k(exp kdec, exp patn, exp list, exp limit)
778
{
823
{
779
  exp t = list;
824
  exp t = list;
780
  int scan = true;
825
  int scan = true;
781
  exp arglist = nilexp, ap;
826
  exp arglist = nilexp, ap;
782
  int nargs = 0;
827
  int nargs = 0;
783
 
828
 
784
  if (pt (list) != nilexp) {
829
  if (pt(list) != nilexp) {
785
    /* build required argument list */
830
    /* build required argument list */
786
    exp p = son (patn);
831
    exp p = son(patn);
787
    while (p != nilexp) {
832
    while (p != nilexp) {
788
      exp arg_h = getexp (nilexp, arglist, 0, p, nilexp, 0, 0, 0);
833
      exp arg_h = getexp(nilexp, arglist, 0, p, nilexp, 0, 0, 0);
789
      arglist = arg_h;
834
      arglist = arg_h;
790
      ++nargs;
835
      ++nargs;
791
      p = (last (p) ? nilexp : bro (p));
836
      p = (last(p)? nilexp : bro(p));
792
    }
837
    }
793
  }
838
  }
794
  while (scan) {
839
  while (scan) {
795
    if (no (t) == 0) {
840
    if (no(t) == 0) {
796
 
841
 
797
      if (pt (t) == nilexp && eq_exp (son (t), patn)) {
842
      if (pt(t) == nilexp && eq_exp(son(t), patn)) {
798
	/* simple correspondence */
843
	/* simple correspondence */
799
	exp e = son (t);
844
	exp e = son(t);
800
	exp f = father (e);
845
	exp f = father(e);
801
	exp tagt = getexp (sh (e), bro (e),  (int)(last (e)),
846
	exp tagt = getexp(sh(e), bro(e), (int)(last(e)),
802
			   kdec, pt (kdec), 0,  0, name_tag);
847
			   kdec, pt(kdec), 0,  0, name_tag);
803
	pt (kdec) = tagt;
848
	pt(kdec) = tagt;
804
	++no (kdec);
849
	++no(kdec);
805
#ifdef NEWDIAGS
850
#ifdef NEWDIAGS
806
	if (diagnose)
851
	if (diagnose) {
807
	  dg_extracted (tagt, *(refto (f, e)));
852
	  dg_extracted(tagt, *(refto(f, e)));
-
 
853
	}
808
#endif
854
#endif
809
	*(refto (f, e)) = tagt;
855
	*(refto(f, e)) = tagt;
810
	no (t) = -1;		/* dealt with */
856
	no(t) = -1;		/* dealt with */
811
	kill_exp (son (t), son (t));
857
	kill_exp(son(t), son(t));
812
      } else
-
 
813
      if (pt (t) != nilexp && name (pt (t)) == name (patn)) {
858
      } else if (pt(t) != nilexp && name(pt(t)) == name(patn)) {
814
	/* try for complex match - at least the operator is correct */
859
	/* try for complex match - at least the operator is correct */
815
	/* check errtreat ??? */
860
	/* check errtreat ??? */
816
	int scan2 = true;
861
	int scan2 = true;
817
	int matched = 0;
862
	int matched = 0;
818
	exp t2 = t, op = pt (t);
863
	exp t2 = t, op = pt(t);
819
 
864
 
820
 
865
 
821
	while (matched >= 0 && scan2) {
866
	while (matched >= 0 && scan2) {
822
	  if (no (t2) == 0 && pt (t2) == op) {
867
	  if (no(t2) == 0 && pt(t2) == op) {
823
	    /* find match in argument list */
868
	    /* find match in argument list */
824
	    ap = arglist;
869
	    ap = arglist;
825
 
870
 
826
	    while (ap != nilexp &&
871
	    while (ap != nilexp &&
827
		   (pt (ap) != nilexp || !eq_exp (son (t2), son (ap)))
872
		  (pt(ap) != nilexp || !eq_exp(son(t2), son(ap)))) {
828
	      )
-
 
829
	      ap = bro (ap);
873
	      ap = bro(ap);
-
 
874
	    }
830
 
875
 
831
	    if (ap == nilexp)
876
	    if (ap == nilexp) {
832
	      matched = -1;
877
	      matched = -1;
833
	    else {
878
	    } else {
834
	      pt (ap) = t2;
879
	      pt(ap) = t2;
835
	      ++matched;
880
	      ++matched;
836
	    }
881
	    }
837
	  }
882
	  }
838
	  if (t2 == limit)
883
	  if (t2 == limit) {
839
	    scan2 = false;
884
	    scan2 = false;
840
	  else
885
	  } else {
841
	    t2 = bro (t2);
886
	    t2 = bro(t2);
-
 
887
	  }
842
	}
888
	}
843
 
889
 
844
	if (matched == nargs) {
890
	if (matched == nargs) {
845
	  exp prev_arg = nilexp, oparg = son (op), cc;
891
	  exp prev_arg = nilexp, oparg = son(op), cc;
846
	  int last_arg;
892
	  int last_arg;
847
 
893
 
848
	  cc = getexp (sh (son (kdec)), op, 1, kdec, pt (kdec), 0,
894
	  cc = getexp(sh(son(kdec)), op, 1, kdec, pt(kdec), 0,
849
		        0, name_tag);
895
		        0, name_tag);
850
	  pt (kdec) = cc;
896
	  pt(kdec) = cc;
851
	  ++no (kdec);
897
	  ++no(kdec);
852
 
898
 
853
	  while (oparg != nilexp) {
899
	  while (oparg != nilexp) {
854
	    last_arg = (int)last (oparg);
900
	    last_arg = (int)last(oparg);
855
	    ap = arglist;
901
	    ap = arglist;
856
	    while (ap != nilexp && son (pt (ap)) != oparg)
902
	    while (ap != nilexp && son(pt(ap)) != oparg) {
857
	      ap = bro (ap);
903
	      ap = bro(ap);
-
 
904
	    }
858
	    if (ap == nilexp) {
905
	    if (ap == nilexp) {
859
	      /* this is one of the other args of op */
906
	      /* this is one of the other args of op */
860
	      if (prev_arg == nilexp)
907
	      if (prev_arg == nilexp) {
861
		son (op) = oparg;
908
		son(op) = oparg;
862
	      else
909
	      } else {
863
		bro (prev_arg) = oparg;
910
		bro(prev_arg) = oparg;
-
 
911
	      }
864
	      clearlast (oparg);
912
	      clearlast(oparg);
865
	      prev_arg = oparg;
913
	      prev_arg = oparg;
866
	    }
914
	    }
867
	    oparg = (last_arg ? nilexp : bro (oparg));
915
	    oparg = (last_arg ? nilexp : bro(oparg));
868
	  }
916
	  }
869
 
917
 
870
	  /* now add combined constant */
918
	  /* now add combined constant */
871
	  bro (prev_arg) = cc;
919
	  bro(prev_arg) = cc;
872
 
920
 
873
	  /* mark those dealt with & clear arglist */
921
	  /* mark those dealt with & clear arglist */
874
	  ap = arglist;
922
	  ap = arglist;
875
	  while (ap != nilexp) {
923
	  while (ap != nilexp) {
876
	    exp deadarg = son (pt (ap));
924
	    exp deadarg = son(pt(ap));
877
	    no (pt (ap)) = -1;
925
	    no(pt(ap)) = -1;
878
	    son (pt (ap)) = nilexp;
926
	    son(pt(ap)) = nilexp;
879
	    pt (ap) = nilexp;
927
	    pt(ap) = nilexp;
880
	    kill_exp (deadarg, deadarg);
928
	    kill_exp(deadarg, deadarg);
881
	    ap = bro (ap);
929
	    ap = bro(ap);
882
	  }
930
	  }
883
	}
931
	}
884
      }
932
      }
885
    }
933
    }
886
    if (t == limit)
934
    if (t == limit) {
887
      scan = false;
935
      scan = false;
888
    else
936
    } else {
889
      t = bro (t);
937
      t = bro(t);
-
 
938
    }
890
  }
939
  }
891
 
940
 
892
  /* return arglist */
941
  /* return arglist */
893
  while (arglist != nilexp) {
942
  while (arglist != nilexp) {
894
    ap = bro (arglist);
943
    ap = bro(arglist);
895
    retcell (arglist);
944
    retcell(arglist);
896
    arglist = ap;
945
    arglist = ap;
897
  }
946
  }
898
}
947
}
899
 
948
 
900
/************************************************************************
949
/************************************************************************
Line 907... Line 956...
907
 *        esc	label: jump to this if e is:
956
 *        esc	label: jump to this if e is:
908
 *			pointer and nil
957
 *			pointer and nil
909
 *			numeric and zero
958
 *			numeric and zero
910
 ************************************************************************/
959
 ************************************************************************/
911
 
960
 
912
static exp safe_arg
961
static exp
913
    PROTO_N ( (e, esc) )
-
 
914
    PROTO_T ( exp e X exp esc )
962
safe_arg(exp e, exp esc)
915
{
963
{
916
  exp decl = getexp (sh (e), nilexp, 0, e, nilexp,
964
  exp decl = getexp(sh(e), nilexp, 0, e, nilexp,
917
		     0,  0, ident_tag);
965
		     0,  0, ident_tag);
918
  exp v1, v2, z, s, konst, tst;
966
  exp v1, v2, z, s, konst, tst;
919
 
967
 
920
  /* make the unsafe value for this shape */
968
  /* make the unsafe value for this shape */
921
  switch (name (sh (e))) {
969
  switch (name(sh(e))) {
922
  case ptrhd:
970
  case ptrhd:
923
    konst = me_null(sh(e), ptr_null, null_tag);
971
    konst = me_null(sh(e), ptr_null, null_tag);
924
    break;
972
    break;
925
  case scharhd:
973
  case scharhd:
926
  case ucharhd:
974
  case ucharhd:
Line 928... Line 976...
928
  case uwordhd:
976
  case uwordhd:
929
  case slonghd:
977
  case slonghd:
930
  case ulonghd:
978
  case ulonghd:
931
  case s64hd:
979
  case s64hd:
932
  case u64hd:
980
  case u64hd:
933
    konst = getexp (sh (e), nilexp, 0, nilexp, nilexp,
981
    konst = getexp(sh(e), nilexp, 0, nilexp, nilexp, 0,  0, val_tag);
934
		    0,  0, val_tag);
-
 
935
    break;
982
    break;
936
  case shrealhd:
983
  case shrealhd:
937
  case realhd:
984
  case realhd:
938
  case doublehd:{
985
  case doublehd: {
939
      flpt f = new_flpt ();
986
      flpt f = new_flpt();
940
      int i;
987
      int i;
941
      for (i = 0; i < MANT_SIZE; ++i)
988
      for (i = 0; i < MANT_SIZE; ++i) {
942
	(flptnos[f].mant)[i] = 0;
989
	(flptnos[f].mant)[i] = 0;
-
 
990
      }
943
      flptnos[f].exp = 0;
991
      flptnos[f].exp = 0;
944
      flptnos[f].sign = 0;
992
      flptnos[f].sign = 0;
945
      konst = getexp (sh (e), nilexp, 0, nilexp, nilexp,
993
      konst = getexp(sh(e), nilexp, 0, nilexp, nilexp, 0, f, real_tag);
946
		      0, f, real_tag);
-
 
947
      break;
994
      break;
948
    }
995
  }
949
  case offsethd:
996
  case offsethd:
950
    konst = f_offset_zero (f_alignment (sh (e)));
997
    konst = f_offset_zero(f_alignment(sh(e)));
951
    break;
998
    break;
952
  default: {
999
  default:
953
      SET(konst);
1000
      SET(konst);
954
      failer (BAD_SHAPE);
1001
      failer(BAD_SHAPE);
955
    };
-
 
956
  }
1002
  }
957
 
1003
 
958
  v1 = getexp (sh (e), nilexp, 0, decl, pt (decl), 0,  0, name_tag);
1004
  v1 = getexp(sh(e), nilexp, 0, decl, pt(decl), 0,  0, name_tag);
959
  pt (decl) = v1;
1005
  pt(decl) = v1;
960
  ++no (decl);
1006
  ++no(decl);
961
  v2 = getexp (sh (e), nilexp, 1, decl, pt (decl), 0,  0, name_tag);
1007
  v2 = getexp(sh(e), nilexp, 1, decl, pt(decl), 0,  0, name_tag);
962
  pt (decl) = v2;
1008
  pt(decl) = v2;
963
  ++no (decl);
1009
  ++no(decl);
964
 
1010
 
965
  tst = getexp (f_top, nilexp, 0, v1, esc, 0,
1011
  tst = getexp(f_top, nilexp, 0, v1, esc, 0,
966
		 0, test_tag);
1012
		 0, test_tag);
967
  settest_number(tst, f_not_equal);
1013
  settest_number(tst, f_not_equal);
968
  ++no (son (esc));
1014
  ++no(son(esc));
969
  setbro (v1, konst);
1015
  setbro(v1, konst);
970
  tst = hc (tst, konst);
1016
  tst = hc(tst, konst);
971
 
1017
 
972
  z = getexp (f_top, v2, 0, tst, nilexp, 0,  0, 0);
1018
  z = getexp(f_top, v2, 0, tst, nilexp, 0,  0, 0);
973
  setbro (tst, z);
1019
  setbro(tst, z);
974
  setlast (tst);
1020
  setlast(tst);
975
  s = getexp (sh (e), decl, 1, z, nilexp, 0,  0, seq_tag);
1021
  s = getexp(sh(e), decl, 1, z, nilexp, 0,  0, seq_tag);
976
  setbro (e, s);
1022
  setbro(e, s);
977
  clearlast (e);
1023
  clearlast(e);
978
  s = hc (s, v2);
1024
  s = hc(s, v2);
979
 
1025
 
980
  return (hc (decl, s));
1026
  return(hc(decl, s));
981
}
1027
}
982
 
1028
 
983
 
1029
 
984
/************************************************************************
1030
/************************************************************************
985
 *  safe_eval	ensure that the evaluation of e cannot fail
1031
 *  safe_eval	ensure that the evaluation of e cannot fail
Line 1007... Line 1053...
1007
 *  Parameters:
1053
 *  Parameters:
1008
 *        e		expression being evaluated
1054
 *        e		expression being evaluated
1009
 *        escape_route	label: jump to this if evaluation would fail
1055
 *        escape_route	label: jump to this if evaluation would fail
1010
 ************************************************************************/
1056
 ************************************************************************/
1011
 
1057
 
1012
static exp safe_eval
1058
static exp
1013
    PROTO_N ( (e, escape_route) )
-
 
1014
    PROTO_T ( exp e X exp escape_route )
1059
safe_eval(exp e, exp escape_route)
1015
{
1060
{
1016
  exp esc_lab, res;
1061
  exp esc_lab, res;
1017
 
1062
 
1018
  if (escape_route == nilexp) {
1063
  if (escape_route == nilexp) {
1019
    /* this is outermost call - construct escape label */
1064
    /* this is outermost call - construct escape label */
1020
    exp z = getexp (f_top, nilexp, 0, nilexp, nilexp, 0,  0, clear_tag);
1065
    exp z = getexp(f_top, nilexp, 0, nilexp, nilexp, 0,  0, clear_tag);
1021
    esc_lab = getexp (sh (e), nilexp, 0, z, nilexp,
1066
    esc_lab = getexp(sh(e), nilexp, 0, z, nilexp,
1022
		      0,  0, labst_tag);
1067
		      0,  0, labst_tag);
1023
  } else
1068
  } else {
1024
    esc_lab = escape_route;
1069
    esc_lab = escape_route;
-
 
1070
  }
1025
 
1071
 
1026
  switch (name (e)) {
1072
  switch (name(e)) {
1027
  case ident_tag:
1073
  case ident_tag:
1028
  case cond_tag:
1074
  case cond_tag:
1029
  case rep_tag:
1075
  case rep_tag:
1030
  case solve_tag:
1076
  case solve_tag:
1031
  case case_tag:  {
1077
  case case_tag:
1032
      SET(res);
1078
      SET(res);
1033
      failer (CONSTC_ERROR);
1079
      failer(CONSTC_ERROR);
1034
      break;
1080
      break;
1035
    };
-
 
1036
  case name_tag:
1081
  case name_tag:
1037
  case env_offset_tag:
1082
  case env_offset_tag:
1038
  case general_env_offset_tag:
1083
  case general_env_offset_tag:
1039
  case real_tag:
1084
  case real_tag:
1040
    res = copy (e);
1085
    res = copy(e);
1041
    break;
1086
    break;
1042
  case div0_tag:
1087
  case div0_tag:
1043
  case div1_tag:
1088
  case div1_tag:
1044
  case div2_tag:
1089
  case div2_tag:
1045
  case fdiv_tag:
1090
  case fdiv_tag:
1046
  case mod_tag:
1091
  case mod_tag:
1047
  case rem2_tag:
1092
  case rem2_tag:
1048
  case rem0_tag:
1093
  case rem0_tag:
1049
  case offset_div_tag:
1094
  case offset_div_tag:
1050
  case offset_div_by_int_tag:
1095
  case offset_div_by_int_tag: {
1051
    {
-
 
1052
      exp arg1 = safe_eval (son (e), esc_lab);
1096
      exp arg1 = safe_eval(son(e), esc_lab);
1053
      exp arg2 = safe_eval (bro (son (e)), esc_lab);
1097
      exp arg2 = safe_eval(bro(son(e)), esc_lab);
1054
      res = copyexp (e);
1098
      res = copyexp(e);
1055
      setson (res, arg1);
1099
      setson(res, arg1);
1056
      arg2 = safe_arg (arg2, esc_lab);
1100
      arg2 = safe_arg(arg2, esc_lab);
1057
      setbro (arg1, arg2);
1101
      setbro(arg1, arg2);
1058
      clearlast (arg1);
1102
      clearlast(arg1);
1059
      res = hc (res, arg2);
1103
      res = hc(res, arg2);
1060
      break;
1104
      break;
1061
    }
1105
  }
1062
  case cont_tag:
1106
  case cont_tag: {
1063
    {
-
 
1064
      exp arg = son (e);
1107
      exp arg = son(e);
1065
      if (name (arg) == name_tag &&
1108
      if (name(arg) == name_tag &&
1066
	  (isglob (son (arg)) || isvar (son (arg))))
1109
	(isglob(son(arg)) || isvar(son(arg))))
1067
	res = copy (e);
-
 
1068
      else {
-
 
1069
	arg = safe_eval (arg, esc_lab);
-
 
1070
	if (!arg_is_reff)
-
 
1071
	  arg = safe_arg (arg, esc_lab);
-
 
1072
	res = copyexp (e);
-
 
1073
	setson (res, arg);
-
 
1074
	res = hc (res, arg);
-
 
1075
      }
-
 
1076
      break;
-
 
1077
    }
-
 
1078
  case reff_tag:
-
 
1079
    {
-
 
1080
      exp arg = son (e);
-
 
1081
      if (name (arg) == name_tag && isglob (son (arg)))
-
 
1082
	res = copy (e);
1110
	res = copy(e);
1083
      else {
1111
      else {
1084
	arg = safe_eval (arg, esc_lab);
1112
	arg = safe_eval(arg, esc_lab);
1085
	if (!arg_is_reff)
1113
	if (!arg_is_reff)
1086
	  arg = safe_arg (arg, esc_lab);
1114
	  arg = safe_arg(arg, esc_lab);
1087
	res = copyexp (e);
1115
	res = copyexp(e);
1088
	setson (res, arg);
1116
	setson(res, arg);
1089
	res = hc (res, arg);
1117
	res = hc(res, arg);
1090
      }
1118
      }
1091
      break;
1119
      break;
-
 
1120
  }
-
 
1121
  case reff_tag: {
-
 
1122
      exp arg = son(e);
-
 
1123
      if (name(arg) == name_tag && isglob(son(arg)))
-
 
1124
	res = copy(e);
-
 
1125
      else {
-
 
1126
	arg = safe_eval(arg, esc_lab);
-
 
1127
	if (!arg_is_reff)
-
 
1128
	  arg = safe_arg(arg, esc_lab);
-
 
1129
	res = copyexp(e);
-
 
1130
	setson(res, arg);
-
 
1131
	res = hc(res, arg);
1092
    }
1132
      }
-
 
1133
      break;
-
 
1134
  }
1093
  default:{
1135
  default: {
1094
      exp k = copyexp (e);
1136
      exp k = copyexp(e);
1095
      exp arg = son (e);
1137
      exp arg = son(e);
1096
      exp p;
1138
      exp p;
1097
      if (arg == nilexp) {
1139
      if (arg == nilexp) {
1098
	res = k;
1140
	res = k;
1099
	break;
1141
	break;
1100
      }
1142
      }
1101
      p = safe_eval (arg, esc_lab);
1143
      p = safe_eval(arg, esc_lab);
1102
      setson (k, p);
1144
      setson(k, p);
1103
      while (!last (arg)) {
1145
      while (!last(arg)) {
1104
	exp safe = safe_eval (bro (arg), esc_lab);
1146
	exp safe = safe_eval(bro(arg), esc_lab);
1105
	setbro (p, safe);
1147
	setbro(p, safe);
1106
	clearlast (p);
1148
	clearlast(p);
1107
	p = bro (p);
1149
	p = bro(p);
1108
	arg = bro (arg);
1150
	arg = bro(arg);
1109
      }
1151
      }
1110
      res = hc (k, p);
1152
      res = hc(k, p);
1111
      break;
1153
      break;
1112
    }
1154
  }
1113
  }
1155
  }
1114
 
1156
 
1115
  arg_is_reff = (name (e) == reff_tag);
1157
  arg_is_reff = (name(e) == reff_tag);
1116
  if (escape_route != nilexp)
1158
  if (escape_route != nilexp) {
1117
    return (res);		/* this was an inner call */
1159
    return (res);		/* this was an inner call */
-
 
1160
  }
1118
 
1161
 
1119
  if (no (son (esc_lab)) == 0) {
1162
  if (no(son(esc_lab)) == 0) {
1120
    /* the escape route is not used - inherently safe */
1163
    /* the escape route is not used - inherently safe */
1121
    retcell (son (esc_lab));
1164
    retcell(son(esc_lab));
1122
    retcell (esc_lab);
1165
    retcell(esc_lab);
1123
    return (res);
1166
    return(res);
1124
  } else {
1167
  } else {
1125
    /* the escape route was used - construct conditional */
1168
    /* the escape route was used - construct conditional */
1126
    exp cond = getexp (sh (e), nilexp, 0, res, nilexp,
1169
    exp cond = getexp(sh(e), nilexp, 0, res, nilexp,
1127
		       0,  0, cond_tag);
1170
		       0,  0, cond_tag);
1128
    exp safe;
1171
    exp safe;
1129
    safe = getexp (sh (e), nilexp, 1, nilexp, nilexp,
1172
    safe = getexp(sh(e), nilexp, 1, nilexp, nilexp,
1130
		   0,  0, clear_tag);
1173
		   0,  0, clear_tag);
1131
    setbro (son (esc_lab), safe);
1174
    setbro(son(esc_lab), safe);
1132
    IGNORE hc (esc_lab, safe);
1175
    IGNORE hc(esc_lab, safe);
1133
    setbro (res, esc_lab);
1176
    setbro(res, esc_lab);
1134
    clearlast (res);
1177
    clearlast(res);
1135
    IGNORE hc (cond, esc_lab);
1178
    IGNORE hc(cond, esc_lab);
1136
    return (cond);
1179
    return(cond);
1137
  }
1180
  }
1138
}
1181
}
1139
 
1182
 
1140
 
1183
 
1141
/************************************************************************
1184
/************************************************************************
Line 1146... Line 1189...
1146
 *        rf           EXP holding loop
1189
 *        rf           EXP holding loop
1147
 *        list_head    exp containing list of constant expressions
1190
 *        list_head    exp containing list of constant expressions
1148
 *                     this must not be empty
1191
 *                     this must not be empty
1149
 ************************************************************************/
1192
 ************************************************************************/
1150
 
1193
 
1151
static void look_for_caonly
1194
static void
1152
    PROTO_N ( (e) )
-
 
1153
    PROTO_T ( exp e )
1195
look_for_caonly(exp e)
1154
{
1196
{
1155
  if (name(e) == name_tag) {
1197
  if (name(e) == name_tag) {
1156
    if (isvar(son(e)))
1198
    if (isvar(son(e))) {
1157
      clearcaonly(son(e));
1199
      clearcaonly(son(e));
-
 
1200
    }
1158
    return;
1201
    return;
1159
  }
1202
  }
1160
  if (name(e) == addptr_tag)
1203
  if (name(e) == addptr_tag) {
1161
    look_for_caonly(son(e));
1204
    look_for_caonly(son(e));
-
 
1205
  }
1162
  if (name(e) == seq_tag || name(e) == ident_tag)
1206
  if (name(e) == seq_tag || name(e) == ident_tag) {
1163
    look_for_caonly(bro(son(e)));
1207
    look_for_caonly(bro(son(e)));
-
 
1208
  }
1164
  return;
1209
  return;
1165
}
1210
}
1166
 
1211
 
-
 
1212
 
1167
static int extract_consts
1213
static int
1168
    PROTO_N ( (issn, rf, list_head) )
-
 
1169
    PROTO_T ( int issn X exp rf X exp list_head )
1214
extract_consts(int issn, exp rf, exp list_head)
1170
{
1215
{
1171
  exp val;
1216
  exp val;
1172
  int changed = 0;		/* result; will be true if we make a change */
1217
  int changed = 0;		/* result; will be true if we make a change */
1173
  exp t = son (list_head);	/* first in list */
1218
  exp t = son(list_head);	/* first in list */
1174
  exp limit = pt (list_head);	/* last in list */
1219
  exp limit = pt (list_head);	/* last in list */
1175
  int contin = true;
1220
  int contin = true;
1176
 
1221
 
1177
  do {
1222
  do {
1178
    if (issn)
1223
    if (issn) {
1179
      val = son (rf);
1224
      val = son(rf);
1180
    else
1225
    } else {
1181
      val = bro (rf);
1226
      val = bro(rf);
-
 
1227
    }
1182
    if (no (t) != 0)		/* this has been dealt with previously - just
1228
    if (no(t) != 0) {
1183
				 * check for end */
1229
      /* this has been dealt with previously - just * check for end */
1184
      contin = (t != limit);
1230
      contin = (t != limit);
1185
    else {
1231
    } else {
1186
      /* this has not been absorbed by a previous constant */
1232
      /* this has not been absorbed by a previous constant */
1187
 
1233
 
1188
      exp e;
1234
      exp e;
1189
      int force = 0;
1235
      int force = 0;
1190
 
1236
 
1191
      if (pt (t) == nilexp) {
1237
      if (pt(t) == nilexp) {
1192
	/* simple constant - no brothers */
1238
	/* simple constant - no brothers */
1193
	exp f;
1239
	exp f;
1194
	e = son (t);
1240
	e = son(t);
1195
	f = father (e);
1241
	f = father(e);
1196
 
1242
 
1197
 
1243
 
1198
 
1244
 
1199
	/* ?????????????????? */
1245
	/* ?????????????????? */
1200
	if (!last (e) && last (bro (e))
-
 
1201
	    && (name (f) == ident_tag)
1246
	if (!last(e) && last(bro(e)) && (name(f) == ident_tag) && !isvar(f)) {
1202
	    && !isvar (f)) {
-
 
1203
	  /* this is an in-register constant declaration */
1247
	  /* this is an in-register constant declaration */
1204
	  /* so remove the force register bit from f so  */
1248
	  /* so remove the force register bit from f so  */
1205
	  /* that it becomes a simple renaming           */
1249
	  /* that it becomes a simple renaming           */
1206
	  clearusereg (f);
1250
	  clearusereg(f);
1207
	  /* and set the force register bit for the      */
1251
	  /* and set the force register bit for the      */
1208
	  /* outer declaration                           */
1252
	  /* outer declaration                           */
1209
	  force = 1;
1253
	  force = 1;
1210
	}
1254
	}
1211
#ifdef NEWDIAGS
1255
#ifdef NEWDIAGS
1212
	e = copy_dg_separate (e);	/* original may remain in use */
1256
	e = copy_dg_separate (e);	/* original may remain in use */
1213
#else
1257
#else
1214
	e = copy (e);
1258
	e = copy(e);
1215
#endif
1259
#endif
1216
	/* so son(t) can be killed or used in declaration */
1260
	/* so son(t) can be killed or used in declaration */
1217
      } else {
1261
      } else {
1218
	/* the next few consts are args of the same operator */
1262
	/* the next few consts are args of the same operator */
1219
	exp op = pt (t), new_c, prev = nilexp, c_arg = nilexp, t2 = t;
1263
	exp op = pt(t), new_c, prev = nilexp, c_arg = nilexp, t2 = t;
1220
	int scan = true;
1264
	int scan = true;
1221
 
1265
 
1222
	new_c = copyexp (op);
1266
	new_c = copyexp(op);
1223
 
1267
 
1224
	while (scan) {
1268
	while (scan) {
1225
	  if (no (t2) == 0 && pt (t2) == op) {
1269
	  if (no(t2) == 0 && pt(t2) == op) {
1226
#ifdef NEWDIAGS
1270
#ifdef NEWDIAGS
1227
	    c_arg = copy_dg_separate (son (t2));
1271
	    c_arg = copy_dg_separate(son(t2));
1228
					/* original may remain in use */
1272
					/* original may remain in use */
1229
#else
1273
#else
1230
	    c_arg = copy (son (t2));
1274
	    c_arg = copy(son(t2));
1231
#endif
1275
#endif
1232
	    if (prev == nilexp)
1276
	    if (prev == nilexp) {
1233
	      son (new_c) = c_arg;
1277
	      son(new_c) = c_arg;
1234
	    else {
1278
	    } else {
1235
	      bro (prev) = c_arg;
1279
	      bro(prev) = c_arg;
1236
	      clearlast (prev);
1280
	      clearlast(prev);
1237
	    }
1281
	    }
1238
	    prev = c_arg;
1282
	    prev = c_arg;
1239
	  }
1283
	  }
1240
	  if (t2 == limit)
1284
	  if (t2 == limit) {
1241
	    scan = false;
1285
	    scan = false;
1242
	  else
1286
	  } else {
1243
	    t2 = bro (t2);
1287
	    t2 = bro(t2);
-
 
1288
	  }
1244
	}
1289
	}
1245
 
1290
 
1246
	e = hc (new_c, c_arg);
1291
	e = hc(new_c, c_arg);
1247
      }
1292
      }
1248
 
1293
 
1249
      if (is_worth (e)) {
1294
      if (is_worth(e)) {
1250
	/* declare new constant */
1295
	/* declare new constant */
1251
	exp konst;
1296
	exp konst;
1252
	exp newdec;
1297
	exp newdec;
1253
	int kill_e = false;
1298
	int kill_e = false;
1254
#ifdef NEWDIAGS
1299
#ifdef NEWDIAGS
1255
	if (diagnose)
1300
	if (diagnose) {
1256
	  strip_dg_context (e);
1301
	  strip_dg_context(e);
-
 
1302
	}
1257
#endif
1303
#endif
1258
	if (props (t) > 1) {
1304
	if (props(t) > 1) {
1259
	  /* this const. is in a conditional in the loop */
1305
	  /* this const. is in a conditional in the loop */
1260
	  /* ensure that extraction from loop does not cause a failure */
1306
	  /* ensure that extraction from loop does not cause a failure */
1261
	  kill_e = true;
1307
	  kill_e = true;
1262
	  konst = safe_eval (e, nilexp);
1308
	  konst = safe_eval(e, nilexp);
1263
	} else
1309
	} else {
1264
	  konst = e;
1310
	  konst = e;
-
 
1311
	}
1265
	newdec = getexp (sh (val), bro (val),
1312
	newdec = getexp(sh(val), bro(val),
1266
		  (int)(last (val)), konst, nilexp, 0,  0, ident_tag);
1313
		(int)(last(val)), konst, nilexp, 0,  0, ident_tag);
1267
	if (has_lj_dest)
1314
	if (has_lj_dest) {
1268
	  setvis(newdec);
-
 
1269
	if (force && isvis(father(e)))
-
 
1270
	  setvis(newdec);
1315
	  setvis(newdec);
1271
	else
1316
	}
1272
	if (force || ismips)
1317
	if (force && isvis(father(e))) {
1273
	  setusereg (newdec);
1318
	  setvis(newdec);
1274
 
-
 
1275
	if (name(sh(konst)) == ptrhd)
1319
	} else if (force || ismips)
1276
	  look_for_caonly(konst);
1320
	  setusereg(newdec);
1277
 
1321
 
-
 
1322
	if (name(sh(konst)) == ptrhd) {
-
 
1323
	  look_for_caonly(konst);
-
 
1324
	}
-
 
1325
 
1278
	bro (konst) = val;
1326
	bro(konst) = val;
1279
	clearlast (konst);
1327
	clearlast(konst);
1280
	bro (val) = newdec;
1328
	bro(val) = newdec;
1281
	setlast (val);
1329
	setlast(val);
1282
	if (issn)
1330
	if (issn) {
1283
	  son (rf) = newdec;
1331
	  son(rf) = newdec;
1284
	else
1332
	} else {
1285
	  bro (rf) = newdec;
1333
	  bro(rf) = newdec;
-
 
1334
	}
1286
 
1335
 
1287
#ifdef NEWDIAGS
1336
#ifdef NEWDIAGS
1288
	if (diagnose) {
1337
	if (diagnose) {
1289
	  make_optim_dg (DGD_EXTRACT, newdec);
1338
	  make_optim_dg(DGD_EXTRACT, newdec);
1290
	}
1339
	}
1291
#endif
1340
#endif
1292
	do_this_k (newdec, e, t, limit);
1341
	do_this_k(newdec, e, t, limit);
1293
	if (kill_e)
1342
	if (kill_e) {
1294
	  kill_exp (e, e);
1343
	  kill_exp(e, e);
-
 
1344
	}
1295
	changed = 1;		/* have made a change */
1345
	changed = 1;		/* have made a change */
1296
      } else
1346
      } else {
1297
	kill_exp (e, e);
1347
	kill_exp(e, e);
-
 
1348
      }
1298
    }
1349
    }
1299
 
1350
 
-
 
1351
    if (t == limit) {
1300
    if (t == limit)		/* that was the last in the list */
1352
      /* that was the last in the list */
1301
      contin = false;
1353
      contin = false;
1302
    else {
1354
    } else {
1303
      exp n = bro (t);
1355
      exp n = bro(t);
1304
      retcell (t);
1356
      retcell(t);
1305
      t = n;
1357
      t = n;
1306
    }
1358
    }
1307
  }
-
 
1308
  while (contin);
1359
  } while (contin);
1309
 
1360
 
1310
  retcell (t);
1361
  retcell(t);
1311
 
1362
 
1312
  retcell (list_head);
1363
  retcell(list_head);
1313
  return (changed);
1364
  return(changed);
1314
}
1365
}
1315
 
1366
 
1316
 
1367
 
1317
/************************************************************************
1368
/************************************************************************
1318
 *  assigns_alias
1369
 *  assigns_alias
1319
 *
1370
 *
1320
 *  scans e - returns true if any aliased variables are assigned to
1371
 *  scans e - returns true if any aliased variables are assigned to
1321
 *
1372
 *
1322
 *
1373
 *
1323
 ************************************************************************/
1374
 ************************************************************************/
1324
 
1375
 
1325
int named_dest
1376
int named_dest(exp dest);
-
 
1377
 
1326
    PROTO_N ( (dest) )
1378
int
1327
    PROTO_T ( exp dest )
1379
named_dest(exp dest)
1328
{
1380
{
1329
  switch (name (dest)) {
1381
  switch (name(dest)) {
1330
  case name_tag:{
1382
  case name_tag:
1331
      if (isvar (son (dest))) {
1383
      if (isvar(son(dest))) {
1332
	if (iscaonly (son (dest)))
1384
	if (iscaonly(son(dest))) {
1333
	  return true;
1385
	  return true;
-
 
1386
	}
1334
	if (isglob(son(dest))) {
1387
	if (isglob(son(dest))) {
1335
	  if (find_glob(son(dest)))
1388
	  if (find_glob(son(dest))) {
1336
	    return true;
1389
	    return true;
-
 
1390
	  }
1337
	  if (glob_index == globmax)
1391
	  if (glob_index == globmax) {
1338
	    return false;
1392
	    return false;
-
 
1393
	  }
1339
	  glob_dest[glob_index++] = son(dest);
1394
	  glob_dest[glob_index++] = son(dest);
1340
	  return true;
1395
	  return true;
1341
	};
1396
	}
1342
      } else if (!isvar(son(dest)) && son (son (dest)) != nilexp) {
1397
      } else if (!isvar(son(dest)) && son(son(dest)) != nilexp) {
1343
	return named_dest (son (son (dest)));
1398
	return named_dest(son(son(dest)));
1344
      }
1399
      }
1345
      return false;
1400
      return false;
1346
    }
-
 
1347
  case addptr_tag:
1401
  case addptr_tag:
1348
  case reff_tag:{
1402
  case reff_tag:
1349
      /* Should we look at bro son to see if it contains an assignment ??? */
1403
      /* Should we look at bro son to see if it contains an assignment ??? */
1350
      return false;
1404
      return false;
1351
    }
-
 
1352
  default:
1405
  default:
1353
    return false;
1406
    return false;
1354
  }
1407
  }
1355
}
1408
}
1356
 
1409
 
1357
int assigns_alias
1410
int
1358
    PROTO_N ( (e) )
-
 
1359
    PROTO_T ( exp e )
1411
assigns_alias(exp e)
1360
{
1412
{
1361
  switch (name (e)) {
1413
  switch (name(e)) {
1362
  case assvol_tag:
1414
  case assvol_tag:
1363
  case ass_tag:{
1415
  case ass_tag: {
1364
      exp dest = son (e);
1416
      exp dest = son(e);
1365
 
1417
 
1366
      if (!named_dest (son (e)))
1418
      if (!named_dest(son(e))) {
1367
	return (true);		/* LHS may be aliassed */
1419
	/* LHS may be aliassed */
-
 
1420
	return(true);
-
 
1421
      } else {
1368
      else			/* check RHS for assignments */
1422
	/* check RHS for assignments */
1369
	return (assigns_alias (bro (dest)));
1423
	return(assigns_alias(bro(dest)));
-
 
1424
      }
1370
    }
1425
    }
1371
 
1426
 
1372
  case name_tag:
1427
  case name_tag:
1373
  case env_offset_tag:
1428
  case env_offset_tag:
1374
  case general_env_offset_tag:
1429
  case general_env_offset_tag:
1375
    return (false);
1430
    return(false);
1376
 
1431
 
1377
  case case_tag:
1432
  case case_tag:
1378
    return (assigns_alias (son (e)));
1433
    return(assigns_alias(son(e)));
1379
    /* NB - must only look at first son */
1434
    /* NB - must only look at first son */
1380
 
1435
 
1381
  case bfass_tag:
1436
  case bfass_tag:
1382
  case apply_tag:
1437
  case apply_tag:
1383
    return (true);		/* pessimist! */
1438
    return (true);		/* pessimist! */
1384
 
1439
 
1385
  default:{
1440
  default: {
1386
      int aa = false;
1441
      int aa = false;
1387
      exp s = son (e);
1442
      exp s = son(e);
1388
 
1443
 
1389
      while ((s != nilexp) && !aa) {
1444
      while ((s != nilexp) && !aa) {
1390
	aa = assigns_alias (s);
1445
	aa = assigns_alias(s);
1391
	if (aa || last (s))
1446
	if (aa || last(s))
1392
	  s = nilexp;
1447
	  s = nilexp;
1393
	else
1448
	else
1394
	  s = bro (s);
1449
	  s = bro(s);
1395
      }
1450
      }
1396
 
1451
 
1397
      return (aa);
1452
      return(aa);
1398
    }
1453
  }
1399
  }
1454
  }
1400
}
1455
}
-
 
1456
 
1401
 
1457
 
1402
/************************************************************************
1458
/************************************************************************
1403
 *  scan_for_lv
1459
 *  scan_for_lv
1404
 *
1460
 *
1405
 *  scans e - returns true if any label may be long jump destination
1461
 *  scans e - returns true if any label may be long jump destination
1406
 *
1462
 *
1407
 *
1463
 *
1408
 ************************************************************************/
1464
 ************************************************************************/
1409
 
1465
 
1410
static int scan_for_lv
1466
static int
1411
    PROTO_N ( (e) )
-
 
1412
    PROTO_T ( exp e )
1467
scan_for_lv(exp e)
1413
{
1468
{
1414
  switch (name (e)) {
1469
  switch (name(e)) {
1415
  case make_lv_tag:
1470
  case make_lv_tag:
1416
    return (true);
1471
    return(true);
1417
 
1472
 
1418
  case name_tag:
1473
  case name_tag:
1419
  case env_offset_tag:
1474
  case env_offset_tag:
1420
  case general_env_offset_tag:
1475
  case general_env_offset_tag:
1421
    return (false);
1476
    return(false);
1422
 
1477
 
1423
  default:{
1478
  default: {
1424
      int aa = false;
1479
      int aa = false;
1425
      exp s = son (e);
1480
      exp s = son(e);
1426
 
1481
 
1427
      while ((s != nilexp) && !aa) {
1482
      while ((s != nilexp) && !aa) {
1428
	aa = scan_for_lv (s);
1483
	aa = scan_for_lv(s);
1429
	if (aa || last (s))
1484
	if (aa || last(s)) {
1430
	  s = nilexp;
1485
	  s = nilexp;
1431
	else
1486
	} else {
1432
	  s = bro (s);
1487
	  s = bro(s);
-
 
1488
	}
1433
      }
1489
      }
1434
 
1490
 
1435
      return (aa);
1491
      return(aa);
1436
    }
1492
  }
1437
  }
1493
  }
1438
}
1494
}
1439
 
1495
 
1440
 
1496
 
1441
/************************************************************************
1497
/************************************************************************
1442
 *  repeat_consts
1498
 *  repeat_consts
1443
 *
1499
 *
1444
 *  calls extract_consts on each element of the list of repeat loops
1500
 *  calls extract_consts on each element of the list of repeat loops
1445
 ************************************************************************/
1501
 ************************************************************************/
1446
 
1502
 
1447
void repeat_consts
1503
void
1448
    PROTO_Z ()
1504
repeat_consts(void)
1449
{
1505
{
1450
  exp reps = get_repeats ();
1506
  exp reps = get_repeats();
1451
 
1507
 
1452
  while (reps != nilexp) {
1508
  while (reps != nilexp) {
1453
    if (son (reps) != nilexp && name (son (reps)) == rep_tag
1509
    if (son(reps) != nilexp && name(son(reps)) == rep_tag
1454
	&& no (reps) < max_loop_depth) {
1510
	&& no(reps) < max_loop_depth) {
1455
      exp loop = son (reps);
1511
      exp loop = son(reps);
1456
      exp sts = bro (son (loop));
1512
      exp sts = bro(son(loop));
1457
      int no_alias;
1513
      int no_alias;
1458
      maxconst mx;
1514
      maxconst mx;
1459
      exp consts;
1515
      exp consts;
1460
 
1516
 
1461
      /* put old identifier memory list into its free list */
1517
      /* put old identifier memory list into its free list */
1462
      memlist **mptr = &mem;
1518
      memlist **mptr = &mem;
1463
 
1519
 
1464
      glob_index = 0;
1520
      glob_index = 0;
1465
      no_alias = !assigns_alias (sts);
1521
      no_alias = !assigns_alias(sts);
1466
      while (*mptr != nilmem)
1522
      while (*mptr != nilmem) {
1467
	mptr = &((*mptr)->next);
1523
	mptr = & ((*mptr) ->next);
-
 
1524
      }
1468
      *mptr = fmem;
1525
      *mptr = fmem;
1469
      fmem = mem;
1526
      fmem = mem;
1470
      mem = nilmem;
1527
      mem = nilmem;
1471
 
1528
 
1472
      mx = mc_list (loop, sts, no_alias, false);
1529
      mx = mc_list(loop, sts, no_alias, false);
1473
 
1530
 
1474
      consts = mx.cont;
1531
      consts = mx.cont;
1475
      /* NB - false forces a list to be produced */
1532
      /* NB - false forces a list to be produced */
1476
 
1533
 
1477
      if (no_alias)
1534
      if (no_alias) {
1478
	set_noalias (reps);	/* preserve for forall processing */
1535
	set_noalias (reps);	/* preserve for forall processing */
-
 
1536
      }
1479
 
1537
 
1480
      if (consts != nilexp) {
1538
      if (consts != nilexp) {
1481
	exp rr;
1539
	exp rr;
1482
	int sn;
1540
	int sn;
1483
	exp fa = father (loop);
1541
	exp fa = father(loop);
1484
	if (son (fa) == loop) {
1542
	if (son(fa) == loop) {
1485
	  sn = 1;
1543
	  sn = 1;
1486
	  rr = fa;
1544
	  rr = fa;
1487
	} else {
1545
	} else {
1488
	  sn = 0;
1546
	  sn = 0;
1489
	  rr = son (fa);
1547
	  rr = son(fa);
1490
	  while (bro (rr) != loop && !last (rr))
1548
	  while (bro(rr) != loop && !last(rr)) {
1491
	    rr = bro (rr);
1549
	    rr = bro(rr);
-
 
1550
	  }
1492
	};
1551
	}
1493
	if (sn || bro (rr) == loop) {
1552
	if (sn || bro(rr) == loop) {
1494
	  while (name(fa) != proc_tag && name(fa) != general_proc_tag
1553
	  while (name(fa) != proc_tag && name(fa) != general_proc_tag &&
1495
		&& name(fa) != hold_tag && name(fa) != hold2_tag)
1554
		 name(fa) != hold_tag && name(fa) != hold2_tag) {
1496
	    fa = father(fa);
1555
	    fa = father(fa);
-
 
1556
	  }
1497
	  if (name(fa) != hold_tag && name(fa) != hold2_tag) {
1557
	  if (name(fa) != hold_tag && name(fa) != hold2_tag) {
1498
	    if (proc_uses_crt_env(fa))
1558
	    if (proc_uses_crt_env(fa)) {
1499
	      has_lj_dest = scan_for_lv (sts);
1559
	      has_lj_dest = scan_for_lv(sts);
1500
	    else
1560
	    } else {
1501
	      has_lj_dest = 0;
1561
	      has_lj_dest = 0;
-
 
1562
	    }
1502
	    IGNORE extract_consts (sn, rr, consts);
1563
	    IGNORE extract_consts(sn, rr, consts);
1503
	  }
1564
	  }
1504
	}
1565
	}
1505
      }
1566
      }
1506
    }
1567
    }
1507
    reps = pt (reps);
1568
    reps = pt(reps);
1508
  }
1569
  }
1509
}
1570
}
1510
 
1571
 
1511
 
1572
 
1512
/************************************************************************
1573
/************************************************************************
Line 1515... Line 1576...
1515
 *  calculates maximum distance of every repeat from a leaf node
1576
 *  calculates maximum distance of every repeat from a leaf node
1516
 *  (this allows repeat processing to be restricted to inner loops)
1577
 *  (this allows repeat processing to be restricted to inner loops)
1517
 *  returns the repeat_list
1578
 *  returns the repeat_list
1518
 ************************************************************************/
1579
 ************************************************************************/
1519
 
1580
 
1520
exp get_repeats
1581
exp
1521
    PROTO_Z ()
1582
get_repeats(void)
1522
{
1583
{
1523
  if (repeat_list != nilexp && !is_dist (repeat_list)) {
1584
  if (repeat_list != nilexp && !is_dist(repeat_list)) {
1524
    exp reps = repeat_list;
1585
    exp reps = repeat_list;
1525
 
1586
 
1526
    while (reps != nilexp) {
1587
    while (reps != nilexp) {
1527
      if (no (reps) == 0) {
1588
      if (no(reps) == 0) {
1528
	/* this is a leaf node */
1589
	/* this is a leaf node */
1529
	/* no(x) is used in dexp to count directly nested loops */
1590
	/* no(x) is used in dexp to count directly nested loops */
1530
	int dist = 0;
1591
	int dist = 0;
1531
	exp sup = reps;
1592
	exp sup = reps;
1532
	do {
1593
	do {
1533
	  set_dist (sup);	/* no(x) is now max dist to leaf */
1594
	  set_dist (sup);	/* no(x) is now max dist to leaf */
1534
	  no (sup) = dist;
1595
	  no(sup) = dist;
1535
	  if (son (sup) != nilexp && name (son (sup)) == rep_tag)
1596
	  if (son(sup) != nilexp && name(son(sup)) == rep_tag) {
1536
	    ++dist;		/* only repeats are significant */
1597
	    ++dist;		/* only repeats are significant */
-
 
1598
	  }
1537
	  sup = bro (sup);	/* go to enclosing repeat */
1599
	  sup = bro(sup);	/* go to enclosing repeat */
1538
	} while (sup != nilexp && (!is_dist (sup) || no (sup) < dist));
1600
	} while (sup != nilexp && (!is_dist(sup) || no(sup) < dist));
1539
      }
1601
      }
1540
      reps = pt (reps);
1602
      reps = pt(reps);
1541
    }
1603
    }
1542
  }
1604
  }
1543
  return (repeat_list);
1605
  return(repeat_list);
1544
}
1606
}
1545
 
1607
 
1546
 
1608
 
1547
/************************************************************************
1609
/************************************************************************
1548
 *  return_repeats
1610
 *  return_repeats
1549
 *
1611
 *
1550
 *  returns the storage used by repeat_list
1612
 *  returns the storage used by repeat_list
1551
 ************************************************************************/
1613
 ************************************************************************/
1552
 
1614
 
1553
void return_repeats
1615
void
1554
    PROTO_Z ()
1616
return_repeats(void)
1555
{
1617
{
1556
  exp reps = repeat_list;
1618
  exp reps = repeat_list;
1557
 
1619
 
1558
  while (reps != nilexp) {
1620
  while (reps != nilexp) {
1559
    exp next = pt (reps);
1621
    exp next = pt(reps);
1560
    retcell (reps);
1622
    retcell(reps);
1561
    reps = next;
1623
    reps = next;
1562
  }
1624
  }
1563
  repeat_list = nilexp;
1625
  repeat_list = nilexp;
1564
}
1626
}