Hi all,

IPA-CP's good_cloning_opportunity_p accepts a clone when

    EVALUATION = time_benefit * freq_sum / size_cost * 1000  >=  
ipa-cp-eval-threshold

i.e. the per-call "benefit density" (time_benefit/size_cost) multiplied by the
summed frequency of all calls that would use the clone.  Because freq_sum scales
with the number/hotness of callers, a function that is called from many hot
sites can clear the threshold with an arbitrarily small per-call benefit: a
large body gets duplicated even though knowing the propagated constant barely
simplifies it.  This is common when the "specialised" parameter is not actually
consumed in the clone but merely forwarded as a runtime argument into a callee
that is itself neither inlined nor cloned, the modelled saving never
materialises, and EVALUATION does not account for the duplication's
code bloat cost.

727.cppcheck_r from SPEC2026 is the motivating case: GCC clones Token::Match 
for varid==0
(time_benefit ~6.8, size ~381) but varid==0 only flows as a runtime argument
into the un-inlined multiCompareImpl; ~600 such .constprop/.part/.isra clones
accumulate across the program.

Gate cloning on a frequency-independent minimum of the same benefit-density
metric IPA-CP already computes for ranking 
(cloning_opportunity_ranking_evaluation,
time_benefit*1000/size_cost).  A clone whose per-call benefit is below
--param=ipa-cp-min-clone-eval (permille of the cloned size, default 30 ~= 3%) is
rejected regardless of how high freq_sum is.  0 disables the check.

The 3% is, of course, somewhat arbitrary, but I think that is the nature
of all these IPA heuristics. Happy for better ideas.

A standalone reproducer is in the bugzilla PR. I can include it in the
patch, though I'm not sure how fragile and convoluted it is for the testsuite.

This patch gives ~9% on cppcheck on an aarch64 machine with -Ofast
-flto.

Bootstrapped and tested on aarch64-none-linux-gnu.

Any comments?
Thanks,
Kyrill

Signed-off-by: Kyrylo Tkachov <[email protected]>

gcc/ChangeLog:

        PR ipa/125607
        * params.opt (-param=ipa-cp-min-clone-eval=): New param.
        * ipa-cp.cc (good_cloning_opportunity_p): Reject a clone whose
        per-call time benefit is below ipa-cp-min-clone-eval ratio
        cloned size.

Attachment: 0001-PR125607-ipa-cp-don-t-clone-a-large-body-for-a-frequ.patch
Description: 0001-PR125607-ipa-cp-don-t-clone-a-large-body-for-a-frequ.patch

Reply via email to