2 * Copyright (C) 1995-2007 University of Karlsruhe. All right reserved.
4 * This file is part of libFirm.
6 * This file may be distributed and/or modified under the terms of the
7 * GNU General Public License version 2 as published by the Free Software
8 * Foundation and appearing in the file LICENSE.GPL included in the
9 * packaging of this file.
11 * Licensees holding valid libFirm Professional Edition licenses may use
12 * this file in accordance with the libFirm Commercial License.
13 * Agreement provided with the Software.
15 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * @brief Control flow optimizations.
23 * @author Goetz Lindenmaier, Michael Beck, Sebastian Hack
30 #include "iroptimize.h"
37 #include "irgraph_t.h"
51 #include "irbackedge_t.h"
56 #include "iropt_dbg.h"
58 /*------------------------------------------------------------------*/
59 /* Control flow optimization. */
61 /* Removes Bad control flow predecessors and empty blocks. A block */
62 /* is empty if it contains only a Jmp node. */
63 /* Blocks can only be removed if they are not needed for the */
64 /* semantics of Phi nodes. */
65 /* Further, we NEVER remove labeled blocks (even if we could move */
67 /*------------------------------------------------------------------*/
70 * Block walker, replacing binary Conds that jumps twice into the same block
76 * ProjX True ProjX False ==> | /
81 * Such pattern are the result of if-conversion.
83 * Note that the simple case that Block has only these two
84 * predecessors are already handled in equivalent_node_Block().
86 static void remove_senseless_conds(ir_node *bl, void *env) {
88 int n = get_Block_n_cfgpreds(bl);
93 for (i = 0; i < n; ++i) {
94 ir_node *pred_i = get_Block_cfgpred(bl, i);
95 ir_node *cond_i = skip_Proj(pred_i);
98 if (is_Cond(cond_i) && get_irn_mode(get_Cond_selector(cond_i)) == mode_b) {
100 for (j = i + 1; j < n; ++j) {
101 ir_node *pred_j = get_Block_cfgpred(bl, j);
102 ir_node *cond_j = skip_Proj(pred_j);
104 if (cond_j == cond_i) {
105 ir_node *jmp = new_r_Jmp(current_ir_graph, get_nodes_block(cond_i));
106 set_irn_n(bl, i, jmp);
107 set_irn_n(bl, j, new_Bad());
109 DBG_OPT_IFSIM2(cond_i, jmp);
118 /** An environment for merge_blocks and collect nodes. */
119 typedef struct _merge_env {
120 int changed; /**< Set if the graph was changed. */
121 int phis_moved; /**< Set if Phi nodes were moved. */
122 plist_t *list; /**< Helper list for all found Switch Conds. */
126 * Removes Tuples from Block control flow predecessors.
127 * Optimizes blocks with equivalent_node(). This is tricky,
128 * as we want to avoid nodes that have as block predecessor Bads.
129 * Therefore we also optimize at control flow operations, depending
130 * how we first reach the Block.
132 static void merge_blocks(ir_node *node, void *ctx) {
135 merge_env *env = ctx;
137 /* clear the link field for ALL nodes first */
138 set_irn_link(node, NULL);
140 if (is_Block(node)) {
142 for (i = get_Block_n_cfgpreds(node) - 1; i >= 0; --i) {
143 ir_node *pred = get_Block_cfgpred(node, i);
144 ir_node *skipped = skip_Tuple(pred);
145 if (pred != skipped) {
146 set_Block_cfgpred(node, i, skipped);
152 new_block = equivalent_node(node);
153 if (new_block != node && ! is_Block_dead(new_block)) {
154 exchange(node, new_block);
158 } else if (get_opt_optimize() && (get_irn_mode(node) == mode_X)) {
159 /* We will soon visit a block. Optimize it before visiting! */
160 ir_node *b = get_nodes_block(skip_Proj(node));
162 if (!is_Block_dead(b)) {
163 new_block = equivalent_node(b);
165 while (irn_not_visited(b) && (!is_Block_dead(new_block)) && (new_block != b)) {
166 /* We would have to run gigo() if new is bad, so we
167 promote it directly below. Nevertheless, we sometimes reach a block
168 the first time through a dataflow node. In this case we optimized the
169 block as such and have to promote the Bad here. */
170 assert((get_opt_control_flow_straightening() ||
171 get_opt_control_flow_weak_simplification()) &&
172 ("strange flag setting"));
173 exchange(b, new_block);
176 new_block = equivalent_node(b);
179 /* normally, we would create a Bad block here, but this must be
180 * prevented, so just set it's cf to Bad.
182 if (is_Block_dead(new_block)) {
183 exchange(node, new_Bad());
192 * Block walker removing control flow from dead block by
193 * inspecting dominance info.
194 * Do not replace blocks by Bad. This optimization shall
195 * ensure, that all Bad control flow predecessors are
196 * removed, and no new other Bads are introduced.
198 * Must be run in the post walker.
200 static void remove_dead_block_cf(ir_node *block, void *env) {
204 /* check block predecessors and turn control flow into bad */
205 for (i = get_Block_n_cfgpreds(block) - 1; i >= 0; --i) {
206 ir_node *pred_X = get_Block_cfgpred(block, i);
208 if (! is_Bad(pred_X)) {
209 ir_node *pred_bl = get_nodes_block(skip_Proj(pred_X));
211 if (is_Block_dead(pred_bl) || (get_Block_dom_depth(pred_bl) < 0)) {
212 set_Block_dead(pred_bl);
213 exchange(pred_X, new_Bad());
221 * Collects all Phi nodes in link list of Block.
222 * Marks all blocks "block_visited" if they contain a node other
223 * than Jmp (and Proj).
224 * Links all Proj nodes to their predecessors.
225 * Collects all switch-Conds in a list.
227 static void collect_nodes(ir_node *n, void *ctx) {
228 ir_op *op = get_irn_op(n);
229 merge_env *env = ctx;
231 if (op == op_Block) {
232 /* mark the block as non-empty if it is labelled */
233 if (has_Block_label(n))
234 mark_Block_block_visited(n);
236 ir_node *b = get_nodes_block(n);
239 /* Collect Phi nodes to compact ins along with block's ins. */
240 set_irn_link(n, get_irn_link(b));
242 } else if (op != op_Jmp && !is_Bad(b)) { /* Check for non empty block. */
243 mark_Block_block_visited(b);
245 if (op == op_Proj) { /* link Proj nodes */
246 ir_node *pred = get_Proj_pred(n);
248 set_irn_link(n, get_irn_link(pred));
249 set_irn_link(pred, n);
250 } else if (op == op_Cond) {
251 ir_node *sel = get_Cond_selector(n);
252 if (mode_is_int(get_irn_mode(sel))) {
253 /* found a switch-Cond, collect */
254 plist_insert_back(env->list, n);
261 /** Returns true if pred is predecessor of block. */
262 static int is_pred_of(ir_node *pred, ir_node *b) {
265 for (i = 0, n = get_Block_n_cfgpreds(b); i < n; ++i) {
266 ir_node *b_pred = get_Block_cfgpred_block(b, i);
267 if (b_pred == pred) return 1;
272 /** Test whether we can optimize away pred block pos of b.
274 * @param b A block node.
275 * @param pos The position of the predecessor block to judge about.
277 * @returns The number of predecessors
279 * The test is rather tricky.
281 * The situation is something like the following:
290 * b merges the control flow of an if-then-else. We may not remove
291 * the 'then' _and_ the 'else' block of an 'if' if there is a Phi
292 * node in b, even if both are empty. The destruction of this Phi
293 * requires that a copy is added before the merge. We have to
294 * keep one of the case blocks to place the copies in.
296 * To perform the test for pos, we must regard predecessors before pos
297 * as already removed.
299 static int test_whether_dispensable(ir_node *b, int pos) {
300 int i, j, n_preds = 1;
301 ir_node *pred = get_Block_cfgpred_block(b, pos);
303 /* Bad blocks will be optimized away, so we don't need space for them */
304 if (is_Block_dead(pred))
307 if (get_Block_block_visited(pred) + 1
308 < get_irg_block_visited(current_ir_graph)) {
310 if (!get_opt_optimize() || !get_opt_control_flow_strong_simplification()) {
311 /* Mark block so that is will not be removed: optimization is turned off. */
312 set_Block_block_visited(pred, get_irg_block_visited(current_ir_graph)-1);
316 /* Seems to be empty. At least we detected this in collect_nodes. */
317 if (!get_irn_link(b)) {
318 /* There are no Phi nodes ==> all predecessors are dispensable. */
319 n_preds = get_Block_n_cfgpreds(pred);
321 /* b's pred blocks and pred's pred blocks must be pairwise disjunct.
322 Handle all pred blocks with preds < pos as if they were already removed. */
323 for (i = 0; i < pos; i++) {
324 ir_node *b_pred = get_Block_cfgpred_block(b, i);
325 if (! is_Block_dead(b_pred) &&
326 get_Block_block_visited(b_pred) + 1
327 < get_irg_block_visited(current_ir_graph)) {
328 for (j = 0; j < get_Block_n_cfgpreds(b_pred); j++) {
329 ir_node *b_pred_pred = get_Block_cfgpred_block(b_pred, j);
330 if (is_pred_of(b_pred_pred, pred))
331 goto non_dispensable;
334 if (is_pred_of(b_pred, pred))
335 goto non_dispensable;
338 for (i = pos +1; i < get_Block_n_cfgpreds(b); i++) {
339 ir_node *b_pred = get_Block_cfgpred_block(b, i);
340 if (is_pred_of(b_pred, pred))
341 goto non_dispensable;
343 /* if we get here, the block is dispensable */
344 n_preds = get_Block_n_cfgpreds(pred);
351 set_Block_block_visited(pred, get_irg_block_visited(current_ir_graph)-1);
356 * This method removed Bad cf predecessors from Blocks and Phis, and removes
357 * empty blocks. A block is empty if it only contains Phi and Jmp nodes.
359 * We first adapt Phi nodes, then Block nodes, as we need the old ins
360 * of the Block to adapt the Phi nodes. We do this by computing new
361 * in arrays, and then replacing the old ones. So far we compute new in arrays
362 * for all nodes, not regarding whether there is a possibility for optimization.
364 * For each predecessor p of a Block b there are three cases:
365 * -1. The predecessor p is a Bad node: just skip it. The in array of b shrinks by one.
366 * -2. The predecessor p is empty. Remove p. All predecessors of p are now
368 * -3. The predecessor p is a block containing useful code. Just keep p as is.
370 * For Phi nodes f we have to check the conditions at the Block of f.
371 * For cases 1 and 3 we proceed as for Blocks. For case 2 we can have two
373 * -2a: The old predecessor of the Phi f is a Phi pred_f IN THE BLOCK REMOVED. In this
374 * case we proceed as for blocks. We remove pred_f. All
375 * predecessors of pred_f now are predecessors of f.
376 * -2b: The old predecessor of f is NOT in the block removed. It might be a Phi, too.
377 * We have to replicate f for each predecessor of the removed block. Or, with
378 * other words, the removed predecessor block has exactly one predecessor.
380 * Further there is a special case for self referencing blocks:
383 * then_b else_b then_b else_b
389 * | | | === optimized to ===> \ | | |
396 * If there is a Phi in pred_b, but we remove pred_b, we have to generate a
397 * Phi in loop_b, that has the ins of the Phi in pred_b and a self referencing
399 * @@@ It is negotiable whether we should do this ... there might end up a copy
400 * from the Phi in the loop when removing the Phis.
402 static void optimize_blocks(ir_node *b, void *ctx) {
403 int i, j, k, n, max_preds, n_preds, p_preds = -1;
406 merge_env *env = ctx;
408 /* Count the number of predecessor if this block is merged with pred blocks
411 for (i = 0, k = get_Block_n_cfgpreds(b); i < k; ++i) {
412 max_preds += test_whether_dispensable(b, i);
414 in = xmalloc(max_preds * sizeof(*in));
416 /*- Fix the Phi nodes of the current block -*/
417 for (phi = get_irn_link(b); phi; ) {
418 assert(get_irn_op(phi) == op_Phi);
420 /* Find the new predecessors for the Phi */
422 for (i = 0, n = get_Block_n_cfgpreds(b); i < n; ++i) {
423 pred = get_Block_cfgpred_block(b, i);
425 if (is_Bad(get_Block_cfgpred(b, i))) {
426 /* case Phi 1: Do nothing */
428 else if (get_Block_block_visited(pred) + 1
429 < get_irg_block_visited(current_ir_graph)) {
430 /* case Phi 2: It's an empty block and not yet visited. */
431 ir_node *phi_pred = get_Phi_pred(phi, i);
433 for (j = 0, k = get_Block_n_cfgpreds(pred); j < k; j++) {
434 /* because of breaking loops, not all predecessors are Bad-clean,
435 * so we must check this here again */
436 if (! is_Bad(get_Block_cfgpred(pred, j))) {
437 if (get_nodes_block(phi_pred) == pred) {
439 assert(get_irn_op(phi_pred) == op_Phi); /* Block is empty!! */
441 in[p_preds++] = get_Phi_pred(phi_pred, j);
444 in[p_preds++] = phi_pred;
450 in[p_preds++] = get_Phi_pred(phi, i);
453 assert(p_preds <= max_preds);
457 /* By removal of Bad ins the Phi might be degenerated. */
458 exchange(phi, in[0]);
460 set_irn_in(phi, p_preds, in);
463 phi = get_irn_link(phi);
466 /*- This happens only if merge between loop backedge and single loop entry.
467 Moreover, it is only needed if predb is the direct dominator of b, else there can be no uses
468 of the Phi's in predb ... -*/
469 for (k = 0, n = get_Block_n_cfgpreds(b); k < n; ++k) {
470 ir_node *predb = get_nodes_block(get_Block_cfgpred(b, k));
472 if (get_Block_block_visited(predb) + 1 < get_irg_block_visited(current_ir_graph)) {
475 /* we found a predecessor block at position k that will be removed */
476 for (phi = get_irn_link(predb); phi; phi = next_phi) {
478 next_phi = get_irn_link(phi);
482 if (get_Block_idom(b) != predb) {
483 /* predb is not the dominator. There can't be uses of pred's Phi nodes, kill them .*/
484 exchange(phi, new_Bad());
486 /* predb is the direct dominator of b. There might be uses of the Phi nodes from
487 predb in further block, so move this phi from the predecessor into the block b */
488 set_nodes_block(phi, b);
489 set_irn_link(phi, get_irn_link(b));
490 set_irn_link(b, phi);
493 /* first, copy all 0..k-1 predecessors */
494 for (i = 0; i < k; i++) {
495 pred = get_Block_cfgpred_block(b, i);
499 } else if (get_Block_block_visited(pred) + 1
500 < get_irg_block_visited(current_ir_graph)) {
501 /* It's an empty block and not yet visited. */
502 for (j = 0; j < get_Block_n_cfgpreds(pred); j++) {
503 if (! is_Bad(get_Block_cfgpred(pred, j)))
511 /* now we are at k, copy the phi predecessors */
512 pred = get_nodes_block(get_Block_cfgpred(b, k));
513 for (i = 0; i < get_Phi_n_preds(phi); i++) {
514 if (! is_Bad(get_Block_cfgpred(pred, i)))
515 in[q_preds++] = get_Phi_pred(phi, i);
518 /* and now all the rest */
519 for (i = k+1; i < get_Block_n_cfgpreds(b); i++) {
520 pred = get_nodes_block(get_Block_cfgpred(b, i));
522 if (is_Bad(get_Block_cfgpred(b, i))) {
524 } else if (get_Block_block_visited(pred) +1
525 < get_irg_block_visited(current_ir_graph)) {
526 /* It's an empty block and not yet visited. */
527 for (j = 0; j < get_Block_n_cfgpreds(pred); j++) {
528 if (! is_Bad(get_Block_cfgpred(pred, j)))
538 exchange(phi, in[0]);
540 set_irn_in(phi, q_preds, in);
543 assert(q_preds <= max_preds);
544 // assert(p_preds == q_preds && "Wrong Phi Fix");
550 /*- Fix the block -*/
552 for (i = 0; i < get_Block_n_cfgpreds(b); i++) {
553 pred = get_Block_cfgpred_block(b, i);
556 /* case 1: Do nothing */
557 } else if (get_Block_block_visited(pred) +1
558 < get_irg_block_visited(current_ir_graph)) {
559 /* case 2: It's an empty block and not yet visited. */
560 assert(get_Block_n_cfgpreds(b) > 1);
561 /* Else it should be optimized by equivalent_node. */
562 for (j = 0; j < get_Block_n_cfgpreds(pred); j++) {
563 ir_node *pred_block = get_Block_cfgpred(pred, j);
565 /* because of breaking loops, not all predecessors are Bad-clean,
566 * so we must check this here again */
567 if (! is_Bad(pred_block))
568 in[n_preds++] = pred_block;
570 /* Remove block as it might be kept alive. */
571 exchange(pred, b/*new_Bad()*/);
574 in[n_preds++] = get_Block_cfgpred(b, i);
577 assert(n_preds <= max_preds);
579 set_irn_in(b, n_preds, in);
582 assert(get_irn_link(b) == NULL || p_preds == -1 || (n_preds == p_preds && "Wrong Phi Fix"));
587 * Block walker: optimize all blocks using the default optimizations.
588 * This removes Blocks that with only a Jmp predecessor.
590 static void remove_simple_blocks(ir_node *block, void *ctx) {
591 ir_node *new_blk = equivalent_node(block);
592 merge_env *env = ctx;
594 if (new_blk != block) {
595 exchange(block, new_blk);
601 * Handle pre-optimized table switch Cond's.
602 * During iropt, all Projs from a switch-Cond are already removed except
603 * the defProj and maybe the taken one.
604 * The defProj cannot be removed WITHOUT looking backwards, so we do this here.
606 * @param cond the switch-Cond
608 * @return non-zero if a switch-Cond was optimized
610 * Expects all Proj's linked to the cond node
612 static int handle_switch_cond(ir_node *cond) {
613 ir_node *sel = get_Cond_selector(cond);
615 ir_node *proj1 = get_irn_link(cond);
616 ir_node *proj2 = get_irn_link(proj1);
619 blk = get_nodes_block(cond);
622 /* this Cond has only one Proj: must be the defProj */
623 assert(get_Cond_defaultProj(cond) == get_Proj_proj(proj1));
624 /* convert it into a Jmp */
625 jmp = new_r_Jmp(current_ir_graph, blk);
626 exchange(proj1, jmp);
628 } else if (get_irn_link(proj2) == NULL) {
629 /* We have two Proj's here. Check if the Cond has
630 a constant argument */
631 tarval *tv = value_of(sel);
633 if (tv != tarval_bad) {
634 /* we have a constant switch */
635 long num = get_tarval_long(tv);
636 long def_num = get_Cond_defaultProj(cond);
638 if (def_num == get_Proj_proj(proj1)) {
639 /* first one is the defProj */
640 if (num == get_Proj_proj(proj2)) {
641 jmp = new_r_Jmp(current_ir_graph, blk);
642 exchange(proj2, jmp);
643 exchange(proj1, new_Bad());
646 } else if (def_num == get_Proj_proj(proj2)) {
647 /* second one is the defProj */
648 if (num == get_Proj_proj(proj1)) {
649 jmp = new_r_Jmp(current_ir_graph, blk);
650 exchange(proj1, jmp);
651 exchange(proj2, new_Bad());
655 /* neither: strange, Cond was not optimized so far */
656 if (num == get_Proj_proj(proj1)) {
657 jmp = new_r_Jmp(current_ir_graph, blk);
658 exchange(proj1, jmp);
659 exchange(proj2, new_Bad());
661 } else if (num == get_Proj_proj(proj2)) {
662 jmp = new_r_Jmp(current_ir_graph, blk);
663 exchange(proj2, jmp);
664 exchange(proj1, new_Bad());
673 /* Optimizations of the control flow that also require changes of Phi nodes.
675 * This optimization performs two passes over the graph.
677 * The first pass collects all Phi nodes in a link list in the block
678 * nodes. Further it performs simple control flow optimizations.
679 * Finally it marks all blocks that do not contain useful
680 * computations, i.e., these blocks might be removed.
682 * The second pass performs the optimizations intended by this algorithm.
683 * It walks only over block nodes and adapts these and the Phi nodes in these blocks,
684 * which it finds in a linked list computed by the first pass.
686 * We use the block_visited flag to mark empty blocks in the first
688 * @@@ It would be better to add a struct in the link field
689 * that keeps the Phi list and the mark. Place it on an obstack, as
690 * we will lose blocks and thereby generate memory leaks.
692 void optimize_cf(ir_graph *irg) {
695 ir_node *cond, *end = get_irg_end(irg);
696 ir_graph *rem = current_ir_graph;
700 assert(get_irg_phase_state(irg) != phase_building);
702 /* if the graph is not pinned, we cannot determine empty blocks */
703 assert(get_irg_pinned(irg) != op_pin_state_floats &&
704 "Control flow optimization need a pinned graph");
706 current_ir_graph = irg;
708 /* FIXME: is this still needed? */
709 edges_deactivate(irg);
714 if (get_opt_optimize() && get_opt_unreachable_code()) {
717 /* kill dead blocks using dom info */
719 irg_block_walk_graph(irg, NULL, remove_dead_block_cf, &env.changed);
721 /* fix the keep-alives */
722 end = get_irg_end(irg);
723 for (i = 0, n = get_End_n_keepalives(end); i < n; ++i) {
724 ir_node *ka = get_End_keepalive(end, i);
727 /* do NOT keep dead blocks */
728 if (get_Block_dom_depth(ka) < 0) {
729 set_End_keepalive(end, i, new_Bad());
732 } else if (is_Block_dead(get_nodes_block(ka)) ||
733 get_Block_dom_depth(get_nodes_block(ka)) < 0) {
734 /* do NOT keep nodes in dead blocks */
735 set_End_keepalive(end, i, new_Bad());
740 irg_block_walk_graph(irg, NULL, remove_senseless_conds, &env.changed);
742 /* Use block visited flag to mark non-empty blocks. */
743 inc_irg_block_visited(irg);
744 set_using_block_visited(irg);
745 set_using_irn_link(irg);
747 env.list = plist_new();
748 irg_walk(end, merge_blocks, collect_nodes, &env);
750 clear_using_block_visited(irg);
751 clear_using_irn_link(irg);
753 /* handle all collected switch-Conds */
754 foreach_plist(env.list, el) {
755 cond = plist_element_get_value(el);
756 env.changed |= handle_switch_cond(cond);
758 plist_free(env.list);
761 /* Handle graph state if was changed. */
762 set_irg_outs_inconsistent(irg);
763 set_irg_doms_inconsistent(irg);
764 set_irg_extblk_inconsistent(irg);
765 set_irg_loopinfo_inconsistent(irg);
768 /* Optimize the standard code. */
771 irg_block_walk(get_irg_end_block(irg), optimize_blocks, remove_simple_blocks, &env);
773 /* Walk all keep alives, optimize them if block, add to new in-array
774 for end if useful. */
775 n = get_End_n_keepalives(end);
777 NEW_ARR_A(ir_node *, in, n);
779 /* in rare cases a node may be kept alive more than once, use the visited flag to detect this */
780 inc_irg_visited(irg);
781 set_using_visited(irg);
783 /* fix the keep alive */
784 for (i = j = 0; i < n; i++) {
785 ir_node *ka = get_End_keepalive(end, i);
787 if (irn_not_visited(ka)) {
788 ir_op *op = get_irn_op(ka);
790 if ((op == op_Block) && Block_not_block_visited(ka)) {
791 /* irg_block_walk() will increase the block visited flag, but we must visit only
792 these blocks that are not visited yet, so decrease it first. */
793 set_irg_block_visited(irg, get_irg_block_visited(irg) - 1);
794 irg_block_walk(ka, optimize_blocks, remove_simple_blocks, &env.changed);
795 mark_irn_visited(ka);
797 } else if (op == op_Phi) {
798 mark_irn_visited(ka);
799 /* don't keep alive dead blocks */
800 if (! is_Block_dead(get_nodes_block(ka)))
802 } else if (is_op_keep(op)) {
803 mark_irn_visited(ka);
804 if (! is_Block_dead(get_nodes_block(ka)))
810 set_End_keepalives(end, j, in);
814 clear_using_visited(irg);
816 if (env.phis_moved) {
817 /* Bad: when we moved Phi's, we might produce dead Phi nodes
819 Some other phases cannot copy with this, so will them.
821 n = get_End_n_keepalives(end);
824 /* Handle graph state if was changed. */
825 set_irg_outs_inconsistent(irg);
827 assure_irg_outs(irg);
829 for (i = j = 0; i < n; ++i) {
830 ir_node *ka = get_End_keepalive(end, i);
835 for (k = get_irn_n_outs(ka) - 1; k >= 0; --k) {
836 ir_node *user = get_irn_out(ka, k);
838 if (user != ka && user != end) {
839 /* Is it a real user or just a self loop ? */
849 set_End_keepalives(end, j, in);
856 /* Handle graph state if was changed. */
857 set_irg_outs_inconsistent(irg);
858 set_irg_doms_inconsistent(irg);
859 set_irg_extblk_inconsistent(irg);
860 set_irg_loopinfo_inconsistent(irg);
864 /* the verifier doesn't work yet with floating nodes */
865 if (get_irg_pinned(irg) == op_pin_state_pinned) {
866 /* after optimize_cf(), only Bad data flow may remain. */
867 if (irg_vrfy_bads(irg, BAD_DF | BAD_BLOCK | TUPLE)) {
868 dump_ir_block_graph(irg, "-vrfy-cf");
869 dump_ir_graph(irg, "-vrfy-cf");
870 fprintf(stderr, "VRFY_BAD in optimize_cf()\n");
874 current_ir_graph = rem;