irconsconfirm.c 15.2 KB
Newer Older
Michael Beck's avatar
Michael Beck committed
1
/*
Matthias Braun's avatar
Matthias Braun committed
2
 * This file is part of libFirm.
3
 * Copyright (C) 2012 University of Karlsruhe.
Michael Beck's avatar
Michael Beck committed
4
 */
5

Matthias Braun's avatar
Matthias Braun committed
6
7
8
9
10
11
/**
 * @file
 * @brief    Construction of Confirm nodes
 * @author   Michael Beck
 * @date     6.2005
 */
12
13
#include "irconsconfirm.h"

Michael Beck's avatar
Michael Beck committed
14
15
16
17
18
19
#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
20
#include "irgwalk.h"
21
#include "irgopt.h"
Matthias Braun's avatar
Matthias Braun committed
22
#include "irtools.h"
23
#include "array.h"
24
25
#include "debug.h"
#include "irflag.h"
Michael Beck's avatar
Michael Beck committed
26
27
28
29

/**
 * Walker environment.
 */
30
typedef struct env_t {
31
32
33
34
	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
35
36
} env_t;

37
38
39
/** The debug handle. */
DEBUG_ONLY(static firm_dbg_module_t *dbg;)

40
/**
41
 * Return the effective use block of a node and its predecessor on
42
43
44
45
46
47
48
 * position pos.
 *
 * @param node  the node
 * @param pos   the position of the used input
 *
 * This handles correctly Phi nodes.
 */
49
50
static ir_node *get_effective_use_block(ir_node *node, int pos)
{
51
	if (is_Phi(node)) {
52
53
54
		/* the effective use of a Phi argument is in its predecessor block */
		node = get_nodes_block(node);
		return get_Block_cfgpred_block(node, pos);
55
56
	}
	return get_nodes_block(node);
57
58
}

59
static ir_node *get_case_value(ir_node *switchn, unsigned pn)
Matthias Braun's avatar
Matthias Braun committed
60
61
62
63
64
{
	ir_graph              *irg       = get_irn_irg(switchn);
	const ir_switch_table *table     = get_Switch_table(switchn);
	size_t                 n_entries = ir_switch_table_get_n_entries(table);
	ir_tarval             *val       = NULL;
Matthias Braun's avatar
Matthias Braun committed
65
	for (size_t e = 0; e < n_entries; ++e) {
Matthias Braun's avatar
Matthias Braun committed
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
		const ir_switch_table_entry *entry
			= ir_switch_table_get_entry_const(table, e);
		if (entry->pn != pn)
			continue;
		/* multiple matching entries gets too complicated for a single
		 * Confirm */
		if (val != NULL)
			return NULL;
		/* case ranges are too complicated too */
		if (entry->min != entry->max)
			return NULL;
		val = entry->min;
	}
	assert(val != NULL);
	return new_r_Const(irg, val);
}

Michael Beck's avatar
Michael Beck committed
83
84
85
86
87
88
/**
 * Handle a CASE-branch.
 *
 * Branch labels are a simple case. We can replace the value
 * by a Const with the branch label.
 */
