Skip to content

Commit

Permalink
[GR-59565] [GR-59764] Add RootNode.prepareForCompilation(...) to dela…
Browse files Browse the repository at this point in the history
…y compilation and offload expensive work to the compiler thread.

PullRequest: graal/19264
  • Loading branch information
chumer committed Nov 25, 2024
2 parents 47da7f5 + 8ac9409 commit ad42202
Show file tree
Hide file tree
Showing 29 changed files with 590 additions and 111 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,10 @@ public String toString(Verbosity verbosity) {
return "";
}
};
final TruffleTierContext context = new TruffleTierContext(partialEvaluator,
final TruffleTierContext context = TruffleTierContext.createInitialContext(
partialEvaluator,
compiler.getOrCreateCompilerOptions(callTarget),
getDebugContext(), callTarget, partialEvaluator.rootForCallTarget(callTarget),
getDebugContext(), callTarget,
compilationIdentifier, getSpeculationLog(),
new TruffleCompilationTask() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public class ClassLinkedByCompilerTest extends PartialEvaluationTest {
public void testClassLinkedByCompiler() {
RootNode root = new RootNodeImpl();
OptimizedCallTarget compilable = (OptimizedCallTarget) root.getCallTarget();
compilable.ensureInitialized();
TruffleCompilationTask task = newTask();
TruffleCompilerImpl compiler = getTruffleCompiler(compilable);
ResolvedJavaType unlinked = getMetaAccess().lookupJavaType(Unlinked.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ private static OptimizedCallTarget compileAST(RootNode rootNode) {
try (DebugContext.Scope s = debug.scope("EncodedGraphCacheTest")) {
TruffleCompilationTask task = newTask();
try (TruffleCompilation compilation = compiler.openCompilation(task, target)) {
target.ensureInitialized();
getTruffleCompilerFromRuntime(target).compileAST(debug, target, compilation.getCompilationId(), task, null);
assertTrue(target.isValid());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,13 @@ private static class MultiTierRootNode extends RootNode {

@Override
public Object execute(VirtualFrame frame) {
boundary();
Object result = callNode.call(frame.getArguments());
if (CompilerDirectives.inInterpreter()) {
return "root:interpreter";
}
boundary();
return callNode.call(frame.getArguments());
return result;
}
}

Expand Down Expand Up @@ -196,10 +198,6 @@ public void testDefault() {
for (int i = 0; i < firstTierCompilationThreshold; i++) {
multiTierTarget.call();
}
Assert.assertEquals("callee:interpreter", multiTierTarget.call());
for (int i = 0; i < firstTierCompilationThreshold; i++) {
multiTierTarget.call();
}
Assert.assertEquals("callee:first-tier", multiTierTarget.call());
for (int i = 0; i < compilationThreshold; i++) {
multiTierTarget.call();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -556,7 +556,7 @@ private void assertExpectations() {

@Test
public void testSplittingBudgetLimit() {
try (Context c = Context.newBuilder(SplittingLimitTestLanguage.ID).build()) {
try (Context c = Context.newBuilder(SplittingLimitTestLanguage.ID).option("engine.CompileImmediately", "false").build()) {
c.eval(SplittingLimitTestLanguage.ID, "");
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -299,10 +299,9 @@ private StructuredGraph partialEval(OptimizedCallTarget compilable, Object[] arg
final PartialEvaluator partialEvaluator = compiler.getPartialEvaluator();
try (PerformanceInformationHandler handler = PerformanceInformationHandler.install(
compiler.getConfig().runtime(), compiler.getOrCreateCompilerOptions(compilable))) {
final TruffleTierContext context = new TruffleTierContext(partialEvaluator,
final TruffleTierContext context = TruffleTierContext.createInitialContext(partialEvaluator,
compiler.getOrCreateCompilerOptions(compilable),
debug, compilable,
partialEvaluator.rootForCallTarget(compilable),
compilation.getCompilationId(), speculationLog,
task,
handler);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ private void testHelper(RootNode rootNode, boolean expectException, String... ou
DebugContext debug = new Builder(compiler.getOrCreateCompilerOptions(target)).build();
try (DebugCloseable d = debug.disableIntercept(); DebugContext.Scope s = debug.scope("PerformanceWarningTest")) {
final OptimizedCallTarget compilable = target;
compilable.ensureInitialized();
TruffleCompilationTask task = PartialEvaluationTest.newTask();
try (TruffleCompilation compilation = compiler.openCompilation(task, compilable)) {
compiler.compileAST(debug, compilable, compilation.getCompilationId(), task, null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,17 @@
package jdk.graal.compiler.truffle.test;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import java.util.List;

import org.junit.Test;

import com.oracle.truffle.api.CallTarget;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
import com.oracle.truffle.api.TruffleStackTrace;
import com.oracle.truffle.api.TruffleStackTraceElement;
import com.oracle.truffle.api.exception.AbstractTruffleException;
Expand Down Expand Up @@ -133,6 +137,147 @@ protected int findBytecodeIndex(Node node, Frame frame) {
}
}

@Test
public void testPrepareForCompilationLastTier() {
PrepareRootNode node = new PrepareRootNode(true);
OptimizedCallTarget target = (OptimizedCallTarget) node.getCallTarget();
target.compile(true);
target.waitForCompilation();
assertTrue(target.isValidLastTier());
assertEquals(new CompilationData(true, 2, true), target.call());
assertEquals(1, node.prepareCount);
assertTrue(target.isValidLastTier());
}

@Test
public void testPrepareForCompilationLastTierReprofile() {
PrepareRootNode node = new PrepareRootNode(false);
OptimizedCallTarget target = (OptimizedCallTarget) node.getCallTarget();
target.compile(true);
target.waitForCompilation();
assertFalse(target.isValidLastTier());
assertNull(target.call());
assertEquals(new CompilationData(true, 2, true), node.compilationData);
assertEquals(1, node.prepareCount);

target.invalidate("test");
node.returnValue = true;

target.compile(true);
target.waitForCompilation();
assertEquals(new CompilationData(true, 2, true), target.call());
assertEquals(2, node.prepareCount);
assertTrue(target.isValidLastTier());
}

@Test
public void testPrepareForCompilationFirstTier() {
PrepareRootNode node = new PrepareRootNode(true);
OptimizedCallTarget target = (OptimizedCallTarget) node.getCallTarget();
target.compile(false);
target.waitForCompilation();
assertTrue(target.isValid());
assertEquals(new CompilationData(true, 1, false), target.call());
assertEquals(1, node.prepareCount);
assertTrue(target.isValid());
}

@Test
public void testPrepareForCompilationFirstTierReprofile() {
PrepareRootNode node = new PrepareRootNode(false);
OptimizedCallTarget target = (OptimizedCallTarget) node.getCallTarget();
target.compile(false);
target.waitForCompilation();
assertFalse(target.isValid());
assertNull(target.call());
assertEquals(new CompilationData(true, 1, false), node.compilationData);
assertEquals(1, node.prepareCount);

target.invalidate("test");
node.returnValue = true;

target.compile(false);
target.waitForCompilation();
assertEquals(new CompilationData(true, 1, false), target.call());
assertEquals(2, node.prepareCount);
assertTrue(target.isValid());

}

@Test
public void testPrepareForCompilationInlined() {
PrepareRootNode node = new PrepareRootNode(true);
node.getCallTarget().call(); // ensure initialized for inlining
ConstantTargetRootNode call = new ConstantTargetRootNode(node);
OptimizedCallTarget target = (OptimizedCallTarget) call.getCallTarget();
target.compile(true);
target.waitForCompilation();
assertTrue(target.isValidLastTier());
assertEquals(1, node.prepareCount);
assertEquals(new CompilationData(false, 2, true), target.call());
assertTrue(target.isValidLastTier());
}

@Test
public void testPrepareForCompilationInlinedReprofile() {
PrepareRootNode node = new PrepareRootNode(false);
node.getCallTarget().call(); // ensure initialized for inlining
ConstantTargetRootNode call = new ConstantTargetRootNode(node);
OptimizedCallTarget target = (OptimizedCallTarget) call.getCallTarget();
target.compile(true);
target.waitForCompilation();
assertTrue(target.isValidLastTier());
assertNull(target.call());
assertEquals(new CompilationData(false, 2, true), node.compilationData);
assertEquals(1, node.prepareCount);

target.invalidate("test");
node.returnValue = true;

target.compile(true);
target.waitForCompilation();
assertTrue(target.isValidLastTier());
assertEquals(2, node.prepareCount);
assertEquals(new CompilationData(false, 2, true), target.call());
assertTrue(target.isValidLastTier());
}

record CompilationData(boolean rootCompilation, int compilationTier, boolean lastTier) {
}

static final class PrepareRootNode extends BaseRootNode {

private volatile int prepareCount = 0;
@CompilationFinal volatile boolean returnValue;
@CompilationFinal volatile CompilationData compilationData;

PrepareRootNode(boolean returnValue) {
this.returnValue = returnValue;
}

@Override
public Object execute(VirtualFrame frame) {
if (CompilerDirectives.inCompiledCode()) {
return compilationData;
}
return null;
}

@Override
protected boolean isTrivial() {
return true;
}

@SuppressWarnings("hiding")
@Override
protected boolean prepareForCompilation(boolean rootCompilation, int compilationTier, boolean lastTier) {
this.prepareCount++;
this.compilationData = new CompilationData(rootCompilation, compilationTier, lastTier);
return returnValue;
}

}

static class ConstantTargetRootNode extends BaseRootNode {

// deliberately
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,9 @@ public long engineId() {
}

@Override
public void prepareForCompilation() {
public boolean prepareForCompilation(boolean rootCompilation, int compilationTier, boolean lastTier) {
try {
HANDLES.prepareForCompilation.invoke(hsHandle);
return (boolean) HANDLES.prepareForCompilation.invoke(hsHandle, rootCompilation, compilationTier, lastTier);
} catch (Throwable t) {
throw handleException(t);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -538,11 +538,10 @@ private StructuredGraph truffleTier(TruffleCompilationWrapper wrapper, DebugCont
* TODO GR-37097 Merge TruffleTierConfiguration and TruffleCompilationWrapper so that
* there is one place where compilation data lives
*/
TruffleTierContext context = new TruffleTierContext(partialEvaluator,
TruffleTierContext context = TruffleTierContext.createInitialContext(partialEvaluator,
wrapper.compilerOptions,
debug,
wrapper.compilable,
partialEvaluator.rootForCallTarget(wrapper.compilable),
wrapper.compilationId, TruffleTierContext.getSpeculationLog(wrapper), wrapper.task,
handler);

Expand Down
Loading

0 comments on commit ad42202

Please sign in to comment.