irconsconfirm.c 16.9 KB
Newer Older
Michael Beck's avatar
Michael Beck committed
1
/*
Michael Beck's avatar
Michael Beck committed
2
 * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
Matthias Braun's avatar
Matthias Braun committed
3
4
 *
 * This file is part of libFirm.
Michael Beck's avatar
Michael Beck committed
5
 *
Matthias Braun's avatar
Matthias Braun committed
6
7
8
9
 * This file may be distributed and/or modified under the terms of the
 * GNU General Public License version 2 as published by the Free Software
 * Foundation and appearing in the file LICENSE.GPL included in the
 * packaging of this file.
Michael Beck's avatar
Michael Beck committed
10
 *
Matthias Braun's avatar
Matthias Braun committed
11
12
13
14
15
16
17
 * Licensees holding valid libFirm Professional Edition licenses may use
 * this file in accordance with the libFirm Commercial License.
 * Agreement provided with the Software.
 *
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE.
Michael Beck's avatar
Michael Beck committed
18
 */
19

Matthias Braun's avatar
Matthias Braun committed
20
21
22
23
24
25
26
/**
 * @file
 * @brief    Construction of Confirm nodes
 * @author   Michael Beck
 * @date     6.2005
 * @version  $Id$
 */
Matthias Braun's avatar
Matthias Braun committed
27
#include "config.h"
28

Michael Beck's avatar
Michael Beck committed
29
30
31
32
33
34
#include "irgraph_t.h"
#include "irnode_t.h"
#include "ircons_t.h"
#include "irgmod.h"
#include "iropt_dbg.h"
#include "iredges_t.h"
Michael Beck's avatar
Michael Beck committed
35
#include "irgwalk.h"
Michael Beck's avatar
Michael Beck committed
36
#include "irprintf.h"
37
#include "irgopt.h"
Matthias Braun's avatar
Matthias Braun committed
38
#include "irtools.h"
39
#include "array_t.h"
40
41
#include "debug.h"
#include "irflag.h"
Michael Beck's avatar
Michael Beck committed
42
43
44
45
46

/**
 * Walker environment.
 */
typedef struct _env_t {
47
48
49
50
	unsigned num_confirms;  /**< Number of inserted Confirm nodes. */
	unsigned num_consts;    /**< Number of constants placed. */
	unsigned num_eq;        /**< Number of equalities placed. */
	unsigned num_non_null;  /**< Number of non-null Confirms. */
Michael Beck's avatar
Michael Beck committed
51
52
} env_t;

53
54
55
/** The debug handle. */
DEBUG_ONLY(static firm_dbg_module_t *dbg;)

56
57
58
59
60
61
62
63
64
/**
 * Return the effective use block of a node and it's predecessor on
 * position pos.
 *
 * @param node  the node
 * @param pos   the position of the used input
 *
 * This handles correctly Phi nodes.
 */
Michael Beck's avatar
Michael Beck committed
65
static ir_node *get_effective_use_block(ir_node *node, int pos) {
66
	if (is_Phi(node)) {
67
68
69
		/* the effective use of a Phi argument is in its predecessor block */
		node = get_nodes_block(node);
		return get_Block_cfgpred_block(node, pos);
70
71
	}
	return get_nodes_block(node);
72
73
}

Michael Beck's avatar
Michael Beck committed
74
75
76
77
78
/**
 * Handle a CASE-branch.
 *
 * @param block   the block which is entered by the branch
 * @param irn     the node expressing the switch value
Michael Beck's avatar
Michael Beck committed
79
 * @param nr      the branch label
Michael Beck's avatar
Michael Beck committed
80
81
82
83
84
 * @param env     statistical environment
 *
 * Branch labels are a simple case. We can replace the value
 * by a Const with the branch label.
 */
