introduce remove_unreachable_blocks
authorAndreas Zwinkau <zwinkau@kit.edu>
Thu, 8 Sep 2011 10:56:39 +0000 (12:56 +0200)
committerAndreas Zwinkau <zwinkau@kit.edu>
Wed, 14 Sep 2011 09:12:58 +0000 (11:12 +0200)
include/libfirm/irgopt.h
ir/ir/unreachable.c [new file with mode: 0644]

index 938662b..a4cf9f7 100644 (file)
@@ -58,6 +58,11 @@ FIRM_API void local_optimize_graph(ir_graph *irg);
  */
 FIRM_API int optimize_graph_df(ir_graph *irg);
 
+/**
+ * Transforms unreachable blocks and nodes in there into Bad nodes
+ */
+FIRM_API void remove_unreachable_blocks(ir_graph *irg);
+
 /**
  * Removes all Bad nodes from a graph.
  *
diff --git a/ir/ir/unreachable.c b/ir/ir/unreachable.c
new file mode 100644 (file)
index 0000000..780ac54
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2011 University of Karlsruhe.  All right reserved.
+ *
+ * This file is part of libFirm.
+ *
+ * This file may be distributed and/or modified under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.GPL included in the
+ * packaging of this file.
+ *
+ * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+ * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE.
+ */
+
+/**
+ * @brief    Convert all unreachable blocks into Bad nodes
+ * @author   Andreas Zwinkau
+ */
+#include "config.h"
+
+#include <assert.h>
+#include <stdbool.h>
+
+#include "irnode_t.h"
+#include "irgopt.h"
+#include "irgmod.h"
+#include "irgwalk.h"
+#include "irtools.h"
+
+/**
+ * Block-walker
+ */
+static void unreachable_to_bad(ir_node *node, void *env)
+{
+       bool *changed = (bool *)env;
+       ir_graph *irg = get_irn_irg(node);
+
+       if (is_Block(node)) {
+               if (get_Block_dom_depth(node) < 0) {
+                       exchange(node, new_r_Bad(irg, mode_BB));
+                       *changed = true;
+               }
+       } else if (is_Bad(node)) {
+               /* nothing to do */
+       } else {
+               ir_node *block = get_nodes_block(node);
+               if (is_Bad(block) || get_Block_dom_depth(block) < 0) {
+                       exchange(node, new_r_Bad(irg, get_irn_mode(node)));
+                       *changed = true;
+               }
+       }
+}
+
+/*
+ * Transforms unreachable blocks and the nodes within into Bad nodes
+ */
+void remove_unreachable_blocks(ir_graph *irg)
+{
+       bool changed = false;
+
+       assure_doms(irg);
+
+       irg_walk_graph(irg, unreachable_to_bad, NULL, &changed);
+
+       if (changed) {
+               edges_deactivate(irg);
+               set_irg_outs_inconsistent(irg);
+       }
+}