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/case_opt.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 79... Line 109...
79
#ifndef max_jump_table_size
109
#ifndef max_jump_table_size
80
#define max_jump_table_size 100
110
#define max_jump_table_size 100
81
#endif
111
#endif
82
#ifndef min_no_of_default_destinations
112
#ifndef min_no_of_default_destinations
83
#define min_no_of_default_destinations 3
113
#define min_no_of_default_destinations 3
84
#endif
114
#endif
85
 
115
 
86
static int density PROTO_S ( ( exp *, int, int, int ) ) ;
116
static int density(exp *, int, int, int);
87
static exp exhaustive_conditional_maker PROTO_S ( ( int, int, exp ) ) ;
117
static exp exhaustive_conditional_maker(int, int, exp);
88
static exp inexhaustive_conditional_maker PROTO_S ( ( int, int, exp, exp ) ) ;
118
static exp inexhaustive_conditional_maker(int, int, exp, exp);
89
static exp set_up_sequence PROTO_S ( ( exp, exp, ntest, int, exp, int ) ) ;
119
static exp set_up_sequence(exp, exp, ntest, int, exp, int);
90
static exp set_up_assign PROTO_S ( ( exp, int ) ) ;
120
static exp set_up_assign(exp, int);
91
static exp set_up_unsigned_test PROTO_S ( ( exp, exp, int, ntest ) ) ;
121
static exp set_up_unsigned_test(exp, exp, int, ntest);
92
static exp like_me_q1 PROTO_S ( ( int, ntest, exp, exp, exp, unsigned char ) ) ;
122
static exp like_me_q1(int, ntest, exp, exp, exp, unsigned char);
93
 
123
 
94
 
124
 
95
/* VARIABLES */
125
/* VARIABLES */
96
 
126
 
97
static int  no_of_nodes;
127
static int  no_of_nodes;
98
static  exp * node_start;
128
static exp *node_start;
99
static  exp * node_end;
129
static exp *node_end;
100
static double *node_weight;
130
static double *node_weight;
101
static unsigned char *node_start_flag;
131
static unsigned char *node_start_flag;
102
static unsigned char *node_end_flag;
132
static unsigned char *node_end_flag;
103
 
133
 
104
 
134
 
105
/* PROCEDURES */
135
/* PROCEDURES */
106
 
136
 
107
 
137
 
108
 
138
 
109
 
139
 
110
 
140
 
111
/*
141
/*
112
 * case_optimisation takes a case_tag and an ident_tag and
142
 * case_optimisation takes a case_tag and an ident_tag and
113
 * splits up the case_tag into parts which it thinks should
143
 * splits up the case_tag into parts which it thinks should
114
 * be done as jump tables.
144
 * be done as jump tables.
115
 */
145
 */
116
exp case_optimisation
146
exp
117
    PROTO_N ( (body, id, shape_of_case, control_expression) )
-
 
118
    PROTO_T ( exp body X exp id X shape shape_of_case X exp control_expression )
