workaround for placement of nodes held only by keepalive edge
authorMatthias Braun <matze@braunis.de>
Thu, 30 Aug 2012 11:46:45 +0000 (13:46 +0200)
committerMatthias Braun <matze@braunis.de>
Thu, 30 Aug 2012 12:19:43 +0000 (14:19 +0200)
This is a workaround for keepalive edges which are probably broken
(adding the stuff to the End node is wrong, it should get added to the
 endless loop somehow)

ir/opt/code_placement.c

index baaabab..0cc25b3 100644 (file)
@@ -44,6 +44,25 @@ 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.
@@ -81,7 +100,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) {
+       if (get_irn_pinned(n) != op_pin_state_floats || float_exceptions(n)) {
                /* we can't move pinned nodes */
                arity = get_irn_arity(n);
                for (i = 0; i < arity; ++i) {