Warning: Undefined variable $n in /usr/local/www/websvn.planix.org/include/diff_util.php on line 243

Warning: Undefined variable $n in /usr/local/www/websvn.planix.org/include/diff_util.php on line 247

Warning: Undefined variable $m in /usr/local/www/websvn.planix.org/include/diff_util.php on line 251
WebSVN – tendra.SVN – Diff – //branches/tendra5/src/installers/common/construct/unroll.c – Rev 5 and 6

Subversion Repositories tendra.SVN

Rev

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

Rev 5 Rev 6
Line -... Line 1...
-
 
1
/*
-
 
2
 * Copyright (c) 2002-2006 The TenDRA Project <http://www.tendra.org/>.
-
 
3
 * All rights reserved.
-
 
4
 *
-
 
5
 * Redistribution and use in source and binary forms, with or without
-
 
6
 * modification, are permitted provided that the following conditions are met:
-
 
7
 *
-
 
8
 * 1. Redistributions of source code must retain the above copyright notice,
-
 
9
 *    this list of conditions and the following disclaimer.
-
 
10
 * 2. Redistributions in binary form must reproduce the above copyright notice,
-
 
11
 *    this list of conditions and the following disclaimer in the documentation
-
 
12
 *    and/or other materials provided with the distribution.
-
 
13
 * 3. Neither the name of The TenDRA Project nor the names of its contributors
-
 
14
 *    may be used to endorse or promote products derived from this software
-
 
15
 *    without specific, prior written permission.
-
 
16
 *
-
 
17
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
-
 
18
 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-
 
19
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-
 
20
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
-
 
21
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-
 
22
 * EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-
 
23
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-
 
24
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-
 
25
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-
 
26
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-
 
27
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
 
28
 *
-
 
29
 * $Id$
-
 
30
 */
1
/*
31
/*
2
    		 Crown Copyright (c) 1997
32
    		 Crown Copyright (c) 1997
3
 
33
 
4
    This TenDRA(r) Computer Program is subject to Copyright
34
    This TenDRA(r) Computer Program is subject to Copyright
5
    owned by the United Kingdom Secretary of State for Defence
35
    owned by the United Kingdom Secretary of State for Defence
Line 41... Line 71...
41
 *
71
 *
42
 * Revision 1.1  1995/04/06  10:44:05  currie
72
 * Revision 1.1  1995/04/06  10:44:05  currie
43
 * Initial revision
73
 * Initial revision
44
 *
74
 *
45
***********************************************************************/
75
***********************************************************************/
46
 
-
 
47
 
-
 
48
 
76
 
49
#include "config.h"
77
#include "config.h"
50
#include "common_types.h"
78
#include "common_types.h"
51
#include "basicread.h"
79
#include "basicread.h"
52
#include "exp.h"
80
#include "exp.h"
Line 59... Line 87...
59
#include "me_fns.h"
87
#include "me_fns.h"
60
#include "install_fns.h"
88
#include "install_fns.h"
61
#include "shapemacs.h"
89
#include "shapemacs.h"
62
#include "unroll.h"
90
#include "unroll.h"
63
 
91
 
64
static int  unroll_complex PROTO_S ( ( exp, int, exp, int, exp, int ) ) ;
92
static int unroll_complex(exp, int, exp, int, exp, int);
65
 
93
 
66
/* MACROS */
94
/* MACROS */
67
 
95
 
68
#define LIMIT 55
96
#define LIMIT 55
69
#define SIMPLE_LIMIT 0
97
#define SIMPLE_LIMIT 0
Line 72... Line 100...
72
#define UNROLL_BY 4
100
#define UNROLL_BY 4
73
 
101
 
74
 
102
 
75
/* VARIABLES */
103
/* VARIABLES */
76
/* All variables initialised */
104
/* All variables initialised */
77
 
105
 
78
static exp names[LIMIT];	/* no init needed */ /* records the uses of the control variable */
106
/* records the uses of the control variable */
-
 
107
static exp names[LIMIT];	/* no init needed */
79
static int names_index;		/* no init needed */
108
static int names_index;		/* no init needed */
-
 
109
/* permit removal of internal test */
80
static int allow_double;	/* no init needed */ /* permit removal of internal test */
110
static int allow_double;	/* no init needed */
81
static int jumps_out;		/* no init needed */
111
static int jumps_out;		/* no init needed */
82
 
112
 
83
/* PROCEDURES */
113
/* PROCEDURES */
84
 
114
 
85
static int  uc_list
115
static int
86
    PROTO_N ( (e, n, control, lia, ul, decr) )
-
 
87
    PROTO_T ( exp e X int n X exp control X int lia X exp ul X int decr )