147
case_optimisation(exp body, exp id, shape shape_of_case, exp control_expression)
119
{
148
{
120
  exp t;
149
	exp t;
121
  exp * ELEMENTS;
150
	exp *ELEMENTS;
122
  int   i;
151
	int i;
123
  int   n;
152
	int n;
124
  int   no_of_cases = 1;
153
	int no_of_cases = 1;
125
  int jump_table_present = 0;
154
	int jump_table_present = 0;
126
 
155
 
127
  no_of_nodes = 0;
156
	no_of_nodes = 0;
128
  /* Calculate the number of cases in the case_tag */
157
	/* Calculate the number of cases in the case_tag */
129
  t = body;
158
	t = body;
130
  while (!last (t)) {
159
	while (!last(t)) {
131
    no_of_cases = no_of_cases + 1;
160
		no_of_cases = no_of_cases + 1;
132
    t = bro (t);
161
		t = bro(t);
133
  }
162
	}
134
 
163
 
135
  ELEMENTS = (exp *) xcalloc (no_of_cases, sizeof (exp));
164
	ELEMENTS = (exp *)xcalloc(no_of_cases, sizeof(exp));
136
  node_start = (exp *) xcalloc (no_of_cases, sizeof (exp));
165
	node_start = (exp *)xcalloc(no_of_cases, sizeof(exp));
137
  node_end = (exp *) xcalloc (no_of_cases, sizeof (exp));
166
	node_end = (exp *)xcalloc(no_of_cases, sizeof(exp));
138
  node_weight = (double *) xcalloc (no_of_cases, sizeof (double));
167
	node_weight = (double *)xcalloc(no_of_cases, sizeof(double));
139
 
168
 
140
  /* Set up the values of these arrays * First set up the ELEMENTS array
169
	/* Set up the values of these arrays * First set up the ELEMENTS array
141
  */
170
	 */
142
  t = body;
171
	t = body;
143
  for (i = 0; i < no_of_cases; i++) {
172
	for (i = 0; i < no_of_cases; i++) {
144
    ELEMENTS[i] = t;
173
		ELEMENTS[i] = t;
145
    t = bro (t);
174
		t = bro(t);
146
  }
175
	}
147
  n = 0;
176
	n = 0;
148
  /* Calculation of where should do jump tables * This sets up the arrays
177
	/* Calculation of where should do jump tables * This sets up the arrays
149
     node_weight, node_start and node_end */
178
	   node_weight, node_start and node_end */
150
  while (n < no_of_cases) {
179
	while (n < no_of_cases) {
151
    int   z;
180
		int z;
152
    double   node_weight_sum = 0.0;
181
		double node_weight_sum = 0.0;
153
    i = no_of_cases - 1;
182
		i = no_of_cases - 1;
-
 
183
		while (density(ELEMENTS, n, i,
154
    while (density (ELEMENTS, n, i, is_signed(sh(control_expression)))
184
			       is_signed(sh(control_expression)))
155
		 < jump_table_density)
185
		       < jump_table_density) {
156
    {
-
 
157
      i--;
186
			i--;
158
    }
187
		}
159
    for (z = n; z <= i; z++) {
188
		for (z = n; z <= i; z++) {
160
      if (son (ELEMENTS[z]) != nilexp) {
189
			if (son(ELEMENTS[z]) != nilexp) {
161
	if (is_signed(sh(control_expression)))
190
				if (is_signed(sh(control_expression))) {
-
 
191
					node_weight_sum +=
162
	  node_weight_sum += ((double) no (son (ELEMENTS[z]))
192
					    ((double)no(son(ELEMENTS[z])) -
163
			      - (double) no (ELEMENTS[z]));
193
					     (double)no(ELEMENTS[z]));
164
	else
194
				} else {
-
 
195
					node_weight_sum +=
165
	  node_weight_sum += ((double) (unsigned long) no (son (ELEMENTS[z]))
196
					    ((double)(unsigned long)no(son(ELEMENTS[z]))
166
			      - (double) (unsigned long) no (ELEMENTS[z]));
197
					     - (double)(unsigned long)no(ELEMENTS[z]));
167
      }
198
				}
-
 
199
			}
168
      node_weight_sum += 1.0;
200
			node_weight_sum += 1.0;
169
    }
201
		}
170
 
202
 
171
    if (node_weight_sum < (double) min_jump_table_size)
203
		if (node_weight_sum < (double)min_jump_table_size) {
172
    {
-
 
173
      i = n;
204
			i = n;
174
    }
205
		}
175
    if (node_weight_sum > (double) max_jump_table_size)
206
		if (node_weight_sum > (double)max_jump_table_size) {
176
    {
-
 
177
      i=n;
207
			i=n;
178
    }
208
		}
179
    if ((i - n) < min_no_of_default_destinations)
209
		if ((i - n) < min_no_of_default_destinations) {
180
    {
-
 
181
      i = n;
210
			i = n;
182
    }
211
		}
183
 
212
 
184
    /* Lump together into a jump_table or a single * Sets up the
213
		/* Lump together into a jump_table or a single * Sets up the
185
       node_start pointers */
214
		   node_start pointers */
186
    node_start[no_of_nodes] = ELEMENTS[n];
215
		node_start[no_of_nodes] = ELEMENTS[n];
187
 
216
 
188
    /* Sets up the node_end pointers */
217
		/* Sets up the node_end pointers */
189
    node_end[no_of_nodes] = (son (ELEMENTS[i]) == nilexp
218
		node_end[no_of_nodes] = (son(ELEMENTS[i]) == nilexp
190
      ? ELEMENTS[i]
-
 
191
      : son (ELEMENTS[i]));
219
					 ? ELEMENTS[i] : son(ELEMENTS[i]));
192
 
220
 
193
    /* sets up the node_weight of the node */
221
		/* sets up the node_weight of the node */
194
    node_weight[no_of_nodes] = 0.0;
222
		node_weight[no_of_nodes] = 0.0;
195
    for (z = n; z <= i; z++) {
223
		for (z = n; z <= i; z++) {
196
      if (son (ELEMENTS[z]) != nilexp) {
224
			if (son(ELEMENTS[z]) != nilexp) {
197
	if (is_signed(sh(control_expression)))
225
				if (is_signed(sh(control_expression))) {
-
 
226
					node_weight[no_of_nodes] +=
198
	  node_weight[no_of_nodes] += ((double) no (son (ELEMENTS[z]))
227
					    ((double)no(son(ELEMENTS[z])) -
199
				       - (double) no (ELEMENTS[z]));
228
					     (double)no(ELEMENTS[z]));
200
        else
229
				} else {
-
 
230
					node_weight[no_of_nodes] +=
201
	  node_weight[no_of_nodes] += ((double) (unsigned long) no (son (ELEMENTS[z]))
231
					    ((double)(unsigned long)no(son(ELEMENTS[z])) -
202
				       - (double) (unsigned long) no (ELEMENTS[z]));
232
					     (double)(unsigned long)no(ELEMENTS[z]));
203
      }
233
				}
-
 
234
			}
204
      node_weight[no_of_nodes] += 1.0;
235
			node_weight[no_of_nodes] += 1.0;
205
    }
236
		}
206
    if (n != i)
237
		if (n != i) {
207
    {
-
 
208
      jump_table_present = 1;
238
			jump_table_present = 1;
209
    }
239
		}
210
 
240
 
211
    no_of_nodes = no_of_nodes + 1;
241
		no_of_nodes = no_of_nodes + 1;
212
    bro (ELEMENTS[i]) = nilexp;
242
		bro(ELEMENTS[i]) = nilexp;
213
    /* Chops up the list for later use */
243
		/* Chops up the list for later use */
214
    setlast (ELEMENTS[i]);
244
		setlast(ELEMENTS[i]);
215
    /* Sets the last of ELEMENTS[i] so can be substituted directly into
245
		/* Sets the last of ELEMENTS[i] so can be substituted directly into
216
       new case_tag's */
246
		   new case_tag's */
217
    n = i + 1;
247
		n = i + 1;
218
  }
248
	}
219
 
249
 
220
#if has_byte_ops
250
#if has_byte_ops
221
  if (!jump_table_present) {
251
	if (!jump_table_present) {
222
    kill_exp(son(id), son(id));
252
		kill_exp(son(id), son(id));
223
    son(id) = control_expression;
253
		son(id) = control_expression;
224
    sh(id) = sh(control_expression);
254
		sh(id) = sh(control_expression);
225
    t = body;
255
		t = body;
226
    for (;;) {
256
		for (;;) {
227
      sh(t) = sh(control_expression);
257
			sh(t) = sh(control_expression);
228
      if (son(t) != nilexp)
258
			if (son(t) != nilexp) {
229
	sh(son(t)) = sh(control_expression);
259
				sh(son(t)) = sh(control_expression);
-
 
260
			}
230
      if (last(t))
261
			if (last(t)) {
231
	break;
262
				break;
232
    }
263
			}
233
  }
264
		}
234
  else {
265
	} else {
235
    kill_exp(control_expression, control_expression);
266
		kill_exp(control_expression, control_expression);
236
  }
267
	}
237
#else
268
#else
238
  kill_exp(control_expression, control_expression);
269
	kill_exp(control_expression, control_expression);
239
  UNUSED(jump_table_present);
270
	UNUSED(jump_table_present);
240
#endif
271
#endif
241
 
272
 
242
  /* Set up the node_start_flag and node_end_flag arrays */
273
	/* Set up the node_start_flag and node_end_flag arrays */
243
  node_start_flag =
274
	node_start_flag =
244
    (unsigned char *) xcalloc (no_of_nodes, sizeof (unsigned char));
275
	    (unsigned char *)xcalloc(no_of_nodes, sizeof(unsigned char));
245
  node_end_flag =
276
	node_end_flag =
246
    (unsigned char *) xcalloc (no_of_nodes, sizeof (unsigned char));
277
	    (unsigned char *)xcalloc(no_of_nodes, sizeof(unsigned char));
247
  for (i=0; i < no_of_nodes; i++) {
278
	for (i=0; i < no_of_nodes; i++) {
248
    node_start_flag[i] = node_end_flag[i] = 0;
279
		node_start_flag[i] = node_end_flag[i] = 0;
249
  }
280
	}
250
  if (shape_of_case == f_bottom)
281
	if (shape_of_case == f_bottom) {
251
  {
-
 
252
    t = exhaustive_conditional_maker (0, no_of_nodes - 1, id);
282
		t = exhaustive_conditional_maker(0, no_of_nodes - 1, id);
253
  }
283
	}
254
  if (shape_of_case == f_top) {
284
	if (shape_of_case == f_top) {
255
    exp COND__TAG;
285
		exp COND__TAG;
256
    exp LABST__TAG;
286
		exp LABST__TAG;
257
    exp TOP__TAG;
287
		exp TOP__TAG;
258
    exp CLEAR__TAG;
288
		exp CLEAR__TAG;
259
 
289
 
260
    TOP__TAG = getexp (f_top, nilexp, 0, nilexp, nilexp, 0, 0, top_tag);
290
		TOP__TAG = getexp(f_top, nilexp, 0, nilexp, nilexp, 0, 0,
-
 
291
				  top_tag);
261
    CLEAR__TAG = getexp (f_top, nilexp, 0, nilexp, nilexp,
292
		CLEAR__TAG = getexp(f_top, nilexp, 0, nilexp, nilexp, 0, 0,
262
	0, 0, clear_tag);
293
				    clear_tag);
263
    LABST__TAG = me_b3 (sh (TOP__TAG), CLEAR__TAG, TOP__TAG, labst_tag);
294
		LABST__TAG = me_b3(sh(TOP__TAG), CLEAR__TAG, TOP__TAG,
-
 
295
				   labst_tag);
264
    t = inexhaustive_conditional_maker (0, no_of_nodes - 1, id,
296
		t = inexhaustive_conditional_maker(0, no_of_nodes - 1, id,
265
	LABST__TAG);
297
						   LABST__TAG);
266
    COND__TAG = me_b3 (f_top, t, LABST__TAG, cond_tag);
298
		COND__TAG = me_b3(f_top, t, LABST__TAG, cond_tag);
267
    t = COND__TAG;
299
		t = COND__TAG;
268
  }
300
	}
269
  xfree ((void*)ELEMENTS);
301
	xfree((void*)ELEMENTS);
270
  xfree ((void*)node_start);
302
	xfree((void*)node_start);
271
  xfree ((void*)node_end);
303
	xfree((void*)node_end);
272
  xfree ((void*)node_weight);
304
	xfree((void*)node_weight);
273
  xfree ((void*)node_start_flag);
305
	xfree((void*)node_start_flag);
274
  xfree ((void*)node_end_flag);
306
	xfree((void*)node_end_flag);
275
  return t;
307
	return t;
276
}
308
}
277
 
