Skip to content

Commit 90d42e7

Browse files
committed
Add constant operand benchmark.
1 parent 423c7ff commit 90d42e7

File tree

1 file changed

+212
-0
lines changed

1 file changed

+212
-0
lines changed
Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
/*
2+
* Copyright (c) 2025, 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 org.graalvm.truffle.benchmark.bytecode_dsl;
42+
43+
import org.graalvm.truffle.benchmark.TruffleBenchmark;
44+
import org.openjdk.jmh.annotations.Benchmark;
45+
import org.openjdk.jmh.annotations.Measurement;
46+
import org.openjdk.jmh.annotations.Param;
47+
import org.openjdk.jmh.annotations.Scope;
48+
import org.openjdk.jmh.annotations.Setup;
49+
import org.openjdk.jmh.annotations.State;
50+
import org.openjdk.jmh.annotations.Warmup;
51+
52+
import com.oracle.truffle.api.RootCallTarget;
53+
import com.oracle.truffle.api.bytecode.BytecodeConfig;
54+
import com.oracle.truffle.api.bytecode.BytecodeLocal;
55+
import com.oracle.truffle.api.bytecode.BytecodeRootNode;
56+
import com.oracle.truffle.api.bytecode.ConstantOperand;
57+
import com.oracle.truffle.api.bytecode.GenerateBytecode;
58+
import com.oracle.truffle.api.bytecode.GenerateBytecodeTestVariants;
59+
import com.oracle.truffle.api.bytecode.GenerateBytecodeTestVariants.Variant;
60+
import com.oracle.truffle.api.bytecode.Operation;
61+
import com.oracle.truffle.api.dsl.Specialization;
62+
import com.oracle.truffle.api.frame.FrameDescriptor;
63+
import com.oracle.truffle.api.nodes.RootNode;
64+
65+
@State(Scope.Benchmark)
66+
@Warmup(iterations = 10, time = 1)
67+
@Measurement(iterations = 5, time = 1)
68+
public class ConstantOperandBenchmark extends TruffleBenchmark {
69+
RootCallTarget rootCallTarget;
70+
71+
@Param({"ConstantOperandBenchmarkRootNodeRegular", "ConstantOperandBenchmarkRootNodeInlined"}) private String implClassName;
72+
73+
@SuppressWarnings("unchecked")
74+
private Class<? extends ConstantOperandBenchmarkRootNode> getImplClass() {
75+
try {
76+
return (Class<? extends ConstantOperandBenchmarkRootNode>) Class.forName(ConstantOperandBenchmark.class.getPackageName() + "." + implClassName);
77+
} catch (ClassNotFoundException e) {
78+
throw new RuntimeException("Could not load bytecode class " + implClassName, e);
79+
}
80+
}
81+
82+
@Setup
83+
public void parseRootNode() {
84+
rootCallTarget = ConstantOperandBenchmarkRootNodeBuilder.invokeCreate(getImplClass(), null, BytecodeConfig.DEFAULT, b -> {
85+
b.beginRoot();
86+
b.beginBlock();
87+
88+
BytecodeLocal x = b.createLocal();
89+
b.beginStoreLocal(x);
90+
b.emitLoadConstant(0);
91+
b.endStoreLocal();
92+
93+
BytecodeLocal count = b.createLocal();
94+
b.beginStoreLocal(count);
95+
b.emitLoadConstant(0);
96+
b.endStoreLocal();
97+
98+
b.beginWhile();
99+
100+
b.beginLt();
101+
b.emitLoadLocal(count);
102+
b.emitLoadArgument(0);
103+
b.endLt();
104+
105+
b.beginBlock();
106+
b.beginStoreLocal(x);
107+
b.beginAddMany(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
108+
b.emitLoadLocal(x);
109+
b.endAddMany();
110+
b.endStoreLocal();
111+
112+
b.beginStoreLocal(count);
113+
b.beginAdd(1);
114+
b.emitLoadLocal(count);
115+
b.endAdd();
116+
b.endStoreLocal();
117+
b.endBlock();
118+
119+
b.endWhile();
120+
121+
b.beginReturn();
122+
b.emitLoadLocal(x);
123+
b.endReturn();
124+
125+
b.endBlock();
126+
b.endRoot();
127+
}).getNode(0).getCallTarget();
128+
}
129+
130+
static final int ITERS = 1_000_000;
131+
132+
@Benchmark
133+
public void execute() {
134+
Object result = rootCallTarget.call(ITERS);
135+
if ((int) result != ITERS * 30) {
136+
throw new AssertionError("bad result: " + result);
137+
}
138+
}
139+
140+
@GenerateBytecodeTestVariants({
141+
@Variant(suffix = "Regular", configuration = @GenerateBytecode(languageClass = BenchmarkLanguage.class, inlinePrimitiveConstants = false)),
142+
@Variant(suffix = "Inlined", configuration = @GenerateBytecode(languageClass = BenchmarkLanguage.class))
143+
})
144+
public abstract static class ConstantOperandBenchmarkRootNode extends RootNode implements BytecodeRootNode {
145+
146+
protected ConstantOperandBenchmarkRootNode(BenchmarkLanguage language, FrameDescriptor frameDescriptor) {
147+
super(language, frameDescriptor);
148+
}
149+
150+
@ConstantOperand(type = int.class)
151+
@Operation
152+
public static final class Add {
153+
@Specialization
154+
public static int doInt(int n, int x) {
155+
return n + x;
156+
}
157+
}
158+
159+
@Operation
160+
public static final class Lt {
161+
@Specialization
162+
public static boolean doInt(int x, int y) {
163+
return x < y;
164+
}
165+
}
166+
167+
@ConstantOperand(type = int.class)
168+
@ConstantOperand(type = int.class)
169+
@ConstantOperand(type = int.class)
170+
@ConstantOperand(type = int.class)
171+
@ConstantOperand(type = int.class)
172+
@ConstantOperand(type = int.class)
173+
@ConstantOperand(type = int.class)
174+
@ConstantOperand(type = int.class)
175+
@ConstantOperand(type = int.class)
176+
@ConstantOperand(type = int.class)
177+
@ConstantOperand(type = int.class)
178+
@ConstantOperand(type = int.class)
179+
@ConstantOperand(type = int.class)
180+
@ConstantOperand(type = int.class)
181+
@ConstantOperand(type = int.class)
182+
@ConstantOperand(type = int.class)
183+
@ConstantOperand(type = int.class)
184+
@ConstantOperand(type = int.class)
185+
@ConstantOperand(type = int.class)
186+
@ConstantOperand(type = int.class)
187+
@ConstantOperand(type = int.class)
188+
@ConstantOperand(type = int.class)
189+
@ConstantOperand(type = int.class)
190+
@ConstantOperand(type = int.class)
191+
@ConstantOperand(type = int.class)
192+
@ConstantOperand(type = int.class)
193+
@ConstantOperand(type = int.class)
194+
@ConstantOperand(type = int.class)
195+
@ConstantOperand(type = int.class)
196+
@ConstantOperand(type = int.class)
197+
@Operation
198+
public static final class AddMany {
199+
@Specialization
200+
public static int doAdd(int n1, int n2, int n3, int n4, int n5, int n6, int n7, int n8, int n9, int n10, //
201+
int n11, int n12, int n13, int n14, int n15, int n16, int n17, int n18, int n19, int n20, //
202+
int n21, int n22, int n23, int n24, int n25, int n26, int n27, int n28, int n29, int n30, int x) {
203+
return n1 + n2 + n3 + n4 + n5 + n6 + n7 + n8 + n9 + n10 + //
204+
n11 + n12 + n13 + n14 + n15 + n16 + n17 + n18 + n19 + n20 + //
205+
n21 + n22 + n23 + n24 + n25 + n26 + n27 + n28 + n29 + n30 + //
206+
x;
207+
}
208+
}
209+
210+
}
211+
212+
}

0 commit comments

Comments
 (0)