Hi, as shown in the testcase (which would eventually be useful for optimizing std::vector's push_back), ipa-prop can use context dependent ranger queries for better value range info.
Bootstrapped/regtested x86_64-linux, OK? Honza gcc/ChangeLog: PR middle-end/110377 * ipa-prop.cc (ipa_compute_jump_functions_for_edge): Add ranger parameter; use ranger instance for rnage queries. (ipa_compute_jump_functions_for_bb): Pass around ranger. (analysis_dom_walker::before_dom_children): Enable ranger. gcc/testsuite/ChangeLog: PR middle-end/110377 * gcc.dg/tree-ssa/pr110377.c: New test. diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr110377.c b/gcc/testsuite/gcc.dg/tree-ssa/pr110377.c new file mode 100644 index 00000000000..cbe3441caea --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr110377.c @@ -0,0 +1,16 @@ +/* { dg-do compile */ +/* { dg-options "-O2 -fdump-ipa-fnsummary" } */ +int test3(int); +__attribute__ ((noinline)) +void test2(int a) +{ + test3(a); +} +void +test(int n) +{ + if (n > 5) + __builtin_unreachable (); + test2(n); +} +/* { dg-final { scan-tree-dump "-INF, 5-INF" "fnsummary" } } */ diff --git a/gcc/ipa-prop.cc b/gcc/ipa-prop.cc index 41c812194ca..693d4805d93 100644 --- a/gcc/ipa-prop.cc +++ b/gcc/ipa-prop.cc @@ -2341,7 +2341,8 @@ ipa_set_jfunc_vr (ipa_jump_func *jf, const ipa_vr &vr) static void ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi, - struct cgraph_edge *cs) + struct cgraph_edge *cs, + gimple_ranger *ranger) { ipa_node_params *info = ipa_node_params_sum->get (cs->caller); ipa_edge_args *args = ipa_edge_args_sum->get_create (cs); @@ -2386,7 +2387,7 @@ ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi, if (TREE_CODE (arg) == SSA_NAME && param_type - && get_range_query (cfun)->range_of_expr (vr, arg) + && get_range_query (cfun)->range_of_expr (vr, arg, cs->call_stmt) && vr.nonzero_p ()) addr_nonzero = true; else if (tree_single_nonzero_warnv_p (arg, &strict_overflow)) @@ -2408,7 +2409,7 @@ ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi, && Value_Range::supports_type_p (param_type) && irange::supports_p (TREE_TYPE (arg)) && irange::supports_p (param_type) - && get_range_query (cfun)->range_of_expr (vr, arg) + && ranger->range_of_expr (vr, arg, cs->call_stmt) && !vr.undefined_p ()) { Value_Range resvr (vr); @@ -2517,7 +2518,8 @@ ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi, from BB. */ static void -ipa_compute_jump_functions_for_bb (struct ipa_func_body_info *fbi, basic_block bb) +ipa_compute_jump_functions_for_bb (struct ipa_func_body_info *fbi, basic_block bb, + gimple_ranger *ranger) { struct ipa_bb_info *bi = ipa_get_bb_info (fbi, bb); int i; @@ -2536,7 +2538,7 @@ ipa_compute_jump_functions_for_bb (struct ipa_func_body_info *fbi, basic_block b && !gimple_call_fnspec (cs->call_stmt).known_p ()) continue; } - ipa_compute_jump_functions_for_edge (fbi, cs); + ipa_compute_jump_functions_for_edge (fbi, cs, ranger); } } @@ -3110,19 +3112,27 @@ class analysis_dom_walker : public dom_walker { public: analysis_dom_walker (struct ipa_func_body_info *fbi) - : dom_walker (CDI_DOMINATORS), m_fbi (fbi) {} + : dom_walker (CDI_DOMINATORS), m_fbi (fbi) + { + m_ranger = enable_ranger (cfun, false); + } + ~analysis_dom_walker () + { + disable_ranger (cfun); + } edge before_dom_children (basic_block) final override; private: struct ipa_func_body_info *m_fbi; + gimple_ranger *m_ranger; }; edge analysis_dom_walker::before_dom_children (basic_block bb) { ipa_analyze_params_uses_in_bb (m_fbi, bb); - ipa_compute_jump_functions_for_bb (m_fbi, bb); + ipa_compute_jump_functions_for_bb (m_fbi, bb, m_ranger); return NULL; }