Michael Beck's avatar
Michael Beck committed
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
static void handle_case(ir_node *block, ir_node *irn, long nr, env_t *env) {
	const ir_edge_t *edge, *next;
	ir_node *c = NULL;

	if (is_Bad(irn))
		return;

	for (edge = get_irn_out_edge_first(irn); edge; edge = next) {
		ir_node *succ = get_edge_src_irn(edge);
		int     pos   = get_edge_src_pos(edge);
		ir_node *blk  = get_effective_use_block(succ, pos);

		next = get_irn_out_edge_next(irn, edge);

		if (block_dominates(block, blk)) {
			/*
			 * Ok, we found a user of irn that is placed
			 * in a block dominated by the branch block.
			 * We can replace the input with the Constant
			 * branch label.
			 */

			if (! c) {
				ir_mode *mode = get_irn_mode(irn);
				ir_type *tp   = get_irn_type(irn);
				tarval *tv    = new_tarval_from_long(nr, mode);
111
				c = new_r_Const_type(current_ir_graph, mode, tv, tp);
Michael Beck's avatar
Michael Beck committed
112
113
114
115
			}

			set_irn_n(succ, pos, c);
			DBG_OPT_CONFIRM_C(irn, c);
116
			DB((dbg, LEVEL_2, "Replacing input %d of node %+F with %+F\n", pos, succ, c));
Michael Beck's avatar
Michael Beck committed
117
118
119
120

			env->num_consts += 1;
		}
	}
121
}  /* handle_case */
Michael Beck's avatar
Michael Beck committed
122

123
124
125
126
127
128
129
130
131
/**
 * Handle a mode_b input of Cond nodes.
 *
 * @param block     the block which is entered by the branch
 * @param selector  the mode_b node expressing the branch condition
 * @param pnc       the true/false condition branch
 * @param env       statistical environment
 */
static void handle_modeb(ir_node *block, ir_node *selector, pn_Cond pnc, env_t *env) {
Matthias Braun's avatar
Matthias Braun committed
132
	ir_node *cond, *old, *cond_block = NULL, *other_blk = NULL, *con = NULL;
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
	ir_node *c_b = NULL, *c_o = NULL;
	const ir_edge_t *edge, *next;

	for (edge = get_irn_out_edge_first(selector); edge; edge = next) {
		ir_node *user     = get_edge_src_irn(edge);
		int     pos       = get_edge_src_pos(edge);
		ir_node *user_blk = get_effective_use_block(user, pos);

		next = get_irn_out_edge_next(selector, edge);
		if (block_dominates(block, user_blk)) {
			/*
			 * Ok, we found a usage of selector in a block
			 * dominated by the branch block.
			 * We can replace the input with true/false.
			 */
			if (con == NULL) {
				con = new_Const(mode_b, pnc == pn_Cond_true ? tarval_b_true : tarval_b_false);
			}
			old = get_irn_n(user, pos);
			set_irn_n(user, pos, con);
			DBG_OPT_CONFIRM_C(old, con);

155
			DB((dbg, LEVEL_2, "Replacing input %d of node %+F with %+F\n", pos, user, con));
156
157
158
159
160
161
162
163
164
165
166
167

			env->num_consts += 1;
		} else {
			int i, n;

			/* get the other block */
			if (other_blk == NULL) {
				/* we have already tested, that block has only ONE Cond predecessor */
				cond = get_Proj_pred(get_Block_cfgpred(block, 0));
				cond_block = get_nodes_block(cond);
				foreach_out_edge(cond, edge) {
					ir_node *proj = get_edge_src_irn(edge);
168
					if (get_Proj_proj(proj) == (long)pnc)
169
170
171
172
173
174
						continue;
					edge = get_irn_out_edge_first(proj);
					other_blk = get_edge_src_irn(edge);
					break;
				}
				assert(other_blk);
175
176
177
178
179
180

			 	/*
				 * Note the special case here: if block is a then, there might be no else
				 * block. In that case the other_block is the user_blk itself and pred_block
				 * is the cond_block ...
				 *
181
				 * Best would be to introduce a block here, removing this critical edge.
182
183
184
185
				 * For some reasons I cannot repair dominance here, so I have to remove
				 * ALL critical edges...
				 * FIXME: This should not be needed if we could repair dominance ...
				 */
186
187
188
189
190
191
192
193
194
195
196
197
			}

			n = get_Block_n_cfgpreds(user_blk);

			/*
			 * We have found a user in a non-dominated block:
			 * check, if all its block predecessors are dominated.
			 * If yes, place a Phi.
			 */
			for (i = n - 1; i >= 0; --i) {
				ir_node *pred_blk = get_Block_cfgpred_block(user_blk, i);

198
199
				if (!block_dominates(block, pred_blk) &&
				    !block_dominates(other_blk, pred_blk)) {
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
					/* can't do anything */
					break;
				}
			}
			if (i < 0) {
				ir_node *phi, **in;

				NEW_ARR_A(ir_node *, in, n);
				/* ok, ALL predecessors are either dominated by block OR other block */
				if (c_b == NULL) {
					ir_node *c_true  = new_Const(mode_b, tarval_b_true);
					ir_node *c_false = new_Const(mode_b, tarval_b_false);
					c_b = new_r_Confirm(current_ir_graph, cond_block, selector,
						pnc == pn_Cond_true ? c_true : c_false, pn_Cmp_Eq);
					c_o = new_r_Confirm(current_ir_graph, cond_block, selector,
						pnc == pn_Cond_false ? c_true : c_false, pn_Cmp_Eq);
				}
				for (i = n - 1; i >= 0; --i) {
					ir_node *pred_blk = get_Block_cfgpred_block(user_blk, i);

					if (block_dominates(block, pred_blk))
						in[i] = c_b;
					else
						in[i] = c_o;
				}
				phi = new_r_Phi(current_ir_graph, user_blk, n, in, mode_b);
				set_irn_n(user, pos, phi);
			}
		}
	}
}