89
static void handle_case(ir_node *block, ir_node *switchn, unsigned pn, env_t *env)
90
{
Matthias Braun's avatar
Matthias Braun committed
91
	ir_node *c        = NULL;
92
	ir_node *selector = get_Switch_selector(switchn);
Michael Beck's avatar
Michael Beck committed
93

Matthias Braun's avatar
Matthias Braun committed
94
95
	/* we can't do usefull things with the default label */
	if (pn == pn_Switch_default)
Michael Beck's avatar
Michael Beck committed
96
97
		return;

98
	foreach_out_edge_safe(selector, edge) {
Michael Beck's avatar
Michael Beck committed
99
		ir_node *succ = get_edge_src_irn(edge);
Matthias Braun's avatar
Matthias Braun committed
100
		int      pos  = get_edge_src_pos(edge);
Michael Beck's avatar
Michael Beck committed
101
102
103
		ir_node *blk  = get_effective_use_block(succ, pos);

		if (block_dominates(block, blk)) {
104
			/* Ok, we found a user of irn that is placed
Michael Beck's avatar
Michael Beck committed
105
106
			 * in a block dominated by the branch block.
			 * We can replace the input with the Constant
107
108
			 * branch label. */
			if (c == NULL) {
Matthias Braun's avatar
Matthias Braun committed
109
				c = get_case_value(switchn, pn);
110
111
112
				if (c == NULL)
					return;
			}
Michael Beck's avatar
Michael Beck committed
113
114

			set_irn_n(succ, pos, c);
Matthias Braun's avatar
Matthias Braun committed
115
			DBG_OPT_CONFIRM_C(selector, 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
}
Michael Beck's avatar
Michael Beck committed
122

123
124
125
126
127
128
129
130
/**
 * 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
 */
131
132
static void handle_modeb(ir_node *block, ir_node *selector, pn_Cond pnc, env_t *env)
{
Matthias Braun's avatar
Matthias Braun committed
133
134
135
136
	ir_node *other_blk = NULL;
	ir_node *con       = NULL;
	ir_node *c_b       = NULL;
	ir_node *c_o       = NULL;
137

138
	foreach_out_edge_safe(selector, edge) {
139
		ir_node *user     = get_edge_src_irn(edge);
Matthias Braun's avatar
Matthias Braun committed
140
		int      pos      = get_edge_src_pos(edge);
141
142
143
144
145
146
147
148
149
		ir_node *user_blk = get_effective_use_block(user, pos);

		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) {
150
151
				ir_graph *irg = get_irn_irg(block);
				con = new_r_Const(irg, pnc == pn_Cond_true ? tarval_b_true : tarval_b_false);
152
			}
Matthias Braun's avatar
Matthias Braun committed
153
			ir_node *old = get_irn_n(user, pos);
154
155
156
			set_irn_n(user, pos, con);
			DBG_OPT_CONFIRM_C(old, con);

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

			env->num_consts += 1;
		} else {
			/* get the other block */
			if (other_blk == NULL) {
				/* we have already tested, that block has only ONE Cond predecessor */
Christoph Mallon's avatar
Christoph Mallon committed
164
165
166
167
				ir_node *const cond = get_Proj_pred(get_Block_cfgpred(block, 0));
				ir_node *const proj = get_Proj_for_pn(cond, pn_Cond_false + pn_Cond_true - pnc);
				assert(proj);
				other_blk = get_edge_src_irn(get_irn_out_edge_first(proj));
168

169
				/*
170
171
172
173
				 * 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 ...
				 *
174
				 * Best would be to introduce a block here, removing this critical edge.
175
176
177
178
				 * 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 ...
				 */
179
180
			}

Matthias Braun's avatar
Matthias Braun committed
181
			int n = get_Block_n_cfgpreds(user_blk);
182
183
184
185
186
187

			/*
			 * We have found a user in a non-dominated block:
			 * check, if all its block predecessors are dominated.
			 * If yes, place a Phi.
			 */
Matthias Braun's avatar
Matthias Braun committed
188
189
			int i;
			for (i = n; i-- > 0; ) {
190
191
				ir_node *pred_blk = get_Block_cfgpred_block(user_blk, i);

192
193
				if (!block_dominates(block, pred_blk) &&
				    !block_dominates(other_blk, pred_blk)) {
194
195
196
197
					/* can't do anything */
					break;
				}
			}
198
			if (i < 0 && n > 0) {
199
				ir_node **in = ALLOCAN(ir_node*, n);
200
201
				/* ok, ALL predecessors are either dominated by block OR other block */
				if (c_b == NULL) {
Matthias Braun's avatar
Matthias Braun committed
202
203
204
					ir_graph *irg     = get_irn_irg(block);
					ir_node  *c_true  = new_r_Const(irg, tarval_b_true);
					ir_node  *c_false = new_r_Const(irg, tarval_b_false);
205
					env->num_consts += 2;
206
207
208
209
210
211
212
					if (pnc == pn_Cond_true) {
						c_b = c_true;
						c_o = c_false;
					} else {
						c_b = c_false;
						c_o = c_true;
					}
213
				}
Matthias Braun's avatar
Matthias Braun committed
214
				for (i = n; i-- > 0; ) {
215
216
217
218
219
220
					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;
				}
Matthias Braun's avatar
Matthias Braun committed
221
				ir_node *phi = new_r_Phi(user_blk, n, in, mode_b);
222
				set_irn_n(user, pos, phi);
223
				env->num_eq += 1;
224
225
226
227
228
			}
		}
	}
}

Michael Beck's avatar
Michael Beck committed
229
230
231
232
233
/**
 * Handle an IF-branch.
 *
 * @param block   the block which is entered by the branch
 * @param cmp     the Cmp node expressing the branch condition
234
 * @param rel     the Compare relation for taking this branch
Michael Beck's avatar
Michael Beck committed
235
236
 * @param env     statistical environment
 */
237
static void handle_if(ir_node *block, ir_node *cmp, ir_relation rel, env_t *env)
238
{
Matthias Braun's avatar
Matthias Braun committed
239
	/* Beware of Bads */
Michael Beck's avatar
Michael Beck committed
240
241
	ir_node *left  = get_Cmp_left(cmp);
	ir_node *right = get_Cmp_right(cmp);
242
	if (is_Bad(left) || is_Bad(right))
Michael Beck's avatar
Michael Beck committed
243
244
245
246
		return;

	/* Do not create Confirm nodes for Cmp(Const, Const) constructs.
	   These are removed anyway */
247
	if (is_Const(left) && is_Const(right))
Michael Beck's avatar
Michael Beck committed
248
249
250
		return;

	/* try to place the constant on the right side for a Confirm */
251
252
	switch (get_irn_opcode(left)) {
	case iro_Address:
253
	case iro_Align:
254
255
	case iro_Const:
	case iro_Offset:
256
	case iro_Size: {
Michael Beck's avatar
Michael Beck committed
257
258
259
260
		ir_node *t = left;
		left  = right;
		right = t;

261
		rel = get_inversed_relation(rel);
262
263
264
265
266
		break;
	}

	default:
		break;
Michael Beck's avatar
Michael Beck committed
267
268
269
270
271
272
	}

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

			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
			} else if (block_dominates(blk, cond_block)
yb9976's avatar
yb9976 committed
293
			           && is_Const(right) && !get_irn_pinned(user)) {
294
295
296
297
				/*
				 * left == Const and we found a movable user of left in a
				 * dominator of the Cond block
				 */
298
				foreach_out_edge_safe(user, user_edge) {
299
300
301
302
303
					ir_node *usr_of_usr = get_edge_src_irn(user_edge);
					int      npos       = get_edge_src_pos(user_edge);
					ir_node *user_blk   = get_effective_use_block(usr_of_usr, npos);

					if (block_dominates(block, user_blk)) {
304
305
306
						/*
						 * The user of the user is dominated by our true/false
						 * block. So, create a copy of user WITH the constant
307
						 * replacing its pos'th input.
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
						 *
						 * 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);
						env->num_eq += 1;
323
324
					}
				}
Michael Beck's avatar
Michael Beck committed
325
326
			}
		}
327
	} else { /* not ir_relation_equal cases */
Michael Beck's avatar
Michael Beck committed
328
329
		ir_node *c = NULL;

330
		foreach_out_edge_safe(left, edge) {
Michael Beck's avatar
Michael Beck committed
331
			ir_node *succ = get_edge_src_irn(edge);
Matthias Braun's avatar
Matthias Braun committed
332
			int      pos  = get_edge_src_pos(edge);
Michael Beck's avatar
Michael Beck committed
333
334
335
336
337
338
339
340
			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).
				 */
Matthias Braun's avatar
Matthias Braun committed
341
				if (c == NULL)
342
					c = new_r_Confirm(block, left, right, rel);
Michael Beck's avatar
Michael Beck committed
343
344

				set_irn_n(succ, pos, c);
345
				DB((dbg, LEVEL_2, "Replacing input %d of node %+F with %+F\n", pos, succ, c));
Michael Beck's avatar
Michael Beck committed
346
347
348
349

				env->num_confirms += 1;
			}
		}
350

Matthias Braun's avatar
Matthias Braun committed
351
		if (!is_Const(right)) {
352
			/* also construct inverse Confirms */
353
354
			ir_node *rc = NULL;

355
			rel = get_inversed_relation(rel);
356
			foreach_out_edge_safe(right, edge) {
357
				ir_node *succ = get_edge_src_irn(edge);
358
359
360
				if (succ == c)
					continue;

Matthias Braun's avatar
Matthias Braun committed
361
362
				int      pos  = get_edge_src_pos(edge);
				ir_node *blk  = get_effective_use_block(succ, pos);
363
364
365
366
367

				if (block_dominates(block, blk)) {
					/*
					 * Ok, we found a usage of right in a block
					 * dominated by the branch block.
368
					 * We can replace the input with a Confirm(right, rel^-1, left).
369
					 */
Matthias Braun's avatar
Matthias Braun committed
370
					if (rc == NULL)
371
						rc = new_r_Confirm(block, right, left, rel);
372

yb9976's avatar
yb9976 committed
373
374
375
376
					if (succ != rc) {
						set_irn_n(succ, pos, rc);
						DB((dbg, LEVEL_2, "Replacing input %d of node %+F with %+F\n", pos, succ, rc));
					}
377
378
379
380
381

					env->num_confirms += 1;
				}
			}
		}
Michael Beck's avatar
Michael Beck committed
382
	}
383
}
Michael Beck's avatar
Michael Beck committed
384
385

