public class SpeculativeGuardMovementPhase extends PostRunCanonicalizationPhase<MidTierContext>
public static int sumInts(int[] ints, Integer negAdjust) {
int sum = 0;
for (int i = 0; i < ints.length; i++) {
if (ints[i] < 0) {
sum += negAdjust; // guard: negAdjust != null
}
sum += ints[i];
}
return sum;
}
It is advantageous to hoist the guard that null checks negAdjust outside the loop since
the guard is loop invariant. However, doing so blindly would miss the fact that the null check is
only performed when ints contains a negative number. That is, the execution of the null
check is correlated with a condition in the loop (namely ints[i] < 0). If the guard is
hoisted and the method is called with negAdjust == null and ints only containing
positive numbers, then the method will deoptimize unnecessarily (since an exception will not be
thrown when executing in the interpreter). To avoid such unnecessary deoptimizations, a
speculation log entry is associated with the hoisted guard such that when it fails, the same
guard hoisting will not be performed in a subsequent compilation.BasePhase.ApplyScope, BasePhase.BasePhaseStatistics, BasePhase.PhaseOptions, BasePhase.SharedGlobalPhaseStatecanonicalizer| Constructor and Description |
|---|
SpeculativeGuardMovementPhase(CanonicalizerPhase canonicalizer) |
| Modifier and Type | Method and Description |
|---|---|
float |
codeSizeIncrease()
Returns a factor
>=1 that determines what the final code size in terms of the sum of
the node code sizes NodeSize of all nodes is. |
static boolean |
performSpeculativeGuardMovement(MidTierContext context,
StructuredGraph graph,
LoopsData loops) |
static boolean |
performSpeculativeGuardMovement(MidTierContext context,
StructuredGraph graph,
LoopsData loops,
NodeBitMap toProcess) |
protected void |
run(StructuredGraph graph,
MidTierContext context) |
applyScopeapply, apply, contractorName, equals, getName, hashCode, shouldDumpAfterAtBasicLevel, shouldDumpBeforeAtBasicLevelclone, getClass, notify, notifyAll, toString, wait, wait, waitcheckContractpublic SpeculativeGuardMovementPhase(CanonicalizerPhase canonicalizer)
public float codeSizeIncrease()
PhaseSizeContract>=1 that determines what the final code size in terms of the sum of
the node code sizes NodeSize of all nodes is.codeSizeIncrease in interface PhaseSizeContractcodeSizeIncrease in class BasePhase<MidTierContext>protected void run(StructuredGraph graph, MidTierContext context)
run in class BasePhase<MidTierContext>public static boolean performSpeculativeGuardMovement(MidTierContext context, StructuredGraph graph, LoopsData loops)
public static boolean performSpeculativeGuardMovement(MidTierContext context, StructuredGraph graph, LoopsData loops, NodeBitMap toProcess)