Hi, On Tue, Nov 05 2024, Jan Hubicka wrote: >> Hi, >> >> when inlining (during the analysis phase) a call graph edge, we update >> all pass-through jump functions corresponding to edges going out of >> the newly inlined function to be relative to the function into which >> we are inlining or to expose the information originally captured for >> the edge that is being inlined. >> >> Similarly, we can combine the value range information in pass-through >> jump functions corresponding to both edges, which is what this patch >> adds - at least for the case when the inlined pass-through is a >> simple, non-arithmetic one, which is the case that we also handle for >> constant and aggregate jump function parts. >> >> Bootstrapped and tested on x86_64-linux, the whole patch series has >> additionally passed LTO and profiled-LTO bootstrap on the same platform >> and a bootstrap and testsuite on ppc64-linux. Aarch64-linux bootstrap >> and testing is in progress. OK for master is that passes too? >> >> Thanks, >> >> Martin >> >> >> gcc/ChangeLog: >> >> 2024-11-01 Martin Jambor <mjam...@suse.cz> >> >> * ipa-cp.h: Forward declare class ipa_vr. >> (ipa_vr_operation_and_type_effects) Declare. >> * ipa-cp.cc (ipa_vr_operation_and_type_effects): Make public. >> * ipa-prop.cc (update_jump_functions_after_inlining): Also update >> value range jump functions. >> --- >> gcc/ipa-cp.cc | 4 ++-- >> gcc/ipa-cp.h | 13 +++++++++++++ >> gcc/ipa-prop.cc | 18 ++++++++++++++++++ >> 3 files changed, 33 insertions(+), 2 deletions(-) >> >> diff --git a/gcc/ipa-prop.cc b/gcc/ipa-prop.cc >> index 012f8a32386..3b24bcbed15 100644 >> --- a/gcc/ipa-prop.cc >> +++ b/gcc/ipa-prop.cc >> @@ -3486,6 +3486,24 @@ update_jump_functions_after_inlining (struct >> cgraph_edge *cs, >> gcc_unreachable (); >> } >> >> + if (src->m_vr && src->m_vr->known_p ()) >> + { >> + value_range svr (src->m_vr->type ()); >> + if (!dst->m_vr || !dst->m_vr->known_p ()) >> + ipa_set_jfunc_vr (dst, *src->m_vr); >> + else if (ipa_vr_operation_and_type_effects (svr, *src->m_vr, >> + NOP_EXPR, >> + dst->m_vr->type (), >> + src->m_vr->type ())) >> + { >> + value_range dvr; >> + dst->m_vr->get_vrange (dvr); >> + dvr.intersect (svr); >> + if (!dvr.undefined_p ()) >> + ipa_set_jfunc_vr (dst, dvr); > I wonder if the undefined check is. If dvr jump function is meaningful, > then dvr.intersect should return subrange of it?
I have seen this happen when the result of the intersection is an empty set (one of the few comments in value-range.h actually describes an undefined range as an "empty range"). I have only seen this happen when the edge has been redirected to builtin_unreachable because, the has been recognized as impossible. But I am not absolutely convinced we can rely on that always being the case. We can decide to not update jump functions for edges leading to gcc_unreachable, after we have given some thought what to do about reference description counts, but that is a separate effort, I'd say. > > We should be also able to combine artihmetics, right? It should be doable, yes. The function would need a bit more surgery, though. I'm adding this to my TODO list. (I'd like to do that after killing the ancestor jump function. And it's kind of interesting what it would mean for more complicated chain of operations like we have for predicates.) Martin