Skip to content

Commit e58e785

Browse files
committed
[GR-32147] Use slots in in inplace ternary operations.
PullRequest: graalpython/2045
2 parents 9236852 + 7685754 commit e58e785

File tree

8 files changed

+91
-22
lines changed

8 files changed

+91
-22
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/list/ListBuiltins.java

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -953,10 +953,7 @@ PNotImplemented doGeneric(Object left, Object right) {
953953

954954
@Builtin(name = __IMUL__, minNumOfPositionalArgs = 2)
955955
@GenerateNodeFactory
956-
abstract static class IMulNode extends PythonBuiltinNode {
957-
958-
public abstract PList execute(VirtualFrame frame, PList list, Object value);
959-
956+
abstract static class IMulNode extends PythonBinaryBuiltinNode {
960957
@Specialization
961958
Object doGeneric(VirtualFrame frame, PList list, Object right,
962959
@Cached ConditionProfile updatedProfile,
@@ -971,7 +968,7 @@ Object doGeneric(VirtualFrame frame, PList list, Object right,
971968
}
972969

973970
protected IMulNode createIMulNode() {
974-
return ListBuiltinsFactory.IMulNodeFactory.create(null);
971+
return ListBuiltinsFactory.IMulNodeFactory.create();
975972
}
976973
}
977974

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/SpecialMethodSlot.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@
6666
import static com.oracle.graal.python.nodes.SpecialMethodNames.__GE__;
6767
import static com.oracle.graal.python.nodes.SpecialMethodNames.__GT__;
6868
import static com.oracle.graal.python.nodes.SpecialMethodNames.__HASH__;
69+
import static com.oracle.graal.python.nodes.SpecialMethodNames.__IADD__;
70+
import static com.oracle.graal.python.nodes.SpecialMethodNames.__IMUL__;
6971
import static com.oracle.graal.python.nodes.SpecialMethodNames.__INDEX__;
7072
import static com.oracle.graal.python.nodes.SpecialMethodNames.__INIT__;
7173
import static com.oracle.graal.python.nodes.SpecialMethodNames.__INSTANCECHECK__;
@@ -249,6 +251,9 @@ public enum SpecialMethodSlot {
249251
RShift(__RSHIFT__),
250252
RRShift(__RRSHIFT__),
251253

254+
IAdd(__IADD__),
255+
IMul(__IMUL__),
256+
252257
Reversed(__REVERSED__),
253258
Bytes(__BYTES__);
254259

@@ -818,6 +823,10 @@ public static SpecialMethodSlot findSpecialSlot(String name) {
818823
return RShift;
819824
case __RRSHIFT__:
820825
return RRShift;
826+
case __IADD__:
827+
return IAdd;
828+
case __IMUL__:
829+
return IMul;
821830
case __REVERSED__:
822831
return Reversed;
823832
case __BYTES__:

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/attributes/SetAttributeNode.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,7 @@
4040
*/
4141
package com.oracle.graal.python.nodes.attributes;
4242

43-
import static com.oracle.graal.python.nodes.SpecialMethodNames.__SETATTR__;
44-
43+
import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot;
4544
import com.oracle.graal.python.nodes.PNodeWithContext;
4645
import com.oracle.graal.python.nodes.call.special.LookupAndCallTernaryNode;
4746
import com.oracle.graal.python.nodes.expression.ExpressionNode;
@@ -57,7 +56,7 @@
5756
public abstract class SetAttributeNode extends StatementNode implements WriteNode {
5857

5958
public static final class Dynamic extends PNodeWithContext {
60-
@Child private LookupAndCallTernaryNode call = LookupAndCallTernaryNode.create(__SETATTR__);
59+
@Child private LookupAndCallTernaryNode call = LookupAndCallTernaryNode.create(SpecialMethodSlot.SetAttr);
6160

6261
public void execute(VirtualFrame frame, Object object, Object key, Object value) {
6362
call.execute(frame, object, key, value);

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/LookupAndCallNonReversibleTernaryNode.java

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,9 @@
4141
package com.oracle.graal.python.nodes.call.special;
4242

4343
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
44+
import com.oracle.graal.python.builtins.objects.function.BuiltinMethodDescriptor.TernaryBuiltinDescriptor;
4445
import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction;
46+
import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot;
4547
import com.oracle.graal.python.nodes.SpecialMethodNames;
4648
import com.oracle.graal.python.nodes.attributes.LookupAttributeInMRONode;
4749
import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode;
@@ -62,6 +64,10 @@ public abstract class LookupAndCallNonReversibleTernaryNode extends LookupAndCal
6264
super(name);
6365
}
6466

67+
LookupAndCallNonReversibleTernaryNode(SpecialMethodSlot slot) {
68+
super(slot);
69+
}
70+
6571
protected static PythonBuiltinClassType getBuiltinClass(Object receiver, GetClassNode getClassNode) {
6672
Object clazz = getClassNode.execute(receiver);
6773
return clazz instanceof PythonBuiltinClassType ? (PythonBuiltinClassType) clazz : null;
@@ -72,6 +78,14 @@ protected static boolean isClazz(PythonBuiltinClassType clazz, Object receiver,
7278
}
7379

7480
protected final PythonTernaryBuiltinNode getTernaryBuiltin(PythonBuiltinClassType clazz) {
81+
if (slot != null) {
82+
Object attribute = slot.getValue(clazz);
83+
if (attribute instanceof TernaryBuiltinDescriptor) {
84+
return ((TernaryBuiltinDescriptor) attribute).createNode();
85+
}
86+
// If the slot does not contain builtin, full lookup wouldn't find a builtin either
87+
return null;
88+
}
7589
Object attribute = LookupAttributeInMRONode.Dynamic.getUncached().execute(clazz, name);
7690
if (attribute instanceof PBuiltinFunction) {
7791
PBuiltinFunction builtinFunction = (PBuiltinFunction) attribute;
@@ -94,7 +108,7 @@ static Object callObjectBuiltin(VirtualFrame frame, Object v, Object w, Object z
94108
Object callObject(VirtualFrame frame, Object arg1, Object arg2, Object arg3,
95109
@SuppressWarnings("unused") @Cached("arg1.getClass()") Class<?> cachedArg1Class,
96110
@Cached GetClassNode getClassNode,
97-
@Cached("create(name)") LookupSpecialBaseNode getattr) {
111+
@Cached("createLookup()") LookupSpecialBaseNode getattr) {
98112
Object klass = getClassNode.execute(arg1);
99113
return dispatchNode.execute(frame, getattr.execute(frame, klass, arg1), arg1, arg2, arg3);
100114
}
@@ -103,7 +117,7 @@ Object callObject(VirtualFrame frame, Object arg1, Object arg2, Object arg3,
103117
@Megamorphic
104118
Object callObjectMegamorphic(VirtualFrame frame, Object arg1, Object arg2, Object arg3,
105119
@Cached GetClassNode getClassNode,
106-
@Cached("create(name)") LookupSpecialBaseNode getattr) {
120+
@Cached("createLookup()") LookupSpecialBaseNode getattr) {
107121
Object klass = getClassNode.execute(arg1);
108122
return dispatchNode.execute(frame, getattr.execute(frame, klass, arg1), arg1, arg2, arg3);
109123
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/LookupAndCallReversibleTernaryNode.java

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242

4343
import com.oracle.graal.python.builtins.objects.PNone;
4444
import com.oracle.graal.python.builtins.objects.PNotImplemented;
45+
import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot;
4546
import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsSameTypeNode;
4647
import com.oracle.graal.python.nodes.SpecialMethodNames;
4748
import com.oracle.graal.python.nodes.classes.IsSubtypeNode;
@@ -72,11 +73,16 @@ public abstract class LookupAndCallReversibleTernaryNode extends LookupAndCallTe
7273
this.handlerFactory = handlerFactory;
7374
}
7475

76+
public LookupAndCallReversibleTernaryNode(SpecialMethodSlot slot, Supplier<NotImplementedHandler> handlerFactory) {
77+
super(slot);
78+
this.handlerFactory = handlerFactory;
79+
}
80+
7581
@Specialization(guards = "v.getClass() == cachedVClass", limit = "getCallSiteInlineCacheMaxDepth()")
7682
Object callObjectR(VirtualFrame frame, Object v, Object w, Object z,
7783
@SuppressWarnings("unused") @Cached("v.getClass()") Class<?> cachedVClass,
78-
@Cached("create(name)") LookupSpecialMethodNode getattr,
79-
@Cached("create(name)") LookupSpecialMethodNode getattrR,
84+
@Cached("createLookup()") LookupSpecialBaseNode getattr,
85+
@Cached("createLookup()") LookupSpecialBaseNode getattrR,
8086
@Cached GetClassNode getClass,
8187
@Cached GetClassNode getClassR,
8288
@Cached IsSubtypeNode isSubtype,
@@ -88,8 +94,8 @@ Object callObjectR(VirtualFrame frame, Object v, Object w, Object z,
8894
@Specialization(replaces = "callObjectR")
8995
@Megamorphic
9096
Object callObjectRMegamorphic(VirtualFrame frame, Object v, Object w, Object z,
91-
@Cached("create(name)") LookupSpecialMethodNode getattr,
92-
@Cached("create(name)") LookupSpecialMethodNode getattrR,
97+
@Cached("createLookup()") LookupSpecialBaseNode getattr,
98+
@Cached("createLookup()") LookupSpecialBaseNode getattrR,
9399
@Cached GetClassNode getClass,
94100
@Cached GetClassNode getClassR,
95101
@Cached IsSubtypeNode isSubtype,
@@ -98,7 +104,7 @@ Object callObjectRMegamorphic(VirtualFrame frame, Object v, Object w, Object z,
98104
return doCallObjectR(frame, v, w, z, getattr, getattrR, getClass, getClassR, isSubtype, isSameTypeNode, notImplementedBranch);
99105
}
100106

101-
private Object doCallObjectR(VirtualFrame frame, Object v, Object w, Object z, LookupSpecialMethodNode getattr, LookupSpecialMethodNode getattrR, GetClassNode getClass, GetClassNode getClassR,
107+
private Object doCallObjectR(VirtualFrame frame, Object v, Object w, Object z, LookupSpecialBaseNode getattr, LookupSpecialBaseNode getattrR, GetClassNode getClass, GetClassNode getClassR,
102108
IsSubtypeNode isSubtype, IsSameTypeNode isSameTypeNode, BranchProfile notImplementedBranch) {
103109
// c.f. mostly slot_nb_power and wrap_ternaryfunc_r. like
104110
// cpython://Object/abstract.c#ternary_op we try all three combinations, and the structure

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/LookupAndCallTernaryNode.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
*/
4141
package com.oracle.graal.python.nodes.call.special;
4242

43+
import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot;
4344
import com.oracle.graal.python.nodes.PNodeWithContext;
4445
import com.oracle.graal.python.nodes.SpecialMethodNames;
4546
import com.oracle.graal.python.runtime.PythonOptions;
@@ -56,6 +57,7 @@ public abstract static class NotImplementedHandler extends PNodeWithContext {
5657
}
5758

5859
protected final String name;
60+
protected final SpecialMethodSlot slot;
5961
@Child protected CallTernaryMethodNode dispatchNode = CallTernaryMethodNode.create();
6062

6163
public abstract Object execute(VirtualFrame frame, Object arg1, Object arg2, Object arg3);
@@ -64,11 +66,32 @@ public static LookupAndCallTernaryNode create(String name) {
6466
return LookupAndCallNonReversibleTernaryNodeGen.create(name);
6567
}
6668

69+
public static LookupAndCallTernaryNode create(SpecialMethodSlot slot) {
70+
return LookupAndCallNonReversibleTernaryNodeGen.create(slot);
71+
}
72+
6773
public static LookupAndCallTernaryNode createReversible(String name, Supplier<NotImplementedHandler> handlerFactory) {
6874
return LookupAndCallReversibleTernaryNodeGen.create(name, handlerFactory);
6975
}
7076

77+
public static LookupAndCallTernaryNode createReversible(SpecialMethodSlot slot, Supplier<NotImplementedHandler> handlerFactory) {
78+
return LookupAndCallReversibleTernaryNodeGen.create(slot, handlerFactory);
79+
}
80+
7181
LookupAndCallTernaryNode(String name) {
7282
this.name = name;
83+
this.slot = null;
84+
}
85+
86+
LookupAndCallTernaryNode(SpecialMethodSlot slot) {
87+
this.slot = slot;
88+
this.name = slot.getName();
89+
}
90+
91+
protected final LookupSpecialBaseNode createLookup() {
92+
if (slot != null) {
93+
return LookupSpecialMethodSlotNode.create(slot);
94+
}
95+
return LookupSpecialMethodNode.create(name);
7396
}
7497
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/expression/InplaceArithmetic.java

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
import com.oracle.graal.python.builtins.objects.PNone;
4747
import com.oracle.graal.python.builtins.objects.function.PArguments;
4848
import com.oracle.graal.python.builtins.objects.function.Signature;
49+
import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot;
4950
import com.oracle.graal.python.nodes.ErrorMessages;
5051
import com.oracle.graal.python.nodes.PRaiseNode;
5152
import com.oracle.graal.python.nodes.SpecialMethodNames;
@@ -58,9 +59,9 @@
5859
import com.oracle.truffle.api.nodes.RootNode;
5960

6061
public enum InplaceArithmetic {
61-
IAdd(SpecialMethodNames.__IADD__, "+=", BinaryArithmetic.Add),
62+
IAdd(SpecialMethodSlot.IAdd, "+=", BinaryArithmetic.Add),
6263
ISub(SpecialMethodNames.__ISUB__, "-=", BinaryArithmetic.Sub),
63-
IMul(SpecialMethodNames.__IMUL__, "*=", BinaryArithmetic.Mul),
64+
IMul(SpecialMethodSlot.IMul, "*=", BinaryArithmetic.Mul),
6465
ITrueDiv(SpecialMethodNames.__ITRUEDIV__, "/=", BinaryArithmetic.TrueDiv),
6566
IFloorDiv(SpecialMethodNames.__IFLOORDIV__, "//=", BinaryArithmetic.FloorDiv),
6667
IMod(SpecialMethodNames.__IMOD__, "%=", BinaryArithmetic.Mod),
@@ -73,24 +74,32 @@ public enum InplaceArithmetic {
7374
IMatMul(SpecialMethodNames.__IMATMUL__, "@", BinaryArithmetic.MatMul);
7475

7576
final String methodName;
77+
final SpecialMethodSlot slot;
7678
final String operator;
7779
final boolean isTernary;
7880
final Supplier<LookupAndCallInplaceNode.NotImplementedHandler> notImplementedHandler;
7981
final BinaryArithmetic binary;
8082
final String binaryOpName;
81-
final String reverseBinaryOpName;
8283

8384
InplaceArithmetic(String methodName, String operator, BinaryArithmetic binary) {
8485
this(methodName, operator, binary, false);
8586
}
8687

88+
InplaceArithmetic(SpecialMethodSlot slot, String operator, BinaryArithmetic binary) {
89+
this(slot.getName(), operator, binary, false, slot);
90+
}
91+
8792
InplaceArithmetic(String methodName, String operator, BinaryArithmetic binary, boolean isTernary) {
93+
this(methodName, operator, binary, isTernary, null);
94+
}
95+
96+
InplaceArithmetic(String methodName, String operator, BinaryArithmetic binary, boolean isTernary, SpecialMethodSlot slot) {
8897
this.methodName = methodName;
8998
this.operator = operator;
9099
this.binary = binary;
91100
this.isTernary = isTernary;
92101
this.binaryOpName = methodName.replaceFirst("__i", "__");
93-
this.reverseBinaryOpName = methodName.replaceFirst("__i", "__r");
102+
this.slot = slot;
94103

95104
this.notImplementedHandler = () -> new LookupAndCallInplaceNode.NotImplementedHandler() {
96105
@Child private PRaiseNode raiseNode = PRaiseNode.create();

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/expression/LookupAndCallInplaceNode.java

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,12 @@
4444
import com.oracle.graal.python.builtins.objects.PNotImplemented;
4545
import com.oracle.graal.python.nodes.PGuards;
4646
import com.oracle.graal.python.nodes.PNodeWithContext;
47-
import com.oracle.graal.python.nodes.attributes.LookupInheritedAttributeNode;
47+
import com.oracle.graal.python.nodes.attributes.LookupAttributeInMRONode;
48+
import com.oracle.graal.python.nodes.attributes.LookupCallableSlotInMRONode;
49+
import com.oracle.graal.python.nodes.attributes.LookupInMROBaseNode;
4850
import com.oracle.graal.python.nodes.call.special.CallBinaryMethodNode;
4951
import com.oracle.graal.python.nodes.call.special.LookupAndCallTernaryNode;
52+
import com.oracle.graal.python.nodes.object.GetClassNode;
5053
import com.oracle.truffle.api.CompilerDirectives;
5154
import com.oracle.truffle.api.dsl.Cached;
5255
import com.oracle.truffle.api.dsl.NodeChild;
@@ -107,11 +110,20 @@ public final Object execute(VirtualFrame frame, Object left, Object right) {
107110

108111
public abstract Object executeTernary(VirtualFrame frame, Object x, Object y, Object z);
109112

113+
protected final LookupInMROBaseNode createInplaceLookup() {
114+
if (arithmetic.slot != null) {
115+
return LookupCallableSlotInMRONode.create(arithmetic.slot);
116+
} else {
117+
return LookupAttributeInMRONode.create(arithmetic.methodName);
118+
}
119+
}
120+
110121
@Specialization
111122
Object doBinary(VirtualFrame frame, Object left, Object right, Object z,
112-
@Cached("create(arithmetic.methodName)") LookupInheritedAttributeNode getattrInplace) {
123+
@Cached GetClassNode getClassNode,
124+
@Cached("createInplaceLookup()") LookupInMROBaseNode lookupInplace) {
113125
Object result;
114-
Object inplaceCallable = getattrInplace.execute(left);
126+
Object inplaceCallable = lookupInplace.execute(getClassNode.execute(left));
115127
if (inplaceCallable != PNone.NO_VALUE) {
116128
// nb.: The only ternary in-place operator is '__ipow__' but according to 'typeobject.c:
117129
// slot_nb_inplace_power', this is always called as binary.

0 commit comments

Comments
 (0)