Skip to content

Commit 34a5a20

Browse files
msimacektimfel
authored andcommitted
Revert monomorphization of unary and binary ops
1 parent 79554d4 commit 34a5a20

File tree

5 files changed

+187
-5
lines changed

5 files changed

+187
-5
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/PBytecodeRootNode.java

Lines changed: 124 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@
137137
import com.oracle.graal.python.nodes.expression.BinaryArithmeticFactory;
138138
import com.oracle.graal.python.nodes.expression.BinaryComparisonNode;
139139
import com.oracle.graal.python.nodes.expression.BinaryComparisonNodeFactory;
140+
import com.oracle.graal.python.nodes.expression.BinaryOp;
140141
import com.oracle.graal.python.nodes.expression.CoerceToBooleanNode;
141142
import com.oracle.graal.python.nodes.expression.CoerceToBooleanNodeFactory;
142143
import com.oracle.graal.python.nodes.expression.ContainsNode;
@@ -148,6 +149,7 @@
148149
import com.oracle.graal.python.nodes.expression.UnaryArithmetic.NegNode;
149150
import com.oracle.graal.python.nodes.expression.UnaryArithmetic.PosNode;
150151
import com.oracle.graal.python.nodes.expression.UnaryArithmeticFactory;
152+
import com.oracle.graal.python.nodes.expression.UnaryOpNode;
151153
import com.oracle.graal.python.nodes.frame.DeleteGlobalNode;
152154
import com.oracle.graal.python.nodes.frame.DeleteGlobalNodeGen;
153155
import com.oracle.graal.python.nodes.frame.ReadGlobalOrBuiltinNode;
@@ -303,6 +305,96 @@ public final class PBytecodeRootNode extends PRootNode implements BytecodeOSRNod
303305
private static final GetNameFromLocalsNode UNCACHED_GET_NAME_FROM_LOCALS = GetNameFromLocalsNode.getUncached();
304306
private static final NodeSupplier<GetNameFromLocalsNode> NODE_GET_NAME_FROM_LOCALS = GetNameFromLocalsNode::create;
305307

