+ /* if the graph is not pinned, we cannot determine empty blocks */
+ assert(get_irg_pinned(irg) != op_pin_state_floats &&
+ "Control flow optimization need a pinned graph");
+
+ assure_irg_properties(irg, IR_GRAPH_PROPERTY_NO_UNREACHABLE_CODE);
+
+ /* First the "simple" optimizations, which do not touch Phis */
+ cfgopt_ignoring_phis(irg);
+
+ /* we use the mark flag to mark removable blocks */
+ ir_reserve_resources(irg, IR_RESOURCE_BLOCK_MARK | IR_RESOURCE_IRN_LINK
+ | IR_RESOURCE_PHI_LIST);
+
+ /*
+ * This pass collects all Phi nodes in a link list in the block
+ * nodes. Further it performs simple control flow optimizations.
+ * Finally it marks all blocks that do not contain useful
+ * computations, i.e., these blocks might be removed.
+ */
+ irg_walk(end, clear_link_and_mark_blocks_removable, collect_nodes, NULL);
+
+ /* assert due to collect_nodes:
+ * 1. removable blocks are now marked as such
+ * 2. phi lists are up to date
+ */
+
+ /* Optimize the standard code.
+ * It walks only over block nodes and adapts these and the Phi nodes in
+ * these blocks, which it finds in a linked list computed before.
+ */
+ assure_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE);
+ irg_block_walk_graph(irg, optimize_blocks, merge_blocks, &env);
+
+ new_end = optimize_in_place(end);
+ if (new_end != end) {
+ set_irg_end(irg, new_end);
+ end = new_end;
+ }
+ remove_End_Bads_and_doublets(end);
+
+ ir_free_resources(irg, IR_RESOURCE_BLOCK_MARK | IR_RESOURCE_IRN_LINK
+ | IR_RESOURCE_PHI_LIST);