Skip to content

Commit 129e955

Browse files
committed
[GR-40336] Add quickening for doubles
PullRequest: graalpython/2396
2 parents 7a34b87 + a02fcca commit 129e955

File tree

15 files changed

+827
-163
lines changed

15 files changed

+827
-163
lines changed

graalpython/com.oracle.graal.python.annotations/src/com/oracle/graal/python/annotations/GenerateEnumConstants.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,10 @@
4545

4646
@Target(ElementType.TYPE)
4747
public @interface GenerateEnumConstants {
48+
enum Type {
49+
INT,
50+
BYTE
51+
}
52+
53+
Type type() default Type.INT;
4854
}

graalpython/com.oracle.graal.python.processor/src/com/oracle/graal/python/processor/GenerateEnumConstantsProcessor.java

Lines changed: 54 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
import javax.tools.Diagnostic.Kind;
5757
import javax.tools.JavaFileObject;
5858

59+
import com.oracle.graal.python.annotations.GenerateEnumConstants;
5960
import com.oracle.graal.python.processor.CodeWriter.Block;
6061

6162
@SupportedAnnotationTypes("com.oracle.graal.python.annotations.GenerateEnumConstants")
@@ -67,59 +68,68 @@ public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment
6768
if (re.processingOver()) {
6869
return false;
6970
}
70-
for (TypeElement annotation : annotations) {
71-
Set<? extends Element> annotatedElements = re.getElementsAnnotatedWith(annotation);
72-
for (Element el : annotatedElements) {
73-
if (el.getKind() == ElementKind.ENUM) {
74-
try {
75-
Element enc = el.getEnclosingElement();
76-
int enclosingTypes = 0;
77-
OUTER: while (enc != null) {
78-
switch (enc.getKind()) {
79-
case CLASS:
80-
case ENUM:
81-
case INTERFACE:
82-
enclosingTypes++;
83-
break;
84-
default:
85-
break OUTER;
86-
}
87-
enc.getEnclosingElement();
71+
Set<? extends Element> annotatedElements = re.getElementsAnnotatedWith(GenerateEnumConstants.class);
72+
for (Element el : annotatedElements) {
73+
GenerateEnumConstants annotation = el.getAnnotation(GenerateEnumConstants.class);
74+
boolean useByte = annotation.type() == GenerateEnumConstants.Type.BYTE;
75+
String elementType = useByte ? "byte" : "int";
76+
if (el.getKind() == ElementKind.ENUM) {
77+
try {
78+
Element enc = el.getEnclosingElement();
79+
int enclosingTypes = 0;
80+
OUTER: while (enc != null) {
81+
switch (enc.getKind()) {
82+
case CLASS:
83+
case ENUM:
84+
case INTERFACE:
85+
enclosingTypes++;
86+
break;
87+
default:
88+
break OUTER;
8889
}
89-
String qualName = ((TypeElement) el).getQualifiedName() + "Constants";
90-
String pkgName = qualName.substring(0, qualName.lastIndexOf('.'));
91-
String className = qualName.substring(qualName.lastIndexOf('.') + 1);
90+
enc.getEnclosingElement();
91+
}
92+
String qualName = ((TypeElement) el).getQualifiedName() + "Constants";
93+
String pkgName = qualName.substring(0, qualName.lastIndexOf('.'));
94+
String className = qualName.substring(qualName.lastIndexOf('.') + 1);
9295

93-
while (enclosingTypes-- > 0) {
94-
className = pkgName.substring(qualName.lastIndexOf('.') + 1) + className;
95-
pkgName = pkgName.substring(0, pkgName.lastIndexOf('.'));
96-
qualName = pkgName + "." + className;
97-
}
96+
while (enclosingTypes-- > 0) {
97+
className = pkgName.substring(qualName.lastIndexOf('.') + 1) + className;
98+
pkgName = pkgName.substring(0, pkgName.lastIndexOf('.'));
99+
qualName = pkgName + "." + className;
100+
}
98101

99-
JavaFileObject file = processingEnv.getFiler().createSourceFile(qualName);
100-
try (CodeWriter w = new CodeWriter(file.openWriter())) {
101-
w.writeLn("// CheckStyle: start generated");
102-
w.writeLn("// Auto generated by GenerateEnumConstantsProcessor at %s", LocalDateTime.now());
103-
w.writeLn("package %s;", pkgName);
104-
w.writeLn();
105-
w.writeLn("public final class %s {", className);
106-
int i = 0;
107-
for (Element enumBit : el.getEnclosedElements()) {
108-
if (enumBit.getKind() == ElementKind.ENUM_CONSTANT) {
109-
String enumName = ((VariableElement) enumBit).getSimpleName().toString();
110-
try (Block b = w.newIndent()) {
111-
w.writeLn("public static final int %s = %d;", enumName, i++);
102+
JavaFileObject file = processingEnv.getFiler().createSourceFile(qualName);
103+
try (CodeWriter w = new CodeWriter(file.openWriter())) {
104+
w.writeLn("// CheckStyle: start generated");
105+
w.writeLn("// Auto generated by GenerateEnumConstantsProcessor at %s", LocalDateTime.now());
106+
w.writeLn("package %s;", pkgName);
107+
w.writeLn();
108+
w.writeLn("public final class %s {", className);
109+
int i = 0;
110+
for (Element enumBit : el.getEnclosedElements()) {
111+
if (enumBit.getKind() == ElementKind.ENUM_CONSTANT) {
112+
String enumName = ((VariableElement) enumBit).getSimpleName().toString();
113+
try (Block b = w.newIndent()) {
114+
int value = i++;
115+
if (useByte) {
116+
if (value <= 0xFF) {
117+
value = (byte) value;
118+
} else {
119+
throw new IllegalArgumentException("Enum constant doesn't fit into byte");
120+
}
112121
}
122+
w.writeLn("public static final %s %s = %d;", elementType, enumName, value);
113123
}
114124
}
115-
w.writeLn("}");
116125
}
117-
} catch (IOException e) {
118-
processingEnv.getMessager().printMessage(Kind.ERROR, e.getMessage(), el);
126+
w.writeLn("}");
119127
}
120-
} else {
121-
processingEnv.getMessager().printMessage(Kind.ERROR, "Can only annotate enums with @GenerateEnumConstants", el);
128+
} catch (IOException e) {
129+
processingEnv.getMessager().printMessage(Kind.ERROR, e.getMessage(), el);
122130
}
131+
} else {
132+
processingEnv.getMessager().printMessage(Kind.ERROR, "Can only annotate enums with @GenerateEnumConstants", el);
123133
}
124134
}
125135
return true;

graalpython/com.oracle.graal.python.test/testData/goldenFiles/CompilerTests/testAugAssignment.co

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Disassembly of <module>:
22
000000 0 LOAD_NAME 0 (a)
3-
000005 2 LOAD_DOUBLE 0 (12.0)
3+
000005 2 LOAD_DOUBLE_O 0 (12.0)
44
000000 4 BINARY_OP 1 (INPLACE_ADD)
55
000000 6 STORE_NAME 0 (a)
66
000000 8 LOAD_NONE

graalpython/com.oracle.graal.python.test/testData/goldenFiles/CompilerTests/testBenchmark.co

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,16 @@ Disassembly of docompute:
1717
000024 6 GET_ITER
1818
000024 >> 7 FOR_ITER 74 (to 81) can quicken
1919
000028 9 STORE_FAST 1 (i) generalizes: 7
20-
000060 11 LOAD_DOUBLE 0 (0.0)
21-
000053 13 STORE_FAST 2 (sum_)
20+
000060 11 LOAD_DOUBLE_D 0 (0.0) can quicken
21+
000053 13 STORE_FAST 2 (sum_) generalizes: 11
2222
000076 15 LOAD_BYTE_I 0 can quicken
2323
000072 17 STORE_FAST 3 (j) generalizes: 15
2424
000092 >> 19 LOAD_FAST 3 (j) can quicken
2525
000096 21 LOAD_FAST 0 (num) can quicken
2626
000092 23 BINARY_OP 14 (LT) can quicken, generalizes: 21, 19
2727
000086 25 POP_AND_JUMP_IF_FALSE 54 (to 79) generalizes: 23
2828
000113 29 LOAD_FAST 2 (sum_) can quicken
29-
000121 31 LOAD_DOUBLE 1 (1.0)
29+
000121 31 LOAD_DOUBLE_D 1 (1.0) can quicken
3030
000130 33 LOAD_FAST 1 (i) can quicken
3131
000134 35 LOAD_FAST 3 (j) can quicken
3232
000130 37 BINARY_OP 0 (ADD) can quicken, generalizes: 35, 33
@@ -41,8 +41,8 @@ Disassembly of docompute:
4141
000159 55 LOAD_FAST 1 (i) can quicken
4242
000128 57 BINARY_OP 0 (ADD) can quicken, generalizes: 55, 53
4343
000163 59 LOAD_BYTE_I 1 can quicken
44-
000128 61 BINARY_OP 0 (ADD) generalizes: 59, 57
45-
000121 63 BINARY_OP 8 (TRUEDIV) can quicken
44+
000128 61 BINARY_OP 0 (ADD) can quicken, generalizes: 59, 57
45+
000121 63 BINARY_OP 8 (TRUEDIV) can quicken, generalizes: 61, 31
4646
000113 65 BINARY_OP 1 (INPLACE_ADD) can quicken, generalizes: 63, 29
4747
000113 67 STORE_FAST 2 (sum_) generalizes: 65
4848
000178 69 LOAD_FAST 3 (j) can quicken
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
Disassembly of <module>:
2-
000001 0 LOAD_BYTE_O -1
3-
000006 2 LOAD_DOUBLE 0 (-7.0)
4-
000000 4 BINARY_OP 4 (MUL)
2+
000001 0 LOAD_BYTE_O -1 can quicken
3+
000006 2 LOAD_DOUBLE_O 0 (-7.0) can quicken
4+
000000 4 BINARY_OP 4 (MUL) generalizes: 2, 0
55
000000 6 RETURN_VALUE

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ private static Object[] extractConstants(RootNode node) {
330330
CodeUnit co = ((PBytecodeRootNode) rootNode).getCodeUnit();
331331
Set<Object> bytecodeConstants = new HashSet<>();
332332
for (int bci = 0; bci < co.code.length;) {
333-
OpCodes op = OpCodes.VALUES[co.code[bci]];
333+
OpCodes op = OpCodes.fromOpCode(co.code[bci]);
334334
if (op.quickens != null) {
335335
op = op.quickens;
336336
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/frame/PFrame.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,14 @@
4242

4343
import com.oracle.graal.python.PythonLanguage;
4444
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
45-
import com.oracle.graal.python.builtins.objects.code.PCode;
4645
import com.oracle.graal.python.builtins.objects.code.CodeNodes.GetCodeRootNode;
46+
import com.oracle.graal.python.builtins.objects.code.PCode;
4747
import com.oracle.graal.python.builtins.objects.frame.FrameBuiltins.GetLocalsNode;
4848
import com.oracle.graal.python.builtins.objects.function.PArguments;
4949
import com.oracle.graal.python.builtins.objects.object.PythonBuiltinObject;
5050
import com.oracle.graal.python.builtins.objects.object.PythonObject;
5151
import com.oracle.graal.python.nodes.PRootNode;
52+
import com.oracle.graal.python.nodes.bytecode.PBytecodeRootNode;
5253
import com.oracle.graal.python.runtime.object.PythonObjectFactory;
5354
import com.oracle.graal.python.util.PythonUtils;
5455
import com.oracle.truffle.api.CompilerAsserts;
@@ -220,6 +221,8 @@ public int getLine() {
220221
if (line == -2) {
221222
if (location == null) {
222223
line = -1;
224+
} else if (location instanceof PBytecodeRootNode) {
225+
return ((PBytecodeRootNode) location).bciToLine(lasti);
223226
} else {
224227
SourceSection sourceSection = location.getEncapsulatingSourceSection();
225228
if (sourceSection == null) {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ints/IntBuiltins.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1343,6 +1343,8 @@ PInt pos(PInt arg) {
13431343
@GenerateNodeFactory
13441344
@TypeSystemReference(PythonArithmeticTypes.class)
13451345
public abstract static class NegNode extends PythonUnaryBuiltinNode {
1346+
public abstract Object execute(int value);
1347+
13461348
@Specialization(rewriteOn = ArithmeticException.class)
13471349
static int neg(int arg) {
13481350
return Math.negateExact(arg);
@@ -1373,6 +1375,10 @@ PInt doPInt(PInt operand) {
13731375
static BigInteger negate(BigInteger value) {
13741376
return value.negate();
13751377
}
1378+
1379+
public static NegNode create() {
1380+
return IntBuiltinsFactory.NegNodeFactory.create();
1381+
}
13761382
}
13771383

13781384
@Builtin(name = J___INVERT__, minNumOfPositionalArgs = 1)

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/compiler/CodeUnit.java

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -143,10 +143,6 @@ public CodeUnit(TruffleString name, TruffleString qualname,
143143
this.generalizeVarsMap = generalizeVarsMap;
144144
}
145145

146-
OpCodes codeForBC(int bc) {
147-
return OpCodes.VALUES[bc];
148-
}
149-
150146
public int bciToSrcOffset(int bci) {
151147
int diffIdx = 0;
152148
int currentOffset = startOffset;
@@ -156,7 +152,7 @@ public int bciToSrcOffset(int bci) {
156152
if (bci <= i) {
157153
break;
158154
} else {
159-
OpCodes op = codeForBC(code[i]);
155+
OpCodes op = OpCodes.fromOpCode(code[i]);
160156
i += op.length();
161157
bytecodeNumber++;
162158
}
@@ -248,8 +244,7 @@ public String toString(byte[] bytecode) {
248244
int oparg = 0;
249245
while (bci < bytecode.length) {
250246
int bcBCI = bci;
251-
int bc = Byte.toUnsignedInt(bytecode[bci++]);
252-
OpCodes opcode = codeForBC(bc);
247+
OpCodes opcode = OpCodes.fromOpCode(bytecode[bci++]);
253248

254249
String[] line = lines.computeIfAbsent(bcBCI, k -> new String[DISASSEMBLY_NUM_COLUMNS]);
255250

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/compiler/CompilationUnit.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,10 @@ private void emitBytecode(Instruction instr, ByteArrayOutputStream buf) throws I
447447
opcode = (instr.quickenOutput & QuickeningTypes.INT) != 0 ? OpCodes.LOAD_BYTE_I : OpCodes.LOAD_BYTE_O;
448448
} else if (opcode == OpCodes.LOAD_INT) {
449449
opcode = (instr.quickenOutput & QuickeningTypes.INT) != 0 ? OpCodes.LOAD_INT_I : OpCodes.LOAD_INT_O;
450+
} else if (opcode == OpCodes.LOAD_LONG) {
451+
opcode = (instr.quickenOutput & QuickeningTypes.LONG) != 0 ? OpCodes.LOAD_LONG_L : OpCodes.LOAD_LONG_O;
452+
} else if (opcode == OpCodes.LOAD_DOUBLE) {
453+
opcode = (instr.quickenOutput & QuickeningTypes.DOUBLE) != 0 ? OpCodes.LOAD_DOUBLE_D : OpCodes.LOAD_DOUBLE_O;
450454
} else if (opcode == OpCodes.LOAD_TRUE) {
451455
opcode = (instr.quickenOutput & QuickeningTypes.BOOLEAN) != 0 ? OpCodes.LOAD_TRUE_B : OpCodes.LOAD_TRUE_O;
452456
} else if (opcode == OpCodes.LOAD_FALSE) {

0 commit comments

Comments
 (0)