Skip to content

Commit e63edec

Browse files
authored
lcb: Generate intrinsics for load and store instructions (#772)
Implementing intrinsic generation for loads. Unfortunately, store intrinsics do not work because we don't have a pointer type.
1 parent cf3014e commit e63edec

18 files changed

+2600
-40
lines changed

vadl/main/resources/templates/lcb/llvm/lib/Target/ISelLowering.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
#include "llvm/Support/ErrorHandling.h"
1010
#include "llvm/Support/raw_ostream.h"
1111
#include "llvm/Support/Debug.h"
12+
#include "llvm/IR/Intrinsics.h"
13+
#include "llvm/IR/Intrinsics[(${namespace})].h"
1214
#include <iostream>
1315

1416
#define DEBUG_TYPE "[(${namespace})]TargetLowering"
@@ -71,6 +73,7 @@ void [(${namespace})]TargetLowering::anchor() {}
7173
[#th:block th:if="${requiresTruncation}"]
7274
setOperationAction(ISD::TRUNCATE, MVT::[(${truncation.dest})], Custom);
7375
[/th:block]
76+
setOperationAction(ISD::INTRINSIC_VOID, MVT::Other, Custom);
7477

7578
setBooleanContents(ZeroOrOneBooleanContent);
7679

@@ -239,9 +242,22 @@ SDValue [(${namespace})]TargetLowering::LowerOperation(SDValue Op, SelectionDAG
239242
return lowerSelect(Op, DAG);
240243
[/th:block]
241244
[#th:block th:if="${requiresTruncation}"]
242-
case ISD::TRUNCATE:
245+
case ISD::TRUNCATE:
243246
return lowerTruncate(Op, DAG);
244247
[/th:block]
248+
case ISD::INTRINSIC_VOID: {
249+
SDLoc DL(Op);
250+
unsigned IntNo = cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue();
251+
SDValue Chain = Op.getOperand(0);
252+
253+
[# th:each="intrinsic : ${zeroOutputInputIntrinsics}" ]
254+
if (IntNo == Intrinsic::[(${intrinsic.intrinsicName})]) {
255+
return SDValue(DAG.getMachineNode([(${namespace})]::[(${intrinsic.instructionName})], DL, MVT::Other, Chain), 0);
256+
}
257+
[/]
258+
259+
break;
260+
}
245261
default : llvm_unreachable("unimplemented operand");
246262
}
247263
}

vadl/main/vadl/cppCodeGen/CppTypeMap.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616

1717
package vadl.cppCodeGen;
1818

19-
import javax.annotation.Nullable;
2019
import vadl.cppCodeGen.model.CppType;
20+
import vadl.gcb.valuetypes.ValueType;
2121
import vadl.types.BitsType;
2222
import vadl.types.BoolType;
2323
import vadl.types.SIntType;
@@ -30,6 +30,26 @@
3030
* the corresponding cpp type.
3131
*/
3232
public class CppTypeMap {
33+
/**
34+
* Returns the cpp type given the {@link Type}. The builtin tablegen tool does not support
35+
* {@code uint8} or {@code uint16}. Therefore, we added a customization.
36+
*/
37+
public static String getCppBuiltinTypeNameByVadlType(ValueType type) {
38+
var width = type.getBitwidth();
39+
if (type.isSigned() && width == 8) {
40+
return "char";
41+
} else if (!type.isSigned() && width == 8) {
42+
return "unsigned char";
43+
} else if (type.isSigned() && width == 16) {
44+
return "short";
45+
} else if (!type.isSigned() && width == 16) {
46+
return "unsigned short";
47+
}
48+
return getCppTypeNameByVadlType(
49+
type.isSigned() ? SIntType.bits(width) : Type.unsignedInt(width)
50+
);
51+
}
52+
3353
/**
3454
* Returns the cpp type given the {@link Type}.
3555
*/

vadl/main/vadl/gcb/passes/GenerateGcbIntrinsicsPass.java

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import javax.annotation.Nullable;
2828
import vadl.configuration.GcbConfiguration;
2929
import vadl.gcb.passes.operands.InstructionOperandsCtx;
30+
import vadl.gcb.passes.operands.model.GcbInstructionImmediateOperand;
3031
import vadl.gcb.passes.operands.model.GcbInstructionOperand;
3132
import vadl.gcb.passes.operands.model.GcbInstructionRegisterFileOperand;
3233
import vadl.pass.Pass;
@@ -104,15 +105,25 @@ public Object execute(PassResults passResults, Specification viam) throws IOExce
104105

105106
var isNoMem = isNoMem(snapshot);
106107
var speculatable = speculatable(snapshot);
108+
var readsMem = !snapshot.getNodes(ReadMemNode.class).toList().isEmpty();
109+
var writesMem = !snapshot.getNodes(WriteMemNode.class).toList().isEmpty();
107110

108111
var attributes = new ArrayList<InstructionIntrinsicAttributesCtx.Attribute>();
109112
if (isNoMem) {
110113
attributes.add(InstructionIntrinsicAttributesCtx.Attribute.NoMem);
114+
} else if (readsMem) {
115+
attributes.add(InstructionIntrinsicAttributesCtx.Attribute.ReadMem);
116+
} else if (writesMem) {
117+
attributes.add(InstructionIntrinsicAttributesCtx.Attribute.WriteMem);
118+
} else {
119+
attributes.add(InstructionIntrinsicAttributesCtx.Attribute.ReadWriteMem);
111120
}
121+
112122
if (speculatable) {
113123
attributes.add(InstructionIntrinsicAttributesCtx.Attribute.Speculatable);
114124
}
115125

126+
116127
var builtinName = instruction.simpleName();
117128
var intrinsicName = gcbConfiguration.targetName().value() + "_" + instruction.simpleName();
118129

@@ -132,12 +143,8 @@ public Object execute(PassResults passResults, Specification viam) throws IOExce
132143
private boolean isRedFlag(Specification viam, Graph snapshot) {
133144
var pc =
134145
Objects.requireNonNull(ensurePresent(viam.isa(), "must be present").pc()).registerTensor();
135-
var hasPc = snapshot.getNodes(ReadsRegisterTensor.class).anyMatch(
146+
return snapshot.getNodes(ReadsRegisterTensor.class).anyMatch(
136147
x -> x.registerTensor().isSingleRegister() && x.registerTensor() == pc);
137-
var hasMemory =
138-
snapshot.getNodes(ReadMemNode.class).findFirst().isPresent() || snapshot.getNodes(
139-
WriteMemNode.class).findFirst().isPresent();
140-
return hasPc || hasMemory;
141148
}
142149

143150
private boolean isMem(Graph snapshot) {
@@ -165,11 +172,12 @@ private boolean speculatable(Graph snapshot) {
165172

166173
private boolean hasValidInputOperands(List<GcbInstructionOperand> operands) {
167174
return operands.stream()
168-
.allMatch(operand -> operand instanceof GcbInstructionRegisterFileOperand);
175+
.allMatch(operand -> operand instanceof GcbInstructionRegisterFileOperand
176+
|| operand instanceof GcbInstructionImmediateOperand);
169177
}
170178

171179
private boolean hasValidOutputOperands(List<GcbInstructionOperand> operands) {
172-
return operands.size() == 1 /* requires exactly one output */
180+
return operands.size() <= 1 /* requires exactly one output and or zero */
173181
&& operands.stream()
174182
.allMatch(operand -> operand instanceof GcbInstructionRegisterFileOperand);
175183
}

vadl/main/vadl/gcb/passes/InstructionIntrinsicAttributesCtx.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,10 @@ public class InstructionIntrinsicAttributesCtx extends DefinitionExtension<Instr
3131
*/
3232
public enum Attribute {
3333
NoMem,
34-
Speculatable
34+
Speculatable,
35+
ReadMem,
36+
WriteMem,
37+
ReadWriteMem
3538
}
3639

3740
private final List<Attribute> attributes;

vadl/main/vadl/lcb/passes/llvmLowering/LlvmLoweringPass.java

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,11 @@
7878
*/
7979
public class LlvmLoweringPass extends Pass {
8080

81-
private boolean generatePatterns;
81+
private final boolean generatePatterns;
8282

8383
public LlvmLoweringPass(LcbConfiguration configuration) {
8484
super(configuration);
85-
this.generatePatterns = !((LcbConfiguration) configuration()).skipPatternGeneration();
85+
this.generatePatterns = !configuration.skipPatternGeneration();
8686
}
8787

8888
/**
@@ -137,9 +137,11 @@ public BaseInstructionInfo withFlags(LlvmLoweringPass.Flags newFlags) {
137137
*/
138138
public record Flags(boolean isTerminator, boolean isBranch, boolean isCall, boolean isReturn,
139139
boolean isPseudo, boolean isCodeGenOnly, boolean mayLoad, boolean mayStore,
140-
boolean isBarrier, boolean isRematerialisable, boolean isAsCheapAsAMove) {
140+
boolean isBarrier, boolean isRematerialisable, boolean isAsCheapAsAMove,
141+
boolean hasSideEffects) {
141142
public static Flags empty() {
142-
return new Flags(false, false, false, false, false, false, false, false, false, false, false);
143+
return new Flags(false, false, false, false, false, false, false, false, false, false, false,
144+
false);
143145
}
144146

145147
/**
@@ -148,7 +150,7 @@ public static Flags empty() {
148150
public static Flags withTerminator(Flags flags) {
149151
return new Flags(true, flags.isBranch, flags.isCall, flags.isReturn, flags.isPseudo,
150152
flags.isCodeGenOnly, flags.mayLoad, flags.mayStore(), flags.isBarrier,
151-
flags.isRematerialisable, flags.isAsCheapAsAMove);
153+
flags.isRematerialisable, flags.isAsCheapAsAMove, flags.hasSideEffects);
152154
}
153155

154156
/**
@@ -157,7 +159,7 @@ public static Flags withTerminator(Flags flags) {
157159
public static Flags withNoTerminator(Flags flags) {
158160
return new Flags(false, flags.isBranch, flags.isCall, flags.isReturn, flags.isPseudo,
159161
flags.isCodeGenOnly, flags.mayLoad, flags.mayStore(), flags.isBarrier,
160-
flags.isRematerialisable, flags.isAsCheapAsAMove);
162+
flags.isRematerialisable, flags.isAsCheapAsAMove, flags.hasSideEffects);
161163
}
162164

163165
/**
@@ -167,7 +169,7 @@ public static Flags withBranch(Flags flags) {
167169
return new Flags(flags.isTerminator(), true, flags.isCall, flags.isReturn, flags.isPseudo,
168170
flags.isCodeGenOnly, flags.mayLoad, flags.mayStore(), flags.isBarrier,
169171
flags.isRematerialisable,
170-
flags.isAsCheapAsAMove);
172+
flags.isAsCheapAsAMove, flags.hasSideEffects);
171173
}
172174

173175
/**
@@ -177,7 +179,7 @@ public static Flags withPseudo(Flags flags) {
177179
return new Flags(flags.isTerminator(), flags.isBranch, flags.isCall, flags.isReturn, true,
178180
flags.isCodeGenOnly, flags.mayLoad, flags.mayStore(), flags.isBarrier,
179181
flags.isRematerialisable,
180-
flags.isAsCheapAsAMove);
182+
flags.isAsCheapAsAMove, flags.hasSideEffects);
181183
}
182184

183185
/**
@@ -187,7 +189,7 @@ public static Flags withBarrier(Flags flags) {
187189
return new Flags(flags.isTerminator(), flags.isBranch, flags.isCall, flags.isReturn,
188190
flags.isPseudo,
189191
flags.isCodeGenOnly, flags.mayLoad, flags.mayStore(), true, flags.isRematerialisable,
190-
flags.isAsCheapAsAMove);
192+
flags.isAsCheapAsAMove, flags.hasSideEffects);
191193
}
192194

193195
/**
@@ -196,7 +198,7 @@ public static Flags withBarrier(Flags flags) {
196198
public static Flags withNoBranch(Flags flags) {
197199
return new Flags(flags.isTerminator(), false, flags.isCall, flags.isReturn, flags.isPseudo,
198200
flags.isCodeGenOnly, flags.mayLoad, flags.mayStore(), flags.isBarrier,
199-
flags.isRematerialisable, flags.isAsCheapAsAMove);
201+
flags.isRematerialisable, flags.isAsCheapAsAMove, flags.hasSideEffects);
200202
}
201203

202204
/**
@@ -206,7 +208,7 @@ public static Flags withIsRematerialisable(Flags flags) {
206208
return new Flags(flags.isTerminator(), flags.isBranch, flags.isCall, flags.isReturn,
207209
flags.isPseudo,
208210
flags.isCodeGenOnly, flags.mayLoad, flags.mayStore(), flags.isBarrier,
209-
true, flags.isAsCheapAsAMove);
211+
true, flags.isAsCheapAsAMove, flags.hasSideEffects);
210212
}
211213

212214

@@ -217,7 +219,7 @@ public static Flags withIsAsCheapAsMove(Flags flags) {
217219
return new Flags(flags.isTerminator(), flags.isBranch, flags.isCall, flags.isReturn,
218220
flags.isPseudo,
219221
flags.isCodeGenOnly, flags.mayLoad, flags.mayStore(), flags.isBarrier,
220-
flags.isRematerialisable, true);
222+
flags.isRematerialisable, true, flags.hasSideEffects);
221223
}
222224

223225
/**
@@ -227,7 +229,7 @@ public static Flags withNoCodeGenOnly(Flags flags) {
227229
return new Flags(flags.isTerminator(), flags.isBranch, flags.isCall, flags.isReturn,
228230
flags.isPseudo,
229231
false, flags.mayLoad, flags.mayStore(), flags.isBarrier,
230-
flags.isRematerialisable, flags.isAsCheapAsAMove);
232+
flags.isRematerialisable, flags.isAsCheapAsAMove, flags.hasSideEffects);
231233
}
232234

233235

@@ -237,7 +239,16 @@ public static Flags withNoCodeGenOnly(Flags flags) {
237239
public static Flags withMayLoad(Flags flags) {
238240
return new Flags(flags.isTerminator(), flags.isBranch, flags.isCall, flags.isReturn,
239241
flags.isPseudo, flags.isCodeGenOnly, true, flags.mayStore(), flags.isBarrier,
240-
flags.isRematerialisable, flags.isAsCheapAsAMove);
242+
flags.isRematerialisable, flags.isAsCheapAsAMove, flags.hasSideEffects);
243+
}
244+
245+
/**
246+
* Given {@link Flags} overwrite the {@code hasSideEffects} to true.
247+
*/
248+
public static Flags withSideEffects(Flags flags) {
249+
return new Flags(flags.isTerminator(), flags.isBranch, flags.isCall, flags.isReturn,
250+
flags.isPseudo, flags.isCodeGenOnly, flags.mayLoad, flags.mayStore(), flags.isBarrier,
251+
flags.isRematerialisable, flags.isAsCheapAsAMove, true);
241252
}
242253
}
243254

vadl/main/vadl/lcb/passes/llvmLowering/strategies/LlvmCompilerInstructionLowerStrategy.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ public Optional<LlvmLoweringRecord.Compiler> lowerInstruction(
113113
mayStore,
114114
false,
115115
false,
116+
false,
116117
false);
117118

118119
var operandCtx =

vadl/main/vadl/lcb/passes/llvmLowering/strategies/LlvmInstructionLoweringStrategy.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ protected LlvmLoweringPass.Flags getFlags(Graph graph) {
158158
var isBarrier = false;
159159
var isRemat = false;
160160
var isAsCheapAsMove = false;
161+
var hasSideEffects = false;
161162

162163
return new LlvmLoweringPass.Flags(
163164
isTerminator,
@@ -170,7 +171,8 @@ protected LlvmLoweringPass.Flags getFlags(Graph graph) {
170171
mayStore,
171172
isBarrier,
172173
isRemat,
173-
isAsCheapAsMove
174+
isAsCheapAsMove,
175+
hasSideEffects
174176
);
175177
}
176178

vadl/main/vadl/lcb/passes/llvmLowering/strategies/instruction/LlvmInstructionLoweringMemoryLoadStrategyImpl.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import vadl.gcb.passes.operands.model.GcbInstructionOperand;
2828
import vadl.gcb.valuetypes.ValueType;
2929
import vadl.lcb.passes.isaMatching.IsaMachineInstructionMatchingPass;
30+
import vadl.lcb.passes.llvmLowering.LlvmLoweringPass;
3031
import vadl.lcb.passes.llvmLowering.domain.machineDag.LcbMachineInstructionParameterNode;
3132
import vadl.lcb.passes.llvmLowering.domain.machineDag.LcbMachineInstructionValueNode;
3233
import vadl.lcb.passes.llvmLowering.domain.selectionDag.LlvmAddSD;
@@ -62,6 +63,13 @@ protected Set<MachineInstructionLabel> getSupportedInstructionLabels() {
6263
return Set.of(MachineInstructionLabel.LOAD_MEM_WITH_IMMEDIATE);
6364
}
6465

66+
@Override
67+
protected LlvmLoweringPass.Flags getFlags(Graph graph) {
68+
var flags = super.getFlags(graph);
69+
70+
return LlvmLoweringPass.Flags.withSideEffects(flags);
71+
}
72+
6573
@Override
6674
protected List<TableGenPattern> generatePatternVariations(
6775
Instruction instruction,

vadl/main/vadl/lcb/passes/llvmLowering/strategies/instruction/LlvmInstructionLoweringMemoryStoreStrategyImpl.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import vadl.gcb.passes.operands.model.GcbInstructionOperand;
2727
import vadl.gcb.valuetypes.ValueType;
2828
import vadl.lcb.passes.isaMatching.IsaMachineInstructionMatchingPass;
29+
import vadl.lcb.passes.llvmLowering.LlvmLoweringPass;
2930
import vadl.lcb.passes.llvmLowering.domain.machineDag.LcbMachineInstructionParameterNode;
3031
import vadl.lcb.passes.llvmLowering.domain.machineDag.LcbMachineInstructionValueNode;
3132
import vadl.lcb.passes.llvmLowering.domain.selectionDag.LlvmAddSD;
@@ -61,6 +62,13 @@ protected Set<MachineInstructionLabel> getSupportedInstructionLabels() {
6162
return Set.of(MachineInstructionLabel.STORE_MEM_WITH_IMMEDIATE);
6263
}
6364

65+
@Override
66+
protected LlvmLoweringPass.Flags getFlags(Graph graph) {
67+
var flags = super.getFlags(graph);
68+
69+
return LlvmLoweringPass.Flags.withSideEffects(flags);
70+
}
71+
6472
@Override
6573
protected List<TableGenPattern> generatePatternVariations(
6674
Instruction instruction,

vadl/main/vadl/lcb/passes/llvmLowering/tablegen/lowering/TableGenInstructionRenderer.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ public static String lower(TableGenMachineInstruction instruction) {
8282
let isBarrier = %d;
8383
let isReMaterializable = %d;
8484
let isAsCheapAsAMove = %d;
85+
let hasSideEffects = %d;
8586
8687
let Constraints = "%s";
8788
let AddedComplexity = 0;
@@ -117,6 +118,7 @@ public static String lower(TableGenMachineInstruction instruction) {
117118
toInt(instruction.getFlags().isBarrier()),
118119
toInt(instruction.getFlags().isRematerialisable()),
119120
toInt(instruction.getFlags().isAsCheapAsAMove()),
121+
toInt(instruction.getFlags().hasSideEffects()),
120122
instruction.constraints()
121123
.stream()
122124
.map(TableGenInstructionRenderer::renderConstraint)

0 commit comments

Comments
 (0)