-
 
278
 
-
 
279
 
309
 
280
 
310
 
281
/*
311
/*
282
 * density is used for calculating whether the elements of the
312
 * density is used for calculating whether the elements of the
283
 * case_tag should be made into jump tables.
313
 * case_tag should be made into jump tables.
284
 */
314
 */
285
static int   density
315
static int
286
    PROTO_N ( (ELEMENTS, start, end, sgn) )
-
 
287
    PROTO_T ( exp * ELEMENTS X int start X int end X int sgn )
316
density(exp *ELEMENTS, int start, int end, int sgn)
288
{
317
{
289
  int   index;
318
	int index;
290
  double numerator;
319
	double numerator;
291
  double denominator;
320
	double denominator;
292
 
321
 
293
  if (son (ELEMENTS[end]) == nilexp)
322
	if (son(ELEMENTS[end]) == nilexp) {
294
  {
-
 
295
    if (sgn)
323
		if (sgn) {
296
      denominator = (double) no (ELEMENTS[end]) - (double) no (ELEMENTS[start]);
324
			denominator = (double)no(ELEMENTS[end]) -
-
 
325
			    (double)no(ELEMENTS[start]);
297
    else
326
		} else {
298
      denominator = (double) (unsigned long) no (ELEMENTS[end])
327
			denominator = (double)(unsigned long)no(ELEMENTS[end]) -
299
	- (double) (unsigned long) no (ELEMENTS[start]);
328
			    (double)(unsigned long)no(ELEMENTS[start]);
300
  }
329
		}
301
  else
330
	} else {
302
  {
-
 
303
    if (sgn)
331
		if (sgn) {
304
      denominator = (double) no (son (ELEMENTS[end])) - (double) no (ELEMENTS[start]);
332
			denominator = (double)no(son(ELEMENTS[end])) -
-
 
333
			    (double)no(ELEMENTS[start]);
305
    else
334
		} else {
-
 
335
			denominator =
306
      denominator = (double) (unsigned long) no (son (ELEMENTS[end]))
336
			    (double)(unsigned long)no(son(ELEMENTS[end])) -
307
	- (double) (unsigned long) no (ELEMENTS[start]);
337
			    (double)(unsigned long)no(ELEMENTS[start]);
308
  }
338
		}
-
 
339
	}
309
 
340
 
310
  denominator = denominator + 1.0;
341
	denominator = denominator + 1.0;
311
  numerator = 0.0;
342
	numerator = 0.0;
312
  for (index = start; index <= end; index++) {
343
	for (index = start; index <= end; index++) {
313
    if (son (ELEMENTS[index]) == nilexp)
344
		if (son(ELEMENTS[index]) == nilexp) {
314
    {
-
 
315
      numerator = numerator + 1.0;
345
			numerator = numerator + 1.0;
316
    }
-
 
317
    else
346
		} else {
318
    {
347
			if (sgn) {
319
      if (sgn)
348
				numerator = numerator +
320
	numerator = numerator + ((double) no (son (ELEMENTS[index]))
349
				    ((double)no(son(ELEMENTS[index])) -
321
				 - (double) no (ELEMENTS[index])) + 1.0;
350
				     (double)no(ELEMENTS[index])) + 1.0;
322
      else
351
			} else {
-
 
352
				numerator = numerator +
323
	numerator = numerator + ((double) (unsigned long) no (son (ELEMENTS[index]))
353
				    ((double)(unsigned long)no(son(ELEMENTS[index])) -
324
				 - (double) (unsigned long) no (ELEMENTS[index])) + 1.0;
354
				     (double)(unsigned long)no(ELEMENTS[index])) + 1.0;
325
    }
355
			}
326
  }
356
		}
-
 
357
	}
327
  return ((int) (100.0*(numerator/denominator)));
358
	return((int)(100.0 * (numerator / denominator)));
328
}
359
}
329
 
