irconsconfirm.c 17 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

29
30
#include "irconsconfirm.h"

Michael Beck's avatar
Michael Beck committed
31
32
33
34
35
36
#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
37
#include "irgwalk.h"
Michael Beck's avatar
Michael Beck committed
38
#include "irprintf.h"
39
#include "irgopt.h"
40
#include "irpass.h"
Matthias Braun's avatar
Matthias Braun committed
41
#include "irtools.h"
42
#include "array_t.h"
43
44
#include "debug.h"
#include "irflag.h"
Michael Beck's avatar
Michael Beck committed
45
46
47
48

/**
 * Walker environment.
 */
49
typedef struct env_t {
50
51
52
53
	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
54
55
} env_t;

56
57
58
/** The debug handle. */
DEBUG_ONLY(static firm_dbg_module_t *dbg;)

59
60
61
62
63
64
65
66
67
/**
 * 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.
 */
68
69
static ir_node *get_effective_use_block(ir_node *node, int pos)
{
70
	if (is_Phi(node)) {
71
72
73
		/* the effective use of a Phi argument is in its predecessor block */
		node = get_nodes_block(node);
		return get_Block_cfgpred_block(node, pos);
74
75
	}
	return get_nodes_block(node);
76
77
}

Michael Beck's avatar
Michael Beck committed
78
79
80
81
82
/**
 * 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
83
 * @param nr      the branch label
Michael Beck's avatar
Michael Beck committed
84
85
86
87
88
 * @param env     statistical environment
 *
 * Branch labels are a simple case. We can replace the value
 * by a Const with the branch label.
 */
89
90
static void handle_case(ir_node *block, ir_node *irn, long nr, env_t *env)
{
Michael Beck's avatar
Michael Beck committed
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
	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) {
Matthias Braun's avatar
Matthias Braun committed
113
114
				ir_mode   *mode = get_irn_mode(irn);
				ir_tarval *tv   = new_tarval_from_long(nr, mode);
115
				c = new_r_Const(current_ir_graph, tv);
Michael Beck's avatar
Michael Beck committed
116
117
118
119
			}

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

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

127
128
129
130
131
132
133
134
/**
 * 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
 */
135
136
static void handle_modeb(ir_node *block, ir_node *selector, pn_Cond pnc, env_t *env)
{
137
	ir_node *cond, *old, *other_blk = NULL, *con = NULL;
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
	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) {
154
155
				ir_graph *irg = get_irn_irg(block);
				con = new_r_Const(irg, pnc == pn_Cond_true ? tarval_b_true : tarval_b_false);
156
157
158
159
160
			}
			old = get_irn_n(user, pos);
			set_irn_n(user, pos, con);
			DBG_OPT_CONFIRM_C(old, con);

161
			DB((dbg, LEVEL_2, "Replacing input %d of node %+F with %+F\n", pos, user, con));
162
163
164
165
166
167
168
169
170
171
172

			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));
				foreach_out_edge(cond, edge) {
					ir_node *proj = get_edge_src_irn(edge);
173
					if (get_Proj_proj(proj) == (long)pnc)
174
175
176
177
178
179
						continue;
					edge = get_irn_out_edge_first(proj);
					other_blk = get_edge_src_irn(edge);
					break;
				}
				assert(other_blk);
180

181
				/*
182
183
184
185
				 * 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 ...
				 *
186
				 * Best would be to introduce a block here, removing this critical edge.
187
188
189
190
				 * 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 ...
				 */
191
192
193
194
195
196
197
198
199
200
201
202
			}

			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);

