Skip to content

Commit c4bb167

Browse files
authored
lcb: Add annotation to overwrite operands (#493)
* ast: Defined new annotation for overwriting operands * viam: Add overwritten nodes to graph * chore: Fix build * viam: Fixed broken layers * ast: Support multiple fields in annotation * lcb: Moved node to LCB * chore: Fixed build * ast: Addressed feedback and use fields directly * ast: Renamed "overwrite operand" to "add operands"
1 parent 3d8c9c3 commit c4bb167

File tree

15 files changed

+568
-28
lines changed

15 files changed

+568
-28
lines changed

sys/aarch64/aarch64.vadl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1764,13 +1764,15 @@ instruction set architecture AArch64Base = {
17641764
}
17651765

17661766
model ExceptionCallInstr (i: InstrWithFunct): IsaDefs = {
1767+
[add operands : imm16]
17671768
instruction $i.id: SuperVisorCallFormat = {
17681769
raise GeneralException (ExceptionClass::$i.funct, 0, PC.next, 0)
17691770
}
17701771
$ExceptionCallEncAsm ($i)
17711772
}
17721773

17731774
model HaltInstr (i: InstrWithFunct): IsaDefs = {
1775+
[add operands : imm16]
17741776
instruction $i.id: SuperVisorCallFormat = {}
17751777
$ExceptionCallEncAsm ($i)
17761778
}
@@ -1797,6 +1799,7 @@ instruction set architecture AArch64Base = {
17971799
}
17981800

17991801
model BTIInstr (i: InstrNoFunct): IsaDefs = {
1802+
[add operands : bti]
18001803
instruction $i.id: BTIFormat = {}
18011804
encoding $i.id = {op = 0b1101'0101'0000'0011, opc = $i.opcode}
18021805
assembly $i.id = ($i.mnemo, btiOp2(bti))

vadl/main/vadl/ast/AnnotationTable.java

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import static java.util.Objects.requireNonNull;
2121
import static vadl.error.Diagnostic.ensure;
2222
import static vadl.error.Diagnostic.error;
23+
import static vadl.viam.ViamError.ensurePresent;
2324

2425
import com.google.errorprone.annotations.concurrent.LazyInit;
2526
import java.math.BigInteger;
@@ -35,6 +36,7 @@
3536
import java.util.function.Supplier;
3637
import java.util.stream.Collectors;
3738
import javax.annotation.Nullable;
39+
import vadl.error.Diagnostic;
3840
import vadl.gcb.annotations.OnlyNegativeNumbersAnnotation;
3941
import vadl.gcb.annotations.SkipPruningAnnotation;
4042
import vadl.gcb.annotations.StatusRegisterAnnotation;
@@ -46,12 +48,14 @@
4648
import vadl.viam.AssemblyDescription;
4749
import vadl.viam.Constant;
4850
import vadl.viam.Encoding;
51+
import vadl.viam.Format;
4952
import vadl.viam.Instruction;
5053
import vadl.viam.MemoryRegion;
5154
import vadl.viam.RegisterTensor;
5255
import vadl.viam.Relocation;
5356
import vadl.viam.annotations.AsmParserCaseSensitive;
5457
import vadl.viam.annotations.AsmParserCommentString;
58+
import vadl.viam.annotations.DefineOperandAnnotation;
5559
import vadl.viam.annotations.EnableHtifAnno;
5660
import vadl.viam.annotations.InstructionUndefinedAnno;
5761

@@ -240,6 +244,17 @@ public class AnnotationTable {
240244
def.addAnnotation(new OnlyNegativeNumbersAnnotation());
241245
}
242246
}).build();
247+
248+
annotationOn(InstructionDefinition.class, "add operands", DefinitionRefAnnotation::new)
249+
.applyViam((def, annotation, lowering) -> {
250+
var fields =
251+
annotation.def.stream()
252+
.map(x -> (Format.Field) ensurePresent(lowering.fetch((RangeFormatField) x),
253+
() -> Diagnostic.error("Cannot find field", x.location()))).toList();
254+
255+
def.addAnnotation(new DefineOperandAnnotation(fields));
256+
}).build();
257+
243258
}
244259

