diff options
author | law <law@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-01-09 16:56:49 +0000 |
---|---|---|
committer | law <law@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-01-09 16:56:49 +0000 |
commit | 8f628ee83a8e26b6bb2a8ad4ff4d0d46cded7ccf (patch) | |
tree | f25d3e3fc6c291e9620d52bbd2922ca9435a0a26 /gcc | |
parent | a150ee15564cbd8d4a5396d90180047952165895 (diff) | |
download | gcc-8f628ee83a8e26b6bb2a8ad4ff4d0d46cded7ccf.tar.gz |
* tree-ssa-dom.c (simplify_cond_and_lookup_avail_expr): Remove
code to propagate the RHS of a cast into COND_EXPR_COND. Remove
now unused arguments. Callers updated.
(eliminate_redundant_computations): Remove now unused arguments,
callers updated.
(local_fold): Remove, no longer used.
(find_equivalent_equality_comparison): Removed from tree-ssa-dom.c
and moved to...
* tree-ssa-forwprop.c (find_equivalent_equality_comparison): Here.
(simplify_cond): New function.
(forward_propagate_into_cond): Call simplify_cond.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@109502 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/tree-ssa-dom.c | 150 | ||||
-rw-r--r-- | gcc/tree-ssa-forwprop.c | 136 |
3 files changed, 156 insertions, 144 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3d9f48e5850..020d1a45711 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2005-01-09 Jeff Law <law@redhat.com> + + * tree-ssa-dom.c (simplify_cond_and_lookup_avail_expr): Remove + code to propagate the RHS of a cast into COND_EXPR_COND. Remove + now unused arguments. Callers updated. + (eliminate_redundant_computations): Remove now unused arguments, + callers updated. + (local_fold): Remove, no longer used. + (find_equivalent_equality_comparison): Removed from tree-ssa-dom.c + and moved to... + * tree-ssa-forwprop.c (find_equivalent_equality_comparison): Here. + (simplify_cond): New function. + (forward_propagate_into_cond): Call simplify_cond. + 2006-01-09 Alexandre Oliva <aoliva@redhat.com> * config/i386/sse.md (*vec_extractv2di_1_sse2): New. diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c index 45a5b7d31ae..3631a218b63 100644 --- a/gcc/tree-ssa-dom.c +++ b/gcc/tree-ssa-dom.c @@ -273,13 +273,12 @@ static void htab_statistics (FILE *, htab_t); static void record_cond (tree, tree); static void record_const_or_copy (tree, tree); static void record_equality (tree, tree); -static tree simplify_cond_and_lookup_avail_expr (tree, stmt_ann_t, int); -static tree find_equivalent_equality_comparison (tree); +static tree simplify_cond_and_lookup_avail_expr (tree); static void record_range (tree, basic_block); static bool extract_range_from_cond (tree, tree *, tree *, int *); static void record_equivalences_from_phis (basic_block); static void record_equivalences_from_incoming_edge (basic_block); -static bool eliminate_redundant_computations (tree, stmt_ann_t); +static bool eliminate_redundant_computations (tree); static void record_equivalences_from_stmt (tree, int, stmt_ann_t); static void thread_across_edge (struct dom_walk_data *, edge); static void dom_opt_finalize_block (struct dom_walk_data *, basic_block); @@ -292,21 +291,6 @@ static void restore_nonzero_vars_to_original_value (void); 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. */ @@ -904,9 +888,7 @@ thread_across_edge (struct dom_walk_data *walk_data, edge e) { cached_lhs = lookup_avail_expr (dummy_cond, false); if (!cached_lhs || ! is_gimple_min_invariant (cached_lhs)) - cached_lhs = simplify_cond_and_lookup_avail_expr (dummy_cond, - NULL, - false); + cached_lhs = simplify_cond_and_lookup_avail_expr (dummy_cond); } } /* We can have conditionals which just test the state of a @@ -1797,99 +1779,13 @@ simple_iv_increment_p (tree stmt) return false; } -/* COND is a condition of the form: - - x == const or x != const - - Look back to x's defining statement and see if x is defined as - - x = (type) y; - - If const is unchanged if we convert it to type, then we can build - the equivalent expression: - - - y == const or y != const - - Which may allow further optimizations. - - Return the equivalent comparison or NULL if no such equivalent comparison - was found. */ - -static tree -find_equivalent_equality_comparison (tree cond) -{ - tree op0 = TREE_OPERAND (cond, 0); - tree op1 = TREE_OPERAND (cond, 1); - tree def_stmt = SSA_NAME_DEF_STMT (op0); - - /* OP0 might have been a parameter, so first make sure it - was defined by a MODIFY_EXPR. */ - if (def_stmt && TREE_CODE (def_stmt) == MODIFY_EXPR) - { - tree def_rhs = TREE_OPERAND (def_stmt, 1); - - - /* If either operand to the comparison is a pointer to - a function, then we can not apply this optimization - as some targets require function pointers to be - canonicalized and in this case this optimization would - eliminate a necessary canonicalization. */ - if ((POINTER_TYPE_P (TREE_TYPE (op0)) - && TREE_CODE (TREE_TYPE (TREE_TYPE (op0))) == FUNCTION_TYPE) - || (POINTER_TYPE_P (TREE_TYPE (op1)) - && TREE_CODE (TREE_TYPE (TREE_TYPE (op1))) == FUNCTION_TYPE)) - return NULL; - - /* Now make sure the RHS of the MODIFY_EXPR is a typecast. */ - if ((TREE_CODE (def_rhs) == NOP_EXPR - || TREE_CODE (def_rhs) == CONVERT_EXPR) - && TREE_CODE (TREE_OPERAND (def_rhs, 0)) == SSA_NAME) - { - tree def_rhs_inner = TREE_OPERAND (def_rhs, 0); - tree def_rhs_inner_type = TREE_TYPE (def_rhs_inner); - tree new; - - if (TYPE_PRECISION (def_rhs_inner_type) - > TYPE_PRECISION (TREE_TYPE (def_rhs))) - return NULL; - - /* If the inner type of the conversion is a pointer to - a function, then we can not apply this optimization - as some targets require function pointers to be - canonicalized. This optimization would result in - canonicalization of the pointer when it was not originally - needed/intended. */ - if (POINTER_TYPE_P (def_rhs_inner_type) - && TREE_CODE (TREE_TYPE (def_rhs_inner_type)) == FUNCTION_TYPE) - return NULL; - - /* What we want to prove is that if we convert OP1 to - the type of the object inside the NOP_EXPR that the - result is still equivalent to SRC. - - 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); - if (is_gimple_val (new) && tree_int_cst_equal (new, op1)) - return build2 (TREE_CODE (cond), TREE_TYPE (cond), - def_rhs_inner, new); - } - } - return NULL; -} - /* STMT is a COND_EXPR for which we could not trivially determine its result. This routine attempts to find equivalent forms of the condition which we may be able to optimize better. It also uses simple value range propagation to optimize conditionals. */ static tree -simplify_cond_and_lookup_avail_expr (tree stmt, - stmt_ann_t ann, - int insert) +simplify_cond_and_lookup_avail_expr (tree stmt) { tree cond = COND_EXPR_COND (stmt); @@ -1908,37 +1804,6 @@ simplify_cond_and_lookup_avail_expr (tree stmt, struct vrp_hash_elt vrp_hash_elt, *vrp_hash_elt_p; void **slot; - /* First see if we have test of an SSA_NAME against a constant - where the SSA_NAME is defined by an earlier typecast which - is irrelevant when performing tests against the given - constant. */ - if (TREE_CODE (cond) == EQ_EXPR || TREE_CODE (cond) == NE_EXPR) - { - tree new_cond = find_equivalent_equality_comparison (cond); - - if (new_cond) - { - /* Update the statement to use the new equivalent - condition. */ - COND_EXPR_COND (stmt) = new_cond; - - /* If this is not a real stmt, ann will be NULL and we - avoid processing the operands. */ - if (ann) - mark_stmt_modified (stmt); - - /* Lookup the condition and return its known value if it - exists. */ - new_cond = lookup_avail_expr (stmt, insert); - if (new_cond) - return new_cond; - - /* The operands have changed, so update op0 and op1. */ - op0 = TREE_OPERAND (cond, 0); - op1 = TREE_OPERAND (cond, 1); - } - } - /* Consult the value range records for this variable (if they exist) to see if we can eliminate or simplify this conditional. @@ -2386,7 +2251,7 @@ propagate_to_outgoing_edges (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED, table. */ static bool -eliminate_redundant_computations (tree stmt, stmt_ann_t ann) +eliminate_redundant_computations (tree stmt) { tree *expr_p, def = NULL_TREE; bool insert = true; @@ -2414,7 +2279,7 @@ eliminate_redundant_computations (tree stmt, stmt_ann_t ann) /* If this is a COND_EXPR and we did not find its expression in the hash table, simplify the condition and try again. */ if (! cached_lhs && TREE_CODE (stmt) == COND_EXPR) - cached_lhs = simplify_cond_and_lookup_avail_expr (stmt, ann, insert); + cached_lhs = simplify_cond_and_lookup_avail_expr (stmt); opt_stats.num_exprs_considered++; @@ -2816,8 +2681,7 @@ optimize_stmt (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED, || TREE_CODE (stmt) == SWITCH_EXPR)); if (may_optimize_p) - may_have_exposed_new_symbols - |= eliminate_redundant_computations (stmt, ann); + may_have_exposed_new_symbols |= eliminate_redundant_computations (stmt); /* Record any additional equivalences created by this statement. */ if (TREE_CODE (stmt) == MODIFY_EXPR) diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c index 979f2b44c4a..2f857dc1076 100644 --- a/gcc/tree-ssa-forwprop.c +++ b/gcc/tree-ssa-forwprop.c @@ -36,7 +36,8 @@ Boston, MA 02110-1301, USA. */ /* This pass propagates the RHS of assignment statements into use sites of the LHS of the assignment. It's basically a specialized - form of tree combination. + form of tree combination. It is hoped all of this can disappear + when we have a generalized tree combiner. Note carefully that after propagation the resulting statement must still be a proper gimple statement. Right now we simply @@ -142,6 +143,9 @@ Boston, MA 02110-1301, USA. */ ptr2 = &x[index]; + We also propagate casts into SWITCH_EXPR and COND_EXPR conditions to + allow us to remove the cast and {NOT_EXPR,NEG_EXPR} into a subsequent + {NOT_EXPR,NEG_EXPR}. This will (of course) be extended as other needs arise. */ @@ -398,6 +402,129 @@ forward_propagate_into_cond_1 (tree cond, tree *test_var_p) return new_cond; } +/* COND is a condition of the form: + + x == const or x != const + + Look back to x's defining statement and see if x is defined as + + x = (type) y; + + If const is unchanged if we convert it to type, then we can build + the equivalent expression: + + + y == const or y != const + + Which may allow further optimizations. + + Return the equivalent comparison or NULL if no such equivalent comparison + was found. */ + +static tree +find_equivalent_equality_comparison (tree cond) +{ + tree op0 = TREE_OPERAND (cond, 0); + tree op1 = TREE_OPERAND (cond, 1); + tree def_stmt = SSA_NAME_DEF_STMT (op0); + + while (def_stmt + && TREE_CODE (def_stmt) == MODIFY_EXPR + && TREE_CODE (TREE_OPERAND (def_stmt, 1)) == SSA_NAME) + def_stmt = SSA_NAME_DEF_STMT (TREE_OPERAND (def_stmt, 1)); + + /* OP0 might have been a parameter, so first make sure it + was defined by a MODIFY_EXPR. */ + if (def_stmt && TREE_CODE (def_stmt) == MODIFY_EXPR) + { + tree def_rhs = TREE_OPERAND (def_stmt, 1); + + /* If either operand to the comparison is a pointer to + a function, then we can not apply this optimization + as some targets require function pointers to be + canonicalized and in this case this optimization would + eliminate a necessary canonicalization. */ + if ((POINTER_TYPE_P (TREE_TYPE (op0)) + && TREE_CODE (TREE_TYPE (TREE_TYPE (op0))) == FUNCTION_TYPE) + || (POINTER_TYPE_P (TREE_TYPE (op1)) + && TREE_CODE (TREE_TYPE (TREE_TYPE (op1))) == FUNCTION_TYPE)) + return NULL; + + /* Now make sure the RHS of the MODIFY_EXPR is a typecast. */ + if ((TREE_CODE (def_rhs) == NOP_EXPR + || TREE_CODE (def_rhs) == CONVERT_EXPR) + && TREE_CODE (TREE_OPERAND (def_rhs, 0)) == SSA_NAME) + { + tree def_rhs_inner = TREE_OPERAND (def_rhs, 0); + tree def_rhs_inner_type = TREE_TYPE (def_rhs_inner); + tree new; + + if (TYPE_PRECISION (def_rhs_inner_type) + > TYPE_PRECISION (TREE_TYPE (def_rhs))) + return NULL; + + /* If the inner type of the conversion is a pointer to + a function, then we can not apply this optimization + as some targets require function pointers to be + canonicalized. This optimization would result in + canonicalization of the pointer when it was not originally + needed/intended. */ + if (POINTER_TYPE_P (def_rhs_inner_type) + && TREE_CODE (TREE_TYPE (def_rhs_inner_type)) == FUNCTION_TYPE) + return NULL; + + /* What we want to prove is that if we convert OP1 to + the type of the object inside the NOP_EXPR that the + result is still equivalent to SRC. + + 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 = 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 build2 (TREE_CODE (cond), TREE_TYPE (cond), + def_rhs_inner, new); + } + } + return NULL; +} + +/* STMT is a COND_EXPR + + This routine attempts to find equivalent forms of the condition + which we may be able to optimize better. */ + +static void +simplify_cond (tree stmt) +{ + tree cond = COND_EXPR_COND (stmt); + + if (COMPARISON_CLASS_P (cond)) + { + tree op0 = TREE_OPERAND (cond, 0); + tree op1 = TREE_OPERAND (cond, 1); + + if (TREE_CODE (op0) == SSA_NAME && is_gimple_min_invariant (op1)) + { + /* First see if we have test of an SSA_NAME against a constant + where the SSA_NAME is defined by an earlier typecast which + is irrelevant when performing tests against the given + constant. */ + if (TREE_CODE (cond) == EQ_EXPR || TREE_CODE (cond) == NE_EXPR) + { + tree new_cond = find_equivalent_equality_comparison (cond); + + if (new_cond) + { + COND_EXPR_COND (stmt) = new_cond; + update_stmt (stmt); + } + } + } + } +} + /* Forward propagate a single-use variable into COND_EXPR as many times as possible. */ @@ -436,6 +563,13 @@ forward_propagate_into_cond (tree cond_expr) bsi_remove (&bsi, true); } } + + /* There are further simplifications that can be performed + on COND_EXPRs. Specifically, when comparing an SSA_NAME + against a constant where the SSA_NAME is the result of a + conversion. Perhaps this should be folded into the rest + of the COND_EXPR simplification code. */ + simplify_cond (cond_expr); } /* We've just substituted an ADDR_EXPR into stmt. Update all the |