308+
private static final IntNodeFunction<UnaryOpNode> UNARY_OP_FACTORY = (int op) -> {
309+
switch (op) {
310+
case UnaryOpsConstants.NOT:
311+
return CoerceToBooleanNode.createIfFalseNode();
312+
case UnaryOpsConstants.POSITIVE:
313+
return PosNode.create();
314+
case UnaryOpsConstants.NEGATIVE:
315+
return NegNode.create();
316+
case UnaryOpsConstants.INVERT:
317+
return InvertNode.create();
318+
default:
319+
throw CompilerDirectives.shouldNotReachHere();
320+
}
321+
};
322+
323+
private static final IntNodeFunction<Node> BINARY_OP_FACTORY = (int op) -> {
324+
switch (op) {
325+
case BinaryOpsConstants.ADD:
326+
return BinaryArithmetic.Add.create();
327+
case BinaryOpsConstants.SUB:
328+
return BinaryArithmetic.Sub.create();
329+
case BinaryOpsConstants.MUL:
330+
return BinaryArithmetic.Mul.create();
331+
case BinaryOpsConstants.TRUEDIV:
332+
return BinaryArithmetic.TrueDiv.create();
333+
case BinaryOpsConstants.FLOORDIV:
334+
return BinaryArithmetic.FloorDiv.create();
335+
case BinaryOpsConstants.MOD:
336+
return BinaryArithmetic.Mod.create();
337+
case BinaryOpsConstants.LSHIFT:
338+
return BinaryArithmetic.LShift.create();
339+
case BinaryOpsConstants.RSHIFT:
340+
return BinaryArithmetic.RShift.create();
341+
case BinaryOpsConstants.AND:
342+
return BinaryArithmetic.And.create();
343+
case BinaryOpsConstants.OR:
344+
return BinaryArithmetic.Or.create();
345+
case BinaryOpsConstants.XOR:
346+
return BinaryArithmetic.Xor.create();
347+
case BinaryOpsConstants.POW:
348+
return BinaryArithmetic.Pow.create();
349+
case BinaryOpsConstants.MATMUL:
350+
return BinaryArithmetic.MatMul.create();
351+
case BinaryOpsConstants.INPLACE_ADD:
352+
return InplaceArithmetic.IAdd.create();
353+
case BinaryOpsConstants.INPLACE_SUB:
354+
return InplaceArithmetic.ISub.create();
355+
case BinaryOpsConstants.INPLACE_MUL:
356+
return InplaceArithmetic.IMul.create();
357+
case BinaryOpsConstants.INPLACE_TRUEDIV:
358+
return InplaceArithmetic.ITrueDiv.create();
359+
case BinaryOpsConstants.INPLACE_FLOORDIV:
360+
return InplaceArithmetic.IFloorDiv.create();
361+
case BinaryOpsConstants.INPLACE_MOD:
362+
return InplaceArithmetic.IMod.create();
363+
case BinaryOpsConstants.INPLACE_LSHIFT:
364+
return InplaceArithmetic.ILShift.create();
365+
case BinaryOpsConstants.INPLACE_RSHIFT:
366+
return InplaceArithmetic.IRShift.create();
367+
case BinaryOpsConstants.INPLACE_AND:
368+
return InplaceArithmetic.IAnd.create();
369+
case BinaryOpsConstants.INPLACE_OR:
370+
return InplaceArithmetic.IOr.create();
371+
case BinaryOpsConstants.INPLACE_XOR:
372+
return InplaceArithmetic.IXor.create();
373+
case BinaryOpsConstants.INPLACE_POW:
374+
return InplaceArithmetic.IPow.create();
375+
case BinaryOpsConstants.INPLACE_MATMUL:
376+
return InplaceArithmetic.IMatMul.create();
377+
case BinaryOpsConstants.EQ:
378+
return BinaryComparisonNode.EqNode.create();
379+
case BinaryOpsConstants.NE:
380+
return BinaryComparisonNode.NeNode.create();
381+
case BinaryOpsConstants.LT:
382+
return BinaryComparisonNode.LtNode.create();
383+
case BinaryOpsConstants.LE:
384+
return BinaryComparisonNode.LeNode.create();
385+
case BinaryOpsConstants.GT:
386+
return BinaryComparisonNode.GtNode.create();
387+
case BinaryOpsConstants.GE:
388+
return BinaryComparisonNode.GeNode.create();
389+
case BinaryOpsConstants.IS:
390+
return IsNode.create();
391+
case BinaryOpsConstants.IN:
392+
return ContainsNode.create();
393+
default:
394+
throw CompilerDirectives.shouldNotReachHere();
395+
}
396+
};
397+
306398
/*
307399
* Create fake GeneratorControlData just to maintain the same generator frame layout as AST
308400
* interpreter. TODO remove
@@ -483,6 +575,11 @@ private interface NodeFunction<A, T> {
483575
T apply(A argument);
484576
}
485577

578+
@FunctionalInterface
579+
private static interface IntNodeFunction<T extends Node> {
580+
T apply(int argument);
581+
}
582+
486583
@SuppressWarnings("unchecked")
487584
private <A, T extends Node> T insertChildNode(Node[] nodes, int nodeIndex, Class<? extends T> cachedClass, NodeFunction<A, T> nodeSupplier, A argument) {
488585
Node node = nodes[nodeIndex];
@@ -512,6 +609,23 @@ private <A, T extends Node> T insertChildNode(Node[] nodes, int nodeIndex, T unc
512609
return CompilerDirectives.castExact(doInsertChildNode(nodes, nodeIndex, nodeSupplier, argument), cachedClass);
513610
}
514611

612+
@SuppressWarnings("unchecked")
613+
private <T extends Node> T insertChildNodeInt(Node[] nodes, int nodeIndex, IntNodeFunction<T> nodeSupplier, int argument) {
614+
Node node = nodes[nodeIndex];
615+
if (node != null) {
616+
return (T) node;
617+
}
618+
return doInsertChildNodeInt(nodes, nodeIndex, nodeSupplier, argument);
619+
}
620+
621+
@SuppressWarnings("unchecked")
622+
private <T extends Node> T doInsertChildNodeInt(Node[] nodes, int nodeIndex, IntNodeFunction<T> nodeSupplier, int argument) {
623+
CompilerDirectives.transferToInterpreterAndInvalidate();
624+
T newNode = nodeSupplier.apply(argument);
625+
nodes[nodeIndex] = insert(newNode);
626+
return newNode;
627+
}
628+
515629
@SuppressWarnings("unchecked")
516630
private <T extends Node, U extends T> U insertChildNode(Node[] nodes, int nodeIndex, Class<U> cachedClass, NodeSupplier<T> nodeSupplier) {
517631
Node node = nodes[nodeIndex];
@@ -943,12 +1057,20 @@ private Object bytecodeLoop(VirtualFrame virtualFrame, Frame localFrame, Frame s
9431057
break;
9441058
case OpCodesConstants.UNARY_OP: {
9451059
int op = Byte.toUnsignedInt(localBC[++bci]);
946-
bytecodeUnaryOp(virtualFrame, stackFrame, stackTop, localNodes, beginBci, op);
1060+
UnaryOpNode opNode = insertChildNodeInt(localNodes, bci, UNARY_OP_FACTORY, op);
1061+
Object value = stackFrame.getObject(stackTop);
1062+
Object result = opNode.execute(virtualFrame, value);
1063+
stackFrame.setObject(stackTop, result);
9471064
break;
9481065
}
9491066
case OpCodesConstants.BINARY_OP: {
9501067
int op = Byte.toUnsignedInt(localBC[++bci]);
951-
stackTop = bytecodeBinaryOp(virtualFrame, stackFrame, stackTop, localNodes, beginBci, op);
1068+
BinaryOp opNode = (BinaryOp) insertChildNodeInt(localNodes, bci, BINARY_OP_FACTORY, op);
1069+
Object right = stackFrame.getObject(stackTop);
1070+
stackFrame.setObject(stackTop--, null);
1071+
Object left = stackFrame.getObject(stackTop);
1072+
Object result = opNode.executeObject(virtualFrame, left, right);
1073+
stackFrame.setObject(stackTop, result);
9521074
break;
9531075
}
9541076
case OpCodesConstants.BINARY_SUBSCR: {
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* The Universal Permissive License (UPL), Version 1.0
6+
*
7+
* Subject to the condition set forth below, permission is hereby granted to any
8+
* person obtaining a copy of this software, associated documentation and/or
9+
* data (collectively the "Software"), free of charge and under any and all
10+
* copyright rights in the Software, and any and all patent rights owned or
11+
* freely licensable by each licensor hereunder covering either (i) the
12+
* unmodified Software as contributed to or provided by such licensor, or (ii)
13+
* the Larger Works (as defined below), to deal in both
14+
*
15+
* (a) the Software, and
16+
*
17+
* (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
18+
* one is included with the Software each a "Larger Work" to which the Software
19+
* is contributed by such licensors),
20+
*
21+
* without restriction, including without limitation the rights to copy, create
22+
* derivative works of, display, perform, and distribute the Software and make,
23+
* use, sell, offer for sale, import, export, have made, and have sold the
24+
* Software and the Larger Work(s), and to sublicense the foregoing rights on
25+
* either these or other terms.
26+
*
27+
* This license is subject to the following condition:
28+
*
29+
* The above copyright notice and either this complete permission notice or at a
30+
* minimum a reference to the UPL must be included in all copies or substantial
31+
* portions of the Software.
32+
*
33+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
38+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
39+
* SOFTWARE.
40+
*/
41+
package com.oracle.graal.python.nodes.expression;
42+
43+
import com.oracle.truffle.api.frame.VirtualFrame;
44+
45+
public interface BinaryOp {
46+
Object executeObject(VirtualFrame frame, Object left, Object right);
47+
}

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,13 @@
3030