245260
/**
@@ -1266,30 +1281,31 @@ void resolveName(AnnotationDefinition definition, SymbolTable.SymbolResolver res
12661281
}
12671282

12681283
class DefinitionRefAnnotation extends Annotation {
1269-
@LazyInit
1270-
Definition def;
1284+
List<Definition> def = new ArrayList<>();
12711285

12721286
private Expr firstVal() {
12731287
return definition.values.getFirst();
12741288
}
12751289

12761290
@Override
12771291
void resolveName(AnnotationDefinition definition, SymbolTable.SymbolResolver resolver) {
1278-
verifyValuesCnt(definition, 1);
12791292
// resolve the symbol of the value
1280-
firstVal().accept(resolver);
1293+
for (var v : definition.values) {
1294+
v.accept(resolver);
1295+
}
12811296
}
12821297

12831298
@Override
12841299
void typeCheck(AnnotationDefinition definition, TypeChecker typeChecker) {
1285-
var v = firstVal();
1286-
ensure(v instanceof Identifier, () -> error("Invalid annotation value", v)
1287-
.description("A single identifier was expected.")
1288-
);
1289-
var target = ((Identifier) v).target();
1290-
ensure(target instanceof Definition, () -> error("Invalid annotation value", v)
1291-
.description("The identifier must reference a definition."));
1292-
def = (Definition) target;
1300+
for (var v : definition.values) {
1301+
ensure(v instanceof Identifier, () -> error("Invalid annotation value", v)
1302+
.description("A single identifier was expected.")
1303+
);
1304+
var target = ((Identifier) v).target();
1305+
ensure(target instanceof Definition, () -> error("Invalid annotation value", v)
1306+
.description("The identifier must reference a definition."));
1307+
def.add((Definition) target);
1308+
}
12931309
}
12941310

12951311
@Override

vadl/main/vadl/cppCodeGen/mixins/CInvalidMixins.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ public interface CInvalidMixins {
4545
interface SideEffect
4646
extends WriteRegTensor, WriteMem, WriteArtificialRes, ProcCall,
4747
WriteStageOutput {
48-
4948
}
5049

5150
@SuppressWarnings("MissingJavadocType")

vadl/main/vadl/gcb/passes/IdentifyFieldUsagePass.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -207,10 +207,7 @@ public Map<Field, List<FieldUsage>> getFieldUsages(Instruction instruction) {
207207
* {@link Format} then return an empty list.
208208
*/
209209
public List<FieldUsage> getFieldUsages(Instruction instruction, Field field) {
210-
var obj = ensureNonNull(fieldUsage.get(instruction),
211-
() -> Diagnostic.error("Cannot find field's usages for instruction",
212-
instruction.location()));
213-
210+
var obj = fieldUsage.getOrDefault(instruction, new IdentityHashMap<>());
214211
return Optional.ofNullable(obj.get(field)).orElse(Collections.emptyList());
215212
}
216213

vadl/main/vadl/iss/passes/tcgLowering/TcgCtx.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,6 @@ List<TcgVRefNode> handle(ProcCallNode toHandle) {
180180
throw new IllegalStateException("ProcCallNode should not exist here.");
181181
}
182182

183-
184183
private TcgVRefNode toNode(TcgV tcgV) {
185184
return toNode(tcgV, new NodeList<>());
186185
}

vadl/main/vadl/lcb/codegen/assembly/AbstractAssemblyInstructionPrinterHandler.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,22 @@
1717
package vadl.lcb.codegen.assembly;
1818

1919
import com.google.errorprone.annotations.concurrent.LazyInit;
20+
import vadl.cppCodeGen.context.CGenContext;
2021
import vadl.cppCodeGen.context.CNodeContext;
2122
import vadl.cppCodeGen.mixins.CDefaultMixins;
23+
import vadl.cppCodeGen.mixins.CInvalidMixins;
24+
import vadl.error.Diagnostic;
25+
import vadl.javaannotations.Handler;
26+
import vadl.lcb.graph.DefinedImmediateSideEffectNode;
2227
import vadl.lcb.passes.llvmLowering.tablegen.model.TableGenInstruction;
2328
import vadl.viam.PrintableInstruction;
29+
import vadl.viam.graph.Node;
2430