116
uc_list(exp e, int n, exp control, int lia, exp ul, int decr)
88
{
117
{
89
  int   c = unroll_complex (e, n, control, lia, ul, decr);
118
	int c = unroll_complex(e, n, control, lia, ul, decr);
90
  if (c < 0 || last (e))
119
	if (c < 0 || last(e)) {
91
    return c;
120
		return c;
92
  return uc_list (bro (e), c, control, lia, ul, decr);
-
 
93
}
-
 
94
 
-
 
95
static int  unroll_complex
-
 
96
    PROTO_N ( (e, n, control, lia, ul, decr) )
-
 
97
    PROTO_T ( exp e X int n X exp control X int lia X exp ul X int decr )
-
 
98
{
-
 
99
  /* e = body - repeated statement less label */
-
 
100
  /* n = complexity maximum */
-
 
101
  /* control = variable declaration for control variable */
-
 
102
  /* lia = boolean, limit is aliased */
-
 
103
  /* ul = variable declaration for limit if not aliased */
-
 
104
  /* decr = unit to decrement by */
-
 
105
  if (n < 0)
-
 
106
    return - 1;	/* complexity exceeded */
-
 
107
 
-
 
108
  if (son (e) == nilexp) {
-
 
109
    if (name(e) == goto_tag)
-
 
110
      allow_double = 0;		/* prevent removal of internal test */
-
 
111
    return n;
-
 
112
  };
-
 
113
 
-
 
114
  switch (name (e)) {
-
 
115
    case test_tag:
-
 
116
    case testbit_tag:
-
 
117
      if (!isunroll(pt(e))) {	/* flag set and cleared by cond_tag below */
-
 
118
	allow_double = 0;	/* prevent removal of internal test; jump out of loop */
-
 
119
      };
-
 
120
      return uc_list (son (e), n - decr, control, lia, ul, decr);
-
 
121
    case goto_tag:
-
 
122
      if (!isunroll(pt(e))) {	/* flag set and cleared by cond_tag below */
-
 
123
	allow_double = 0;	/* prevent removal of internal test; jump out of loop */
-
 
124
      };
-
 
125
      return n-1;
-
 
126
    case cond_tag:
-
 
127
      {
-
 
128
	int t;
-
 
129
        setunroll(bro(son(e)));		/* mark internal label */
-
 
130
	if (name(sh(son(e))) == bothd) {
-
 
131
	  t = unroll_complex(son(e), n - (4*decr), control, lia, ul, 0);
-
 
132
	  t = unroll_complex(bro(son(e)), t - decr, control, lia, ul, decr);
-
 
133
	}
121
	}
134
	else {
-
 
135
	  t = unroll_complex(son(e), n - decr, control, lia, ul, decr);
-
 
136
	  t = unroll_complex(bro(son(e)), t - decr, control, lia, ul, decr);
-
 
137
	};
-
 
138
	clearunroll(bro(son(e)));	/* unmark it */
-
 
139
	return t;
-
 
140
      };
-
 
141
    case ass_tag:
-
 
142
    case assvol_tag:
-
 
143
      {
-
 
144
	exp assdest = son(e);	/* destination of assignment */
-
 
145
	if (name(assdest) == name_tag && son(assdest) == ul)
-
 
146
	  allow_double = 0;	/* prevent removal of internal test; assigning to limit */
-
 
147
	if (lia) {
-
 
148
	  if (name(assdest) == name_tag && !isvar(son(assdest)))
-
 
149
	    allow_double = 0;	/* prevent removal of internal test; perhaps assigning to limit */
-
 
150
	  if (name(assdest) == name_tag && !iscaonly(son(assdest)))
-
 
151
	    allow_double = 0;	/* prevent removal of internal test; perhaps assigning to limit */
-
 
152
	};
-
 
153
        return uc_list (son (e), n - decr, control, lia, ul, decr);
-
 
154
      };
-
 
155
    case name_tag:
-
 
156
      if (son (e) == control) { /* is this the control variable? */
-
 
157
	exp t;
-
 
158
	if (!last (e) || name (bro (e)) != cont_tag)
-
 
159
	  allow_double = 0;	/* any use but contents -> no test elim */
-
 
160
	else {	/* it is a cont */
-
 
161
	  t = bro (e);
-
 
162
#if isalpha
-
 
163
	  if (!last(t) || name(bro(t)) != chvar_tag ||
-
 
164
	      last (bro(t)) || name (bro(bro (t))) != val_tag || !last (bro (bro(t))) ||
-
 
165
	      name (bro (bro (bro(t)))) != offset_mult_tag)
-
 
166
	    allow_double = 0;	/* not offset_mult -> no test elim */
-
 
167
	  else
-
 
168
	    names[names_index++] = bro(e);	/* record the use */
-
 
169
#else
-
 
170
	  if (last (t) || name (bro (t)) != val_tag || !last (bro (t)) ||
-
 
171
	      name (bro (bro (t))) != offset_mult_tag)
-
 
172
	    allow_double = 0;	/* not offset_mult -> no test elim */
-
 
173
	  else
-
 
174
	    names[names_index++] = bro(e);	/* record the use */
-
 
175
#endif
-
 
176
	};
-
 
177
      };
-
 
178
      return n - decr;
-
 
179
    case apply_tag:
-
 
180
    case solve_tag:
-
 
181
      return - 1;	/* no unroll */
-
 
182
    case case_tag:
-
 
183
      return unroll_complex (son (e), n - decr, control, lia, ul, decr);
-
 
184
    case string_tag:
-
 
185
    case env_offset_tag:
-
 
186
    case general_env_offset_tag:
-
 
187
      return n - decr;	/* decrease the complexity count */
-
 
188
    case top_tag:
-
 
189
    case prof_tag:
-
 
190
    case clear_tag:
-
 
191
      return n;
-
 
192
    case labst_tag:
-
 
193
      return unroll_complex (bro (son (e)), n, control, lia, ul, decr);
-
 
194
    case seq_tag:
-
 
195
      return uc_list (son (e), n, control, lia, ul, decr);
122
	return uc_list(bro(e), c, control, lia, ul, decr);
196
    case round_tag:
-
 
197
    case fplus_tag:
-
 
198
    case fminus_tag:
-
 
199
    case fmult_tag:
-
 
200
    case fdiv_tag:
-
 
201
    case fabs_tag:
-
 
202
    case fneg_tag:
-
 
203
    case fpower_tag:
-
 
204
    case fmax_tag:
-
 
205
    case fmin_tag:
-
 
206
    case float_tag:
-
 
207
    case chfl_tag:
-
 
208
      return uc_list (son (e), n - (16*decr), control, lia, ul, decr);	/* heavy flpt ops */
-
 
209
    default:
-
 
210
      return uc_list (son (e), n - decr, control, lia, ul, decr);	/* other ops decrease complexity by 1 */
-
 
211
  };
-
 
212
}
123
}
213
 
