diff options
author | Richard Biener <rguenther@suse.de> | 2016-11-02 08:11:48 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2016-11-02 08:11:48 +0000 |
commit | 4280df0abc2d692924ab45dd95c6ef0dc61703ea (patch) | |
tree | a595a1c01294129e7de48c90bd9172c950be737f /gcc | |
parent | 9815687d8e3044e21be5b17fe155299f67c08a01 (diff) | |
download | gcc-4280df0abc2d692924ab45dd95c6ef0dc61703ea.zip gcc-4280df0abc2d692924ab45dd95c6ef0dc61703ea.tar.gz gcc-4280df0abc2d692924ab45dd95c6ef0dc61703ea.tar.bz2 |
tree-vrp.c (evrp_dom_walker::before_dom_children): Call infer_value_range on stmt ops and update value-ranges.
2016-11-02 Richard Biener <rguenther@suse.de>
* tree-vrp.c (evrp_dom_walker::before_dom_children): Call
infer_value_range on stmt ops and update value-ranges.
Dump visited stmts and blocks.
(evrp_dom_walker::push_value_range): Dump changes.
(evrp_dom_walker::pop_value_range): Likewise.
(evrp_dom_walker::try_find_new_range): Avoid noop changes.
* gcc.dg/tree-ssa/vrp111.c: New testcase.
* gcc.dg/tree-ssa/pr20702.c: Disable EVRP.
* gcc.dg/tree-ssa/pr21086.c: Likewise.
* gcc.dg/tree-ssa/pr58480.c: Likewise.
* gcc.dg/tree-ssa/vrp08.c: Likewise.
From-SVN: r241774
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/pr20702.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/pr21086.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/pr58480.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/vrp08.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/vrp111.c | 13 | ||||
-rw-r--r-- | gcc/tree-vrp.c | 122 |
8 files changed, 132 insertions, 28 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5446521..163f5f6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2016-11-02 Richard Biener <rguenther@suse.de> + + * tree-vrp.c (evrp_dom_walker::before_dom_children): Call + infer_value_range on stmt ops and update value-ranges. + Dump visited stmts and blocks. + (evrp_dom_walker::push_value_range): Dump changes. + (evrp_dom_walker::pop_value_range): Likewise. + (evrp_dom_walker::try_find_new_range): Avoid noop changes. + 2016-11-01 Trevor Saunders <tbsaunde+gcc@tbsaunde.org> * emit-rtl.c (prev_nonnote_insn_bb): Change argument type to diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 42b667d..20ef692 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2016-11-02 Richard Biener <rguenther@suse.de> + + * gcc.dg/tree-ssa/vrp111.c: New testcase. + * gcc.dg/tree-ssa/pr20702.c: Disable EVRP. + * gcc.dg/tree-ssa/pr21086.c: Likewise. + * gcc.dg/tree-ssa/pr58480.c: Likewise. + * gcc.dg/tree-ssa/vrp08.c: Likewise. + 2016-11-01 David Edelsohn <dje.gcc@gmail.com> * gfortran.dg/pr70937.f90: require-effective-target lto. diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr20702.c b/gcc/testsuite/gcc.dg/tree-ssa/pr20702.c index cc7370c..c8968577 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr20702.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr20702.c @@ -4,7 +4,7 @@ immediate successors of the basic block. */ /* { dg-do compile } */ -/* { dg-options "-O2 -fno-tree-dominator-opts -fdump-tree-vrp1-details -fdelete-null-pointer-checks" } */ +/* { dg-options "-O2 -fno-tree-dominator-opts -fdisable-tree-evrp -fdump-tree-vrp1-details -fdelete-null-pointer-checks" } */ extern void bar (int); diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr21086.c b/gcc/testsuite/gcc.dg/tree-ssa/pr21086.c index e8b62c2..950371b 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr21086.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr21086.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-vrp1 -fdump-tree-dce2 -fdelete-null-pointer-checks" } */ +/* { dg-options "-O2 -fdisable-tree-evrp -fdump-tree-vrp1 -fdump-tree-dce2 -fdelete-null-pointer-checks" } */ int foo (int *p) diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr58480.c b/gcc/testsuite/gcc.dg/tree-ssa/pr58480.c index 7df8f8a..42898e7 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr58480.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr58480.c @@ -1,5 +1,5 @@ /* { dg-do compile { target { ! keeps_null_pointer_checks } } } */ -/* { dg-options "-O2 -fdump-tree-vrp1 -fdelete-null-pointer-checks" } */ +/* { dg-options "-O2 -fdisable-tree-evrp -fdump-tree-vrp1 -fdelete-null-pointer-checks" } */ extern void eliminate (void); extern void* f1 (void *a, void *b) __attribute__((nonnull)); diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp08.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp08.c index 023b4eb..c2da30b 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/vrp08.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp08.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fno-tree-fre -fdump-tree-vrp1-details -fdelete-null-pointer-checks" } */ +/* { dg-options "-O2 -fno-tree-fre -fdisable-tree-evrp -fdump-tree-vrp1-details -fdelete-null-pointer-checks" } */ /* Compile with -fno-tree-fre -O2 to prevent CSEing *p. */ int diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp111.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp111.c new file mode 100644 index 0000000..2511c19 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp111.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-evrp" } */ + +void foo (void *p) __attribute__((nonnull(1))); + +void bar (void *p) +{ + foo (p); + if (!p) + __builtin_abort (); +} + +/* { dg-final { scan-tree-dump-not "abort" "evrp" } } */ diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index fcdb341..68fe2ac 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -10650,18 +10650,17 @@ public: } virtual edge before_dom_children (basic_block); virtual void after_dom_children (basic_block); - void push_value_range (const_tree var, value_range *vr); - value_range *pop_value_range (const_tree var); + void push_value_range (tree var, value_range *vr); + value_range *pop_value_range (tree var); value_range *try_find_new_range (tree op, tree_code code, tree limit); /* Cond_stack holds the old VR. */ - auto_vec<std::pair <const_tree, value_range*> > stack; + auto_vec<std::pair <tree, value_range*> > stack; bitmap need_eh_cleanup; auto_vec<gimple *> stmts_to_fixup; auto_vec<gimple *> stmts_to_remove; }; - /* Find new range for OP such that (OP CODE LIMIT) is true. */ value_range * @@ -10679,6 +10678,10 @@ evrp_dom_walker::try_find_new_range (tree op, tree_code code, tree limit) PUSH old value in the stack with the old VR. */ if (vr.type == VR_RANGE || vr.type == VR_ANTI_RANGE) { + if (old_vr->type == vr.type + && vrp_operand_equal_p (old_vr->min, vr.min) + && vrp_operand_equal_p (old_vr->max, vr.max)) + return NULL; value_range *new_vr = vrp_value_range_pool.allocate (); *new_vr = vr; return new_vr; @@ -10696,7 +10699,10 @@ evrp_dom_walker::before_dom_children (basic_block bb) edge_iterator ei; edge e; - push_value_range (NULL_TREE, NULL); + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, "Visiting BB%d\n", bb->index); + + stack.safe_push (std::make_pair (NULL_TREE, (value_range *)NULL)); edge pred_e = NULL; FOR_EACH_EDGE (e, ei, bb->preds) @@ -10723,6 +10729,11 @@ evrp_dom_walker::before_dom_children (basic_block bb) && (INTEGRAL_TYPE_P (TREE_TYPE (gimple_cond_lhs (stmt))) || POINTER_TYPE_P (TREE_TYPE (gimple_cond_lhs (stmt))))) { + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "Visiting controlling predicate "); + print_gimple_stmt (dump_file, stmt, 0, 0); + } /* Entering a new scope. Try to see if we can find a VR here. */ tree op1 = gimple_cond_rhs (stmt); @@ -10778,6 +10789,11 @@ evrp_dom_walker::before_dom_children (basic_block bb) continue; value_range vr_result = VR_INITIALIZER; bool interesting = stmt_interesting_for_vrp (phi); + if (interesting && dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "Visiting PHI node "); + print_gimple_stmt (dump_file, phi, 0, 0); + } if (!has_unvisited_preds && interesting) extract_range_from_phi_node (phi, &vr_result); @@ -10814,6 +10830,12 @@ evrp_dom_walker::before_dom_children (basic_block bb) bool was_noreturn = (is_gimple_call (stmt) && gimple_call_noreturn_p (stmt)); + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "Visiting stmt "); + print_gimple_stmt (dump_file, stmt, 0, 0); + } + if (gcond *cond = dyn_cast <gcond *> (stmt)) { vrp_visit_cond_stmt (cond, &taken_edge); @@ -10825,6 +10847,7 @@ evrp_dom_walker::before_dom_children (basic_block bb) gimple_cond_make_false (cond); else gcc_unreachable (); + update_stmt (stmt); } } else if (stmt_interesting_for_vrp (stmt)) @@ -10873,6 +10896,55 @@ evrp_dom_walker::before_dom_children (basic_block bb) else set_defs_to_varying (stmt); + /* See if we can derive a range for any of STMT's operands. */ + tree op; + ssa_op_iter i; + FOR_EACH_SSA_TREE_OPERAND (op, stmt, i, SSA_OP_USE) + { + tree value; + enum tree_code comp_code; + + /* If OP is used in such a way that we can infer a value + range for it, and we don't find a previous assertion for + it, create a new assertion location node for OP. */ + if (infer_value_range (stmt, op, &comp_code, &value)) + { + /* If we are able to infer a nonzero value range for OP, + then walk backwards through the use-def chain to see if OP + was set via a typecast. + If so, then we can also infer a nonzero value range + for the operand of the NOP_EXPR. */ + if (comp_code == NE_EXPR && integer_zerop (value)) + { + tree t = op; + gimple *def_stmt = SSA_NAME_DEF_STMT (t); + while (is_gimple_assign (def_stmt) + && CONVERT_EXPR_CODE_P + (gimple_assign_rhs_code (def_stmt)) + && TREE_CODE + (gimple_assign_rhs1 (def_stmt)) == SSA_NAME + && POINTER_TYPE_P + (TREE_TYPE (gimple_assign_rhs1 (def_stmt)))) + { + t = gimple_assign_rhs1 (def_stmt); + def_stmt = SSA_NAME_DEF_STMT (t); + + /* Add VR when (T COMP_CODE value) condition is + true. */ + value_range *op_range + = try_find_new_range (t, comp_code, value); + if (op_range) + push_value_range (t, op_range); + } + } + /* Add VR when (OP COMP_CODE value) condition is true. */ + value_range *op_range = try_find_new_range (op, + comp_code, value); + if (op_range) + push_value_range (op, op_range); + } + } + /* Try folding stmts with the VR discovered. */ bool did_replace = replace_uses_in (stmt, op_with_constant_singleton_value_range); @@ -10938,42 +11010,44 @@ evrp_dom_walker::after_dom_children (basic_block bb ATTRIBUTE_UNUSED) gcc_checking_assert (!stack.is_empty ()); while (stack.last ().first != NULL_TREE) pop_value_range (stack.last ().first); - pop_value_range (stack.last ().first); + stack.pop (); } /* Push the Value Range of VAR to the stack and update it with new VR. */ void -evrp_dom_walker::push_value_range (const_tree var, value_range *vr) +evrp_dom_walker::push_value_range (tree var, value_range *vr) { - if (vr != NULL) + if (SSA_NAME_VERSION (var) >= num_vr_values) + return; + if (dump_file && (dump_flags & TDF_DETAILS)) { - unsigned ver = SSA_NAME_VERSION (var); - gcc_checking_assert (vr_value); - stack.safe_push (std::make_pair (var, vr_value[ver])); - - if (ver < num_vr_values) - vr_value[ver] = vr; + fprintf (dump_file, "pushing new range for "); + print_generic_expr (dump_file, var, 0); + fprintf (dump_file, ": "); + dump_value_range (dump_file, vr); + fprintf (dump_file, "\n"); } - else - stack.safe_push (std::make_pair (var, vr)); + stack.safe_push (std::make_pair (var, get_value_range (var))); + vr_value[SSA_NAME_VERSION (var)] = vr; } /* Pop the Value Range from the vrp_stack and update VAR with it. */ value_range * -evrp_dom_walker::pop_value_range (const_tree var) +evrp_dom_walker::pop_value_range (tree var) { value_range *vr = stack.last ().second; - if (vr != NULL) + gcc_checking_assert (var == stack.last ().first); + if (dump_file && (dump_flags & TDF_DETAILS)) { - unsigned ver = SSA_NAME_VERSION (var); - gcc_checking_assert (var == stack.last ().first); - gcc_checking_assert (vr_value); - - if (ver < num_vr_values) - vr_value[ver] = vr; + fprintf (dump_file, "popping range for "); + print_generic_expr (dump_file, var, 0); + fprintf (dump_file, ", restoring "); + dump_value_range (dump_file, vr); + fprintf (dump_file, "\n"); } + vr_value[SSA_NAME_VERSION (var)] = vr; stack.pop (); return vr; } |