-
 
330
 
360
 
331
 
361
 
332
/*
362
/*
333
 * set_up_sequence creates a simple sequence with a
363
 * set_up_sequence creates a simple sequence with a
334
 * test_tag.
364
 * test_tag.
335
 */
365
 */
336
static exp set_up_sequence
366
static exp
337
    PROTO_N ( (left, right, test, integer_value, id, probability) )
367
set_up_sequence(exp left, exp right, ntest test, int integer_value, exp id,
338
    PROTO_T ( exp left X exp right X ntest test X int integer_value X exp id X int probability )
368
		int probability)
339
{
369
{
340
  exp SEQ__TAG;
370
	exp SEQ__TAG;
341
  exp ZERO__TAG;
371
	exp ZERO__TAG;
342
  exp TEST__TAG;
372
	exp TEST__TAG;
343
  exp NAME__TAG;
373
	exp NAME__TAG;
344
  exp VAL__TAG;
374
	exp VAL__TAG;
345
  exp CONT__TAG;
375
	exp CONT__TAG;
346
 
376
 
347
  /* sets up the test_tag                      */
377
	/* sets up the test_tag */
348
  NAME__TAG = me_obtain (id);
378
	NAME__TAG = me_obtain(id);
349
  CONT__TAG = me_u3 (sh (id), NAME__TAG, cont_tag);
379
	CONT__TAG = me_u3(sh(id), NAME__TAG, cont_tag);
350
  VAL__TAG = me_shint (sh (CONT__TAG), integer_value);
380
	VAL__TAG = me_shint(sh(CONT__TAG), integer_value);
351
  TEST__TAG = like_me_q1 (probability, test, right, CONT__TAG,
381
	TEST__TAG = like_me_q1(probability, test, right, CONT__TAG, VAL__TAG,
352
      VAL__TAG, test_tag);
382
			       test_tag);
353
  /* sets up the seq_tag for the conditional   */
383
	/* sets up the seq_tag for the conditional */
354
  ZERO__TAG = me_u3 (f_top, TEST__TAG, 0);
384
	ZERO__TAG = me_u3(f_top, TEST__TAG, 0);
355
  SEQ__TAG = me_b3 (sh (left), ZERO__TAG, left, seq_tag);
385
	SEQ__TAG = me_b3(sh(left), ZERO__TAG, left, seq_tag);
356
  return SEQ__TAG;
386
	return SEQ__TAG;
357
}
387
}
358
 
