Skip to content

Commit 5af3d82

Browse files
authored
Merge pull request #64 from OpenVADL/feature/optimze-arithmetic-truncate
iss: Optimize generated ISS and extend CLI to skip optimizations
2 parents ed85e5a + 90588fb commit 5af3d82

37 files changed

+1063
-167
lines changed

.github/workflows/build-riscv-toolchain.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,7 @@ jobs:
3030
needs: build
3131
uses: ./.github/workflows/reusable-image-merge.yml
3232
with:
33-
image: ghcr.io/openvadl/riscv-toolchain
33+
image: ghcr.io/openvadl/riscv-toolchain
34+
tags: |
35+
latest
36+
medany-rv32i-rv32im-rv32impriv-rv64i-rv64im-rv64impriv

.github/workflows/reusable-image-merge.yml

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@ on:
1010
description: 'The name of the image'
1111
required: true
1212
type: string
13+
tags:
14+
description: 'Tags in metadata-action format'
15+
required: false
16+
type: string
17+
default: latest
1318

1419
jobs:
1520
merge:
@@ -44,11 +49,7 @@ jobs:
4449
uses: docker/metadata-action@v5
4550
with:
4651
images: ${{ inputs.image }}
47-
tags: |
48-
type=ref,event=branch
49-
type=ref,event=pr
50-
type=semver,pattern={{version}}
51-
type=semver,pattern={{major}}.{{minor}}
52+
tags: ${{ inputs.tags }}
5253

5354
- name: Create manifest list and push
5455
working-directory: ${{ runner.temp }}/digests

java-annotations/main/vadl/javaannotations/HandlerProcessor.java

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.io.IOException;
2121
import java.io.Writer;
2222
import java.util.ArrayList;
23+
import java.util.Comparator;
2324
import java.util.HashMap;
2425
import java.util.HashSet;
2526
import java.util.List;
@@ -43,6 +44,7 @@
4344
import javax.lang.model.element.Modifier;
4445
import javax.lang.model.element.TypeElement;
4546
import javax.lang.model.element.VariableElement;
47+
import javax.lang.model.type.DeclaredType;
4648
import javax.lang.model.type.TypeKind;
4749
import javax.lang.model.type.TypeMirror;
4850
import javax.lang.model.util.Elements;
@@ -497,20 +499,11 @@ private void generateDispatcher(TypeElement handlerClass, TypeMirror baseType,
497499
+ " handler, " + contextParams + baseTypeName
498500
+ " obj) {\n");
499501

500-
// Sort handler methods by specificity
502+
// Sort handler methods by subtypes (more specific types at start)
501503
List<HandlerMethod> sortedHandlerMethods = new ArrayList<>(handlerMethods.values());
502-
sortedHandlerMethods.sort((hm1, hm2) -> {
503-
TypeMirror type1 = hm1.handleType;
504-
TypeMirror type2 = hm2.handleType;
505-
506-
if (typeUtils.isSubtype(type1, type2) && !typeUtils.isSameType(type1, type2)) {
507-
return -1; // type1 is more specific
508-
} else if (typeUtils.isSubtype(type2, type1) && !typeUtils.isSameType(type1, type2)) {
509-
return 1; // type2 is more specific
510-
} else {
511-
return 0; // Unrelated types
512-
}
513-
});
504+
sortedHandlerMethods.sort(Comparator.comparingInt(
505+
hm -> -getInheritanceDepth(hm.handleType)) // negative inheritance
506+
);
514507

515508
var contextParamNames =
516509
contextTypes.stream().map(p -> typeMirrorSimpleName(p).toLowerCase() + ", ")
@@ -565,6 +558,15 @@ private void generateDispatcher(TypeElement handlerClass, TypeMirror baseType,
565558
}
566559
}
567560

