[13] RFR (S): 8059241: C2: Excessive RemoveUseless passes during incremental inlining

Vladimir Ivanov vladimir.x.ivanov at oracle.com
Fri Jan 25 03:18:18 UTC 2019


I'd like to revive the fix for 8059241 [1].

Quoting original review request:

   "According to -XX:+CITime, C2 spends too much time in incremental
inlining (see the bug for the numbers).


The fix is two-fold:

   (1) Reduce PhaseRemoveUseless frequency: inline in larger chunks until
IR size LiveNodeCountInliningCutoff, then eliminate dead nodes.

   (2) Have a relatively small (10%) gap between
LiveNodeCountInliningCutoff and actual limit when inlining step is
finished to give the algorithm some space to "breath" (hence smallest
inlining chunk produce at least 10%*LiveNodeCountInliningCutoff nodes)."

At that time, the blocker issue was that skipping RemoveUseless/IGVN 
exposed dead nodes during consequent parsing [2] and I didn't find a 
good solution without sacrifice too much improvement.

I believe I have it now: parsing is good at handling local dead code, 
but the problem arise when inlining is resumed from a call node on 
consequent iterations (e.g., uncommon trap dominating the call being 
inlined). So, when return path is dead after inlining, cleanup is 
performed before initiating next iteration. It allows to purge any 
effectively dead call sites pending inlining.

Also, there's a fix for unrelated problem exposed during testing [3]:

It's unsafe to repeatedly call PhaseGVN::transform() on TypeNode because 
it may cause a type change and then hitting assert due to changed hash 
in TypeNode::set_type() (called from Node::raise_bottom_type()) because 
type node hash depends on its type.

Testing: hs-precheckin-comp, tier1-5 \w -XX:+AlwaysIncrementalInline

I ran Octane w/ -XX:+CITime and observed significant reduction in 
"Incremental Inline" times (~50% off on IGVN, 80-95% off on "Prune 

Best regards,
Vladimir Ivanov




static inline Node* addP_of_X2P(PhaseGVN *phase,
                                  Node* base,
                                  Node* dispX,
                                  bool negate = false) {
    if (negate) {
-    dispX = new SubXNode(phase->MakeConX(0), phase->transform(dispX));
+    dispX = phase->transform(new SubXNode(phase->MakeConX(0), dispX));
    return new AddPNode(phase->C->top(),
                        phase->transform(new CastX2PNode(base)),
-                      phase->transform(dispX));
+                      dispX);

More information about the hotspot-compiler-dev mailing list