Skip to content

Commit 45578f9

Browse files
committed
compile time improvements for large truffle graphs in economy
1 parent b470827 commit 45578f9

39 files changed

+661
-198
lines changed

compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/core/test/OptimizeOffsetAddressTest.java

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,20 @@
2727
import org.junit.Assume;
2828
import org.junit.Test;
2929

30-
import jdk.graal.compiler.core.phases.EconomyHighTier;
31-
import jdk.graal.compiler.core.phases.EconomyMidTier;
3230
import jdk.graal.compiler.graph.Graph;
3331
import jdk.graal.compiler.nodes.StructuredGraph;
3432
import jdk.graal.compiler.nodes.calc.AddNode;
33+
import jdk.graal.compiler.phases.common.CanonicalizerPhase;
34+
import jdk.graal.compiler.phases.common.DeoptimizationGroupingPhase;
3535
import jdk.graal.compiler.phases.common.FloatingReadPhase;
36+
import jdk.graal.compiler.phases.common.FrameStateAssignmentPhase;
37+
import jdk.graal.compiler.phases.common.GuardLoweringPhase;
38+
import jdk.graal.compiler.phases.common.HighTierLoweringPhase;
39+
import jdk.graal.compiler.phases.common.LoopSafepointInsertionPhase;
40+
import jdk.graal.compiler.phases.common.MidTierLoweringPhase;
3641
import jdk.graal.compiler.phases.common.OptimizeOffsetAddressPhase;
42+
import jdk.graal.compiler.phases.common.RemoveValueProxyPhase;
43+
import jdk.graal.compiler.phases.common.WriteBarrierAdditionPhase;
3744
import jdk.graal.compiler.phases.tiers.Suites;
3845