Michael Beck's avatar
Michael Beck committed
232
233
234
235
236
237
238
239
/**
 * Handle an IF-branch.
 *
 * @param block   the block which is entered by the branch
 * @param cmp     the Cmp node expressing the branch condition
 * @param pnc     the Compare relation for taking this branch
 * @param env     statistical environment
 */
Michael Beck's avatar
Michael Beck committed
240
241
242
static void handle_if(ir_node *block, ir_node *cmp, pn_Cmp pnc, env_t *env) {
	ir_node *left  = get_Cmp_left(cmp);
	ir_node *right = get_Cmp_right(cmp);
243
	ir_node *cond_block;
Michael Beck's avatar
Michael Beck committed
244
245
246
247
	ir_op *op;
	const ir_edge_t *edge, *next;

	/* Beware of Bads */
248
	if (is_Bad(left) || is_Bad(right))
Michael Beck's avatar
Michael Beck committed
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
		return;

	op = get_irn_op(left);

	/* Do not create Confirm nodes for Cmp(Const, Const) constructs.
	   These are removed anyway */
	if (op == op_Const && is_Const(right))
		return;

	/* try to place the constant on the right side for a Confirm */
	if (op == op_Const || op == op_SymConst) {
		ir_node *t = left;

		left  = right;
		right = t;

		pnc = get_inversed_pnc(pnc);
	}

	/*
	 * First case: both values are identical.
	 * replace the left one by the right (potentially const) one.
	 */
	if (pnc == pn_Cmp_Eq) {
273
		cond_block = get_Block_cfgpred_block(block, 0);
Michael Beck's avatar
Michael Beck committed
274
		for (edge = get_irn_out_edge_first(left); edge; edge = next) {
275
			ir_node *user = get_edge_src_irn(edge);
Michael Beck's avatar
Michael Beck committed
276
			int     pos   = get_edge_src_pos(edge);
277
			ir_node *blk  = get_effective_use_block(user, pos);
Michael Beck's avatar
Michael Beck committed
278
279
280
281
282
283
284
285

			next = get_irn_out_edge_next(left, edge);
			if (block_dominates(block, blk)) {
				/*
				 * Ok, we found a usage of left in a block
				 * dominated by the branch block.
				 * We can replace the input with right.
				 */
286
				set_irn_n(user, pos, right);
Michael Beck's avatar
Michael Beck committed
287
288
				DBG_OPT_CONFIRM(left, right);

289
				DB((dbg, LEVEL_2, "Replacing input %d of node %+F with %+F\n", pos, user, right));
Michael Beck's avatar
Michael Beck committed
290
291

				env->num_eq += 1;
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
			} else if (block_dominates(blk, cond_block)) {
				if (is_Const(right) && get_irn_pinned(user) == op_pin_state_floats) {
					/*
					 * left == Const and we found a movable user of left in a
					 * dominator of the Cond block
					 */
					const ir_edge_t *edge, *next;
					for (edge = get_irn_out_edge_first(user); edge; edge = next) {
						ir_node *usr_of_usr = get_edge_src_irn(edge);
						int      npos = get_edge_src_pos(edge);
						ir_node *blk  = get_effective_use_block(usr_of_usr, npos);

						next = get_irn_out_edge_next(user, edge);
						if (block_dominates(block, blk)) {
							/*
							 * The user of the user is dominated by our true/false
							 * block. So, create a copy of user WITH the constant
							 * replacing it's pos'th input.
							 *
							 * This is always good for unop's and might be good
							 * for binops.
							 *
							 * If user has other user in the false/true block, code
							 * placement will move it down.
							 * If there are users in cond block or upper, we create
							 * "redundant ops", because one will have a const op,
							 * the other no const ...
							 */
							ir_node *new_op = exact_copy(user);
							set_nodes_block(new_op, block);
							set_irn_n(new_op, pos, right);
							set_irn_n(usr_of_usr, npos, new_op);
						}
					}
				}
Michael Beck's avatar
Michael Beck committed
327
328
329
330
331
			}
		}
	} else { /* not pn_Cmp_Eq cases */
		ir_node *c = NULL;

332
		foreach_out_edge_safe(left, edge, next) {
Michael Beck's avatar
Michael Beck committed
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
			ir_node *succ = get_edge_src_irn(edge);
			int     pos   = get_edge_src_pos(edge);
			ir_node *blk  = get_effective_use_block(succ, pos);

			if (block_dominates(block, blk)) {
				/*
				 * Ok, we found a usage of left in a block
				 * dominated by the branch block.
				 * We can replace the input with a Confirm(left, pnc, right).
				 */
				if (! c)
					c = new_r_Confirm(current_ir_graph, block, left, right, pnc);

				pos = get_edge_src_pos(edge);
				set_irn_n(succ, pos, c);
348
				DB((dbg, LEVEL_2, "Replacing input %d of node %+F with %+F\n", pos, succ, c));
Michael Beck's avatar
Michael Beck committed
349
350
351
352

				env->num_confirms += 1;
			}
		}
353
354
355

		if (! is_Const(right)) {
			/* also construct inverse Confirms */
356
357
			ir_node *rc = NULL;

358
			pnc = get_inversed_pnc(pnc);
359
			foreach_out_edge_safe(right, edge, next) {
360
				ir_node *succ = get_edge_src_irn(edge);
361
362
363
364
365
366
367
368
				int     pos;
				ir_node *blk;

				if (succ == c)
					continue;

				pos  = get_edge_src_pos(edge);
				blk  = get_effective_use_block(succ, pos);
369
370
371
372
373
374
375

				if (block_dominates(block, blk)) {
					/*
					 * Ok, we found a usage of right in a block
					 * dominated by the branch block.
					 * We can replace the input with a Confirm(right, pnc^-1, left).
					 */
376
377
					if (! rc)
						rc = new_r_Confirm(current_ir_graph, block, right, left, pnc);
378
379

					pos = get_edge_src_pos(edge);
380
381
					set_irn_n(succ, pos, rc);
					DB((dbg, LEVEL_2, "Replacing input %d of node %+F with %+F\n", pos, succ, rc));
382
383
384
385
386

					env->num_confirms += 1;
				}
			}
		}
Michael Beck's avatar
Michael Beck committed
387
	}
388
}  /* handle_if */
Michael Beck's avatar
Michael Beck committed
389
390