2531
/**
2632
* Abstract class for assembly printing functionality.
2733
*/
2834
public abstract class AbstractAssemblyInstructionPrinterHandler
29-
implements CDefaultMixins.AllExpressions {
35+
implements CDefaultMixins.AllExpressions, CInvalidMixins {
3036

3137
protected final PrintableInstruction instruction;
3238
protected final TableGenInstruction tableGenInstruction;
@@ -43,4 +49,12 @@ public AbstractAssemblyInstructionPrinterHandler(PrintableInstruction instructio
4349
this.instruction = instruction;
4450
this.tableGenInstruction = tableGenInstruction;
4551
}
52+
53+
@Handler
54+
@SuppressWarnings("MissingJavadocMethod")
55+
public void handle(CGenContext<Node> ctx, DefinedImmediateSideEffectNode node) {
56+
throw Diagnostic.error(
57+
"not supported",
58+
node.location()).build();
59+
}
4660
}

vadl/main/vadl/lcb/codegen/assembly/AssemblyInstructionPrinterImmediateHandler.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import java.util.stream.Stream;
2828
import vadl.cppCodeGen.context.CGenContext;
2929
import vadl.cppCodeGen.context.CNodeContext;
30+
import vadl.cppCodeGen.mixins.CInvalidMixins;
3031
import vadl.error.Diagnostic;
3132
import vadl.gcb.passes.IdentifyFieldUsagePass;
3233
import vadl.gcb.passes.operands.ReferencesFormatField;
@@ -95,7 +96,7 @@
9596
@DispatchFor(
9697
value = Node.class,
9798
context = CNodeContext.class,
98-
include = {"vadl.viam"}
99+
include = {"vadl.viam", "vadl.lcb.graph"}
99100
)
100101
public class AssemblyInstructionPrinterImmediateHandler
101102
extends AbstractAssemblyInstructionPrinterHandler {

vadl/main/vadl/lcb/codegen/assembly/AssemblyInstructionPrinterLabelHandler.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import java.util.ArrayList;
2222
import vadl.cppCodeGen.context.CGenContext;
2323
import vadl.cppCodeGen.context.CNodeContext;
24+
import vadl.cppCodeGen.mixins.CInvalidMixins;
2425
import vadl.error.Diagnostic;
2526
import vadl.javaannotations.DispatchFor;
2627
import vadl.lcb.passes.llvmLowering.tablegen.model.TableGenInstruction;
@@ -41,7 +42,7 @@
4142
@DispatchFor(
4243
value = Node.class,
4344
context = CNodeContext.class,
44-
include = {"vadl.viam"}
45+
include = {"vadl.viam", "vadl.lcb.graph"}
4546
)
4647
public class AssemblyInstructionPrinterLabelHandler
4748
extends AssemblyInstructionPrinterImmediateHandler {
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
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.lcb.graph;
18+
19+
import java.util.List;
20+
import javax.annotation.Nullable;
21+
import vadl.javaannotations.viam.Input;
22+
import vadl.viam.graph.GraphNodeVisitor;
23+
import vadl.viam.graph.Node;
24+
import vadl.viam.graph.dependency.ExpressionNode;
25+
import vadl.viam.graph.dependency.SideEffectNode;
26+
27+
/**
28+
* Node which indicates that a field or field access function is used. This is required for the LCB
29+
* since not all operands of an instruction must be part of a behavior.
30+
*/
31+
public class DefinedImmediateSideEffectNode extends SideEffectNode {
32+
@Input
33+
private ExpressionNode value;
34+
35+
public DefinedImmediateSideEffectNode(@Nullable ExpressionNode condition, ExpressionNode value) {
36+
super(condition);
37+
this.value = value;
38+
}
39+
40+
@Override
41+
public Node copy() {
42+
return new DefinedImmediateSideEffectNode(condition != null
43+
? condition.copy() : null,
44+
value.copy());
45+
}
46+
47+
@Override
48+
public Node shallowCopy() {
49+
return new DefinedImmediateSideEffectNode(condition, value);
50+
}
51+
52+
@Override
53+
public <T extends GraphNodeVisitor> void accept(T visitor) {
54+
visitor.visit(this);
55+
}
56+
57+
@Override
58+
protected void collectInputs(List<Node> collection) {
59+
super.collectInputs(collection);
60+
collection.add(value);
61+
}
62+
63+
@Override
64+
public void applyOnInputsUnsafe(
65+
vadl.viam.graph.GraphVisitor.Applier<vadl.viam.graph.Node> visitor) {
66+
super.applyOnInputsUnsafe(visitor);
67+
value = visitor.apply(this, value, ExpressionNode.class);
68+
}
69+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
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.lcb.passes;
18+
19+
import java.io.IOException;
20+
import javax.annotation.Nullable;
21+
import vadl.configuration.GeneralConfiguration;
22+
import vadl.lcb.graph.DefinedImmediateSideEffectNode;
23+
import vadl.pass.Pass;
24+
import vadl.pass.PassName;
25+
import vadl.pass.PassResults;
26+
import vadl.viam.Specification;
27+
import vadl.viam.annotations.DefineOperandAnnotation;
28+
import vadl.viam.graph.dependency.FieldRefNode;
29+
30+
/**
31+
* Reads all the {@link DefineOperandAnnotation} and adds them as
32+
* {@link DefinedImmediateSideEffectNode}.
33+
*/
34+
public class OverwriteInputOperandsPass extends Pass {
35+
public OverwriteInputOperandsPass(GeneralConfiguration configuration) {
36+
super(configuration);
37+
}
38+
39+
@Override
40+
public PassName getName() {
41+
return new PassName("OverwriteInputOperandsPass");
42+
}
43+
44+
@Nullable
45+
@Override
46+
public Object execute(PassResults passResults, Specification viam) throws IOException {
47+
var machineInstructions = viam.isa().stream()
48+
.flatMap(isa -> isa.ownInstructions().stream())
49+
.filter(x -> x.hasAnnotation(DefineOperandAnnotation.class));
50+
51+
machineInstructions.forEach(machineInstruction -> {
52+
var annotation = machineInstruction.expectAnnotation(DefineOperandAnnotation.class);
53+
54+
for (var field : annotation.inputs()) {
55+
machineInstruction.behavior().addWithInputs(
56+
new DefinedImmediateSideEffectNode(null, new FieldRefNode(field, field.type())));
57+
}
58+
});
59+
60+
return null;
61+
}
62+
}

0 commit comments

Comments
 (0)