124
 
-
 
125
 
214
void simple_unroll
126
static int
215
    PROTO_N ( (candidate, body, inc, te) )
-
 
216
    PROTO_T ( exp candidate X exp body X exp inc X exp te )
127
unroll_complex(exp e, int n, exp control, int lia, exp ul, int decr)
217
{
128
{
218
    /* candidate = rep_tag */
129
	/* e = body - repeated statement less label */
219
    /* body = repeated statement less label, assignment and test */
130
	/* n = complexity maximum */
220
    /* inc = the single assignment to the control variable */
131
	/* control = variable declaration for control variable */
221
    /* te = the final test - only jump to repeat label */
132
	/* lia = boolean, limit is aliased */
222
    exp second_body = copy (body);	/* repeated statement less label, assignment and test */
133
	/* ul = variable declaration for limit if not aliased */
223
    exp second_inc = copy (inc);	/* assignment to control */
134
	/* decr = unit to decrement by */
224
    exp second_test = copy (te);
135
	if (n < 0) {
225
    exp z = getexp (f_top, te, 0, nilexp, nilexp, 0, 0, 0);
136
		return - 1;	/* complexity exceeded */
-
 
137
	}
-
 
138
 
226
    exp seq = getexp (f_top, bro (son (candidate)), 1,
139
	if (son(e) == nilexp) {
227
        z, nilexp, 0, 0, seq_tag);
140
		if (name(e) == goto_tag) {
228
    exp cond_labst;
141
			/* prevent removal of internal test */
229
    exp cl1, mt;
142
			allow_double = 0;
230
    exp cond, f;
143
		}
231
    exp * point;
144
		return n;
232
    float freq = fno(bro(son(candidate)));
-
 
-
 
145
	}
233
 
146
 
292
 
384
 
293
    setunrolled (candidate);
385
		kill_exp(sum, sum);
-
 
386
	}
294
    return;
387
	return body;
295
}
388
}
296
 
389
 
297
static exp inc_offset
-
 
298
    PROTO_N ( (var, sha, konst, body, i) )
-
 
299
    PROTO_T ( exp var X shape sha X exp konst X exp body X int i )
-
 
300
{
-
 
301
  exp sum, t;
-
 
302
  exp id = son(var);
-
 
303
  exp rest = pt(id);
-
 
304
  body = copy(body);
-
 
305
  if (names_index > 0) {	/* count of offset_mult uses of control variable */
-
 
306
    t = pt(id);
-
 
307
    sum = me_u3(sha, copy(var), cont_tag);
-
 
308
    sum = hold_check(me_b3(sha, sum,
-
 
309
	  		     me_shint(sha, i*no(konst)), plus_tag));	/* variable + i */
-
 
310
 
-
 
311
    for (i = 0; i < names_index; ++i) {
-
 
312
      exp q = pt(t);
-
 
313
      exp b = bro(t);
-
 
314
      replace(bro(t), copy(sum), body);	/* replace the offset_mults in body */
-
 
315
      kill_exp(b, b);
-
 
316
      t = q;
-
 
317
    };
-
 
318
    if (t != rest)
-
 
319
      failer("unroll failure");
-
 
320
 
390
 
321
    kill_exp(sum, sum);
-
 
322
  };
391
void
323
  return body;
-
 
324
}
-
 
325
 
-
 
326
void unroll_trans
-
 
327
    PROTO_N ( (candidate, body, inc, te, limit, nt, var, konst, reps, times) )
-
 
328
    PROTO_T ( exp candidate X exp body X exp inc X exp te X exp limit X
392
unroll_trans(exp candidate, exp body, exp inc, exp te, exp limit, int nt,
329
	      int nt X exp var X exp konst X exp reps X int times )
393
	     exp var, exp konst, exp reps, int times)
