Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – tendra.SVN – Blame – /branches/tendra5-amd64/src/installers/common/construct/unroll.c – Rev 6

Subversion Repositories tendra.SVN

Rev

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

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