2 * Copyright (C) 2011 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 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * @brief Remove unreachable code
18 * @author Andreas Zwinkau
20 * This is done by elminiating all edges into the unreachable code. So that
21 * after that the unreachable code should be dead.
36 static bool is_block_unreachable(ir_node *block)
38 return get_Block_dom_depth(block) < 0;
42 * Eliminate block- and phi-inputs pointing to unreachable code
44 static void unreachable_to_bad(ir_node *node, void *env)
46 bool *changed = (bool *)env;
52 /* optimisation: we do not have to do anything inside the unreachable
54 if (is_block_unreachable(node))
57 arity = get_irn_arity(node);
58 irg = get_irn_irg(node);
59 for (i = 0; i < arity; ++i) {
60 ir_node *pred = get_Block_cfgpred(node, i);
61 if (is_Bad(pred) || !is_block_unreachable(get_nodes_block(pred)))
63 set_irn_n(node, i, new_r_Bad(irg, mode_X));
66 } else if (is_Phi(node)) {
67 ir_node *block = get_nodes_block(node);
71 /* optimisation: we do not have to do anything inside the unreachable
73 if (is_block_unreachable(block))
76 irg = get_irn_irg(node);
77 arity = get_irn_arity(node);
78 for (i = 0; i < arity; ++i) {
80 ir_node *phi_pred = get_irn_n(node, i);
83 block_pred = get_Block_cfgpred(block, i);
84 if (!is_Bad(block_pred) && !is_block_unreachable(get_nodes_block(block_pred)))
87 set_irn_n(node, i, new_r_Bad(irg, get_irn_mode(node)));
94 * remove kept nodes in unreachable blocks
96 static void remove_unreachable_keeps(ir_graph *irg)
98 ir_node *end = get_irg_end(irg);
99 int arity = get_irn_arity(end);
100 ir_node **new_in = XMALLOCN(ir_node*, arity);
104 for (i = 0; i < arity; ++i) {
105 ir_node *ka = get_End_keepalive(end, i);
106 ir_node *block = is_Block(ka) ? ka : get_nodes_block(ka);
107 if (is_block_unreachable(block))
109 new_in[new_arity++] = ka;
111 if (new_arity != arity)
112 set_End_keepalives(end, new_arity, new_in);
116 void remove_unreachable_code(ir_graph *irg)
118 bool changed = false;
120 assure_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE);
122 irg_walk_graph(irg, unreachable_to_bad, NULL, &changed);
123 remove_unreachable_keeps(irg);
125 confirm_irg_properties(irg, changed
126 ? IR_GRAPH_PROPERTY_NO_CRITICAL_EDGES
127 | IR_GRAPH_PROPERTY_NO_TUPLES
128 | IR_GRAPH_PROPERTY_ONE_RETURN
129 | IR_GRAPH_PROPERTY_MANY_RETURNS
130 : IR_GRAPH_PROPERTIES_ALL);
131 add_irg_properties(irg, IR_GRAPH_PROPERTY_NO_UNREACHABLE_CODE);