203
204
				if (!block_dominates(block, pred_blk) &&
				    !block_dominates(other_blk, pred_blk)) {
205
206
207
208
209
210
211
212
213
214
					/* 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) {
215
216
217
					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);
218
					env->num_consts += 2;
219
220
221
222
223
224
225
					if (pnc == pn_Cond_true) {
						c_b = c_true;
						c_o = c_false;
					} else {
						c_b = c_false;
						c_o = c_true;
					}
226
227
228
229
230
231
232
233
234
				}
				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;
				}
235
				phi = new_r_Phi(user_blk, n, in, mode_b);
236
				set_irn_n(user, pos, phi);
237
				env->num_eq += 1;
238
239
240
241
242
			}
		}
	}
}

Michael Beck's avatar
Michael Beck committed
243
244
245
246
247
/**
 * Handle an IF-branch.
 *
 * @param block   the block which is entered by the branch
 * @param cmp     the Cmp node expressing the branch condition
248
 * @param rel     the Compare relation for taking this branch
Michael Beck's avatar
Michael Beck committed
249
250
 * @param env     statistical environment
 */
251
static void handle_if(ir_node *block, ir_node *cmp, ir_relation rel, env_t *env)
252
{
Michael Beck's avatar
Michael Beck committed
253
254
	ir_node *left  = get_Cmp_left(cmp);
	ir_node *right = get_Cmp_right(cmp);
255
	ir_node *cond_block;
Michael Beck's avatar
Michael Beck committed
256
257
258
259
	ir_op *op;
	const ir_edge_t *edge, *next;

	/* Beware of Bads */
260
	if (is_Bad(left) || is_Bad(right))
Michael Beck's avatar
Michael Beck committed
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
		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;

277
		rel = get_inversed_relation(rel);
Michael Beck's avatar
Michael Beck committed
278
279
280
281
282
283
	}

	/*
	 * First case: both values are identical.
	 * replace the left one by the right (potentially const) one.
	 */
284
	if (rel == ir_relation_equal) {
285
		cond_block = get_Block_cfgpred_block(block, 0);
Michael Beck's avatar
Michael Beck committed
286
		for (edge = get_irn_out_edge_first(left); edge; edge = next) {
287
			ir_node *user = get_edge_src_irn(edge);
Michael Beck's avatar
Michael Beck committed
288
			int     pos   = get_edge_src_pos(edge);
289
			ir_node *blk  = get_effective_use_block(user, pos);
Michael Beck's avatar
Michael Beck committed
290
291
292
293
294
295
296
297

			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.
				 */
298
				set_irn_n(user, pos, right);
Michael Beck's avatar
Michael Beck committed
299
300
				DBG_OPT_CONFIRM(left, right);

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

				env->num_eq += 1;
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
			} else if (block_dominates(blk, cond_block)
					&& 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);
						env->num_eq += 1;
338
339
					}
				}
Michael Beck's avatar
Michael Beck committed
340
341
			}
		}
342
	} else { /* not ir_relation_equal cases */
Michael Beck's avatar
Michael Beck committed
343
344
		ir_node *c = NULL;

345
		foreach_out_edge_safe(left, edge, next) {
Michael Beck's avatar
Michael Beck committed
346
347
348
349
350
351
352
353
354
355
356
			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)
357
					c = new_r_Confirm(block, left, right, rel);
Michael Beck's avatar
Michael Beck committed
358
359
360

				pos = get_edge_src_pos(edge);
				set_irn_n(succ, pos, c);
361
				DB((dbg, LEVEL_2, "Replacing input %d of node %+F with %+F\n", pos, succ, c));
Michael Beck's avatar
Michael Beck committed
362
363
364
365

				env->num_confirms += 1;
			}
		}
366
367
368

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

371
			rel = get_inversed_relation(rel);
372
			foreach_out_edge_safe(right, edge, next) {
373
				ir_node *succ = get_edge_src_irn(edge);
374
375
376
377
378
379
380
381
				int     pos;
				ir_node *blk;

				if (succ == c)
					continue;

				pos  = get_edge_src_pos(edge);
				blk  = get_effective_use_block(succ, pos);
382
383
384
385
386

				if (block_dominates(block, blk)) {
					/*
					 * Ok, we found a usage of right in a block
					 * dominated by the branch block.
387
					 * We can replace the input with a Confirm(right, rel^-1, left).
388
					 */
389
					if (! rc)
390
						rc = new_r_Confirm(block, right, left, rel);
391
392

					pos = get_edge_src_pos(edge);
393
394
					set_irn_n(succ, pos, rc);
					DB((dbg, LEVEL_2, "Replacing input %d of node %+F with %+F\n", pos, succ, rc));
395
396
397
398
399

					env->num_confirms += 1;
				}
			}
		}