/**
391
 * Pre-block-walker: Called for every block to insert Confirm nodes
Michael Beck's avatar
Michael Beck committed
392
 */
393
static void insert_Confirm_in_block(ir_node *block, void *env) {
Michael Beck's avatar
Michael Beck committed
394
395
396
397
398
399
400
401
402
403
404
	ir_node *cond, *proj, *selector;
	ir_mode *mode;

	/*
	 * we can only handle blocks with only ONE control flow
	 * predecessor yet.
	 */
	if (get_Block_n_cfgpreds(block) != 1)
		return;

	proj = get_Block_cfgpred(block, 0);
405
	if (! is_Proj(proj))
Michael Beck's avatar
Michael Beck committed
406
407
408
		return;

	cond = get_Proj_pred(proj);
409
	if (! is_Cond(cond))
Michael Beck's avatar
Michael Beck committed
410
411
412
413
414
415
416
417
418
		return;

	selector = get_Cond_selector(cond);
	mode = get_irn_mode(selector);

	if (mode == mode_b) {
		ir_node *cmp;
		pn_Cmp pnc;

419
		handle_modeb(block, selector, get_Proj_proj(proj), env);
420

Michael Beck's avatar
Michael Beck committed
421
		/* this should be an IF, check this */
422
		if (! is_Proj(selector))
Michael Beck's avatar
Michael Beck committed
423
424
425
			return;

		cmp = get_Proj_pred(selector);
426
		if (! is_Cmp(cmp))
Michael Beck's avatar
Michael Beck committed
427
428
429
430
431
432
			return;

		pnc = get_Proj_proj(selector);

		if (get_Proj_proj(proj) != pn_Cond_true) {
			/* it's the false branch */
433
			mode = get_irn_mode(get_Cmp_left(cmp));
Michael Beck's avatar
Michael Beck committed
434
435
			pnc = get_negated_pnc(pnc, mode);
		}
436
		DB((dbg, LEVEL_2, "At %+F using %+F Confirm %=\n", block, cmp, pnc));
Michael Beck's avatar
Michael Beck committed
437
438
439
440
441
442
443
444
445
446
447

		handle_if(block, cmp, pnc, env);
	} else if (mode_is_int(mode)) {
		long proj_nr = get_Proj_proj(proj);

		/* this is a CASE, but we cannot handle the default case */
		if (proj_nr == get_Cond_defaultProj(cond))
			return;

		handle_case(block, get_Cond_selector(cond), proj_nr, env);
	}
448
449
}  /* insert_Confirm_in_block */

