Skip to content

Commit 795cb28

Browse files
raph-amiardHugoGGuerrier
authored andcommitted
Perf: Use specializations for selector's rec expr
1 parent 77f1480 commit 795cb28

File tree

3 files changed

+196
-119
lines changed

3 files changed

+196
-119
lines changed

lkql_jit/language/src/main/java/com/adacore/lkql_jit/langkit_translator/passes/TranslationPass.java

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121
import com.adacore.lkql_jit.nodes.arguments.ExprArg;
2222
import com.adacore.lkql_jit.nodes.arguments.NamedArg;
2323
import com.adacore.lkql_jit.nodes.declarations.*;
24-
import com.adacore.lkql_jit.nodes.declarations.selector.RecExpr;
24+
import com.adacore.lkql_jit.nodes.declarations.selector.RecExprs;
25+
import com.adacore.lkql_jit.nodes.declarations.selector.RecExprsFactory;
2526
import com.adacore.lkql_jit.nodes.declarations.selector.SelectorDeclaration;
2627
import com.adacore.lkql_jit.nodes.expressions.*;
2728
import com.adacore.lkql_jit.nodes.expressions.block_expression.BlockBody;
@@ -1134,22 +1135,21 @@ public LKQLNode visit(Liblkqllang.Query query) {
11341135

11351136
@Override
11361137
public LKQLNode visit(Liblkqllang.RecExpr recExpr) {
1137-
final boolean recurseHasUnpack = recExpr.fRecurseUnpack() instanceof
1138-
Liblkqllang.UnpackPresent;
1139-
final Expr recurseExpr = (Expr) recExpr.fRecurseExpr().accept(this);
1140-
1141-
final boolean resultHasUnpack = recExpr.fResultUnpack() instanceof
1142-
Liblkqllang.UnpackPresent;
1143-
final Expr resultExpr = recExpr.fResultExpr().isNone()
1144-
? null
1145-
: (Expr) recExpr.fResultExpr().accept(this);
1146-
return new RecExpr(
1147-
loc(recExpr),
1148-
recurseHasUnpack,
1149-
recurseExpr,
1150-
resultHasUnpack,
1151-
resultExpr
1152-
);
1138+
if (recExpr.fResultExpr().isNone()) {
1139+
return RecExprsFactory.UnaryRecExprNodeGen.create(
1140+
loc(recExpr),
1141+
recExpr.fRecurseUnpack() instanceof Liblkqllang.UnpackPresent,
1142+
(Expr) recExpr.fRecurseExpr().accept(this)
1143+
);
1144+
} else {
1145+
return new RecExprs.BinaryRecExpr(
1146+
loc(recExpr),
1147+
recExpr.fRecurseUnpack() instanceof Liblkqllang.UnpackPresent,
1148+
(Expr) recExpr.fRecurseExpr().accept(this),
1149+
recExpr.fResultUnpack() instanceof Liblkqllang.UnpackPresent,
1150+
(Expr) recExpr.fResultExpr().accept(this)
1151+
);
1152+
}
11531153
}
11541154

11551155
// --- Lists

lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/declarations/selector/RecExpr.java

Lines changed: 0 additions & 102 deletions
This file was deleted.
Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
//
2+
// Copyright (C) 2005-2025, AdaCore
3+
// SPDX-License-Identifier: GPL-3.0-or-later
4+
//
5+
6+
package com.adacore.lkql_jit.nodes.declarations.selector;
7+
8+
import com.adacore.lkql_jit.LKQLTypeSystemGen;
9+
import com.adacore.lkql_jit.exception.LKQLRuntimeException;
10+
import com.adacore.lkql_jit.nodes.expressions.Expr;
11+
import com.adacore.lkql_jit.runtime.values.LKQLRecValue;
12+
import com.adacore.lkql_jit.runtime.values.lists.BaseLKQLList;
13+
import com.adacore.lkql_jit.utils.LKQLTypesHelper;
14+
import com.oracle.truffle.api.CompilerDirectives;
15+
import com.oracle.truffle.api.dsl.Fallback;
16+
import com.oracle.truffle.api.dsl.NodeChild;
17+
import com.oracle.truffle.api.dsl.Specialization;
18+
import com.oracle.truffle.api.frame.VirtualFrame;
19+
import com.oracle.truffle.api.nodes.Node;
20+
import com.oracle.truffle.api.source.SourceSection;
21+
22+
/**
23+
* Container class: contains every node class for rec expressions in selectors.
24+
*/
25+
public class RecExprs {
26+
27+
/**
28+
* Node for rec expression with only one parameter.
29+
*/
30+
@NodeChild(value = "expr", type = Expr.class)
31+
public abstract static class UnaryRecExpr extends Expr {
32+
33+
@CompilerDirectives.CompilationFinal
34+
private final boolean unpack;
35+
36+
public UnaryRecExpr(SourceSection location, boolean unpack) {
37+
super(location);
38+
this.unpack = unpack;
39+
}
40+
41+
@SuppressWarnings("unused")
42+
public boolean hasUnpack() {
43+
return unpack;
44+
}
45+
46+
@Specialization(guards = "hasUnpack()")
47+
public Object unpack(BaseLKQLList val) {
48+
return new LKQLRecValue(val.getContent(), val.getContent());
49+
}
50+
51+
@Specialization(guards = "!hasUnpack()")
52+
public Object noUnpack(Object val) {
53+
Object[] valArray;
54+
if (LKQLTypeSystemGen.isNullish(val)) {
55+
valArray = new Object[0];
56+
} else {
57+
valArray = new Object[] { val };
58+
}
59+
60+
return new LKQLRecValue(valArray, valArray);
61+
}
62+
63+
@Fallback
64+
public Object error(Object val) {
65+
assert unpack;
66+
throw LKQLRuntimeException.wrongType(
67+
LKQLTypesHelper.LKQL_ITERABLE,
68+
LKQLTypesHelper.fromJava(val),
69+
this
70+
);
71+
}
72+
73+
@Override
74+
public String toString(int indentLevel) {
75+
return null;
76+
}
77+
}
78+
79+
/**
80+
* Node for one parameter of a rec expression with two parameters (either
81+
* the recurse part or the result part).
82+
*/
83+
public abstract static class SubRecExpr extends Node {
84+
85+
@CompilerDirectives.CompilationFinal
86+
private final boolean unpack;
87+
88+
private final SourceSection location;
89+
90+
@Override
91+
public SourceSection getSourceSection() {
92+
return location;
93+
}
94+
95+
protected SubRecExpr(SourceSection location, boolean unpack) {
96+
this.location = location;
97+
this.unpack = unpack;
98+
}
99+
100+
public abstract Object[] execute(Object value);
101+
102+
@SuppressWarnings("unused")
103+
public boolean hasUnpack() {
104+
return unpack;
105+
}
106+
107+
@Specialization(guards = "hasUnpack()")
108+
public Object[] unpack(BaseLKQLList val) {
109+
return val.getContent();
110+
}
111+
112+
@Specialization(guards = "!hasUnpack()")
113+
public Object[] noUnpack(Object val) {
114+
if (LKQLTypeSystemGen.isNullish(val)) {
115+
return new Object[0];
116+
} else {
117+
return new Object[] { val };
118+
}
119+
}
120+
121+
@Fallback
122+
public Object[] error(Object val) {
123+
assert unpack;
124+
throw LKQLRuntimeException.wrongType(
125+
LKQLTypesHelper.LKQL_ITERABLE,
126+
LKQLTypesHelper.fromJava(val),
127+
this
128+
);
129+
}
130+
}
131+
132+
/**
133+
* Rec expr with both a recurse and a result sub-expression.
134+
*/
135+
public static class BinaryRecExpr extends Expr {
136+
137+
@Child
138+
private Expr recurseExpr;
139+
140+
@Child
141+
private Expr resultExpr;
142+
143+
private final SubRecExpr recurseSubRecExpr;
144+
private final SubRecExpr resultSubRecExpr;
145+
146+
public BinaryRecExpr(
147+
SourceSection location,
148+
boolean recurseHasUnpack,
149+
Expr recurseExpr,
150+
boolean resultHasUnpack,
151+
Expr resultExpr
152+
) {
153+
super(location);
154+
this.recurseExpr = recurseExpr;
155+
this.recurseSubRecExpr = RecExprsFactory.SubRecExprNodeGen.create(
156+
recurseExpr.getSourceSection(),
157+
recurseHasUnpack
158+
);
159+
this.resultSubRecExpr = RecExprsFactory.SubRecExprNodeGen.create(
160+
resultExpr.getSourceSection(),
161+
resultHasUnpack
162+
);
163+
164+
this.resultExpr = resultExpr;
165+
}
166+
167+
@Override
168+
public Object executeGeneric(VirtualFrame frame) {
169+
var recurseVal = recurseSubRecExpr.execute(recurseExpr.executeGeneric(frame));
170+
var resultVal = resultSubRecExpr.execute(resultExpr.executeGeneric(frame));
171+
return new LKQLRecValue(recurseVal, resultVal);
172+
}
173+
174+
@Override
175+
public String toString(int indentLevel) {
176+
return null;
177+
}
178+
}
179+
}

0 commit comments

Comments
 (0)