This "physically" separates forwprop and combining all stmts to allow an easy lattice implementation.
Committed. Richard. 2014-03-13 Richard Biener <rguent...@suse.de> * tree-ssa-forwprop.c (ssa_forward_propagate_and_combine): Split out combining with gimple_match_and_simplify to a separate "pass". Implement a lattice. Index: gcc/tree-ssa-forwprop.c =================================================================== *** gcc/tree-ssa-forwprop.c (revision 208478) --- gcc/tree-ssa-forwprop.c (working copy) *************** along with GCC; see the file COPYING3. *** 52,57 **** --- 52,59 ---- #include "optabs.h" #include "tree-ssa-propagate.h" #include "tree-ssa-dom.h" + #include "tree-cfgcleanup.h" + #include "tree-into-ssa.h" /* This pass propagates the RHS of assignment statements into use sites of the LHS of the assignment. It's basically a specialized *************** simplify_mult (gimple_stmt_iterator *gsi *** 3571,3576 **** --- 3573,3580 ---- } + static vec<tree> lattice; + /* Primitive "lattice" function for gimple_match_and_simplify to discard matches on names whose definition contains abnormal SSA names. */ *************** static tree *** 3578,3589 **** fwprop_ssa_val (tree name) { if (TREE_CODE (name) == SSA_NAME ! /* ??? Instead match-and-simplify should make sure to not ! return a sequence that references abnormal SSA names. */ ! && (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (name) ! || (gimple_code (SSA_NAME_DEF_STMT (name)) != GIMPLE_PHI ! && stmt_references_abnormal_ssa_name (SSA_NAME_DEF_STMT (name))))) ! return NULL_TREE; return name; } --- 3582,3593 ---- fwprop_ssa_val (tree name) { if (TREE_CODE (name) == SSA_NAME ! && SSA_NAME_VERSION (name) < lattice.length ()) ! { ! tree val = lattice[SSA_NAME_VERSION (name)]; ! if (val) ! return val; ! } return name; } *************** ssa_forward_propagate_and_combine (void) *** 3598,3603 **** --- 3602,3665 ---- cfg_changed = false; + /* Combine stmts with the stmts defining their operands. Do that + in an order that guarantees visiting SSA defs before SSA uses. */ + lattice.create (num_ssa_names); + lattice.quick_grow_cleared (num_ssa_names); + int *postorder = XNEWVEC (int, n_basic_blocks_for_fn (cfun)); + int postorder_num = inverted_post_order_compute (postorder); + for (int i = 0; i < postorder_num; ++i) + { + bb = BASIC_BLOCK_FOR_FN (cfun, postorder[i]); + /* ??? Maybe want to handle degenerate PHIs to populate + the lattice more optimistically. */ + for (gimple_stmt_iterator gsi = gsi_start_bb (bb); + !gsi_end_p (gsi); gsi_next (&gsi)) + { + gimple stmt = gsi_stmt (gsi); + + if (gimple_match_and_simplify (&gsi, fwprop_ssa_val)) + { + stmt = gsi_stmt (gsi); + if (maybe_clean_or_replace_eh_stmt (stmt, stmt) + && gimple_purge_dead_eh_edges (bb)) + cfg_changed = true; + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "gimple_match_and_simplified to "); + print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); + } + } + + /* Fill up the lattice. */ + if (gimple_assign_single_p (stmt)) + { + tree lhs = gimple_assign_lhs (stmt); + tree rhs = gimple_assign_rhs1 (stmt); + if (TREE_CODE (lhs) == SSA_NAME) + { + if (TREE_CODE (rhs) == SSA_NAME) + lattice[SSA_NAME_VERSION (lhs)] = fwprop_ssa_val (rhs); + else if (is_gimple_min_invariant (rhs)) + lattice[SSA_NAME_VERSION (lhs)] = rhs; + else + lattice[SSA_NAME_VERSION (lhs)] = lhs; + } + } + } + } + free (postorder); + lattice.release (); + + /* ??? Code below doesn't expect non-renamed VOPs and the above + doesn't keep virtual operand form up-to-date. */ + if (cfg_changed) + { + cleanup_tree_cfg (); + cfg_changed = false; + } + update_ssa (TODO_update_ssa_only_virtuals); + FOR_EACH_BB_FN (bb, cfun) { gimple_stmt_iterator gsi; *************** ssa_forward_propagate_and_combine (void) *** 3699,3719 **** /* Mark stmt as potentially needing revisiting. */ gimple_set_plf (stmt, GF_PLF_1, false); - if (gimple_match_and_simplify (&gsi, fwprop_ssa_val)) - { - stmt = gsi_stmt (gsi); - if (maybe_clean_or_replace_eh_stmt (stmt, stmt) - && gimple_purge_dead_eh_edges (bb)) - cfg_changed = true; - changed = true; - if (dump_file && (dump_flags & TDF_DETAILS)) - { - fprintf (dump_file, "gimple_match_and_simplified to "); - print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); - } - } - - if (!changed) switch (gimple_code (stmt)) { case GIMPLE_ASSIGN: --- 3761,3766 ----