450
451
452
453
454
455
/**
 * Checks if a node is a non-null Confirm.
 */
static int is_non_null_Confirm(const ir_node *ptr) {
	for (;;) {
		if (! is_Confirm(ptr))
456
			break;
457
458
459
460
461
462
463
464
		if (get_Confirm_cmp(ptr) == pn_Cmp_Lg) {
			ir_node *bound = get_Confirm_bound(ptr);

			if (is_Const(bound) && is_Const_null(bound))
				return 1;
		}
		ptr = get_Confirm_value(ptr);
	}
465
466
467
468
469
470
471
472
	/*
	 * While a SymConst is not a Confirm, it is non-null
	 * anyway. This helps to reduce the number of
	 * constructed Confirms.
	 */
	if (is_SymConst_addr_ent(ptr))
		return 1;
	return 0;
473
474
}  /* is_non_null_Confirm */

475
/**
476
 * The given pointer will be dereferenced, add non-null Confirms.
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
 *
 * @param ptr    a node representing an address
 * @param block  the block of the dereferencing instruction
 * @param env    environment
 */
static void insert_non_null(ir_node *ptr, ir_node *block, env_t *env) {
	const ir_edge_t *edge, *next;
	ir_node         *c = NULL;

	foreach_out_edge_safe(ptr, edge, next) {
		ir_node *succ = get_edge_src_irn(edge);
		int     pos;
		ir_node *blk;


492
493
		/* for now, we place a Confirm only in front of a Cmp */
		if (! is_Cmp(succ))
494
			continue;
495
496
497
498

		pos = get_edge_src_pos(edge);
		blk = get_effective_use_block(succ, pos);

499
		if (block_dominates(block, blk)) {
500
501
502
503
504
505
506
507
508
509
510
511
512
			/*
			 * Ok, we found a usage of ptr in a block
			 * dominated by the Load/Store block.
			 * We can replace the input with a Confirm(ptr, !=, NULL).
			 */
			if (c == NULL) {
				ir_mode *mode = get_irn_mode(ptr);
				c = new_Const(mode, get_mode_null(mode));

				c = new_r_Confirm(current_ir_graph, block, ptr, c, pn_Cmp_Lg);
			}

			set_irn_n(succ, pos, c);
513
			DB((dbg, LEVEL_2, "Replacing input %d of node %+F with %+F\n", pos, succ, c));
514

515
			env->num_non_null += 1;
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
			env->num_confirms += 1;
		}
	}
}  /* insert_non_null */

/**
 * Pre-walker: Called for every node to insert Confirm nodes
 */
static void insert_Confirm(ir_node *node, void *env) {
	ir_node *ptr;

	switch (get_irn_opcode(node)) {
	case iro_Block:
		insert_Confirm_in_block(node, env);
		break;
	case iro_Load:
		ptr = get_Load_ptr(node);
		if (! is_non_null_Confirm(ptr))
			insert_non_null(ptr, get_nodes_block(node), env);
		break;
	case iro_Store:
		ptr = get_Store_ptr(node);
		if (! is_non_null_Confirm(ptr))
			insert_non_null(ptr, get_nodes_block(node), env);
		break;
	default:
		break;
	}
544
}  /* insert_Confirm */
Michael Beck's avatar
Michael Beck committed
545
546
547
548

