Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ci.jsonnet
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@
logs+: [
"default.iprof.gz",
"default.lcov",
"host-inlining.txt.gz",
],
}),
}),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2025, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
Expand Down Expand Up @@ -91,8 +91,8 @@ private RegexResult() {

private static final String NUMBER_OF_REGEX_RESULT_TYPES = "1";

@GenerateCached
@GenerateInline(inlineByDefault = true)
@GenerateCached(false)
@GenerateInline
@GenerateUncached
public abstract static class InteropReadMemberNode extends Node {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2021, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
Expand Down Expand Up @@ -275,7 +275,7 @@ static long doit(VirtualFrame frame, PBuffered self, Object off, int whence,
@Cached("create(T_SEEK)") CheckIsClosedNode checkIsClosedNode,
@Cached BufferedIONodes.CheckIsSeekabledNode checkIsSeekabledNode,
@Cached BufferedIONodes.AsOffNumberNode asOffNumberNode,
@Cached(inline = true) BufferedIONodes.SeekNode seekNode) {
@Cached BufferedIONodes.SeekNode seekNode) {
checkIsClosedNode.execute(frame, self);
checkIsSeekabledNode.execute(frame, self);
long pos = asOffNumberNode.execute(frame, inliningTarget, off, TypeError);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ RawTellNode doIt(@Cached(inline = false) RawTellNode node) {
}
}

@GenerateInline(inlineByDefault = true)
@GenerateInline
@GenerateCached(false)
abstract static class RawTellIgnoreErrorNode extends PNodeWithContext {
public abstract long execute(VirtualFrame frame, Node inliningTarget, PBuffered self);
Expand Down Expand Up @@ -337,7 +337,7 @@ protected static void readWrite(VirtualFrame frame, PBuffered self,
* implementation of cpython/Modules/_io/bufferedio.c:_io__Buffered_seek_impl
*/
@GenerateInline
@GenerateCached
@GenerateCached(false)
abstract static class SeekNode extends PNodeWithContext {

public abstract long execute(VirtualFrame frame, Node inliningTarget, PBuffered self, long off, int whence);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -535,8 +535,8 @@ static PComplex runGeneric(Node inliningTarget, Object value,
* avoid eager and explicit conversion.
*/
@ImportStatic(PythonUtils.class)
@GenerateInline(inlineByDefault = true)
@GenerateCached
@GenerateInline
@GenerateCached(false)
@GenerateUncached
public abstract static class CastToNativeLongNode extends PNodeWithContext {
public abstract long execute(Node inliningTarget, boolean arg);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,6 @@
import com.oracle.truffle.api.dsl.GenerateInline;
import com.oracle.truffle.api.dsl.GenerateUncached;
import com.oracle.truffle.api.dsl.ImportStatic;
import com.oracle.truffle.api.dsl.NeverDefault;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.nodes.DenyReplace;
import com.oracle.truffle.api.nodes.Node;
Expand Down Expand Up @@ -1991,8 +1990,8 @@ private static TpSlots initializeNativeSlots(PythonAbstractNativeObject nativeKl
}
}

@GenerateInline(inlineByDefault = true)
@GenerateCached
@GenerateInline
@GenerateCached(false)
@ImportStatic(PGuards.class)
public abstract static class GetCachedTpSlotsNode extends Node {
public abstract TpSlots execute(Node inliningTarget, Object pythonClass);
Expand Down Expand Up @@ -2025,25 +2024,16 @@ public static GetCachedTpSlotsNode getUncached() {
}
}

@GenerateInline(inlineByDefault = true)
@GenerateCached
@GenerateInline
@GenerateCached(false)
@GenerateUncached
public abstract static class GetObjectSlotsNode extends Node {
public abstract TpSlots execute(Node inliningTarget, Object pythonObject);

public final TpSlots executeCached(Object pythonObject) {
return execute(this, pythonObject);
}

public static TpSlots executeUncached(Object pythonObject) {
return GetObjectSlotsNodeGen.getUncached().execute(null, pythonObject);
}

@NeverDefault
public static GetObjectSlotsNode create() {
return GetObjectSlotsNodeGen.create();
}

// Note: it seems that switching the GetClassNode with an adhoc GetClassNode variant that
// does not have any inline caches does not change peak at least for micro:if-polymorph
// TODO: verify this on all benchmarks and get rid of the IC if possible
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
* and {@code _Py_EnterRecursiveCall}.
*/
@GenerateUncached
@GenerateInline(inlineByDefault = true)
@GenerateInline
@GenerateCached(false)
public abstract class PyEnterRecursiveCallNode extends PNodeWithContext {
protected abstract PythonThreadState execute(Node inliningTarget, TruffleString errorMessage, Object formatArg, boolean withFormatArg);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
* {@link com.oracle.graal.python.util.OverflowException}.
*/
@GenerateUncached
@GenerateInline(inlineByDefault = true)
@GenerateInline
@GenerateCached(false)
public abstract class PyLongAsLongAndOverflowNode extends PNodeWithContext {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ Object doIt(VirtualFrame frame, Object object,
@Bind Node inliningTarget,
@Cached GetClassNode getClassNode,
@Cached GetCachedTpSlotsNode getSlotsNode,
@Cached(inline = true) MergedObjectTypeModuleGetFixedAttributeNode innerNode) {
@Cached MergedObjectTypeModuleGetFixedAttributeNode innerNode) {
Object type = getClassNode.execute(inliningTarget, object);
TpSlots slots = getSlotsNode.execute(inliningTarget, type);
return innerNode.execute(frame, inliningTarget, object, key, type, slots);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@
* inlining, but the caller is expected to keep its identity stable for the lifetime of the node.
*/
@GenerateInline
@GenerateCached
@GenerateCached(false)
public abstract class MergedObjectTypeModuleGetFixedAttributeNode extends PNodeWithContext {

public abstract Object execute(VirtualFrame frame, Node inliningTarget, Object object, TruffleString key, Object type, TpSlots slots);
Expand Down
25 changes: 24 additions & 1 deletion mx.graalpython/mx_graalpython.py
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,13 @@ def graalpy_native_pgo_build_and_test(args=None):
if mx_sdk_vm_ng.get_bootstrap_graalvm_version() < mx.VersionSpec("25.0"):
mx.abort("python-native-pgo not supported on GraalVM < 25")

host_inlining_log = Path(SUITE.dir) / "host-inlining.txt"
host_inlining_log_gz = Path(str(host_inlining_log) + ".gz")
if host_inlining_log.exists():
host_inlining_log.unlink()
if host_inlining_log_gz.exists():
host_inlining_log_gz.unlink()

with set_env(GRAALPY_PGO_PROFILE=""):
mx.log(mx.colorize("[PGO] Building PGO-instrumented native image", color="yellow"))
build_home = graalpy_standalone_home('native', enterprise=True, build=True)
Expand Down Expand Up @@ -469,11 +476,19 @@ def graalpy_native_pgo_build_and_test(args=None):
if not os.path.isfile(iprof_path):
mx.abort(f"[PGO] Could not find profile file at expected location: {iprof_path}")

with set_env(GRAALPY_PGO_PROFILE=str(iprof_path)):
with set_env(GRAALPY_PGO_PROFILE=str(iprof_path), GRAALPY_HOST_INLINING_LOG=str(host_inlining_log)):
mx.log(mx.colorize("[PGO] Building optimized native image with collected profile", color="yellow"))
native_bin = graalpy_standalone('native', enterprise=True, build=True)

mx.log(mx.colorize(f"[PGO] Optimized PGO build complete: {native_bin}", color="yellow"))
if host_inlining_log.exists():
mx.log(mx.colorize(f"[PGO] Host inlining log at: {host_inlining_log}", color="yellow"))
with open(host_inlining_log, 'rb') as f_in, gzip.open(host_inlining_log_gz, 'wb') as f_out:
shutil.copyfileobj(f_in, f_out)
host_inlining_log.unlink()
mx.log(mx.colorize(f"[PGO] Gzipped host inlining log at: {host_inlining_log_gz}", color="yellow"))
else:
mx.warn(f"[PGO] Host inlining log was not produced at expected location: {host_inlining_log}")

iprof_gz_path = str(iprof_path) + '.gz'
with open(iprof_path, 'rb') as f_in, gzip.open(iprof_gz_path, 'wb') as f_out:
Expand Down Expand Up @@ -948,6 +963,14 @@ def graalpy_standalone_home(standalone_type, enterprise=False, dev=False, build=
mx_args.append(f"--extra-image-builder-argument=--pgo={pgo_profile}")
mx_args.append(f"--extra-image-builder-argument=-H:+UnlockExperimentalVMOptions")
mx_args.append(f"--extra-image-builder-argument=-H:+PGOPrintProfileQuality")
if host_inlining_log := os.environ.get("GRAALPY_HOST_INLINING_LOG"):
mx_args.extend([
f"--extra-image-builder-argument=-H:Log=HostInliningPhase,~CanonicalizerPhase,~GraphBuilderPhase",
f"--extra-image-builder-argument=-H:+TruffleHostInliningPrintExplored",
f"--extra-image-builder-argument=-H:MethodFilter=com.oracle.graal.python.*.*",
f"--extra-image-builder-argument=-H:-UnlockExperimentalVMOptions",
f"--extra-image-builder-argument=-Dgraal.LogFile={host_inlining_log}",
])
else:
mx_args.append(f"--extra-image-builder-argument=--pgo-instrument")
mx_args.append(f"--extra-image-builder-argument=-H:+UnlockExperimentalVMOptions")
Expand Down
Loading