-
 
359
 
-
 
360
 
388
 
361
 
389
 
362
/*
390
/*
363
 * set_up_conditional creates a conditional based on a simple
391
 * set_up_conditional creates a conditional based on a simple
364
 * integer test.
392
 * integer test.
365
 */
393
 */
366
static exp set_up_conditional
394
static exp
367
    PROTO_N ( (left, right, test, integer_value, id, probability) )
395
set_up_conditional(exp left, exp right, ntest test, int integer_value, exp id,
368
    PROTO_T ( exp left X exp right X ntest test X int integer_value X exp id X int probability )
396
		   int probability)
369
{
397
{
370
  exp CLEAR__TAG;
398
	exp CLEAR__TAG;
371
  exp LABST__TAG;
399
	exp LABST__TAG;
372
  exp NAME__TAG;
400
	exp NAME__TAG;
373
  exp VAL__TAG;
401
	exp VAL__TAG;
374
  exp TEST__TAG;
402
	exp TEST__TAG;
375
  exp ZERO__TAG;
403
	exp ZERO__TAG;
376
  exp SEQ__TAG;
404
	exp SEQ__TAG;
377
  exp COND__TAG;
405
	exp COND__TAG;
378
  exp CONT__TAG;
406
	exp CONT__TAG;
379
 
407
 
380
  /* Sets up the labst_tag for the conditional */
408
	/* Sets up the labst_tag for the conditional */
381
  CLEAR__TAG = getexp (f_top, nilexp, 0, nilexp, nilexp, 0, 0, clear_tag);
409
	CLEAR__TAG = getexp(f_top, nilexp, 0, nilexp, nilexp, 0, 0, clear_tag);
382
  LABST__TAG = me_b3 (sh (right), CLEAR__TAG, right, labst_tag);
410
	LABST__TAG = me_b3(sh(right), CLEAR__TAG, right, labst_tag);
383
  /* sets up the test_tag                      */
411
	/* sets up the test_tag */
384
  NAME__TAG = me_obtain (id);
412
	NAME__TAG = me_obtain(id);
385
  CONT__TAG = me_u3 (sh (id), NAME__TAG, cont_tag);
413
	CONT__TAG = me_u3(sh(id), NAME__TAG, cont_tag);
386
  VAL__TAG = me_shint (sh (CONT__TAG), integer_value);
414
	VAL__TAG = me_shint(sh(CONT__TAG), integer_value);
387
  TEST__TAG = like_me_q1 (probability, test, LABST__TAG,
415
	TEST__TAG = like_me_q1(probability, test, LABST__TAG, CONT__TAG,
388
      CONT__TAG, VAL__TAG, test_tag);
416
			       VAL__TAG, test_tag);
389
  /* sets up the seq_tag for the conditional   */
417
	/* sets up the seq_tag for the conditional */
390
  ZERO__TAG = me_u3 (f_top, TEST__TAG, 0);
418
	ZERO__TAG = me_u3(f_top, TEST__TAG, 0);
391
  SEQ__TAG = me_b3 (sh (left), ZERO__TAG, left, seq_tag);
419
	SEQ__TAG = me_b3(sh(left), ZERO__TAG, left, seq_tag);
392
  /* sets up the cond_tag                      */
420
	/* sets up the cond_tag */
393
  COND__TAG = me_b3 (f_bottom, SEQ__TAG, LABST__TAG, cond_tag);
421
	COND__TAG = me_b3(f_bottom, SEQ__TAG, LABST__TAG, cond_tag);
394
  return COND__TAG;
422
	return COND__TAG;
395
}
423
}
396
 
-
 
397
 
-
 
398
 
424
 
399
 
425
 
400
/*
426
/*
401
 * set_up_exhaustive_case does exactly what it suggests.
427
 * set_up_exhaustive_case does exactly what it suggests.
402
 */
428
 */
403
static exp set_up_exhaustive_case
429
static exp
404
    PROTO_N ( (body_of_case, id) )
-
 
405
    PROTO_T ( exp body_of_case X exp id )
430
set_up_exhaustive_case(exp body_of_case, exp id)
406
{
431
{
407
  exp NAME__TAG;
432
	exp NAME__TAG;
408
  exp CASE__TAG;
433
	exp CASE__TAG;
409
  exp CONT__TAG;
434
	exp CONT__TAG;
410
  exp r;
435
	exp r;
411
 
436
 
412
  NAME__TAG = me_obtain (id);
437
	NAME__TAG = me_obtain(id);
413
  CONT__TAG = me_u3 (sh (id), NAME__TAG, cont_tag);
438
	CONT__TAG = me_u3(sh(id), NAME__TAG, cont_tag);
414
  CASE__TAG = getexp (f_bottom, nilexp, 0, CONT__TAG, nilexp,
439
	CASE__TAG = getexp(f_bottom, nilexp, 0, CONT__TAG, nilexp, 0, 0,
415
      0, 0, case_tag);
440
			   case_tag);
416
  bro (CONT__TAG) = body_of_case;
441
	bro(CONT__TAG) = body_of_case;
417
  clearlast (CONT__TAG);
442
	clearlast(CONT__TAG);
418
  r = body_of_case;
443
	r = body_of_case;
419
  while (!last (r))
444
	while (!last(r)) {
420
  {
-
 
421
    r = bro (r);
445
		r = bro(r);
422
  }
446
	}
423
 
447
 
424
  bro (r) = CASE__TAG;
448
	bro(r) = CASE__TAG;
425
  return CASE__TAG;
449
	return CASE__TAG;
426
}
450
}
427
 