/*
 * Construct Confirm nodes
 */
Michael Beck's avatar
Michael Beck committed
549
550
551
void construct_confirms(ir_graph *irg) {
	env_t env;
	int edges_active = edges_activated(irg);
Michael Beck's avatar
Michael Beck committed
552

553
554
555

	FIRM_DBG_REGISTER(dbg, "firm.ana.confirm");

556
557
	remove_critical_cf_edges(irg);

Michael Beck's avatar
Michael Beck committed
558
559
	/* we need dominance info */
	assure_doms(irg);
Michael Beck's avatar
Michael Beck committed
560

Michael Beck's avatar
Michael Beck committed
561
562
	assert(get_irg_pinned(irg) == op_pin_state_pinned &&
	       "Nodes must be placed to insert Confirms");
Michael Beck's avatar
Michael Beck committed
563

Michael Beck's avatar
Michael Beck committed
564
565
566
567
	if (! edges_active) {
		/* We need edges */
		edges_activate(irg);
	}
Michael Beck's avatar
Michael Beck committed
568

Michael Beck's avatar
Michael Beck committed
569
570
571
	env.num_confirms = 0;
	env.num_consts   = 0;
	env.num_eq       = 0;
572
	env.num_non_null = 0;
Michael Beck's avatar
Michael Beck committed
573

574
	if (get_opt_global_null_ptr_elimination()) {
575
576
577
578
579
580
		/* do global NULL test elimination */
		irg_walk_graph(irg, insert_Confirm, NULL, &env);
	} else {
		/* now, visit all blocks and add Confirms where possible */
		irg_block_walk_graph(irg, insert_Confirm_in_block, NULL, &env);
	}
Michael Beck's avatar
Michael Beck committed
581

Michael Beck's avatar
Michael Beck committed
582
583
584
	if (env.num_confirms | env.num_consts | env.num_eq) {
		/* we have add nodes or changed DF edges */
		set_irg_outs_inconsistent(irg);
Michael Beck's avatar
Michael Beck committed
585

Michael Beck's avatar
Michael Beck committed
586
587
588
		/* the new nodes are not in the loop info */
		set_irg_loopinfo_inconsistent(irg);
	}
Michael Beck's avatar
Michael Beck committed
589

590
591
592
	DB((dbg, LEVEL_1, "# Confirms inserted : %u\n", env.num_confirms));
	DB((dbg, LEVEL_1, "# Const replacements: %u\n", env.num_consts));
	DB((dbg, LEVEL_1, "# node equalities   : %u\n", env.num_eq));
593
	DB((dbg, LEVEL_1, "# non-null Confirms : %u\n", env.num_non_null));
Michael Beck's avatar
Michael Beck committed
594

Michael Beck's avatar
Michael Beck committed
595
596
597
	/* deactivate edges if they where off */
	if (! edges_active)
		edges_deactivate(irg);
598
}  /* construct_confirms */
Michael Beck's avatar
Michael Beck committed
599

Matthias Braun's avatar
Matthias Braun committed
600
#if 0
Michael Beck's avatar
Michael Beck committed
601
/**
Michael Beck's avatar
Michael Beck committed
602
 * Post-walker: Remove Confirm nodes
Michael Beck's avatar
Michael Beck committed
603
604
 */
static void rem_Confirm(ir_node *n, void *env) {
Michael Beck's avatar
Michael Beck committed
605
	(void) env;
606
	if (is_Confirm(n)) {
Michael Beck's avatar
Michael Beck committed
607
608
609
610
611
		ir_node *value = get_Confirm_value(n);
		if (value != n)
			exchange(n, value);
		else {
			/*
612
			 * Strange: a Confirm is its own bound. This can happen
Michael Beck's avatar
Michael Beck committed
613
614
615
616
617
			 * in dead blocks when Phi nodes are already removed.
			 */
			exchange(n, new_Bad());
		}
	}
618
}  /* rem_Confirm */
Matthias Braun's avatar
Matthias Braun committed
619
#endif
Michael Beck's avatar
Michael Beck committed
620
621
622
623
624

/*
 * Remove all Confirm nodes from a graph.
 */
void remove_confirms(ir_graph *irg) {
625
626
	int rem = get_opt_remove_confirm();

627
628
	set_opt_remove_confirm(1);
	optimize_graph_df(irg);
629
	set_opt_remove_confirm(rem);
630
}  /* remove_confirms */