3946
/**
@@ -55,9 +62,22 @@ public void testSnippet0() {
5562

5663
StructuredGraph graph = parseEager("snippet0", StructuredGraph.AllowAssumptions.YES);
5764

58-
new EconomyHighTier().apply(graph, getDefaultHighTierContext());
65+
// resembling an economy phase plan with floating reads
66+
67+
CanonicalizerPhase canonicalizer = CanonicalizerPhase.createSingleShot();
68+
canonicalizer.apply(graph, getDefaultHighTierContext());
69+
new HighTierLoweringPhase(canonicalizer, true).apply(graph, getDefaultHighTierContext());
70+
5971
new FloatingReadPhase(createCanonicalizerPhase()).apply(graph, getDefaultMidTierContext());
60-
new EconomyMidTier().apply(graph, getDefaultMidTierContext());
72+
73+
new RemoveValueProxyPhase(canonicalizer).apply(graph, getDefaultMidTierContext());
74+
new LoopSafepointInsertionPhase().apply(graph, getDefaultMidTierContext());
75+
new GuardLoweringPhase().apply(graph, getDefaultMidTierContext());
76+
new MidTierLoweringPhase(canonicalizer).apply(graph, getDefaultMidTierContext());
77+
new FrameStateAssignmentPhase().apply(graph, getDefaultMidTierContext());
78+
new DeoptimizationGroupingPhase().apply(graph, getDefaultMidTierContext());
79+
canonicalizer.apply(graph, getDefaultMidTierContext());
80+
new WriteBarrierAdditionPhase().apply(graph, getDefaultMidTierContext());
6181

6282
assertTrue(graph.getNodes().filter(AddNode.class).count() == 4);
6383
new OptimizeOffsetAddressPhase(createCanonicalizerPhase()).apply(graph, getDefaultLowTierContext());

compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/truffle/test/NodeLimitTest.java

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,6 @@
2727
import java.util.function.Function;
2828
import java.util.function.Supplier;
2929

30-
import jdk.graal.compiler.core.common.PermanentBailoutException;
31-
import jdk.graal.compiler.nodes.StructuredGraph;
32-
import jdk.graal.compiler.phases.contract.NodeCostUtil;
3330
import org.graalvm.polyglot.Context;
3431
import org.junit.Assert;
3532
import org.junit.Assume;
@@ -44,6 +41,10 @@
4441
import com.oracle.truffle.runtime.OptimizedCallTarget;
4542
import com.oracle.truffle.runtime.OptimizedRuntimeOptions;
4643

44+
import jdk.graal.compiler.core.common.PermanentBailoutException;
45+
import jdk.graal.compiler.nodes.StructuredGraph;
46+
import jdk.graal.compiler.phases.contract.NodeCostUtil;
47+
4748
public class NodeLimitTest extends PartialEvaluationTest {
4849

4950
@Before
@@ -66,8 +67,48 @@ public void oneRootNodeTestEnoughGraalNodeCount() {
6667
expectAllOK(NodeLimitTest::createRootNode);
6768
}
6869

70+
// test that the timeout function during PE works
71+
@Test(expected = PermanentBailoutException.class)
72+
public void testTimeOutLimit() {
73+
// note the timeout may be subject to scaling (up) because we are running with assertions
74+
final int secondTimeout = 2;
75+
setupContext(Context.newBuilder().allowAllAccess(true).allowExperimentalOptions(true).option("compiler.CompilationTimeout", String.valueOf(secondTimeout)).build());
76+
77+
// NOTE: the following code is intentionally written to explode during partial evaluation!
78+
// It is wrong in almost every way possible.
79+
final RootNode rootNode = new TestRootNode() {
80+
@Override
81+
public Object execute(VirtualFrame frame) {
82+
recurse();
83+
foo();
84+
return null;
85+
}
86+
87+
@ExplodeLoop
88+
private void recurse() {
89+
for (int i = 0; i < 1000; i++) {
90+
getF().apply(0);
91+
}
92+
}
93+
94+
private Function<Integer, Integer> getF() {
95+
return new Function<>() {
96+
@Override
97+
public Integer apply(Integer integer) {
98+
return integer < 500 ? getF().apply(integer + 1) : 0;
99+
}
100+
};
101+
}
102+
};
103+
partialEval((OptimizedCallTarget) rootNode.getCallTarget(), new Object[]{});
104+
}
105+
106+
// test the limit by setting a small one, normally the limit is not enabled
69107
@Test(expected = PermanentBailoutException.class)
70-
public void testDefaultLimit() {
108+
public void testSetLimit() {
109+
// a small resonable default to ensure if a user sets it the functionality works
110+
setupContext(Context.newBuilder().allowAllAccess(true).allowExperimentalOptions(true).option("compiler.MaximumGraalGraphSize", String.valueOf(5000)).build());
111+
71112
// NOTE: the following code is intentionally written to explode during partial evaluation!
72113
// It is wrong in almost every way possible.
73114
final RootNode rootNode = new TestRootNode() {
@@ -80,7 +121,7 @@ public Object execute(VirtualFrame frame) {
80121

81122
@ExplodeLoop
82123
private void recurse() {
83-
for (int i = 0; i < 100; i++) {
124+
for (int i = 0; i < 1000; i++) {
84125
getF().apply(0);
85126
}
86127
}

compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/truffle/test/PartialEvaluationTest.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343

4444
import jdk.graal.compiler.code.CompilationResult;
4545
import jdk.graal.compiler.core.common.CompilationIdentifier;
46+
import jdk.graal.compiler.core.common.util.CompilationAlarm;
4647
import jdk.graal.compiler.debug.DebugContext;
4748
import jdk.graal.compiler.graph.Graph;
4849
import jdk.graal.compiler.graph.Node;
@@ -265,6 +266,7 @@ protected StructuredGraph partialEvalWithNodeEventListener(OptimizedCallTarget c
265266
return partialEval(compilable, arguments, listener);
266267
}
267268

269+
@SuppressWarnings("try")
268270
private StructuredGraph partialEval(OptimizedCallTarget compilable, Object[] arguments, Graph.NodeEventListener nodeEventListener) {
269271
// Executed AST so that all classes are loaded and initialized.
270272
if (!preventProfileCalls) {
@@ -298,7 +300,8 @@ private StructuredGraph partialEval(OptimizedCallTarget compilable, Object[] arg
298300
TruffleTier truffleTier = compiler.getTruffleTier();
299301
final PartialEvaluator partialEvaluator = compiler.getPartialEvaluator();
300302
try (PerformanceInformationHandler handler = PerformanceInformationHandler.install(
301-
compiler.getConfig().runtime(), compiler.getOrCreateCompilerOptions(compilable))) {
303+
compiler.getConfig().runtime(), compiler.getOrCreateCompilerOptions(compilable));
304+
CompilationAlarm alarm = CompilationAlarm.trackCompilationPeriod(debug.getOptions())) {
302305
final TruffleTierContext context = TruffleTierContext.createInitialContext(partialEvaluator,
303306
compiler.getOrCreateCompilerOptions(compilable),
304307
debug, compilable,

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/common/util/CompilationAlarm.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,7 @@ private void handleIntermediateRoots(StructuredGraph graph) {
276276
ResolvedJavaMethod method = graph.method();
277277
PhaseTreeNode newRoot = new PhaseTreeIntermediateRoot(String.format("IntermediateRoot -> %s", method == null ? graph : method.format("%H.%n(%p)")), graph);
278278
newRoot.parent = currentNode;
279+
newRoot.startTimeNS = System.nanoTime();
279280
currentNode.addChild(newRoot);
280281
currentNode = newRoot;
281282
}

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/phases/EconomyHighTier.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ public class EconomyHighTier extends BaseTier<HighTierContext> {
3232

3333
@SuppressWarnings("this-escape")
3434
public EconomyHighTier() {
35-
CanonicalizerPhase canonicalizer = CanonicalizerPhase.create();
35+
appendPhase(EconomyMarkFixReadsPhase.SINGLETON);
36+
CanonicalizerPhase canonicalizer = CanonicalizerPhase.createSingleShot();
3637
appendPhase(canonicalizer);
3738
appendPhase(new HighTierLoweringPhase(canonicalizer, true));
3839
}

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/phases/EconomyLowTier.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import jdk.graal.compiler.phases.common.AddressLoweringPhase;
3232
import jdk.graal.compiler.phases.common.BarrierSetVerificationPhase;
3333
import jdk.graal.compiler.phases.common.CanonicalizerPhase;
34+
import jdk.graal.compiler.phases.common.EconomyPiRemovalPhase;
3435
import jdk.graal.compiler.phases.common.ExpandLogicPhase;
3536
import jdk.graal.compiler.phases.common.InitMemoryVerificationPhase;
3637
import jdk.graal.compiler.phases.common.LowTierLoweringPhase;
@@ -46,10 +47,12 @@ public EconomyLowTier(OptionValues options) {
4647
if (Graph.Options.VerifyGraalGraphs.getValue(options)) {
4748
appendPhase(new InitMemoryVerificationPhase());
4849
}
49-
CanonicalizerPhase canonicalizer = CanonicalizerPhase.create();
50+
CanonicalizerPhase canonicalizer = CanonicalizerPhase.createSingleShot();
5051
appendPhase(new LowTierLoweringPhase(canonicalizer));
5152
appendPhase(new ExpandLogicPhase(canonicalizer));
5253

54+
appendPhase(new EconomyPiRemovalPhase(canonicalizer));
55+
5356
if (Assertions.assertionsEnabled()) {
5457
appendPhase(new BarrierSetVerificationPhase());
5558
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
package jdk.graal.compiler.core.phases;
26+
27+
import java.util.Optional;
28+
29+
import jdk.graal.compiler.nodes.GraphState;
30+
import jdk.graal.compiler.nodes.StructuredGraph;
31+
import jdk.graal.compiler.phases.BasePhase;
32+
import jdk.graal.compiler.phases.Phase;
33+
34+
public class EconomyMarkFixReadsPhase extends Phase {
35+
36+
@Override
37+
public Optional<BasePhase.NotApplicable> notApplicableTo(GraphState graphState) {
38+
return ALWAYS_APPLICABLE;
39+
}
40+
41+
@Override
42+
protected void run(StructuredGraph graph) {
43+
}
44+
45+
@Override
46+
public void updateGraphState(GraphState graphState) {
47+
/*
48+
* In economy we never allow floating reads for the sake of compile speed, thus we mark the
49+
* graph as already having fix reads.
50+
*/
51+
super.updateGraphState(graphState);
52+
graphState.setAfterStage(GraphState.StageFlag.FIXED_READS);
53+
}
54+
55+
public static final EconomyMarkFixReadsPhase SINGLETON = new EconomyMarkFixReadsPhase();
56+
}

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/phases/EconomyMidTier.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
package jdk.graal.compiler.core.phases;
2626

