Skip to content

Commit 7385b8a

Browse files
committed
[GR-46038] Minor performance tweaks
PullRequest: graalpython/2816
2 parents f626c72 + d7b0987 commit 7385b8a

File tree

4 files changed

+90
-51
lines changed

4 files changed

+90
-51
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/code/CodeNodes.java

Lines changed: 9 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,6 @@
7979
import com.oracle.truffle.api.frame.VirtualFrame;
8080
import com.oracle.truffle.api.nodes.Node;
8181
import com.oracle.truffle.api.nodes.RootNode;
82-
import com.oracle.truffle.api.profiles.InlinedBranchProfile;
8382
import com.oracle.truffle.api.profiles.InlinedConditionProfile;
8483
import com.oracle.truffle.api.source.Source;
8584
import com.oracle.truffle.api.strings.TruffleString;
@@ -233,44 +232,28 @@ static Signature doCached(Node inliningTarget, @SuppressWarnings("unused") PCode
233232
return getInSingleContextMode(inliningTarget, cachedCode);
234233
}
235234

236-
public static Signature getInSingleContextMode(Node inliningTarget, PFunction fun, InlinedBranchProfile firstExecution) {
235+
public static Signature getInSingleContextMode(Node inliningTarget, PFunction fun) {
237236
assert isSingleContext(inliningTarget);
238-
if (CompilerDirectives.inCompiledCode() && CompilerDirectives.isPartialEvaluationConstant(fun.getCode())) {
239-
getInSingleContextMode(inliningTarget, fun.getCode());
240-
}
241-
PCode code = fun.getCode();
242-
Signature signature = code.signature;
243-
if (signature == null) {
244-
firstExecution.enter(inliningTarget);
245-
RootCallTarget ct = code.initializeCallTarget();
246-
signature = code.initializeSignature(ct);
237+
CompilerAsserts.partialEvaluationConstant(fun);
238+
if (CompilerDirectives.inCompiledCode()) {
239+
return getInSingleContextMode(inliningTarget, fun.getCode());
240+
} else {
241+
PCode code = fun.getCode();
242+
return code.getSignature();
247243
}
248-
return signature;
249244
}
250245

251246
public static Signature getInSingleContextMode(Node inliningTarget, PCode code) {
252247
assert isSingleContext(inliningTarget);
253248
CompilerAsserts.partialEvaluationConstant(code);
254-
if (code.signature == null) {
255-
CompilerDirectives.transferToInterpreterAndInvalidate();
256-
code.initializeSignature(code.initializeCallTarget());
257-
}
258-
return code.signature;
249+
return code.getSignature();
259250
}
260251

261252
@Specialization(replaces = "doCached")
262253
static Signature getGeneric(Node inliningTarget, PCode code,
263254
@Cached InlinedConditionProfile signatureProfile,
264255
@Cached InlinedConditionProfile ctProfile) {
265-
Signature signature = code.signature;
266-
if (signatureProfile.profile(inliningTarget, signature == null)) {
267-
RootCallTarget ct = code.callTarget;
268-
if (ctProfile.profile(inliningTarget, ct == null)) {
269-
ct = code.initializeCallTarget();
270-
}
271-
signature = code.initializeSignature(ct);
272-
}
273-
return signature;
256+
return code.getSignature(inliningTarget, signatureProfile);
274257
}
275258
}
276259

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/code/PCode.java

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@
7676
import com.oracle.graal.python.util.Supplier;
7777
import com.oracle.truffle.api.CallTarget;
7878
import com.oracle.truffle.api.CompilerAsserts;
79+
import com.oracle.truffle.api.CompilerDirectives;
80+
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
7981
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
8082
import com.oracle.truffle.api.RootCallTarget;
8183
import com.oracle.truffle.api.dsl.Cached;
@@ -84,8 +86,10 @@
8486
import com.oracle.truffle.api.interop.UnsupportedMessageException;
8587
import com.oracle.truffle.api.library.ExportLibrary;
8688
import com.oracle.truffle.api.library.ExportMessage;
89+
import com.oracle.truffle.api.nodes.Node;
8790
import com.oracle.truffle.api.nodes.RootNode;
8891
import com.oracle.truffle.api.object.Shape;
92+
import com.oracle.truffle.api.profiles.InlinedConditionProfile;
8993
import com.oracle.truffle.api.source.SourceSection;
9094
import com.oracle.truffle.api.strings.TruffleString;
9195

@@ -109,7 +113,7 @@ public final class PCode extends PythonBuiltinObject {
109113
// set. Otherwise, these are lazily created from the supplier.
110114
private Supplier<CallTarget> callTargetSupplier;
111115
RootCallTarget callTarget;
112-
Signature signature;
116+
@CompilationFinal private Signature signature;
113117

114118
// number of local variables
115119
private int nlocals = -1;
@@ -559,6 +563,23 @@ public boolean takesVarKeywordArgs() {
559563
return PCode.takesVarKeywordArgs(getFlags());
560564
}
561565

566+
public Signature getSignature() {
567+
return getSignature(null, InlinedConditionProfile.getUncached());
568+
}
569+
570+
public Signature getSignature(Node inliningTarget, InlinedConditionProfile signatureProfile) {
571+
if (signatureProfile.profile(inliningTarget, signature == null)) {
572+
if (CompilerDirectives.isPartialEvaluationConstant(this)) {
573+
CompilerDirectives.transferToInterpreterAndInvalidate();
574+
}
575+
if (callTarget == null) {
576+
callTarget = initializeCallTarget();
577+
}
578+
signature = initializeSignature(callTarget);
579+
}
580+
return signature;
581+
}
582+
562583
@TruffleBoundary
563584
synchronized Signature initializeSignature(RootCallTarget rootCallTarget) {
564585
if (signature == null) {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/argument/CreateArgumentsNode.java

Lines changed: 55 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
import java.util.Arrays;
5151
import java.util.List;
5252

53+
import com.oracle.graal.python.PythonLanguage;
5354
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
5455
import com.oracle.graal.python.builtins.objects.code.CodeNodes;
5556
import com.oracle.graal.python.builtins.objects.code.PCode;
@@ -85,9 +86,11 @@
8586
import com.oracle.truffle.api.dsl.Bind;
8687
import com.oracle.truffle.api.dsl.Cached;
8788
import com.oracle.truffle.api.dsl.Cached.Exclusive;
89+
import com.oracle.truffle.api.dsl.Cached.Shared;
8890
import com.oracle.truffle.api.dsl.GenerateCached;
8991
import com.oracle.truffle.api.dsl.GenerateInline;
9092
import com.oracle.truffle.api.dsl.GenerateUncached;
93+
import com.oracle.truffle.api.dsl.Idempotent;
9194
import com.oracle.truffle.api.dsl.ImportStatic;
9295
import com.oracle.truffle.api.dsl.Specialization;
9396
import com.oracle.truffle.api.nodes.ExplodeLoop;
@@ -113,12 +116,11 @@ public abstract class CreateArgumentsNode extends PNodeWithContext {
113116
Object[] doMethodCached(@SuppressWarnings("unused") PMethodBase method, Object[] userArguments, PKeyword[] keywords,
114117
@Bind("this") Node inliningTarget,
115118
@Cached CreateAndCheckArgumentsNode createAndCheckArgumentsNode,
116-
@Cached InlinedBranchProfile wasFirst,
117119
@Cached(value = "method", weak = true) PMethodBase cachedMethod) {
118120

119121
CompilerAsserts.partialEvaluationConstant(getFunction(cachedMethod));
120122
// Following getters should fold since getFunction(cachedMethod) is constant
121-
Signature signature = GetSignatureNode.getMethodSignatureSingleContext(cachedMethod, inliningTarget, wasFirst);
123+
Signature signature = GetSignatureNode.getMethodSignatureSingleContext(cachedMethod, inliningTarget);
122124
Object[] defaults = GetDefaultsNode.getMethodDefaults(cachedMethod);
123125
PKeyword[] kwdefaults = GetKeywordDefaultsNode.getMethodKeywords(cachedMethod);
124126
Object self = cachedMethod.getSelf();
@@ -133,12 +135,11 @@ Object[] doMethodCached(@SuppressWarnings("unused") PMethodBase method, Object[]
133135
Object[] doMethodFunctionAndSelfCached(PMethodBase method, Object[] userArguments, PKeyword[] keywords,
134136
@Bind("this") Node inliningTarget,
135137
@Cached CreateAndCheckArgumentsNode createAndCheckArgumentsNode,
136-
@Cached InlinedBranchProfile wasFirst,
137138
@Cached(value = "getFunction(method)", weak = true) @SuppressWarnings("unused") Object cachedFunction,
138139
@Cached(value = "method.getSelf()", weak = true) Object cachedSelf,
139140
@Cached(value = "getClassObject(method)", weak = true) Object cachedClassObject) {
140141
// Following getters should fold since getFunction(cachedMethod) is constant
141-
Signature signature = GetSignatureNode.getFunctionSignatureSingleContext(inliningTarget, wasFirst, cachedFunction);
142+
Signature signature = GetSignatureNode.getFunctionSignatureSingleContext(inliningTarget, cachedFunction);
142143
Object[] defaults = GetDefaultsNode.getFunctionDefaults(cachedFunction);
143144
PKeyword[] kwdefaults = GetKeywordDefaultsNode.getFunctionKeywords(cachedFunction);
144145
return createAndCheckArgumentsNode.execute(inliningTarget, method, userArguments, keywords, signature, cachedSelf, cachedClassObject, defaults, kwdefaults, isMethodCall(cachedSelf));
@@ -147,11 +148,10 @@ Object[] doMethodFunctionAndSelfCached(PMethodBase method, Object[] userArgument
147148
@Specialization(guards = {"isSingleContext()", "getFunction(method) == cachedFunction"}, limit = "getVariableArgumentInlineCacheLimit()", replaces = "doMethodFunctionAndSelfCached")
148149
Object[] doMethodFunctionCached(PMethodBase method, Object[] userArguments, PKeyword[] keywords,
149150
@Bind("this") Node inliningTarget,
150-
@Cached InlinedBranchProfile wasFirst,
151151
@Cached CreateAndCheckArgumentsNode createAndCheckArgumentsNode,
152152
@Cached(value = "getFunction(method)", weak = true) @SuppressWarnings("unused") Object cachedFunction) {
153153
// Following getters should fold since getFunction(cachedMethod) is constant
154-
Signature signature = GetSignatureNode.getFunctionSignatureSingleContext(inliningTarget, wasFirst, cachedFunction);
154+
Signature signature = GetSignatureNode.getFunctionSignatureSingleContext(inliningTarget, cachedFunction);
155155
Object[] defaults = GetDefaultsNode.getFunctionDefaults(cachedFunction);
156156
PKeyword[] kwdefaults = GetKeywordDefaultsNode.getFunctionKeywords(cachedFunction);
157157
Object self = method.getSelf();
@@ -163,10 +163,8 @@ Object[] doMethodFunctionCached(PMethodBase method, Object[] userArguments, PKey
163163
Object[] doFunctionCached(PFunction callable, Object[] userArguments, PKeyword[] keywords,
164164
@Bind("this") Node inliningTarget,
165165
@Cached CreateAndCheckArgumentsNode createAndCheckArgumentsNode,
166-
@Cached InlinedBranchProfile firstExecution,
167166
@Cached(value = "callable", weak = true) @SuppressWarnings("unused") PFunction cachedCallable) {
168-
169-
Signature signature = CodeNodes.GetCodeSignatureNode.getInSingleContextMode(inliningTarget, callable, firstExecution);
167+
Signature signature = CodeNodes.GetCodeSignatureNode.getInSingleContextMode(inliningTarget, cachedCallable);
170168
Object[] defaults = cachedCallable.getDefaults();
171169
PKeyword[] kwdefaults = cachedCallable.getKwDefaults();
172170
return createAndCheckArgumentsNode.execute(inliningTarget, callable, userArguments, keywords, signature, null, null, defaults, kwdefaults, false);
@@ -706,11 +704,26 @@ private static void storeKeywordsOrRaise(Object callee, Object[] arguments, PKey
706704
protected abstract static class SearchNamedParameterNode extends Node {
707705
public abstract int execute(TruffleString[] parameters, TruffleString name);
708706

709-
@Specialization(guards = {"cachedLen == parameters.length", "cachedLen <= 32"})
707+
@Idempotent // I think this is true, I would just like the assertion
708+
protected static boolean nameIsAtIndex(TruffleString[] parameters, TruffleString name, int index) {
709+
return uncached(parameters, name, TruffleString.EqualNode.getUncached()) == index;
710+
}
711+
712+
@SuppressWarnings("unused")
713+
@Specialization(guards = {"name == cachedName", "parameters == cachedParameters", "nameIsAtIndex(cachedParameters, cachedName, index)"}, limit = "1")
714+
static int cachedSingle(TruffleString[] parameters, TruffleString name,
715+
@Cached("name") TruffleString cachedName,
716+
@Cached(value = "parameters", dimensions = 0) TruffleString[] cachedParameters,
717+
@Shared @Cached TruffleString.EqualNode equalNode,
718+
@Cached("uncached(parameters, name, equalNode)") int index) {
719+
return index;
720+
}
721+
722+
@Specialization(guards = {"cachedLen == parameters.length", "cachedLen <= 32"}, replaces = "cachedSingle")
710723
@ExplodeLoop
711-
int cached(TruffleString[] parameters, TruffleString name,
724+
static int cached(TruffleString[] parameters, TruffleString name,
712725
@Cached("parameters.length") int cachedLen,
713-
@Cached TruffleString.EqualNode equalNode) {
726+
@Shared @Cached TruffleString.EqualNode equalNode) {
714727
int idx = -1;
715728
for (int i = 0; i < cachedLen; i++) {
716729
if (equalNode.execute(parameters[i], name, TS_ENCODING)) {
@@ -721,8 +734,8 @@ int cached(TruffleString[] parameters, TruffleString name,
721734
}
722735

723736
@Specialization(replaces = "cached")
724-
int uncached(TruffleString[] parameters, TruffleString name,
725-
@Cached TruffleString.EqualNode equalNode) {
737+
static int uncached(TruffleString[] parameters, TruffleString name,
738+
@Shared @Cached TruffleString.EqualNode equalNode) {
726739
for (int i = 0; i < parameters.length; i++) {
727740
if (equalNode.execute(parameters[i], name, TS_ENCODING)) {
728741
return i;
@@ -919,11 +932,34 @@ protected abstract static class FindKwDefaultNode extends Node {
919932

920933
public abstract PKeyword execute(PKeyword[] kwdefaults, TruffleString kwname);
921934

922-
@Specialization(guards = {"kwdefaults.length == cachedLength", "cachedLength < 32"})
935+
@Idempotent
936+
protected final boolean isSingleContext() {
937+
return PythonLanguage.get(this).isSingleContext();
938+
}
939+
940+
@Idempotent // I think this is true, I would just like the assertion
941+
protected static boolean kwIsCorrect(PKeyword[] kwdefaults, TruffleString kwname, PKeyword result) {
942+
return doUncached(kwdefaults, kwname, TruffleString.EqualNode.getUncached()) == result;
943+
}
944+
945+
protected static TruffleString.EqualNode getUncachedEqualNode() {
946+
return TruffleString.EqualNode.getUncached();
947+
}
948+
949+
@SuppressWarnings("unused")
950+
@Specialization(guards = {"kwname == cachedKwName", "kwdefaults == cachedKwdefaults", "isSingleContext()", "kwIsCorrect(cachedKwdefaults, cachedKwName, result)"}, limit = "1")
951+
PKeyword cachedSingle(PKeyword[] kwdefaults, TruffleString kwname,
952+
@Cached("kwname") TruffleString cachedKwName,
953+
@Cached(value = "kwdefaults", weak = true, dimensions = 0) PKeyword[] cachedKwdefaults,
954+
@Cached(value = "doUncached(kwdefaults, kwname, getUncachedEqualNode())", weak = true) PKeyword result) {
955+
return result;
956+
}
957+
958+
@Specialization(guards = {"kwdefaults.length == cachedLength", "cachedLength < 32"}, replaces = "cachedSingle")
923959
@ExplodeLoop(kind = LoopExplosionKind.FULL_UNROLL_UNTIL_RETURN)
924-
PKeyword doCached(PKeyword[] kwdefaults, TruffleString kwname,
960+
static PKeyword doCached(PKeyword[] kwdefaults, TruffleString kwname,
925961
@Cached("kwdefaults.length") int cachedLength,
926-
@Cached TruffleString.EqualNode equalNode) {
962+
@Shared @Cached TruffleString.EqualNode equalNode) {
927963
for (int j = 0; j < cachedLength; j++) {
928964
if (equalNode.execute(kwdefaults[j].getName(), kwname, TS_ENCODING)) {
929965
return kwdefaults[j];
@@ -933,8 +969,8 @@ PKeyword doCached(PKeyword[] kwdefaults, TruffleString kwname,
933969
}
934970

935971
@Specialization(replaces = "doCached")
936-
PKeyword doUncached(PKeyword[] kwdefaults, TruffleString kwname,
937-
@Cached TruffleString.EqualNode equalNode) {
972+
static PKeyword doUncached(PKeyword[] kwdefaults, TruffleString kwname,
973+
@Shared @Cached TruffleString.EqualNode equalNode) {
938974
for (int j = 0; j < kwdefaults.length; j++) {
939975
if (equalNode.execute(kwdefaults[j].getName(), kwname, TS_ENCODING)) {
940976
return kwdefaults[j];

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/builtins/FunctionNodes.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@
6666
import com.oracle.truffle.api.dsl.ImportStatic;
6767
import com.oracle.truffle.api.dsl.Specialization;
6868
import com.oracle.truffle.api.nodes.Node;
69-
import com.oracle.truffle.api.profiles.InlinedBranchProfile;
7069

7170
public abstract class FunctionNodes {
7271

@@ -226,18 +225,18 @@ public static Signature executeUncached(Object function) {
226225
/**
227226
* Fast-path if method is a partial evaluation constant, and we are in single context mode.
228227
*/
229-
public static Signature getMethodSignatureSingleContext(PMethodBase method, Node inliningTarget, InlinedBranchProfile wasFirst) {
228+
public static Signature getMethodSignatureSingleContext(PMethodBase method, Node inliningTarget) {
230229
CompilerAsserts.partialEvaluationConstant(method);
231-
return getFunctionSignatureSingleContext(inliningTarget, wasFirst, method.getFunction());
230+
return getFunctionSignatureSingleContext(inliningTarget, method.getFunction());
232231
}
233232

234233
/**
235234
* Fast-path if method is a partial evaluation constant, and we are in single context mode.
236235
*/
237-
public static Signature getFunctionSignatureSingleContext(Node inliningTarget, InlinedBranchProfile wasFirst, Object fun) {
236+
public static Signature getFunctionSignatureSingleContext(Node inliningTarget, Object fun) {
238237
CompilerAsserts.partialEvaluationConstant(fun);
239238
if (fun instanceof PFunction f) {
240-
return CodeNodes.GetCodeSignatureNode.getInSingleContextMode(inliningTarget, f, wasFirst);
239+
return CodeNodes.GetCodeSignatureNode.getInSingleContextMode(inliningTarget, f);
241240
} else if (fun instanceof PBuiltinFunction f) {
242241
return f.getSignature();
243242
}

0 commit comments

Comments
 (0)