561+
private int getInheritanceDepth(TypeMirror type) {
562+
int depth = 0;
563+
while (type != null && !type.toString().equals(Object.class.getName())) {
564+
depth++;
565+
type = ((TypeElement) ((DeclaredType) type).asElement()).getSuperclass();
566+
}
567+
return depth;
568+
}
569+
568570
private String typeMirrorSimpleName(TypeMirror typeMirror) {
569571
return typeMirror.toString().substring(typeMirror.toString().lastIndexOf('.') + 1);
570572
}
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
// SPDX-FileCopyrightText : © 2025 TU Wien <vadl@tuwien.ac.at>
2+
// SPDX-License-Identifier: GPL-3.0-or-later
3+
//
4+
// This program is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// This program is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU General Public License
15+
// along with this program. If not, see <https://www.gnu.org/licenses/>.
16+
17+
package vadl.cli;
18+
19+
import java.util.Arrays;
20+
import java.util.Comparator;
21+
import java.util.Iterator;
22+
import java.util.stream.Collectors;
23+
import javax.annotation.Nonnull;
24+
import org.apache.commons.lang3.stream.Streams;
25+
import picocli.CommandLine;
26+
import vadl.configuration.IssConfiguration;
27+
28+
class Helpers {
29+
}
30+
31+
32+
class IssOptsConverter implements CommandLine.ITypeConverter<IssConfiguration.IssOptsToSkip>,
33+
Iterable<String> {
34+
35+
@Override
36+
public IssConfiguration.IssOptsToSkip convert(String value) {
37+
if (value.equals("help")) {
38+
// Calculate the maximum width of option names
39+
int maxOptionLength = Arrays.stream(IssConfiguration.IssOptsToSkip.values())
40+
.map(opt -> toCliName(opt).length())
41+
.max(Integer::compare)
42+
.orElse(0);
43+
44+
// Define the indentation for descriptions
45+
int descriptionIndent = 6 + maxOptionLength; // 6 accounts for " - " and two spaces
46+
47+
// Print help message for available options
48+
System.out.println("Available optimizations to skip:");
49+
Arrays.stream(IssConfiguration.IssOptsToSkip.values())
50+
.sorted(Comparator.comparing(v -> v.name()))
51+
.forEach(opt ->
52+
printFormattedOption(toCliName(opt), opt.desc, maxOptionLength,
53+
descriptionIndent));
54+
55+
System.exit(0);
56+
}
57+
58+
try {
59+
return IssConfiguration.IssOptsToSkip.valueOf(value.toUpperCase().replace('-', '_'));
60+
} catch (IllegalArgumentException e) {
61+
throw new CommandLine.TypeConversionException(
62+
"\nAvailable options are %s".formatted(
63+
Streams.of(iterator()).sorted().collect(Collectors.joining(", "))
64+
)
65+
);
66+
}
67+
}
68+
69+
@Nonnull
70+
@Override
71+
public Iterator<String> iterator() {
72+
return Arrays.stream(IssConfiguration.IssOptsToSkip.values())
73+
.map(this::toCliName)
74+
.sorted()
75+
.iterator();
76+
}
77+
78+
private String toCliName(IssConfiguration.IssOptsToSkip value) {
79+
return value.name().toLowerCase().replace('_', '-');
80+
}
81+
82+
private static void printFormattedOption(String optionName, String description, int nameWidth,
83+
int descriptionIndent) {
84+
// Split the description into lines
85+
String[] lines = description.split("\n", -1);
86+
87+
// Print the first line with the option name
88+
System.out.printf(" - %-" + nameWidth + "s %s%n", optionName, lines[0]);
89+
90+
// Print subsequent lines with indentation
91+
String format = "%" + (descriptionIndent + 2) + "s%s%n";
92+
for (int i = 1; i < lines.length; i++) {
93+
System.out.printf(format, "", lines[i]);
94+
}
95+
}
96+
}

vadl-cli/main/vadl/cli/IssCommand.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import java.nio.file.Files;
2727
import java.nio.file.Path;
2828
import java.security.NoSuchAlgorithmException;
29+
import java.util.EnumSet;
2930
import org.apache.commons.io.file.PathUtils;
3031
import picocli.CommandLine;
3132
import picocli.CommandLine.Command;
@@ -54,6 +55,14 @@ public class IssCommand extends BaseCommand {
5455
description = "Download and prepare QEMU before generating ISS.")
5556
private boolean init;
5657

