+/**
+ * Data flow optimization walker.
+ */
+static void opt_walker(ir_node *n, void *env) {
+ pdeq *waitq = env;
+ ir_node *optimized;
+
+ optimized = optimize_in_place_2(n);
+ set_irn_link(optimized, NULL);
+
+ if (optimized != n) {
+ const ir_edge_t *edge;
+
+ exchange(n, optimized);
+ foreach_out_edge(optimized, edge) {
+ ir_node *succ = get_edge_src_irn(edge);
+
+ if (get_irn_link(succ) != waitq) {
+ pdeq_putr(waitq, succ);
+ set_irn_link(succ, waitq);
+ }
+ }
+ }
+}
+
+void optimize_graph_df(ir_graph *irg) {
+ pdeq *waitq = new_pdeq();
+ int state = edges_activated(irg);
+
+ if (! state)
+ edges_activate(irg);
+
+ if (get_opt_global_cse())
+ set_irg_pinned(current_ir_graph, op_pin_state_floats);
+
+ /* Clean the value_table in irg for the CSE. */
+ del_identities(irg->value_table);
+ irg->value_table = new_identities();
+
+ if (get_irg_dom_state(current_ir_graph) == dom_consistent)
+ irg_block_walk_graph(irg, NULL, kill_dead_blocks, NULL);
+
+ /* invalidate info */
+ set_irg_outs_inconsistent(irg);
+ set_irg_doms_inconsistent(irg);
+ set_irg_loopinfo_inconsistent(irg);
+
+ /* walk over the graph */
+ irg_walk_graph(irg, NULL, opt_walker, waitq);
+
+ /* finish the wait queue */
+ while (! pdeq_empty(waitq)) {
+ ir_node *n = pdeq_getl(waitq);
+ opt_walker(n, waitq);
+ }
+
+ del_pdeq(waitq);
+
+ if (! state)
+ edges_deactivate(irg);
+}
+