-
 
428
 
-
 
429
 
451
 
430
 
452
 
431
/*
453
/*
432
 * set_up_inexhaustive_case does exactly what it suggests.
454
 * set_up_inexhaustive_case does exactly what it suggests.
433
 */
455
 */
434
static exp set_up_inexhaustive_case
456
static exp
435
    PROTO_N ( (body_of_case, id, default_exp) )
-
 
436
    PROTO_T ( exp body_of_case X exp id X exp default_exp )
457
set_up_inexhaustive_case(exp body_of_case, exp id, exp default_exp)
437
{
458
{
438
  exp NAME__TAG;
459
	exp NAME__TAG;
439
  exp GOTO__TAG;
460
	exp GOTO__TAG;
440
  exp CASE__TAG;
461
	exp CASE__TAG;
441
  exp ZERO__TAG;
462
	exp ZERO__TAG;
442
  exp SEQ__TAG;
463
	exp SEQ__TAG;
443
  exp CONT__TAG;
464
	exp CONT__TAG;
444
  exp r;
465
	exp r;
445
 
466
 
446
  NAME__TAG = me_obtain (id);
467
	NAME__TAG = me_obtain(id);
447
  CONT__TAG = me_u3 (sh (id), NAME__TAG, cont_tag);
468
	CONT__TAG = me_u3(sh(id), NAME__TAG, cont_tag);
448
  /* shape of case is f_top since it is not exhaustive */
469
	/* shape of case is f_top since it is not exhaustive */
449
  CASE__TAG = getexp (f_top, nilexp, 0, CONT__TAG, nilexp,
470
	CASE__TAG = getexp(f_top, nilexp, 0, CONT__TAG, nilexp, 0, 0, case_tag);
450
      0, 0, case_tag);
-
 
451
  bro (CONT__TAG) = body_of_case;
471
	bro(CONT__TAG) = body_of_case;
452
  clearlast (CONT__TAG);
472
	clearlast(CONT__TAG);
453
  r = body_of_case;
473
	r = body_of_case;
454
  while (!last (r))
474
	while (!last(r)) {
455
    r = bro (r);
475
		r = bro(r);
-
 
476
	}
456
  bro (r) = CASE__TAG;
477
	bro(r) = CASE__TAG;
457
  GOTO__TAG = getexp (f_bottom, nilexp, 0, nilexp, nilexp,
478
	GOTO__TAG = getexp(f_bottom, nilexp, 0, nilexp, nilexp, 0, 0, goto_tag);
458
      0, 0, goto_tag);
-
 
459
  pt (GOTO__TAG) = default_exp;
479
	pt(GOTO__TAG) = default_exp;
460
  no (son (default_exp))++;
480
	no(son(default_exp)) ++;
461
  ZERO__TAG = me_u3 (f_top, CASE__TAG, 0);
481
	ZERO__TAG = me_u3(f_top, CASE__TAG, 0);
462
  /* doesn't matter what shape zero_tag is */
482
	/* doesn't matter what shape zero_tag is */
463
  SEQ__TAG = me_b3 (f_bottom, ZERO__TAG, GOTO__TAG, seq_tag);
483
	SEQ__TAG = me_b3(f_bottom, ZERO__TAG, GOTO__TAG, seq_tag);
464
  return SEQ__TAG;
484
	return SEQ__TAG;
465
}
485
}
-
 
486
 
466
 
487
 
467
/*
488
/*
468
 * like_me_q1 sets up a test_tag and is very similar to me_q1.
489
 * like_me_q1 sets up a test_tag and is very similar to me_q1.
469
 * me_q1 is found in me_fns.c
490
 * me_q1 is found in me_fns.c
470
 */
491
 */
471
static exp like_me_q1
492
static exp
472
    PROTO_N ( (prob, nt, lab, arg1, arg2, nm) )
-
 
473
    PROTO_T ( int prob X ntest nt X exp lab X exp arg1 X exp arg2 X unsigned char nm )
493
like_me_q1(int prob, ntest nt, exp lab, exp arg1, exp arg2, unsigned char nm)
474
{
494
{
475
  exp r;
495
	exp r;
476
 
496
 
477
  r = getexp (f_top, nilexp, 0, arg1, lab, 0, 0, nm);
497
	r = getexp(f_top, nilexp, 0, arg1, lab, 0, 0, nm);
478
  no (r) = prob;
498
	no(r) = prob;
479
  settest_number (r, nt);
499
	settest_number(r, nt);
480
  setbro (arg1, arg2);
500
	setbro(arg1, arg2);
481
  clearlast (arg1);
501
	clearlast(arg1);
482
  ++no (son (lab));
502
	++no(son(lab));
483
  setfather (r, arg2);
503
	setfather(r, arg2);
484
  return r;
504
	return r;
485
}
505
}
486
 