/**
386
 * Pre-block-walker: Called for every block to insert Confirm nodes
Michael Beck's avatar
Michael Beck committed
387
 */
388
static void insert_Confirm_in_block(ir_node *block, void *data)
389
{
Michael Beck's avatar
Michael Beck committed
390
391
392
393
394
395
396
	/*
	 * we can only handle blocks with only ONE control flow
	 * predecessor yet.
	 */
	if (get_Block_n_cfgpreds(block) != 1)
		return;

Matthias Braun's avatar
Matthias Braun committed
397
	ir_node *proj = get_Block_cfgpred(block, 0);
Matthias Braun's avatar
Matthias Braun committed
398
	if (!is_Proj(proj))
Michael Beck's avatar
Michael Beck committed
399
400
		return;

Matthias Braun's avatar
Matthias Braun committed
401
402
	env_t   *env = (env_t*)data;
	ir_node *cond = get_Proj_pred(proj);
Matthias Braun's avatar
Matthias Braun committed
403
	if (is_Switch(cond)) {
404
		unsigned proj_nr = get_Proj_num(proj);
Matthias Braun's avatar
Matthias Braun committed
405
		handle_case(block, cond, proj_nr, env);
406
	} else if (is_Cond(cond)) {
Matthias Braun's avatar
Matthias Braun committed
407
		ir_node *selector = get_Cond_selector(cond);
408
		handle_modeb(block, selector, (pn_Cond) get_Proj_num(proj), env);
Matthias Braun's avatar
Matthias Braun committed
409
		if (!is_Cmp(selector))
Michael Beck's avatar
Michael Beck committed
410
411
			return;

Matthias Braun's avatar
Matthias Braun committed
412
		ir_relation rel = get_Cmp_relation(selector);
Michael Beck's avatar
Michael Beck committed
413

Matthias Braun's avatar
Matthias Braun committed
414
415
		/* it's the false branch */
		if (get_Proj_num(proj) != pn_Cond_true)
416
			rel = get_negated_relation(rel);
417
		DB((dbg, LEVEL_2, "At %+F using %+F Confirm %=\n", block, selector, rel));
Michael Beck's avatar
Michael Beck committed
418

419
		handle_if(block, selector, rel, env);
Michael Beck's avatar
Michael Beck committed
420
	}
421
}
422

