X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fopt%2Fcode_placement.c;h=0540e2126d862729717861441c674df5d26fa07b;hb=2b76ea5c55c405a6aefc64ffa07b8c810a7fd7f1;hp=0cc25b353c928c8c9d22534db86cda5e4ffa8fc0;hpb=babe0f4cc35d4b25e34e62a07324e2dd061e7cc8;p=libfirm diff --git a/ir/opt/code_placement.c b/ir/opt/code_placement.c index 0cc25b353..0540e2126 100644 --- a/ir/opt/code_placement.c +++ b/ir/opt/code_placement.c @@ -44,25 +44,6 @@ static bool is_block_reachable(ir_node *block) return get_Block_dom_depth(block) >= 0; } -/** - * Firm keepalive edges are broken (the user should really be the endless loop - * and not the End node.) This wrong place of the user will lead to wrong - * results in place_early()/place_late(). We work around these problems by not - * moving nodes which just have keepalive edges as their users (or no users at - * all) - */ -static bool float_exceptions(const ir_node *node) -{ - foreach_out_edge(node, edge) { - ir_node *succ = get_edge_src_irn(edge); - if (is_End(succ)) - continue; - /* found a real user */ - return false; - } - return true; -} - /** * Find the earliest correct block for node n. --- Place n into the * same Block as its dominance-deepest Input. @@ -100,7 +81,7 @@ static void place_floats_early(ir_node *n, waitq *worklist) * This works because in firm each cycle contains a Phi or Block node * (which are pinned) */ - if (get_irn_pinned(n) != op_pin_state_floats || float_exceptions(n)) { + if (get_irn_pinned(n) != op_pin_state_floats || only_used_by_keepalive(n)) { /* we can't move pinned nodes */ arity = get_irn_arity(n); for (i = 0; i < arity; ++i) { @@ -302,6 +283,13 @@ static ir_node *get_deepest_common_dom_ancestor(ir_node *node, ir_node *dca) dca = consumer_dom_dca(dca, succ, node); } } + /* respect the keepalive rule: if our only user is a keepalive, then we must + * not move the node any further */ + if (dca == NULL) { + assert(only_used_by_keepalive(node)); + return get_nodes_block(node); + } + foreach_out_edge_kind(node, edge, EDGE_KIND_DEP) { ir_node *succ = get_edge_src_irn(edge); assert(is_block_reachable(get_nodes_block(succ)));