Hey, I'm going to do more testing on this, but it seems this patch reduces the number of DOM iterations from the number of else if statements in pr19097 to 2 DOM iterations. This is a massive savings and the savings if from calling fold_build2 (cond_code, boolean_type_node, op0, op1) in thread_across_edge since the folded expression is now saved for the rest of the iteration where the folded expression wasn't before. Since this is such a huge gain, I'm skeptical that it is truly correct. Comments?
Jim Index: tree-ssa-dom.c =================================================================== RCS file: /cvsroot/gcc/gcc/gcc/tree-ssa-dom.c,v retrieving revision 2.127 diff -u -p -r2.127 tree-ssa-dom.c --- tree-ssa-dom.c 2 Aug 2005 00:12:39 -0000 2.127 +++ tree-ssa-dom.c 25 Aug 2005 06:31:56 -0000 @@ -294,21 +294,6 @@ static void restore_nonzero_vars_to_orig static inline bool unsafe_associative_fp_binop (tree); -/* Local version of fold that doesn't introduce cruft. */ - -static tree -local_fold (tree t) -{ - t = fold (t); - - /* Strip away useless type conversions. Both the NON_LVALUE_EXPR that - may have been added by fold, and "useless" type conversions that might - now be apparent due to propagation. */ - STRIP_USELESS_TYPE_CONVERSION (t); - - return t; -} - /* Allocate an EDGE_INFO for edge E and attach it to E. Return the new EDGE_INFO structure. */ @@ -795,21 +780,27 @@ thread_across_edge (struct dom_walk_data dummy_cond = walk_data->global_data; if (! dummy_cond) { - dummy_cond = build (cond_code, boolean_type_node, op0, op1); - dummy_cond = build (COND_EXPR, void_type_node, - dummy_cond, NULL, NULL); + cached_lhs = fold_build2 (cond_code, boolean_type_node, op0, op1); + dummy_cond = build3 (COND_EXPR, void_type_node, + cached_lhs, NULL, NULL); walk_data->global_data = dummy_cond; } + else if ((cached_lhs = fold_binary (cond_code, boolean_type_node, + op0, op1))) + { + COND_EXPR_COND (dummy_cond) = cached_lhs; + } else { TREE_SET_CODE (COND_EXPR_COND (dummy_cond), cond_code); TREE_OPERAND (COND_EXPR_COND (dummy_cond), 0) = op0; TREE_OPERAND (COND_EXPR_COND (dummy_cond), 1) = op1; + cached_lhs = COND_EXPR_COND (dummy_cond); } + STRIP_USELESS_TYPE_CONVERSION (cached_lhs); /* If the conditional folds to an invariant, then we are done, otherwise look it up in the hash tables. */ - cached_lhs = local_fold (COND_EXPR_COND (dummy_cond)); if (! is_gimple_min_invariant (cached_lhs)) { cached_lhs = lookup_avail_expr (dummy_cond, false); @@ -1813,18 +1804,22 @@ simplify_rhs_and_lookup_avail_expr (tree if (rhs_def_code != rhs_code) { if (rhs_def_code == MINUS_EXPR) - t = build (MINUS_EXPR, type, outer_const, def_stmt_op1); + t = fold_build2 (MINUS_EXPR, type, outer_const, + def_stmt_op1); else - t = build (MINUS_EXPR, type, def_stmt_op1, outer_const); + t = fold_build2 (MINUS_EXPR, type, def_stmt_op1, + outer_const); rhs_code = PLUS_EXPR; } else if (rhs_def_code == MINUS_EXPR) - t = build (PLUS_EXPR, type, def_stmt_op1, outer_const); + t = fold_build2 (PLUS_EXPR, type, def_stmt_op1, + outer_const); else - t = build (rhs_def_code, type, def_stmt_op1, outer_const); - t = local_fold (t); - t = build (rhs_code, type, def_stmt_op0, t); - t = local_fold (t); + t = fold_build2 (rhs_def_code, type, def_stmt_op1, + outer_const); + STRIP_USELESS_TYPE_CONVERSION (t); + t = fold_build2 (rhs_code, type, def_stmt_op0, t); + STRIP_USELESS_TYPE_CONVERSION (t); /* If the result is a suitable looking gimple expression, then use it instead of the original for STMT. */ @@ -1928,11 +1923,11 @@ find_equivalent_equality_comparison (tre If that is true, the build and return new equivalent condition which uses the source of the typecast and the new constant (which has only changed its type). */ - new = build1 (TREE_CODE (def_rhs), def_rhs_inner_type, op1); - new = local_fold (new); + new = fold_build1 (TREE_CODE (def_rhs), def_rhs_inner_type, op1); + STRIP_USELESS_TYPE_CONVERSION (new); if (is_gimple_val (new) && tree_int_cst_equal (new, op1)) - return build (TREE_CODE (cond), TREE_TYPE (cond), - def_rhs_inner, new); + return build2 (TREE_CODE (cond), TREE_TYPE (cond), + def_rhs_inner, new); } } return NULL; @@ -2714,7 +2709,7 @@ record_equivalences_from_stmt (tree stmt if (rhs) { /* Build a new statement with the RHS and LHS exchanged. */ - new = build (MODIFY_EXPR, TREE_TYPE (stmt), rhs, lhs); + new = build2 (MODIFY_EXPR, TREE_TYPE (stmt), rhs, lhs); create_ssa_artficial_load_stmt (new, stmt);