423
424
425
/**
 * Checks if a node is a non-null Confirm.
 */
Matthias Braun's avatar
Matthias Braun committed
426
static bool is_non_null_Confirm(const ir_node *ptr)
427
{
428
	for (;;) {
Matthias Braun's avatar
Matthias Braun committed
429
		if (!is_Confirm(ptr))
430
			break;
431
		if (get_Confirm_relation(ptr) == ir_relation_less_greater) {
432
433
			ir_node *bound = get_Confirm_bound(ptr);

434
			if (is_irn_null(bound))
Matthias Braun's avatar
Matthias Braun committed
435
				return true;
436
437
438
		}
		ptr = get_Confirm_value(ptr);
	}
439
	/*
440
	 * While an Address is not a Confirm, it is non-null
441
442
443
	 * anyway. This helps to reduce the number of
	 * constructed Confirms.
	 */
444
	if (is_Address(ptr))
Matthias Braun's avatar
Matthias Braun committed
445
446
		return true;
	return false;
447
}
448

449
/**
450
 * The given pointer will be dereferenced, add non-null Confirms.
451
452
453
454
455
 *
 * @param ptr    a node representing an address
 * @param block  the block of the dereferencing instruction
 * @param env    environment
 */
456
457
static void insert_non_null(ir_node *ptr, ir_node *block, env_t *env)
{
458
	ir_node *c = NULL;
459

460
	foreach_out_edge_safe(ptr, edge) {
461
		/* for now, we place a Confirm only in front of a Cmp */
Matthias Braun's avatar
Matthias Braun committed
462
		ir_node *succ = get_edge_src_irn(edge);
Matthias Braun's avatar
Matthias Braun committed
463
		if (!is_Cmp(succ))
464
			continue;
465

Matthias Braun's avatar
Matthias Braun committed
466
467
		int      pos = get_edge_src_pos(edge);
		ir_node *blk = get_effective_use_block(succ, pos);
468

469
		if (block_dominates(block, blk)) {
470
471
472
473
474
475
			/*
			 * 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) {
476
477
				ir_mode  *mode = get_irn_mode(ptr);
				ir_graph *irg  = get_irn_irg(block);
478
				c = new_r_Const_null(irg, mode);
479
				c = new_r_Confirm(block, ptr, c, ir_relation_less_greater);
480
481
482
			}

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

485
			env->num_non_null += 1;
486
487
488
			env->num_confirms += 1;
		}
	}
489
}
490
491
492
493

/**
 * Pre-walker: Called for every node to insert Confirm nodes
 */
494
static void insert_Confirm(ir_node *node, void *data)
495
{
Matthias Braun's avatar
Matthias Braun committed
496
	env_t *env = (env_t*)data;
497
498
499
500
	switch (get_irn_opcode(node)) {
	case iro_Block:
		insert_Confirm_in_block(node, env);
		break;
Matthias Braun's avatar
Matthias Braun committed
501
502
	case iro_Load: {
		ir_node *ptr = get_Load_ptr(node);
Matthias Braun's avatar
Matthias Braun committed
503
		if (!is_non_null_Confirm(ptr))
504
505
			insert_non_null(ptr, get_nodes_block(node), env);
		break;
Matthias Braun's avatar
Matthias Braun committed
506
507
508
	}
	case iro_Store: {
		ir_node *ptr = get_Store_ptr(node);
Matthias Braun's avatar
Matthias Braun committed
509
		if (!is_non_null_Confirm(ptr))
510
511
			insert_non_null(ptr, get_nodes_block(node), env);
		break;
Matthias Braun's avatar
Matthias Braun committed
512
	}
513
514
515
	default:
		break;
	}
516
}
Michael Beck's avatar
Michael Beck committed
517

518
void construct_confirms(ir_graph *irg)
519
{
520
521
	FIRM_DBG_REGISTER(dbg, "firm.ana.confirm");

522
	assure_irg_properties(irg,
523
		IR_GRAPH_PROPERTY_CONSISTENT_OUT_EDGES
524
		| IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE
525
		| IR_GRAPH_PROPERTY_NO_BADS
526
527
		| IR_GRAPH_PROPERTY_NO_CRITICAL_EDGES);

Matthias Braun's avatar
Matthias Braun committed
528
	assert(get_irg_pinned(irg) == op_pin_state_pinned);
Michael Beck's avatar
Michael Beck committed
529

Matthias Braun's avatar
Matthias Braun committed
530
	env_t env;
Michael Beck's avatar
Michael Beck committed
531
532
533
	env.num_confirms = 0;
	env.num_consts   = 0;
	env.num_eq       = 0;
534
	env.num_non_null = 0;
Michael Beck's avatar
Michael Beck committed
535

536
	if (get_opt_global_null_ptr_elimination()) {
537
538
539
540
541
542
		/* 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
543

544
545
546
	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));
547
	DB((dbg, LEVEL_1, "# non-null Confirms : %u\n", env.num_non_null));
Michael Beck's avatar
Michael Beck committed
548

549
	confirm_irg_properties(irg, IR_GRAPH_PROPERTIES_CONTROL_FLOW);
550
}
Michael Beck's avatar
Michael Beck committed
551

552
static void remove_confirm(ir_node *n, void *env)
553
{
Matthias Braun's avatar
Matthias Braun committed
554
	(void)env;
555
556
557
	if (!is_Confirm(n))
		return;

Matthias Braun's avatar
Matthias Braun committed
558
	ir_node *value = get_Confirm_value(n);
559
560
	exchange(n, value);
}
Michael Beck's avatar
Michael Beck committed
561

562
563
void remove_confirms(ir_graph *irg)
{
564
	irg_walk_graph(irg, NULL, remove_confirm, NULL);
565
	confirm_irg_properties(irg, IR_GRAPH_PROPERTIES_CONTROL_FLOW);
566
}