58+
@CommandLine.Option(names = "--skip",
59+
description = "Optimizations to be skipped. Valid values: ${COMPLETION-CANDIDATES}",
60+
split = ",",
61+
converter = IssOptsConverter.class, completionCandidates = IssOptsConverter.class
62+
)
63+
private EnumSet<IssConfiguration.IssOptsToSkip> skipOpts = EnumSet.noneOf(
64+
IssConfiguration.IssOptsToSkip.class);
65+
5766
private static final String QEMU_VERSION = "9.2.2";
5867
private static final String QEMU_DOWNLOAD_URL =
5968
"https://github.com/qemu/qemu/archive/refs/tags/v" + QEMU_VERSION + ".tar.gz";
@@ -65,11 +74,14 @@ public class IssCommand extends BaseCommand {
6574
PassOrder passOrder(GeneralConfiguration configuration) throws IOException {
6675
var issConfig = new IssConfiguration(configuration);
6776
issConfig.setDryRun(dryRun);
77+
issConfig.setOptsToSkip(skipOpts);
6878
return PassOrders.iss(issConfig);
6979
}
7080

7181
@Override
7282
public Integer call() {
83+
// the ISS may perform a QEMU setup if --init is set.
84+
// this must be done before anything else.
7385
if (!setup()) {
7486
// if setup failed, return exit code 1
7587
return 1;

vadl/main/resources/templates/htmlDump/index.html

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
<!-- SPDX-FileCopyrightText : © 2025 TU Wien <vadl@tuwien.ac.at> -->
2+
<!-- SPDX-License-Identifier: GPL-3.0-or-later -->
3+
<!-- -->
4+
<!-- This program is free software: you can redistribute it and/or modify -->
5+
<!-- it under the terms of the GNU General Public License as published by -->
6+
<!-- the Free Software Foundation, either version 3 of the License, or -->
7+
<!-- (at your option) any later version. -->
8+
<!-- -->
9+
<!-- This program is distributed in the hope that it will be useful, -->
10+
<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of -->
11+
<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -->
12+
<!-- GNU General Public License for more details. -->
13+
<!-- -->
14+
<!-- You should have received a copy of the GNU General Public License -->
15+
<!-- along with this program. If not, see <https://www.gnu.org/licenses/>. -->
16+
117
<!DOCTYPE html>
218
<html lang="en">
319
<head>
@@ -16,6 +32,9 @@
1632
padding: 0.125rem 0.625rem;
1733
border-radius: 0.25rem;
1834
}
35+
.badge-orange {
36+
background-color: rgb(255 207 181);
37+
}
1938
.graph-container > svg {
2039
height: 100%;
2140
width: 100%;
@@ -87,6 +106,7 @@ <h4 class="text-md font-semibold tracking-wide text-gray-900">[[${singlePass.pas
87106
<span class="badge text-blue-800 text-sm">[[${singlePass.pass.className}]]</span>
88107
</div>
89108
</div>
109+
<span th:if="${singlePass.skipped}" class="badge badge-orange text-sm text-orange-800 ml-auto mr-5">Skipped</span>
90110
<i th:if="${hasLink}" class="fa-solid fa-book-open ml-auto mr-5"></i>
91111
</div>
92112

vadl/main/vadl/configuration/IssConfiguration.java

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package vadl.configuration;
1818

19+
import java.util.EnumSet;
1920
import vadl.iss.passes.tcgLowering.Tcg_32_64;
2021

2122
/**
@@ -25,10 +26,29 @@
2526
*/
2627
public class IssConfiguration extends GeneralConfiguration {
2728

29+
/**
30+
* ISS optimization that can be skipped using the CLI.
31+
*/
32+
public enum IssOptsToSkip {
33+
OPT_BUILT_INS("QEMU specific optimizations of VADL built-in calls."),
34+
OPT_ARGS("Argument preparation optimization for VADL built-in calls. \n"
35+
+ "E.g., removes truncation of VADL::add arguments."),
36+
OPT_VAR_ALLOC("Reduces required number of temporary TCG variables to a minimum."),
37+
OPT_JMP_SLOTS("Uses QEMU jump slot optimization to chain jumps between TBs."),
38+
OPT_CTRL_FLOW("Optimizes control flow within an instruction.");
39+
40+
public final String desc;
41+
42+
IssOptsToSkip(String desc) {
43+
this.desc = desc;
44+
}
45+
}
46+
2847
// is set by the IssConfigurationPass
2948
private String targetName;
3049
private boolean insnCount;
3150
private Tcg_32_64 targetSize;
51+
private EnumSet<IssOptsToSkip> optsToSkip;
3252

3353
/**
3454
* Constructs a {@link IssConfiguration}.
@@ -38,28 +58,20 @@ public IssConfiguration(GeneralConfiguration generalConfig) {
3858
targetName = "unknown";
3959
insnCount = false;
4060
targetSize = Tcg_32_64.i64;
41-
}
42-
43-
/**
44-
* Constructs IssConfiguration.
45-
*
46-
* @param insnCount used to determine if the iss generates add instruction for special
47-
* cpu register (QEMU)
48-
*/
49-
public IssConfiguration(GeneralConfiguration generalConfig, boolean insnCount) {
50-
super(generalConfig);
51-
this.targetName = "unknown";
52-
this.insnCount = insnCount;
53-
targetSize = Tcg_32_64.i64;
54-
61+
optsToSkip = EnumSet.noneOf(IssOptsToSkip.class);
5562
}
5663

5764
public static IssConfiguration from(GeneralConfiguration generalConfig) {
5865
return new IssConfiguration(generalConfig);
5966
}
6067

68+
/**
69+
* Construct the configuration from a general configuration.
70+
*/
6171
public static IssConfiguration from(GeneralConfiguration generalConfig, boolean insnCounting) {
62-
return new IssConfiguration(generalConfig, insnCounting);
72+
var config = new IssConfiguration(generalConfig);
73+
config.insnCount = insnCounting;
74+
return config;
6375
}
6476

6577
public String targetName() {
@@ -85,4 +97,13 @@ public void setInsnCounting(boolean insnCounting) {
8597
public void setTargetSize(Tcg_32_64 targetSize) {
8698
this.targetSize = targetSize;
8799
}
100+
101+
public boolean isSkip(IssOptsToSkip optsToSkip) {
102+
return this.optsToSkip.contains(optsToSkip);
103+
}
104+
105+
public void setOptsToSkip(
106+
EnumSet<IssOptsToSkip> optsToSkip) {
107+
this.optsToSkip = optsToSkip;
108+
}
88109
}

vadl/main/vadl/dump/HtmlDumpPass.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,8 @@ private static Map<String, Object> mapPassResult(PassResults.SingleResult single
290290
"passKey", singleResult.passKey().value(),
291291
"pass", mapPass(singleResult.pass()),
292292
"duration", singleResult.durationMs(),
293-
"hasLink", hasLink
293+
"hasLink", hasLink,
294+
"skipped", singleResult.skipped()
294295
);
295296
}
296297

vadl/main/vadl/error/DiagUtils.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package vadl.error;
1818

19+
import java.util.Objects;
1920
import vadl.utils.SourceLocation;
2021
import vadl.viam.graph.Node;
2122

@@ -36,7 +37,8 @@ public static void throwNotAllowed(Node node, String what) {
3637
SourceLocation loc = !node.sourceLocation().equals(SourceLocation.INVALID_SOURCE_LOCATION)
3738
? node.sourceLocation()
3839
: node.ensureGraph().parentDefinition().sourceLocation();
39-
throw Diagnostic.error(what + " are not allowed here", loc)
40+
throw Diagnostic.error(
41+
what + " are not allowed in " + Objects.requireNonNull(node.graph()).name, loc)
4042
.note("THIS IS AN INTERNAL ERROR")
4143
.build();
4244
}

0 commit comments

Comments
 (0)