3131
@NodeChild(value = "leftNode", type = ExpressionNode.class)
3232
@NodeChild(value = "rightNode", type = ExpressionNode.class)
33-
public abstract class BinaryOpNode extends ExpressionNode {
33+
public abstract class BinaryOpNode extends ExpressionNode implements BinaryOp {
3434
public abstract ExpressionNode getLeftNode();
3535

3636
public abstract ExpressionNode getRightNode();
3737

3838
// TODO: (tfel) refactor this method (executeWith) into a separate node. Right now this breaks
3939
// the lengths we go to to avoid boxing :(
40+
@Override
4041
public abstract Object executeObject(VirtualFrame frame, Object left, Object right);
4142
}

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@
5959
@NodeChild("arg")
6060
@NodeChild("arg2")
6161
@NodeChild("arg3")
62-
public abstract class LookupAndCallInplaceNode extends ExpressionNode {
62+
public abstract class LookupAndCallInplaceNode extends ExpressionNode implements BinaryOp {
6363

6464
public abstract static class NotImplementedHandler extends PNodeWithContext {
6565
public abstract Object execute(Object arg, Object arg2);
@@ -104,6 +104,11 @@ private LookupAndCallTernaryNode ensureLookupAndCallTernaryNode() {
104104
return lookupAndCallTernaryNode;
105105
}
106106

107+
@Override
108+
public final Object executeObject(VirtualFrame frame, Object left, Object right) {
109+
return execute(frame, left, right);
110+
}
111+
107112
public final Object execute(VirtualFrame frame, Object left, Object right) {
108113
return executeTernary(frame, left, right, PNone.NO_VALUE);
109114
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/object/IsNode.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
import com.oracle.graal.python.builtins.objects.str.StringNodes;
5757
import com.oracle.graal.python.builtins.objects.type.PythonBuiltinClass;
5858
import com.oracle.graal.python.nodes.bytecode.PBytecodeGeneratorFunctionRootNode;
59+
import com.oracle.graal.python.nodes.expression.BinaryOp;
5960
import com.oracle.graal.python.nodes.generator.GeneratorFunctionRootNode;
6061
import com.oracle.graal.python.runtime.PythonContext;
6162
import com.oracle.graal.python.runtime.PythonOptions;
@@ -67,6 +68,7 @@
6768
import com.oracle.truffle.api.dsl.GenerateUncached;
6869
import com.oracle.truffle.api.dsl.ImportStatic;
6970
import com.oracle.truffle.api.dsl.Specialization;
71+
import com.oracle.truffle.api.frame.VirtualFrame;
7072
import com.oracle.truffle.api.interop.InteropLibrary;
7173
import com.oracle.truffle.api.library.CachedLibrary;
7274
import com.oracle.truffle.api.nodes.Node;
@@ -75,12 +77,17 @@
7577

7678
@ImportStatic(PythonOptions.class)
7779
@GenerateUncached
78-
public abstract class IsNode extends Node {
80+
public abstract class IsNode extends Node implements BinaryOp {
7981

8082
protected abstract boolean executeInternal(Object left, Object right);
8183

8284
protected abstract boolean executeInternal(boolean left, Object right);
8385

86+
@Override
87+
public final Object executeObject(VirtualFrame frame, Object left, Object right) {
88+
return execute(left, right);
89+
}
90+
8491
public final boolean execute(Object left, Object right) {
8592
return left == right || executeInternal(left, right);
8693
}

0 commit comments

Comments
 (0)