-
 
487
 
-
 
488
 
506
 
489
 
507
 
490
/*
508
/*
491
 *  find_the_split_value is used by exhaustive_conditional_maker
509
 *  find_the_split_value is used by exhaustive_conditional_maker
492
 *  and inexhaustive_conditional_maker in order to calculate
510
 *  and inexhaustive_conditional_maker in order to calculate
493
 *  where to do a comparison.
511
 *  where to do a comparison.
494
 */
512
 */
495
static int   find_the_split_value
513
static int
496
    PROTO_N ( (start, end) )
-
 
497
    PROTO_T ( int start X int end )
514
find_the_split_value(int start, int end)
498
{
515
{
499
  int   w;
516
	int w;
500
  int   split_value;
517
	int split_value;
501
  double   halfway_value;
518
	double halfway_value;
502
  double   best_diff;
519
	double best_diff;
503
  double   count;
520
	double count;
504
 
521
 
505
  count = 0.0;
522
	count = 0.0;
506
  halfway_value = 0.0;
523
	halfway_value = 0.0;
507
  for (w = start; w <= end; w++)
524
	for (w = start; w <= end; w++) {
508
  {
-
 
509
    halfway_value += node_weight[w];
525
		halfway_value += node_weight[w];
510
  }
526
	}
511
  halfway_value = halfway_value / 2.0;
527
	halfway_value = halfway_value / 2.0;
512
  best_diff = node_weight[start] - halfway_value;
528
	best_diff = node_weight[start] - halfway_value;
513
  if (best_diff < 0.0)
529
	if (best_diff < 0.0) {
514
  {
-
 
515
    best_diff = - best_diff;
530
		best_diff = - best_diff;
516
  }
531
	}
517
  split_value = start;
532
	split_value = start;
518
  for (w = start; w <= end; w++) {
533
	for (w = start; w <= end; w++) {
519
    count += node_weight[w];
534
		count += node_weight[w];
520
    if ((count - halfway_value) < best_diff
535
		if ((count - halfway_value) < best_diff &&
521
	&& (halfway_value - count) < best_diff)
536
		    (halfway_value - count) < best_diff) {
522
    {
-
 
523
      split_value = w;
537
			split_value = w;
524
      best_diff = count - halfway_value;
538
			best_diff = count - halfway_value;
525
      if (best_diff < 0.0)
539
			if (best_diff < 0.0) {
526
      {
-
 
527
	best_diff = - best_diff;
540
				best_diff = - best_diff;
528
      }
541
			}
529
    }
542
		}
530
  }
543
	}
531
  return split_value;
544
	return split_value;
532
}
545
}
533
 
-
 
534
 
546
 
535
 
-
 
536
 
547
 
537
/*
548
/*
538
 * exhaustive_conditional_maker is the recursive routine for
549
 * exhaustive_conditional_maker is the recursive routine for
539
 * making the internal transformed tdf in the case of an
550
 * making the internal transformed tdf in the case of an
540
 * exhaustive case_tag.
551
 * exhaustive case_tag.
541
 */
552
 */
542
static exp exhaustive_conditional_maker
553
static exp
543
    PROTO_N ( (start, end, id) )
-
 
544
    PROTO_T ( int start X int end X exp id )
554
exhaustive_conditional_maker(int start, int end, exp id)
545
{
555
{
546
  int   split_value;
556
	int split_value;
547
  exp option_left;
557
	exp option_left;
548
  exp option_right;
558
	exp option_right;
549
  exp t;
559
	exp t;
550
 
560
 
551
  /* first test to see if we have only one node */
561
	/* first test to see if we have only one node */
552
  if (start == end) {
562
	if (start == end) {
553
    /* Check to see if not a jump table      */
563
		/* Check to see if not a jump table */
554
    if (bro (node_start[start]) == nilexp) {
564
		if (bro(node_start[start]) == nilexp) {
555
      t = getexp (f_bottom, nilexp, 0, nilexp, nilexp, 0, 0, goto_tag);
565
			t = getexp(f_bottom, nilexp, 0, nilexp, nilexp, 0, 0,
-
 
566
				   goto_tag);
556
      pt (t) = pt (node_start[start]);
567
			pt(t) = pt(node_start[start]);
557
      return t;
568
			return t;
558
    }
-
 
559
    else {
569
		} else {
560
      /* We must have to make a jump table    */
570
			/* We must have to make a jump table */
561
      return set_up_exhaustive_case (node_start[start], id);
571
			return set_up_exhaustive_case(node_start[start], id);
562
    }
572
		}
563
  }
573
	}
564
  split_value = find_the_split_value (start, end);
574
	split_value = find_the_split_value(start, end);
565
  if (split_value == end)
575
	if (split_value == end) {
566
    split_value --;
576
		split_value --;
-
 
577
	}
567
  option_left = exhaustive_conditional_maker (split_value + 1, end, id);
578
	option_left = exhaustive_conditional_maker(split_value + 1, end, id);
568
  option_right = exhaustive_conditional_maker (start, split_value, id);
579
	option_right = exhaustive_conditional_maker(start, split_value, id);
569
  return set_up_conditional (option_left, option_right,
580
	return set_up_conditional(option_left, option_right,
570
      f_greater_than_or_equal,
581
				  f_greater_than_or_equal,
571
      no (node_start[split_value + 1]),
582
				  no(node_start[split_value + 1]), id, 1000);
572
      id, 1000);
-
 
573
}
583
}
574
 