330
{
394
{
331
  /* candidate = rep_tag */
395
	/* candidate = rep_tag */
332
  /* body = repeated statement less label, assignment and test */
396
	/* body = repeated statement less label, assignment and test */
333
  /* inc = the single assignment to the control variable */
397
	/* inc = the single assignment to the control variable */
334
  /* te = the final test - only jump to repeat label */
398
	/* te = the final test - only jump to repeat label */
335
  /* limit = the limit exp */
399
	/* limit = the limit exp */
336
  /* nt = the test number */
400
	/* nt = the test number */
337
  /* var = name_tag for control variable */
401
	/* var = name_tag for control variable */
338
  /* konst = the value added to the control variable */
402
	/* konst = the value added to the control variable */
339
  /* reps = current element of the repeat list */
403
	/* reps = current element of the repeat list */
340
  /* times = no of times to unroll */
404
	/* times = no of times to unroll */
341
  float freq = fno(bro(son(candidate)));
405
	float freq = fno(bro(son(candidate)));
-
 
406
	if (allow_double && no(konst) == 1 &&
342
  if (allow_double && no(konst) == 1 && 	/* allow_double==0 prevents test elimination */
407
	    /* allow_double==0 prevents test elimination */
343
      (nt == (int)f_greater_than || nt == (int)f_greater_than_or_equal) &&
408
	    (nt == (int)f_greater_than || nt == (int)f_greater_than_or_equal) &&
344
		/* the permitted tests - we are counting upwards */
409
	    /* the permitted tests - we are counting upwards */
345
      ((name(limit) == name_tag && !isvar(son(limit))) ||
410
	    ((name(limit) == name_tag && !isvar(son(limit))) ||
346
	 name(limit) == val_tag ||
411
	     name(limit) == val_tag ||
347
	(name(limit) == cont_tag && name(son(limit)) == name_tag &&
412
	     (name(limit) == cont_tag && name(son(limit)) == name_tag &&
348
	    isvar(son(son(limit)))))	/* permitted forms of limit */
413
	      isvar(son(son(limit)))))	/* permitted forms of limit */
349
      ) {
414
	   ) {
350
		/* unroll and remove the internal increment and test */
415
		/* unroll and remove the internal increment and test */
351
 
416
 
352
    int i;
417
		int i;
353
    shape sha = sh(konst);
418
		shape sha = sh(konst);
354
    exp branches [UNROLL_MAX + 2];	/* 0 - (times-2) are preliminaries
419
		/* 0 - (times - 2) are preliminaries (times - 1) is test out
355
					   (times-1) is test out
420
		 * times is the loop (times + 1) is the end */
356
					   times is the loop
421
		exp branches [UNROLL_MAX + 2];
357
					   (times+1) is the end */
422
		/* used to jump out after < times */
358
    exp test_out = copy(te);		/* used to jump out after < times */
423
		exp test_out = copy(te);
359
    exp temp, temp1, bc, repeater, lrep, res, id, temp2;
424
		exp temp, temp1, bc, repeater, lrep, res, id, temp2;
360
    exp new_c = me_shint(sha, times*no(konst));	/* used to increment the control variable */
425
		/* used to increment the control variable */
361
 
-
 
362
    settest_number(test_out,
-
 
363
		   (int)int_inverse_ntest[test_number(test_out)]);
-
 
364
 
-
 
365
    for (i = 0; i < times + 2; ++i) {	/* set up labst for branches */
-
 
366
      exp lia = me_shint(sha, (((i > 1) && (i < (times-1))) || i >= times) ? 2: 1);
-
 
367
      exp li = getexp(f_bottom, nilexp, 0, lia, nilexp, 0, 0, labst_tag);
-
 
368
      fno(li) = (float) (freq / 20.0);
-
 
369
      name(lia) = clear_tag;
-
 
370
      clearlast(lia);
-
 
371
      branches[i] = li;
-
 
372
    };
-
 
373
    SET(branches);
-
 
374
    sh(branches[times+1]) = f_top;
-
 
375
 
-
 
376
 
-
 
377
    for (i = 0; i < times - 1; ++ i) {	/* set up preliminaries */
-
 
378
      exp sub = me_b3(f_top, copy(body), copy(inc), 0);
-
 
379
      exp seq = me_b3(f_bottom, sub,
-
 
380
		 getexp(f_bottom, nilexp, 0, nilexp, branches[i+1], 0, 0, goto_tag), seq_tag);
-
 
381
      bro(son(branches[i])) = seq;
-
 
382
      setlast(seq);
-
 
383
      bro(seq) = branches[i];
-
 
384
    };
-
 
385
 
-
 
386
    pt(test_out) = branches[times+1];
-
 
387
    temp = me_u3(f_top, test_out, 0);
426
		exp new_c = me_shint(sha, times * no(konst));
388
    temp = me_b3(f_bottom, temp,
-
 
389
		 getexp(f_bottom, nilexp, 0, nilexp, branches[times], 0, 0, goto_tag), seq_tag);
-
 
390
    bro(son(branches[times-1])) = temp;
-
 
391
    setlast(temp);
-
 
392
    bro(temp) = branches[times-1];
-
 
393
 
-
 
394
    temp = copy(body);
-
 
395
    temp1 = temp;
-
 
396
    if (jumps_out) {
-
 
397
      bro(temp1) = copy(inc);
-
 
398
      clearlast(temp1);
-
 
399
      temp1 = bro(temp1);
-
 
400
    };
-
 
401
    for (i = 1; i < times - 1; ++i) {
-
 
402
      if (jumps_out)
-
 
403
	bro(temp1) = copy(body);
-
 
404
      else
-
 
405
        bro(temp1) = inc_offset(var, sha, konst, body, i);
-
 
406
      clearlast(temp1);
-
 
407
      temp1 = bro(temp1);
-
 
408
      if (jumps_out) {
-
 
409
	bro(temp1) = copy(inc);
-
 
410
        clearlast(temp1);
-
 
411
        temp1 = bro(temp1);
-
 
412
      };
-
 
413
    };
-
 
414
    bc = getexp(f_top, nilexp, 0, temp, nilexp, 0, 0, 0);
-
 
415
    setlast(temp1);
-
 
416
    bro(temp1) = bc;
-
 
417
    if (jumps_out)
-
 
418
      bc = me_b3(f_top, bc, copy(body), seq_tag);
-
 
419
    else {
-
 
420
      bc = me_b3(f_top, bc, inc_offset(var, sha, konst, body, i), seq_tag);
-
 
421
      kill_exp(body, body);
-
 
422
    };
-
 
423
 
-
 
424
    if (jumps_out)
-
 
425
      kill_exp(new_c, new_c);
-
 
426
    else
-
 
427
      replace(bro(son(bro(var))), new_c, new_c);	/* replace konst by times*konst */
-
 
428
 
427
 
429
    temp = me_b3(f_top, bc, inc, 0);
428
		settest_number(test_out,
430
    temp = me_b3(f_top, temp, te, seq_tag);
-
 
431
    lrep = me_b3(f_top, me_shint(sha, 1), temp, labst_tag);
429
			       (int)int_inverse_ntest[test_number(test_out)]);
432
    fno(lrep) = freq / (float)times;
-
 
433
    name(son(lrep)) = clear_tag;
-
 
434
    repeater = me_b3(f_top, f_make_top(), lrep, rep_tag);
-
 
435
    son(reps) = repeater;
-
 
436
    pt(te) = lrep;	/* label in repeater */
-
 
437
    pt(test_out) = branches[times+1];
-
 
438
 
430
 
-
 
431
		for (i = 0; i < times + 2; ++i) {
-
 
432
			/* set up labst for branches */
-
 
433
			exp lia = me_shint(sha, (((i > 1) &&
-
 
434
						  (i < (times - 1))) ||
439
    temp = f_make_top();
435
						 i >= times) ? 2 : 1);
-
 
436
			exp li = getexp(f_bottom, nilexp, 0, lia, nilexp, 0, 0,
-
 
437
					labst_tag);
440
    bro(son(branches[times+1])) = temp;
438
			fno(li) = (float)(freq / 20.0);
-
 
439
			name(lia) = clear_tag;
441
    setlast(temp);
440
			clearlast(lia);
-
 
441
			branches[i] = li;
-
 
442
		}
-
 
443
		SET(branches);
442
    bro(temp) = branches[times+1];
444
		sh(branches[times+1]) = f_top;
443
 
445
 
444
    temp = me_u3(f_top, repeater, 0);
-
 
445
    temp = me_b3(f_bottom, temp,
-
 
446
		 getexp(f_bottom, nilexp, 0, nilexp, branches[times+1], 0, 0, goto_tag), seq_tag);
-
 
447
    bro(son(branches[times])) = temp;
-
 
448
    setlast(temp);
-
 
449
    bro(temp) = branches[times];
-
 
450
 
446
 
451
    temp = me_u3(sha, copy(var), cont_tag);
447
		for (i = 0; i < times - 1; ++ i) {
452
    temp1 = copy(limit);
448
			/* set up preliminaries */
453
    sh(temp1) = sha;
449
			exp sub = me_b3(f_top, copy(body), copy(inc), 0);
454
    temp = hold_check(me_b3(sha, temp1, temp, minus_tag));
450
			exp seq = me_b3(f_bottom, sub,
455
    if (nt == (int)f_greater_than) {
451
					getexp(f_bottom, nilexp, 0, nilexp,
456
      temp = hold_check(me_b3(sha, temp, me_shint(sha, 1), plus_tag));
452
					       branches[i + 1], 0, 0, goto_tag),
457
    };
453
					seq_tag);
458
    temp = hold_check(me_b3(sha, temp,
454
			bro(son(branches[i])) = seq;
-
 
455
			setlast(seq);
459
				 me_shint(sha, times-1), and_tag));
456
			bro(seq) = branches[i];
-
 
457
		}
460
 
458
 
461
    id = me_startid(sha, temp, 0);
459
		pt(test_out) = branches[times+1];
462
    temp = getexp(f_top, nilexp, 0, me_obtain(id), branches[times], 0, 0, test_tag);
460
		temp = me_u3(f_top, test_out, 0);
463
    settest_number(temp, f_not_equal);
461
		temp = me_b3(f_bottom, temp,
464
    bro(son(temp)) = me_shint(sha, 0);
462
			     getexp(f_bottom, nilexp, 0, nilexp,
465
    setlast(bro(son(temp)));
463
				    branches[times], 0, 0, goto_tag), seq_tag);
466
    bro(bro(son(temp))) = temp;
464
		bro(son(branches[times - 1])) = temp;
467
    temp1 = temp;
465
		setlast(temp);
-
 
466
		bro(temp) = branches[times - 1];
468
 
467
 
-
 
468
		temp = copy(body);
-
 
469
		temp1 = temp;
-
 
470
		if (jumps_out) {
-
 
471
			bro(temp1) = copy(inc);
-
 
472
			clearlast(temp1);
-
 
473
			temp1 = bro(temp1);
-
 
474
		}
469
    for (i = 1; i < (times-1); ++i) {
475
		for (i = 1; i < times - 1; ++i) {
-
 
476
			if (jumps_out) {
-
 
477
				bro(temp1) = copy(body);
-
 
478
			} else {
470
      temp2 = getexp(f_top, nilexp, 0, me_obtain(id), branches[times-i-1], 0, 0, test_tag);
479
				bro(temp1) = inc_offset(var, sha, konst, body,
-
 
480
							i);
-
 
481
			}
-
 
482
			clearlast(temp1);
471
      settest_number(temp2, f_not_equal);
483
			temp1 = bro(temp1);
-
 
484
			if (jumps_out) {
472
      bro(son(temp2)) = me_shint(sha, i);
485
				bro(temp1) = copy(inc);
473
      setlast(bro(son(temp2)));
486
				clearlast(temp1);
474
      bro(bro(son(temp2))) = temp2;
487
				temp1 = bro(temp1);
-
 
488
			}
-
 
489
		}
475
      settest_number(temp, f_not_equal);
490
		bc = getexp(f_top, nilexp, 0, temp, nilexp, 0, 0, 0);
476
      clearlast(temp1);
491
		setlast(temp1);
477
      bro(temp1) = temp2;
492
		bro(temp1) = bc;
478
      temp1 = temp2;
493
		if (jumps_out) {
-
 
494
			bc = me_b3(f_top, bc, copy(body), seq_tag);
-
 
495
		} else {
-
 
496
			bc = me_b3(f_top, bc, inc_offset(var, sha, konst, body,
-
 
497
							 i), seq_tag);
-
 
498
			kill_exp(body, body);
479
    };
499
		}
480
 
500
 
481
    bc = getexp(f_top, nilexp, 0, temp, nilexp, 0, 0, 0);
-
 
482
    setlast(temp1);
501
		if (jumps_out) {
483
    bro(temp1) = bc;
502
			kill_exp(new_c, new_c);
484
    bc = me_b3(f_bottom, bc,
503
		} else {
485
	 getexp(f_bottom, nilexp, 0, nilexp, branches[0], 0, 0, goto_tag), seq_tag);
504
			/* replace konst by times * konst */
486
    id = me_complete_id(id, bc);
505
			replace(bro(son(bro(var))), new_c, new_c);
-
 
506
		}
487
 
507
 
488
    temp1 = id;
508
		temp = me_b3(f_top, bc, inc, 0);
489
    for (i = 0; i < (times+2); ++i) {
509
		temp = me_b3(f_top, temp, te, seq_tag);
490
      bro(temp1) = branches[i];
510
		lrep = me_b3(f_top, me_shint(sha, 1), temp, labst_tag);
491
      clearlast(temp1);
511
		fno(lrep) = freq / (float)times;
492
      temp1 = bro(temp1);
512
		name(son(lrep)) = clear_tag;
493
    };
-
 
494
    res = getexp(f_top, nilexp, 0, id, nilexp, 0, 0, solve_tag);
513
		repeater = me_b3(f_top, f_make_top(), lrep, rep_tag);
495
    setlast(temp1);
514
		son(reps) = repeater;
496
    bro(temp1) = res;
515
		pt(te) = lrep;	/* label in repeater */
497
    setunrolled(repeater);
516
		pt(test_out) = branches[times+1];
498
 
517
 
-
 
518
		temp = f_make_top();
-
 
519
		bro(son(branches[times + 1])) = temp;
-
 
520
		setlast(temp);
-
 
521
		bro(temp) = branches[times + 1];
-
 
522
 
-
 
523
		temp = me_u3(f_top, repeater, 0);
-
 
524
		temp = me_b3(f_bottom, temp,
-
 
525
			     getexp(f_bottom, nilexp, 0, nilexp,
-
 
526
				    branches[times + 1], 0, 0, goto_tag),
-
 
527
			     seq_tag);
-
 
528
		bro(son(branches[times])) = temp;
-
 
529
		setlast(temp);
-
 
530
		bro(temp) = branches[times];
-
 
531
 
-
 
532
		temp = me_u3(sha, copy(var), cont_tag);
-
 
533
		temp1 = copy(limit);
-
 
534
		sh(temp1) = sha;
-
 
535
		temp = hold_check(me_b3(sha, temp1, temp, minus_tag));
-
 
536
		if (nt == (int)f_greater_than) {
-
 
537
			temp = hold_check(me_b3(sha, temp, me_shint(sha, 1),
-
 
538
						plus_tag));
-
 
539
		}
-
 
540
		temp = hold_check(me_b3(sha, temp, me_shint(sha, times - 1),
-
 
541
					and_tag));
-
 
542
 
-
 
543
		id = me_startid(sha, temp, 0);
-
 
544
		temp = getexp(f_top, nilexp, 0, me_obtain(id), branches[times],
-
 
545
			      0, 0, test_tag);
-
 
546
		settest_number(temp, f_not_equal);
-
 
547
		bro(son(temp)) = me_shint(sha, 0);
-
 
548
		setlast(bro(son(temp)));
-
 
549
		bro(bro(son(temp))) = temp;
-
 
550
		temp1 = temp;
-
 
551
 
-
 
552
		for (i = 1; i < (times - 1); ++i) {
-
 
553
			temp2 = getexp(f_top, nilexp, 0, me_obtain(id),
-
 
554
				       branches[times - i - 1], 0, 0, test_tag);
-
 
555
			settest_number(temp2, f_not_equal);
-
 
556
			bro(son(temp2)) = me_shint(sha, i);
-
 
557
			setlast(bro(son(temp2)));
-
 
558
			bro(bro(son(temp2))) = temp2;
-
 
559
			settest_number(temp, f_not_equal);
-
 
560
			clearlast(temp1);
-
 
561
			bro(temp1) = temp2;
-
 
562
			temp1 = temp2;
-
 
563
		}
-
 
564
 
-
 
565
		bc = getexp(f_top, nilexp, 0, temp, nilexp, 0, 0, 0);
-
 
566
		setlast(temp1);
-
 
567
		bro(temp1) = bc;
-
 
568
		bc = me_b3(f_bottom, bc,
-
 
569
			   getexp(f_bottom, nilexp, 0, nilexp, branches[0], 0,
-
 
570
				  0, goto_tag), seq_tag);
-
 
571
		id = me_complete_id(id, bc);
-
 
572
 
-
 
573
		temp1 = id;
-
 
574
		for (i = 0; i < (times + 2); ++i) {
-
 
575
			bro(temp1) = branches[i];
-
 
576
			clearlast(temp1);
-
 
577
			temp1 = bro(temp1);
-
 
578
		}
-
 
579
		res = getexp(f_top, nilexp, 0, id, nilexp, 0, 0, solve_tag);
-
 
580
		setlast(temp1);
-
 
581
		bro(temp1) = res;
-
 
582
		setunrolled(repeater);
-
 
583
 
499
    replace(candidate, res, res);
584
		replace(candidate, res, res);
500
  }
585
	}
501
#if is80x86
586
#if is80x86
502
  else
587
	else {
503
    simple_unroll (candidate, body, inc, te);
588
		simple_unroll(candidate, body, inc, te);
-
 
589
	}
504
#endif
590
#endif
505
  return;
591
	return;
506
}
592
}
507
 