Michael Beck's avatar
Michael Beck committed
400
	}
401
}  /* handle_if */
Michael Beck's avatar
Michael Beck committed
402
403

/**
404
 * Pre-block-walker: Called for every block to insert Confirm nodes
Michael Beck's avatar
Michael Beck committed
405
 */
406
static void insert_Confirm_in_block(ir_node *block, void *data)
407
{
Michael Beck's avatar
Michael Beck committed
408
409
	ir_node *cond, *proj, *selector;
	ir_mode *mode;
410
	env_t   *env = (env_t*) data;
Michael Beck's avatar
Michael Beck committed
411
412
413
414
415
416
417
418
419

	/*
	 * 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);
420
	if (! is_Proj(proj))
Michael Beck's avatar
Michael Beck committed
421
422
423
		return;

	cond = get_Proj_pred(proj);
424
	if (! is_Cond(cond))
Michael Beck's avatar
Michael Beck committed
425
426
427
428
429
430
431
		return;

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

	if (mode == mode_b) {
		ir_node *cmp;
432
		ir_relation rel;
Michael Beck's avatar
Michael Beck committed
433

434
		handle_modeb(block, selector, (pn_Cond) get_Proj_proj(proj), env);
435

Michael Beck's avatar
Michael Beck committed
436
		/* this should be an IF, check this */
437
		if (! is_Proj(selector))
Michael Beck's avatar
Michael Beck committed
438
439
440
			return;

		cmp = get_Proj_pred(selector);
441
		if (! is_Cmp(cmp))
Michael Beck's avatar
Michael Beck committed
442
443
			return;

444
		rel = get_Cmp_relation(cmp);
Michael Beck's avatar
Michael Beck committed
445
446
447

		if (get_Proj_proj(proj) != pn_Cond_true) {
			/* it's the false branch */
448
			mode = get_irn_mode(get_Cmp_left(cmp));
449
			rel = get_negated_relation(rel);
Michael Beck's avatar
Michael Beck committed
450
		}
451
		DB((dbg, LEVEL_2, "At %+F using %+F Confirm %=\n", block, cmp, rel));
Michael Beck's avatar
Michael Beck committed
452

453
		handle_if(block, cmp, rel, env);
Michael Beck's avatar
Michael Beck committed
454
455
456
457
	} else if (mode_is_int(mode)) {
		long proj_nr = get_Proj_proj(proj);

		/* this is a CASE, but we cannot handle the default case */
458
		if (proj_nr == get_Cond_default_proj(cond))
Michael Beck's avatar
Michael Beck committed
459
460
461
462
			return;

		handle_case(block, get_Cond_selector(cond), proj_nr, env);
	}
463
464
}  /* insert_Confirm_in_block */

465
466
467
/**
 * Checks if a node is a non-null Confirm.
 */
