2 * This file is part of libFirm.
3 * Copyright (C) 2012 University of Karlsruhe.
7 * @brief Remove unreachable code
8 * @author Andreas Zwinkau
10 * This is done by elminiating all edges into the unreachable code. So that
11 * after that the unreachable code should be dead.
26 static bool is_block_unreachable(ir_node *block)
28 return get_Block_dom_depth(block) < 0;
32 * Eliminate block- and phi-inputs pointing to unreachable code
34 static void unreachable_to_bad(ir_node *node, void *env)
36 bool *changed = (bool *)env;
42 /* optimisation: we do not have to do anything inside the unreachable
44 if (is_block_unreachable(node))
47 arity = get_irn_arity(node);
48 irg = get_irn_irg(node);
49 for (i = 0; i < arity; ++i) {
50 ir_node *pred = get_Block_cfgpred(node, i);
51 if (is_Bad(pred) || !is_block_unreachable(get_nodes_block(pred)))
53 set_irn_n(node, i, new_r_Bad(irg, mode_X));
56 } else if (is_Phi(node)) {
57 ir_node *block = get_nodes_block(node);
61 /* optimisation: we do not have to do anything inside the unreachable
63 if (is_block_unreachable(block))
66 irg = get_irn_irg(node);
67 arity = get_irn_arity(node);
68 for (i = 0; i < arity; ++i) {
70 ir_node *phi_pred = get_irn_n(node, i);
73 block_pred = get_Block_cfgpred(block, i);
74 if (!is_Bad(block_pred) && !is_block_unreachable(get_nodes_block(block_pred)))
77 set_irn_n(node, i, new_r_Bad(irg, get_irn_mode(node)));
84 * remove kept nodes in unreachable blocks
86 static void remove_unreachable_keeps(ir_graph *irg)
88 ir_node *end = get_irg_end(irg);
89 int arity = get_irn_arity(end);
90 ir_node **new_in = XMALLOCN(ir_node*, arity);
94 for (i = 0; i < arity; ++i) {
95 ir_node *ka = get_End_keepalive(end, i);
96 ir_node *block = is_Block(ka) ? ka : get_nodes_block(ka);
97 if (is_block_unreachable(block))
99 new_in[new_arity++] = ka;
101 if (new_arity != arity)
102 set_End_keepalives(end, new_arity, new_in);
106 void remove_unreachable_code(ir_graph *irg)
108 bool changed = false;
110 assure_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE);
112 irg_walk_graph(irg, unreachable_to_bad, NULL, &changed);
113 remove_unreachable_keeps(irg);
115 confirm_irg_properties(irg, changed
116 ? IR_GRAPH_PROPERTY_NO_CRITICAL_EDGES
117 | IR_GRAPH_PROPERTY_NO_TUPLES
118 | IR_GRAPH_PROPERTY_ONE_RETURN
119 | IR_GRAPH_PROPERTY_MANY_RETURNS
120 : IR_GRAPH_PROPERTIES_ALL);
121 add_irg_properties(irg, IR_GRAPH_PROPERTY_NO_UNREACHABLE_CODE);