593
 
-
 
594
 
508
void unroller
595
void
509
    PROTO_Z ()
596
unroller(void)
510
{
597
{
511
  exp reps = repeat_list;
598
  exp reps = repeat_list;
512
  exp candidate;
599
  exp candidate;
513
  exp labst;
600
  exp labst;
514
  exp rb;
601
  exp rb;
515
 
602
 
516
 
603
 
517
  while (reps != nilexp) {
604
  while (reps != nilexp) {
518
    if (no (reps) == 0 && son (reps) != nilexp &&
605
    if (no(reps) == 0 && son(reps) != nilexp && name(son(reps)) == rep_tag) {
519
	name (son (reps)) == rep_tag) {
-
 
520
      /* this is a leaf repeat node */
606
      /* this is a leaf repeat node */
521
      candidate = son (reps);	/* this is the repeat */
607
      candidate = son(reps);		/* this is the repeat */
522
      labst = bro (son (candidate));	/* the repeated statement */
608
      labst = bro(son(candidate));	/* the repeated statement */
523
      rb = bro (son (labst));	/* the repeated statement less label */
609
      rb = bro(son(labst));		/* the repeated statement less label */
524
 
610
 
525
      if (name (son (candidate)) == top_tag &&
611
      if (name(son(candidate)) == top_tag && no(son(labst)) == 1 &&
526
	  no (son (labst)) == 1 &&
-
 
527
	  name (rb) == seq_tag &&
-
 
528
	  name (bro (son (rb))) == seq_tag) {
612
	  name(rb) == seq_tag && name(bro(son(rb))) == seq_tag) {
529
/*
613
/*
530
 
-
 
531
	rep_tag
614
	rep_tag
532
	top_tag	labst_tag
615
	top_tag	labst_tag
533
		count		seq_tag
616
	count		seq_tag
534
				0	seq_tag
617
	0	seq_tag
535
 
-
 
536
*/
618
*/
537
	exp final = bro (son (rb));
619
	exp final = bro(son(rb));
538
	exp body = son (son (rb));
620
	exp body = son(son(rb));
539
	exp ass = son (son (final));
621
	exp ass = son(son(final));
540
	exp te = bro (son (final));
622
	exp te = bro(son(final));
541
	if (name (ass) == ass_tag && name (te) == test_tag) {
623
	if (name(ass) == ass_tag && name(te) == test_tag) {
542
/*
-
 
543
 
-
 
544
	rep_tag
-
 
545
	top_tag	labst_tag
-
 
546
		count		seq_tag
-
 
547
				0	seq_tag = final
-
 
548
				body	0	test_tag = te
-
 
549
					ass_tag = ass
-
 
550
 
-
 
551
*/
-
 
552
	  exp dest = son (ass);
-
 
553
	  exp val = bro (dest);
-
 
554
	  if (name (dest) == name_tag && isvar (son (dest)) &&
-
 
555
	      iscaonly (son (dest)) && shape_size (sh (val)) == 32) {
-
 
556
/*
624
/*
557
 
-
 
558
	rep_tag
625
	rep_tag
559
	top_tag	labst_tag
626
	top_tag	labst_tag
560
		count		seq_tag
627
	count		seq_tag
561
				0	seq_tag = final
628
	0	seq_tag = final
562
				body	0	test_tag = te
629
	body	0	test_tag = te
563
					ass_tag = ass
630
	ass_tag = ass
564
					name = dest	val (32)
-
 
565
					var & ca
-
 
566
*/
631
*/
567
	    if (name (val) == plus_tag && name (son (val)) == cont_tag &&
632
	  exp dest = son(ass);
568
		name (son (son (val))) == name_tag &&
633
	  exp val = bro(dest);
569
		son (son (son (val))) == son (dest) &&
634
	  if (name(dest) == name_tag && isvar(son(dest)) &&
570
		name (bro (son (val))) == val_tag) {
635
	      iscaonly(son(dest)) && shape_size(sh(val)) == 32) {
571
/*
636
/*
572
 
637
 
573
	rep_tag
638
	rep_tag
574
	top_tag	labst_tag
639
	top_tag	labst_tag
575
		count		seq_tag
640
	count		seq_tag
576
				0	seq_tag = final
641
	0	seq_tag = final
577
				body	0	test_tag = te
642
	body	0	test_tag = te
578
					ass_tag = ass
643
	ass_tag = ass
579
					name = dest	plus_tag =val (32)
644
	name = dest	val (32)
580
					var & ca	cont_tag	val_tag
645
	var & ca
581
							name_tag -> dest
-
 
582
*/
646
*/
583
	      exp konst = bro (son (val));
-
 
584
	      int   nt = (int)test_number (te);
-
 
585
	      if (name (son (te)) == cont_tag &&
647
	    if (name(val) == plus_tag && name(son(val)) == cont_tag &&
586
		  name (son (son (te))) == name_tag &&
648
		name(son(son(val))) == name_tag &&
587
		  pt (te) == labst &&
649
		son(son(son(val))) == son(dest) &&
588
		  son (son (son (te))) == son (dest)) {
650
		name(bro(son(val))) == val_tag) {
589
/*
651
/*
590
 
652
 
591
	rep_tag
653
	rep_tag
592
	top_tag	labst_tag
654
	top_tag	labst_tag
-
 
655
	count		seq_tag
-
 
656
	0	seq_tag = final
-
 
657
	body	0	test_tag = te
-
 
658
	ass_tag = ass
-
 
659
	name = dest	plus_tag =val (32)
-
 
660
	var & ca	cont_tag	val_tag
-
 
661
	name_tag -> dest
-
 
662
*/
-
 
663
	      exp konst = bro(son(val));
-
 
664
	      int nt = (int)test_number(te);
-
 
665
	      if (name(son(te)) == cont_tag && name(son(son(te))) == name_tag &&
-
 
666
		  pt(te) == labst && son(son(son(te))) == son(dest)) {
-
 
667
/*
-
 
668
	rep_tag
-
 
669
	top_tag	labst_tag
593
		count	seq_tag
670
	count	seq_tag
594
			0	seq_tag = final
671
	0	seq_tag = final
595
			body	0					test_tag(nt, labst) = te
672
	body	0	test_tag(nt, labst) = te
596
				ass_tag = ass				cont_tag
673
	ass_tag = ass	cont_tag
597
				name = dest	plus_tag =val (32)	name_tag -> dest
674
	name = dest	plus_tag =val (32)	name_tag -> dest
598
				var & ca	cont_tag val_tag = konst
675
	var & ca	cont_tag val_tag = konst
599
						name_tag -> dest
676
	name_tag -> dest
600
*/
677
*/
601
		int   count;
678
		int count;
602
		exp limit = bro(son(te));
679
		exp limit = bro(son(te));
603
		exp unaliased_limit = nilexp;
680
		exp unaliased_limit = nilexp;
604
		int limit_is_aliased = 0;
681
		int limit_is_aliased = 0;
605
 
682
 
606
		if (name(limit) == cont_tag &&
-
 
607
			name(son(limit)) == name_tag &&
683
		if (name(limit) == cont_tag && name(son(limit)) == name_tag &&
608
			isvar(son(son(limit)))) {
684
		    isvar(son(son(limit)))) {
609
/*
685
/*
610
 
-
 
611
	rep_tag
686
	rep_tag
612
	top_tag	labst_tag
687
	top_tag	labst_tag
613
		count	seq_tag
688
	count	seq_tag
614
			0	seq_tag = final
689
	0	seq_tag = final
615
			body	0					test_tag(nt, labst) = te
690
	body	0	test_tag(nt, labst) = te
616
				ass_tag = ass				cont_tag	cont_tag = limit
691
	ass_tag = ass	cont_tag	cont_tag = limit
617
				name = dest	plus_tag =val (32)	name_tag -> dest
692
	name = dest	plus_tag =val (32)	name_tag -> dest
618
				var & ca	cont_tag val_tag = konst
693
	var & ca	cont_tag val_tag = konst
619
						name_tag -> dest
694
	name_tag -> dest
620
*/
695
*/
621
		  if (iscaonly(son(son(limit))))
696
		  if (iscaonly(son(son(limit)))) {
622
		    unaliased_limit = son(son(limit));
697
		    unaliased_limit = son(son(limit));
623
		  else
698
		  } else {
624
		    limit_is_aliased = 1;
699
		    limit_is_aliased = 1;
-
 
700
		  }
625
		};
701
		}
626
 
702
 
627
		names_index = 0;
703
		names_index = 0;
628
		allow_double = 1;
704
		allow_double = 1;
629
		jumps_out = 0;
705
		jumps_out = 0;
630
		count = unroll_complex (body, LIMIT, son (dest),
706
		count = unroll_complex(body, LIMIT, son(dest), limit_is_aliased,
631
				limit_is_aliased, unaliased_limit, 1);
707
				       unaliased_limit, 1);
632
		if (count >= 0) {
708
		if (count >= 0) {
633
		  unroll_trans (candidate, body, ass, te,
709
		  unroll_trans(candidate, body, ass, te, limit, nt, dest, konst,
634
				limit, nt, dest, konst, reps, UNROLL_BY);
710
			       reps, UNROLL_BY);
635
		};
711
		}
636
	      };
712
	      }
637
	    }
-
 
638
	    else {
713
	    } else {
639
	      int count;
714
	      int count;
640
	      names_index = 0;
715
	      names_index = 0;
641
	      allow_double = 0;
716
	      allow_double = 0;
642
	      count = unroll_complex (body, SIMPLE_LIMIT, nilexp,
717
	      count = unroll_complex(body, SIMPLE_LIMIT, nilexp, 0, nilexp, 1);
643
				0, nilexp, 1);
-
 
644
	      if (count >= 0) {
718
	      if (count >= 0) {
645
	        simple_unroll(candidate, body, ass, te);
719
	        simple_unroll(candidate, body, ass, te);
646
	      };
720
	      }
647
  	    };
721
  	    }
648
	  };
722
	  }
649
	}
723
	}
650
      };
724
      }
651
    };
725
    }
652
    reps = pt (reps);
726
    reps = pt(reps);
653
  };
727
  }
654
  return;
728
  return;
655
}
729
}