468
469
static int is_non_null_Confirm(const ir_node *ptr)
{
470
471
	for (;;) {
		if (! is_Confirm(ptr))
472
			break;
473
		if (get_Confirm_relation(ptr) == ir_relation_less_greater) {
474
475
476
477
478
479
480
			ir_node *bound = get_Confirm_bound(ptr);

			if (is_Const(bound) && is_Const_null(bound))
				return 1;
		}
		ptr = get_Confirm_value(ptr);
	}
481
482
483
484
485
486
487
488
	/*
	 * 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;
489
490
}  /* is_non_null_Confirm */

491
/**
492
 * The given pointer will be dereferenced, add non-null Confirms.
493
494
495
496
497
 *
 * @param ptr    a node representing an address
 * @param block  the block of the dereferencing instruction
 * @param env    environment
 */
498
499
static void insert_non_null(ir_node *ptr, ir_node *block, env_t *env)
{
500
501
502
503
504
505
506
507
508
	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;


509
510
		/* for now, we place a Confirm only in front of a Cmp */
		if (! is_Cmp(succ))
511
			continue;
512
513
514
515

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

516
		if (block_dominates(block, blk)) {
517
518
519
520
521
522
			/*
			 * 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) {
523
524
525
				ir_mode  *mode = get_irn_mode(ptr);
				ir_graph *irg  = get_irn_irg(block);
				c = new_r_Const(irg, get_mode_null(mode));
526
				c = new_r_Confirm(block, ptr, c, ir_relation_less_greater);
527
528
529
			}

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

532
			env->num_non_null += 1;
533
534
535
536
537
538
539
540
			env->num_confirms += 1;
		}
	}
}  /* insert_non_null */

/**
 * Pre-walker: Called for every node to insert Confirm nodes
 */
541
static void insert_Confirm(ir_node *node, void *data)
542
{
543
	ir_node *ptr;
544
	env_t   *env = (env_t*) data;
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562

	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;
	}
563
}  /* insert_Confirm */
Michael Beck's avatar
Michael Beck committed
564
565
566
567

/*
 * Construct Confirm nodes
 */
568
569
void construct_confirms(ir_graph *irg)
{
Michael Beck's avatar
Michael Beck committed
570
571
	env_t env;
	int edges_active = edges_activated(irg);
Michael Beck's avatar
Michael Beck committed
572

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

575
576
	remove_critical_cf_edges(irg);

Michael Beck's avatar
Michael Beck committed
577
578
	/* we need dominance info */
	assure_doms(irg);
Michael Beck's avatar
Michael Beck committed
579

Michael Beck's avatar
Michael Beck committed
580
581
	assert(get_irg_pinned(irg) == op_pin_state_pinned &&
	       "Nodes must be placed to insert Confirms");
Michael Beck's avatar
Michael Beck committed
582

Michael Beck's avatar
Michael Beck committed
583
584
585
586
	if (! edges_active) {
		/* We need edges */
		edges_activate(irg);
	}
Michael Beck's avatar
Michael Beck committed
587

Michael Beck's avatar
Michael Beck committed
588
589
590
	env.num_confirms = 0;
	env.num_consts   = 0;
	env.num_eq       = 0;
591
	env.num_non_null = 0;
Michael Beck's avatar
Michael Beck committed
592

593
	if (get_opt_global_null_ptr_elimination()) {
594
595
596
597
598
599
		/* 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
600

Michael Beck's avatar
Michael Beck committed
601
602
603
	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
604

Michael Beck's avatar
Michael Beck committed
605
606
607
		/* the new nodes are not in the loop info */
		set_irg_loopinfo_inconsistent(irg);
	}
Michael Beck's avatar
Michael Beck committed
608

609
610
611
	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));
612
	DB((dbg, LEVEL_1, "# non-null Confirms : %u\n", env.num_non_null));
Michael Beck's avatar
Michael Beck committed
613

Michael Beck's avatar
Michael Beck committed
614
615
616
	/* deactivate edges if they where off */
	if (! edges_active)
		edges_deactivate(irg);
617
}  /* construct_confirms */
Michael Beck's avatar
Michael Beck committed
618

619
/* Construct a pass. */
620
621
ir_graph_pass_t *construct_confirms_pass(const char *name)
{
622
	return def_graph_pass(name ? name : "confirm", construct_confirms);
623
624
}  /* construct_confirms_pass */

625
static void remove_confirm(ir_node *n, void *env)
626
{
627
628
	ir_node *value;

Michael Beck's avatar
Michael Beck committed
629
	(void) env;
630
631
632
633
634
635
	if (!is_Confirm(n))
		return;

	value = get_Confirm_value(n);
	exchange(n, value);
}
Michael Beck's avatar
Michael Beck committed
636
637
638
639

/*
 * Remove all Confirm nodes from a graph.
 */
640
641
void remove_confirms(ir_graph *irg)
{
642
	irg_walk_graph(irg, NULL, remove_confirm, NULL);
643
}  /* remove_confirms */
644
645

/* Construct a pass. */
646
647
ir_graph_pass_t *remove_confirms_pass(const char *name)
{
648
	return def_graph_pass(name ? name : "rem_confirm", remove_confirms);
649
}  /* remove_confirms_pass */