Skip to content

Commit 4efe59c

Browse files
committed
Merge branch 'topic/opt_clean' into 'master'
LKQL JIT optimization See merge request eng/libadalang/langkit-query-language!506
2 parents 5627bf5 + 5f00b62 commit 4efe59c

File tree

150 files changed

+2282
-2216
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

150 files changed

+2282
-2216
lines changed

lkql/build/railroad-diagrams/term.svg

Lines changed: 6 additions & 6 deletions
Loading

lkql/lkql.lkt

Lines changed: 26 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
lexer lkql_lexer {
22

3-
BigLongRArrow
43
@trivia()
54
Whitespace <- p"[ \\t\\n\\r]"
65
Dot <- "."
@@ -39,57 +38,32 @@ lexer lkql_lexer {
3938
LArrow <- "<-"
4039
BigRArrow <- "=>"
4140
Box <- "<>"
42-
@symbol()
43-
Let <- "let"
44-
@symbol()
45-
SelectTok <- "select"
46-
@symbol()
47-
FromTok <- "from"
48-
@symbol()
49-
ThroughTok <- "through"
50-
@symbol()
51-
When <- "when"
52-
@symbol()
53-
Val <- "val"
54-
@symbol()
55-
Fun <- "fun"
56-
@symbol()
57-
Import <- "import"
58-
@symbol()
59-
Selector <- "selector"
60-
@symbol()
61-
Match <- "match"
62-
@symbol()
63-
Rec <- "rec"
64-
@symbol()
65-
For <- "for"
66-
@symbol()
67-
Skip <- "skip"
68-
@symbol()
69-
Is <- "is"
70-
@symbol()
71-
In <- "in"
72-
@symbol()
73-
TrueLit <- "true"
74-
@symbol()
75-
FalseLit <- "false"
76-
@symbol()
77-
If <- "if"
78-
@symbol()
79-
Else <- "else"
80-
@symbol()
81-
Then <- "then"
82-
@symbol()
83-
Not <- "not"
84-
@symbol()
85-
Null <- "null"
86-
@symbol()
87-
New <- "new"
41+
@symbol() Let <- "let"
42+
@symbol() SelectTok <- "select"
43+
@symbol() FromTok <- "from"
44+
@symbol() ThroughTok <- "through"
45+
@symbol() When <- "when"
46+
@symbol() Val <- "val"
47+
@symbol() Fun <- "fun"
48+
@symbol() Import <- "import"
49+
@symbol() Selector <- "selector"
50+
@symbol() Match <- "match"
51+
@symbol() Rec <- "rec"
52+
@symbol() For <- "for"
53+
@symbol() Skip <- "skip"
54+
@symbol() Is <- "is"
55+
@symbol() In <- "in"
56+
@symbol() TrueLit <- "true"
57+
@symbol() FalseLit <- "false"
58+
@symbol() If <- "if"
59+
@symbol() Else <- "else"
60+
@symbol() Then <- "then"
61+
@symbol() Not <- "not"
62+
@symbol() Null <- "null"
63+
@symbol() New <- "new"
8864
Integer <- p"[0-9]+"
89-
@symbol()
90-
Identifier <- p"[a-z][A-Za-z0-9_]*"
91-
@symbol()
92-
UpperIdentifier <- p"[A-Za-z][A-Za-z0-9_]*"
65+
@symbol() Identifier <- p"[a-z][A-Za-z0-9_]*"
66+
@symbol() UpperIdentifier <- p"[A-Za-z][A-Za-z0-9_]*"
9367
String <- p"\"(\\\\.|[^\"])*\""
9468
@trivia()
9569
Comment <- p"#(.?)+"
@@ -245,10 +219,10 @@ grammar lkql_grammar {
245219
| string_literal
246220
| block_string_literal
247221
| bool_literal
248-
| unit_literal
249222
| NullLiteral("null")
250223
| integer
251224
| anonymous_function
225+
| unit_literal
252226
| pick("(" expr ")")
253227
| if_then_else
254228
| block_expr

lkql_checker/share/lkql/stdlib.lkql

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
|" These functions may be moved in the future in Libadalang or LKQL's builtin
55
|" library.
66

7+
import stdlib_internal
8+
79
selector super_types
810
|" Yields the chain of super types of the given type, as viewed from that
911
|" type. Hence, for a type T which public view derives from a type A but
@@ -33,15 +35,10 @@ selector semantic_parent
3335
| null => ()
3436
| * => rec(this.p_semantic_parent())
3537

36-
selector children_no_nested
38+
fun children_no_nested(node) =
3739
|" Return all children nodes starting from a base subprogram body, but not
3840
|" entering in nested bodies.
39-
40-
| BodyNode =>
41-
# Don't recurse on bodies except if it's the root node (depth == 0)
42-
rec(*if depth == 0 then this.children else [])
43-
| null => ()
44-
| * => rec(*this.children)
41+
stdlib_internal.children_no_nested_implem((node, true))
4542

4643
fun all(iterable) =
4744
|" Return whether all elements in the given iterable are truthy
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
selector children_no_nested_implem
2+
|" Internal implementation selector for `children_no_nested`
3+
# Don't recurse on bodies except if it's the root node (depth == 0)
4+
| (BodyNode, false) => rec(())
5+
| (n@AdaNode, *) => rec(*[(c, false) for c in n.children], *n.children)
6+
7+
# TODO: This branch shouldn't ever be taken, but we miss a raise expression
8+
# to verify it
9+
| * => rec(())

lkql_jit/benchmarks/src/test/java/com/adacore/lkql_jit/TruffleBenchmark.java

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,16 @@
1212
/** This class is the base for all Truffle benchmarks. */
1313
@Warmup(iterations = 5, time = 1)
1414
@Measurement(iterations = 5, time = 1)
15-
@Fork(value = 1, jvmArgsAppend = "-Dgraalvm.locatorDisabled=true")
15+
@Fork(
16+
value = 1,
17+
jvmArgsAppend = {
18+
"-Dgraalvm.locatorDisabled=true",
19+
// NOTE: If you need to debug truffle benchmarks you can add the following options
20+
// "-Dgraal.Dump=Truffle:1",
21+
// "-Dgraal.PrintGraph=Network",
22+
"--add-opens=org.graalvm.truffle/com.oracle.truffle.api.strings=ALL-UNNAMED",
23+
}
24+
)
1625
@BenchmarkMode(Mode.AverageTime)
1726
@OutputTimeUnit(TimeUnit.MICROSECONDS)
1827
@State(Scope.Benchmark)
@@ -27,9 +36,18 @@ public class TruffleBenchmark {
2736

2837
@Setup
2938
public void setup() {
30-
this.context = Context.create();
39+
final var contextBuilder = Context.newBuilder("lkql", "js", "sl");
40+
configure(contextBuilder);
41+
context = contextBuilder.build();
42+
pre();
3143
}
3244

45+
/** Provide a hook to pass custom options to the contextBuilder in benchmarks */
46+
public void configure(Context.Builder contextBuilder) {}
47+
48+
/** Provide a hook to run arbitrary setup code before running the benchmark */
49+
public void pre() {}
50+
3351
@TearDown
3452
public void tearDown() {
3553
this.context.close();
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
//
2+
// Copyright (C) 2005-2025, AdaCore
3+
// SPDX-License-Identifier: GPL-3.0-or-later
4+
//
5+
6+
package com.adacore.lkql_jit.benchmarks;
7+
8+
import com.adacore.lkql_jit.TruffleBenchmark;
9+
import org.openjdk.jmh.annotations.Benchmark;
10+
11+
public class ClosureBenchmark extends TruffleBenchmark {
12+
13+
private static final String lkqlClosure =
14+
"""
15+
fun foo(v) = {
16+
fun bar(w) = {
17+
fun baz(x) = {
18+
v + w + x
19+
};
20+
baz
21+
};
22+
bar
23+
}
24+
25+
val clos = foo(12)(13)
26+
fun r() = clos(14)
27+
repeat(1000000, r)
28+
""";
29+
30+
private static final String jsClosure =
31+
"""
32+
function foo(v) {
33+
function bar(w) {
34+
function baz(x) {
35+
return v + w + x;
36+
}
37+
return baz;
38+
}
39+
return bar;
40+
}
41+
42+
var clos = foo(12)(13)
43+
44+
function r() {
45+
return clos(14)
46+
}
47+
48+
for (let i = 0; i < 1000000; i++) {
49+
r()
50+
}
51+
""";
52+
53+
// ----- Benchmark methods -----
54+
55+
@Benchmark
56+
public void truffle_lkql() {
57+
this.context.eval("lkql", lkqlClosure);
58+
}
59+
60+
@Benchmark
61+
public void truffle_js() {
62+
this.context.eval("js", jsClosure);
63+
}
64+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
//
2+
// Copyright (C) 2005-2025, AdaCore
3+
// SPDX-License-Identifier: GPL-3.0-or-later
4+
//
5+
6+
package com.adacore.lkql_jit.benchmarks;
7+
8+
import com.adacore.lkql_jit.TruffleBenchmark;
9+
import org.openjdk.jmh.annotations.Benchmark;
10+
11+
public class ClosureCreationBenchmark extends TruffleBenchmark {
12+
13+
@Benchmark
14+
public void truffle_js() {
15+
this.context.eval(
16+
"js",
17+
"""
18+
function foo(v) {
19+
function bar(w) {
20+
function baz(x) {
21+
return v + w + x;
22+
}
23+
return baz;
24+
}
25+
return bar;
26+
}
27+
28+
for (let i = 0; i < 10000; i++) {
29+
foo(12)(13)(14)
30+
}
31+
"""
32+
);
33+
}
34+
35+
@Benchmark
36+
public void truffle_lkql() {
37+
this.context.eval(
38+
"lkql",
39+
"""
40+
fun foo(v) = {
41+
fun bar(w) = {
42+
fun baz(x) = {
43+
v + w + x
44+
};
45+
baz
46+
};
47+
bar
48+
}
49+
50+
repeat(10000, () => foo(12)(13)(14))
51+
"""
52+
);
53+
}
54+
}

lkql_jit/cli/src/main/java/com/adacore/lkql_jit/cli/BaseLKQLChecker.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,7 @@ public abstract class BaseLKQLChecker extends AbstractLanguageLauncher {
3232
public static final String checkerSource =
3333
"""
3434
val analysis_units = specified_units()
35-
val roots = [unit.root for unit in analysis_units]
36-
37-
map(roots, (root) => node_checker(root))
35+
map(analysis_units, (unit) => node_checker(unit.root))
3836
map(analysis_units, (unit) => unit_checker(unit))
3937
""";
4038

0 commit comments

Comments
 (0)