-
 
575
 
-
 
576
 
584
 
577
 
585
 
578
/*
586
/*
579
 * inexhaustive_conditional_maker is the recursive routine for
587
 * inexhaustive_conditional_maker is the recursive routine for
580
 * making the internal transformed tdf in the case of an
588
 * making the internal transformed tdf in the case of an
581
 * inexhaustive case_tag.
589
 * inexhaustive case_tag.
801
 
849
 
802
    option_right =
850
		option_right =
803
      inexhaustive_conditional_maker (start, split_value,
851
		    inexhaustive_conditional_maker(start, split_value, id,
804
	id, default_exp);
852
						   default_exp);
805
    option_left =
853
		option_left =
806
      inexhaustive_conditional_maker (split_value + 1, end,
854
		    inexhaustive_conditional_maker(split_value + 1, end, id,
807
	id, default_exp);
855
						   default_exp);
808
    return set_up_conditional (option_left, option_right,
856
		return set_up_conditional(option_left, option_right,
-
 
857
					  f_greater_than,
809
	f_greater_than, no (node_end[split_value]), id, 1000);
858
					  no(node_end[split_value]), id, 1000);
810
  }
859
	}
811
}
860
}
812
 
-
 
813
 
861
 
814
 
862
 
815
/*
863
/*
816
 * set_up_assign takes a variable and adds an integer to
864
 * set_up_assign takes a variable and adds an integer to
817
 * it, and replaces it.
865
 * it, and replaces it.
818
 */
866
 */
819
static exp set_up_assign
867
static exp
820
    PROTO_N ( (id, number) )
-
 
821
    PROTO_T ( exp id X int number )
868
set_up_assign(exp id, int number)
822
{
869
{
823
  exp NAME__TAG;
870
	exp NAME__TAG;
824
  exp VAL__TAG;
871
	exp VAL__TAG;
825
  exp CONT__TAG;
872
	exp CONT__TAG;
826
  exp PLUS__TAG;
873
	exp PLUS__TAG;
827
  exp ASSIGN__TAG;
874
	exp ASSIGN__TAG;
828
 
875
 
829
  NAME__TAG = me_obtain (id);
876
	NAME__TAG = me_obtain(id);
830
  VAL__TAG = me_shint (sh (id), number);
877
	VAL__TAG = me_shint(sh(id), number);
831
  CONT__TAG = me_u3 (sh (id), NAME__TAG, cont_tag);
878
	CONT__TAG = me_u3(sh(id), NAME__TAG, cont_tag);
832
  PLUS__TAG = me_b3 (sh (id), CONT__TAG, VAL__TAG, plus_tag);
879
	PLUS__TAG = me_b3(sh(id), CONT__TAG, VAL__TAG, plus_tag);
833
  ASSIGN__TAG = me_b3 (f_top, me_obtain (id), PLUS__TAG, ass_tag);
880
	ASSIGN__TAG = me_b3(f_top, me_obtain(id), PLUS__TAG, ass_tag);
834
  return ASSIGN__TAG;
881
	return ASSIGN__TAG;
835
}
882
}
-
 
883
 
-
 
884
 
836
/*
885
/*
837
 * set_up_unsigned_test returns a test_tag. The test is
886
 * set_up_unsigned_test returns a test_tag. The test is
838
 * specified, along with the value to be tested against
887
 * specified, along with the value to be tested against
839
 * the default_exp labst_tag and the var_tag to test
888
 * the default_exp labst_tag and the var_tag to test
840
 * against.
889
 * against.
841
 */
890
 */
842
static exp set_up_unsigned_test
891
static exp
843
    PROTO_N ( (default_exp, id, test_value, test) )
-
 
844
    PROTO_T ( exp default_exp X exp id X int test_value X ntest test )
892
set_up_unsigned_test(exp default_exp, exp id, int test_value, ntest test)
845
{
893
{
846
  exp NAME__TAG;
894
	exp NAME__TAG;
847
  exp CHVAR__TAG;
895
	exp CHVAR__TAG;
848
  exp CONT__TAG;
896
	exp CONT__TAG;
849
  exp VAL__TAG;
897
	exp VAL__TAG;
850
  exp TEST__TAG;
898
	exp TEST__TAG;
851
 
899
 
852
  NAME__TAG = me_obtain (id);
900
	NAME__TAG = me_obtain(id);
853
  CONT__TAG = me_u3 (sh (id), NAME__TAG, cont_tag);
901
	CONT__TAG = me_u3(sh(id), NAME__TAG, cont_tag);
854
  CHVAR__TAG = hold_check(me_u3 (ulongsh, CONT__TAG, chvar_tag));
902
	CHVAR__TAG = hold_check(me_u3(ulongsh, CONT__TAG, chvar_tag));
855
  VAL__TAG = me_shint (ulongsh, test_value);
903
	VAL__TAG = me_shint(ulongsh, test_value);
856
  TEST__TAG = like_me_q1 (1000, test, default_exp, CHVAR__TAG,
904
	TEST__TAG = like_me_q1(1000, test, default_exp, CHVAR__TAG, VAL__TAG,
857
      VAL__TAG, test_tag);
905
			       test_tag);
858
  return TEST__TAG;
906
	return TEST__TAG;
859
}
907
}