2727
import jdk.graal.compiler.phases.common.CanonicalizerPhase;
28+
import jdk.graal.compiler.phases.common.DeoptimizationGroupingPhase;
2829
import jdk.graal.compiler.phases.common.FrameStateAssignmentPhase;
2930
import jdk.graal.compiler.phases.common.GuardLoweringPhase;
3031
import jdk.graal.compiler.phases.common.LoopSafepointInsertionPhase;
@@ -37,12 +38,13 @@ public class EconomyMidTier extends BaseTier<MidTierContext> {
3738

3839
@SuppressWarnings("this-escape")
3940
public EconomyMidTier() {
40-
CanonicalizerPhase canonicalizer = CanonicalizerPhase.create();
41+
CanonicalizerPhase canonicalizer = CanonicalizerPhase.createSingleShot();
4142
appendPhase(new RemoveValueProxyPhase(canonicalizer));
4243
appendPhase(new LoopSafepointInsertionPhase());
4344
appendPhase(new GuardLoweringPhase());
4445
appendPhase(new MidTierLoweringPhase(canonicalizer));
4546
appendPhase(new FrameStateAssignmentPhase());
47+
appendPhase(new DeoptimizationGroupingPhase());
4648
appendPhase(canonicalizer);
4749
appendPhase(new WriteBarrierAdditionPhase());
4850
}

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/meta/DefaultHotSpotLoweringProvider.java

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -793,7 +793,9 @@ private void lowerKlassLayoutHelperNode(KlassLayoutHelperNode n, LoweringTool to
793793
StructuredGraph graph = n.graph();
794794
assert !n.getHub().isConstant();
795795
AddressNode address = createOffsetAddress(graph, n.getHub(), runtime.getVMConfig().klassLayoutHelperOffset);
796-
n.replaceAtUsagesAndDelete(graph.unique(new FloatingReadNode(address, HotSpotReplacementsUtil.KLASS_LAYOUT_HELPER_LOCATION, null, n.stamp(NodeView.DEFAULT), null, BarrierType.NONE)));
796+
ReadNode memoryRead = graph.add(new ReadNode(address, HotSpotReplacementsUtil.KLASS_LAYOUT_HELPER_LOCATION, null, n.stamp(NodeView.DEFAULT), null, BarrierType.NONE));
797+
graph.addAfterFixed(tool.lastFixedNode(), memoryRead);
798+
n.replaceAtUsagesAndDelete(memoryRead);
797799
}
798800

799801
private void lowerHubGetClassNode(HubGetClassNode n, LoweringTool tool) {
@@ -856,7 +858,7 @@ private void lowerInvoke(Invoke invoke, LoweringTool tool, StructuredGraph graph
856858
ResolvedJavaType receiverType = invoke.getReceiverType();
857859
if (hsMethod.isInVirtualMethodTable(receiverType)) {
858860
JavaKind wordKind = runtime.getTarget().wordJavaKind;
859-
ValueNode hub = createReadHub(graph, receiver, tool);
861+
ValueNode hub = createReadHub(graph, receiver, tool, tool.lastFixedNode());
860862

861863
ReadNode metaspaceMethod = createReadVirtualMethod(graph, hub, hsMethod, receiverType);
862864
// We use LocationNode.ANY_LOCATION for the reads that access the
@@ -907,7 +909,7 @@ public ValueNode staticFieldBase(StructuredGraph graph, ResolvedJavaField f) {
907909
}
908910

909911
@Override
910-
protected ValueNode createReadArrayComponentHub(StructuredGraph graph, ValueNode arrayHub, boolean isKnownObjectArray, FixedNode anchor) {
912+
protected ValueNode createReadArrayComponentHub(StructuredGraph graph, ValueNode arrayHub, boolean isKnownObjectArray, FixedNode anchor, LoweringTool tool, FixedWithNextNode insertAfter) {
911913
GuardingNode guard = null;
912914
if (!isKnownObjectArray) {
913915
/*
@@ -918,7 +920,9 @@ protected ValueNode createReadArrayComponentHub(StructuredGraph graph, ValueNode
918920
guard = AbstractBeginNode.prevBegin(anchor);
919921
}
920922
AddressNode address = createOffsetAddress(graph, arrayHub, runtime.getVMConfig().arrayClassElementOffset);
921-
return graph.unique(new FloatingReadNode(address, HotSpotReplacementsUtil.OBJ_ARRAY_KLASS_ELEMENT_KLASS_LOCATION, null, KlassPointerStamp.klassNonNull(), guard));
923+
ReadNode read = graph.add(new ReadNode(address, HotSpotReplacementsUtil.OBJ_ARRAY_KLASS_ELEMENT_KLASS_LOCATION, null, KlassPointerStamp.klassNonNull(), guard, BarrierType.NONE));
924+
graph.addAfterFixed(insertAfter, read);
925+
return read;
922926
}
923927

924928
private void lowerLoadMethodNode(LoadMethodNode loadMethodNode) {
@@ -1140,7 +1144,7 @@ private ReadNode createReadVirtualMethod(StructuredGraph graph, ValueNode hub, i
11401144
}
11411145

11421146
@Override
1143-
protected ValueNode createReadHub(StructuredGraph graph, ValueNode object, LoweringTool tool) {
1147+
protected ValueNode createReadHub(StructuredGraph graph, ValueNode object, LoweringTool tool, FixedWithNextNode insertAfter) {
11441148
GraalHotSpotVMConfig config = runtime.getVMConfig();
11451149

11461150
if (tool.getLoweringStage() != LoweringTool.StandardLoweringStage.LOW_TIER) {
@@ -1153,17 +1157,22 @@ protected ValueNode createReadHub(StructuredGraph graph, ValueNode object, Lower
11531157
hubStamp = hubStamp.compressed(config.getKlassEncoding());
11541158
}
11551159

1160+
FixedWithNextNode effectiveInsertAfter = insertAfter;
1161+
11561162
if (config.useCompactObjectHeaders) {
11571163
AddressNode address = createOffsetAddress(graph, object, config.markOffset);
1158-
FloatingReadNode memoryRead = graph.unique(new FloatingReadNode(address, COMPACT_HUB_LOCATION, null, StampFactory.forKind(JavaKind.Long), null, BarrierType.NONE));
1164+
ReadNode memoryRead = graph.add(new ReadNode(address, COMPACT_HUB_LOCATION, null, StampFactory.forKind(JavaKind.Long), null, BarrierType.NONE));
1165+
graph.addAfterFixed(insertAfter, memoryRead);
1166+
effectiveInsertAfter = memoryRead;
11591167
ValueNode rawCompressedHubWordSize = graph.addOrUnique(UnsignedRightShiftNode.create(memoryRead, ConstantNode.forInt(config.markWordKlassShift, graph), NodeView.DEFAULT));
11601168
ValueNode rawCompressedHub = graph.addOrUnique(NarrowNode.create(rawCompressedHubWordSize, 32, NodeView.DEFAULT));
11611169
ValueNode compressedKlassPointer = graph.addOrUnique(PointerCastNode.create(hubStamp, rawCompressedHub));
11621170
return HotSpotCompressionNode.uncompress(graph, compressedKlassPointer, config.getKlassEncoding());
11631171
}
11641172
AddressNode address = createOffsetAddress(graph, object, config.hubOffset);
11651173
LocationIdentity hubLocation = config.useCompressedClassPointers ? COMPRESSED_HUB_LOCATION : HUB_LOCATION;
1166-
FloatingReadNode memoryRead = graph.unique(new FloatingReadNode(address, hubLocation, null, hubStamp, null, BarrierType.NONE));
1174+
ReadNode memoryRead = graph.add(new ReadNode(address, hubLocation, null, hubStamp, null, BarrierType.NONE));
1175+
graph.addAfterFixed(effectiveInsertAfter, memoryRead);
11671176
if (config.useCompressedClassPointers) {
11681177
return HotSpotCompressionNode.uncompress(graph, memoryRead, config.getKlassEncoding());
11691178
} else {

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/stubs/Stub.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@
4141
import jdk.graal.compiler.core.common.CompilationIdentifier;
4242
import jdk.graal.compiler.core.common.GraalOptions;
4343
import jdk.graal.compiler.core.common.LibGraalSupport;
44+
import jdk.graal.compiler.core.phases.EconomyHighTier;
45+
import jdk.graal.compiler.core.phases.EconomyMarkFixReadsPhase;
4446
import jdk.graal.compiler.core.target.Backend;
4547
import jdk.graal.compiler.debug.DebugContext;
4648
import jdk.graal.compiler.debug.DebugContext.Builder;
@@ -312,11 +314,16 @@ public void updateGraphState(GraphState graphState) {
312314
}
313315

314316
protected Suites createSuites() {
315-
Suites defaultSuites = providers.getSuites().getDefaultSuites(options, providers.getLowerer().getTarget().arch).copy();
317+
Suites original = providers.getSuites().getDefaultSuites(options, providers.getLowerer().getTarget().arch);
318+
Suites defaultSuites = original.copy();
316319

317320
PhaseSuite<HighTierContext> emptyHighTier = new PhaseSuite<>();
321+
318322
emptyHighTier.appendPhase(new DisableOverflownCountedLoopsPhase());
319323
emptyHighTier.appendPhase(new EmptyHighTier());
324+
if (original.getHighTier() instanceof EconomyHighTier) {
325+
emptyHighTier.appendPhase(EconomyMarkFixReadsPhase.SINGLETON);
326+
}
320327

321328
defaultSuites.getMidTier().removeSubTypePhases(Speculative.class);
322329
defaultSuites.getLowTier().removeSubTypePhases(Speculative.class);

0 commit comments

Comments
 (0)