aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-vrp.c
diff options
context:
space:
mode:
authorJeff Law <law@redhat.com>2017-03-16 13:21:23 -0600
committerJeff Law <law@gcc.gnu.org>2017-03-16 13:21:23 -0600
commit8d7437be4725af093548429f6e4c80a7867cdb41 (patch)
treee61e028074af01a48111ce51857df9f8bfae080a /gcc/tree-vrp.c
parent9fc900af68527b00d67f11f897e1fe77a176bee2 (diff)
downloadgcc-8d7437be4725af093548429f6e4c80a7867cdb41.zip
gcc-8d7437be4725af093548429f6e4c80a7867cdb41.tar.gz
gcc-8d7437be4725af093548429f6e4c80a7867cdb41.tar.bz2
re PR tree-optimization/71437 (Performance regression after r235817)
PR tree-optimization/71437 * tree-ssa-dom.c (pfn_simplify): Add basic_block argument. All callers changed. (simplify_stmt_for_jump_threading): Add basic_block argument. All callers changed. (lhs_of_dominating_assert): Moved from here into tree-vrp.c. (dom_opt_dom_walker::thread_across_edge): Remove handle_dominating_asserts argument. All callers changed. (record_temporary_equivalences_from_stmts_at_dest): Corresponding changes. Remove calls to lhs_of_dominating_assert. Other uses of handle_dominating_asserts turn into unconditional code (simplify_control_stmt_condition_1): Likewise. (simplify_control_stmt_condition): Likewise. (thread_through_normal_block, thread_across_edge): Likewise. * tree-ssa-threadedge.h (thread_across_edge): Corresponding changes. * tree-vrp.c (lhs_of_dominating_assert): Move here. Return original object if it is not an SSA_NAME. (simplify_stmt_for_jump_threading): Call lhs_of_dominating_assert before calling into the VRP specific simplifiers. (identify_jump_threads): Remove handle_dominating_asserts argument. From-SVN: r246207
Diffstat (limited to 'gcc/tree-vrp.c')
-rw-r--r--gcc/tree-vrp.c48
1 files changed, 42 insertions, 6 deletions
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 2a4c764..82ef742 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -10749,6 +10749,33 @@ vrp_fold_stmt (gimple_stmt_iterator *si)
/* Unwindable const/copy equivalences. */
const_and_copies *equiv_stack;
+/* Return the LHS of any ASSERT_EXPR where OP appears as the first
+ argument to the ASSERT_EXPR and in which the ASSERT_EXPR dominates
+ BB. If no such ASSERT_EXPR is found, return OP. */
+
+static tree
+lhs_of_dominating_assert (tree op, basic_block bb, gimple *stmt)
+{
+ imm_use_iterator imm_iter;
+ gimple *use_stmt;
+ use_operand_p use_p;
+
+ if (TREE_CODE (op) == SSA_NAME)
+ {
+ FOR_EACH_IMM_USE_FAST (use_p, imm_iter, op)
+ {
+ use_stmt = USE_STMT (use_p);
+ if (use_stmt != stmt
+ && gimple_assign_single_p (use_stmt)
+ && TREE_CODE (gimple_assign_rhs1 (use_stmt)) == ASSERT_EXPR
+ && TREE_OPERAND (gimple_assign_rhs1 (use_stmt), 0) == op
+ && dominated_by_p (CDI_DOMINATORS, bb, gimple_bb (use_stmt)))
+ return gimple_assign_lhs (use_stmt);
+ }
+ }
+ return op;
+}
+
/* A trivial wrapper so that we can present the generic jump threading
code with a simple API for simplifying statements. STMT is the
statement we want to simplify, WITHIN_STMT provides the location
@@ -10756,13 +10783,20 @@ const_and_copies *equiv_stack;
static tree
simplify_stmt_for_jump_threading (gimple *stmt, gimple *within_stmt,
- class avail_exprs_stack *avail_exprs_stack ATTRIBUTE_UNUSED)
+ class avail_exprs_stack *avail_exprs_stack ATTRIBUTE_UNUSED,
+ basic_block bb)
{
if (gcond *cond_stmt = dyn_cast <gcond *> (stmt))
- return vrp_evaluate_conditional (gimple_cond_code (cond_stmt),
- gimple_cond_lhs (cond_stmt),
- gimple_cond_rhs (cond_stmt),
- within_stmt);
+ {
+ tree op0 = gimple_cond_lhs (cond_stmt);
+ op0 = lhs_of_dominating_assert (op0, bb, stmt);
+
+ tree op1 = gimple_cond_rhs (cond_stmt);
+ op1 = lhs_of_dominating_assert (op1, bb, stmt);
+
+ return vrp_evaluate_conditional (gimple_cond_code (cond_stmt),
+ op0, op1, within_stmt);
+ }
/* We simplify a switch statement by trying to determine which case label
will be taken. If we are successful then we return the corresponding
@@ -10773,6 +10807,8 @@ simplify_stmt_for_jump_threading (gimple *stmt, gimple *within_stmt,
if (TREE_CODE (op) != SSA_NAME)
return NULL_TREE;
+ op = lhs_of_dominating_assert (op, bb, stmt);
+
value_range *vr = get_value_range (op);
if ((vr->type != VR_RANGE && vr->type != VR_ANTI_RANGE)
|| symbolic_range_p (vr))
@@ -10948,7 +10984,7 @@ identify_jump_threads (void)
if (e->flags & (EDGE_IGNORE | EDGE_COMPLEX))
continue;
- thread_across_edge (dummy, e, true, equiv_stack, NULL,
+ thread_across_edge (dummy, e, equiv_stack, NULL,
simplify_stmt_for_jump_threading);
}
}