Skip to content

Commit 5deea85

Browse files
committed
[𝘀𝗽𝗿] initial version
Created using spr 1.3.8-beta.1
2 parents 4b54836 + 329a308 commit 5deea85

File tree

9 files changed

+137
-85
lines changed

9 files changed

+137
-85
lines changed
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
include "llvm/Target/Target.td"
2+
3+
class MyReg<string n> : Register<n> {
4+
let Namespace = "MyTarget";
5+
}
6+
7+
class MyClass<int size, list<ValueType> types, dag registers>
8+
: RegisterClass<"MyTarget", types, size, registers> {
9+
let Size = size;
10+
}
11+
12+
def X0 : MyReg<"x0">;
13+
def X1 : MyReg<"x1">;
14+
def X2 : MyReg<"x2">;
15+
def X3 : MyReg<"x3">;
16+
def XRegs : RegisterClass<"MyTarget", [i32], 32, (add X0, X1, X2, X3)>;
17+
def Y0 : MyReg<"y0">;
18+
def Y1 : MyReg<"y1">;
19+
def Y2 : MyReg<"y2">;
20+
def Y3 : MyReg<"y3">;
21+
def YRegs : RegisterClass<"MyTarget", [i64], 64, (add Y0, Y1, X2, X3)>;
22+
23+
class TestInstruction : Instruction {
24+
let Size = 2;
25+
let Namespace = "MyTarget";
26+
let hasSideEffects = false;
27+
let hasExtraSrcRegAllocReq = false;
28+
let hasExtraDefRegAllocReq = false;
29+
30+
field bits<16> Inst;
31+
bits<3> dst;
32+
bits<3> src;
33+
bits<3> opcode;
34+
35+
let Inst{2-0} = dst;
36+
let Inst{5-3} = src;
37+
let Inst{7-5} = opcode;
38+
}

llvm/test/TableGen/RegClassByHwMode.td

Lines changed: 6 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
// RUN: llvm-tblgen -gen-instr-info -I %p/../../include %s -o - | FileCheck -check-prefix=INSTRINFO %s
2-
// RUN: llvm-tblgen -gen-asm-matcher -I %p/../../include %s -o - | FileCheck -check-prefix=ASMMATCHER %s
3-
// RUN: llvm-tblgen -gen-disassembler -I %p/../../include %s -o - | FileCheck -check-prefix=DISASM %s
4-
// RUN: llvm-tblgen -gen-dag-isel -I %p/../../include %s -o - | FileCheck -check-prefix=ISEL-SDAG %s
5-
// RUN: llvm-tblgen -gen-global-isel -I %p/../../include %s -o - | FileCheck -check-prefix=ISEL-GISEL %s
1+
// RUN: llvm-tblgen -gen-instr-info -I %S -I %p/../../include %s -o - | FileCheck -check-prefix=INSTRINFO %s
2+
// RUN: llvm-tblgen -gen-asm-matcher -I %S -I %p/../../include %s -o - | FileCheck -check-prefix=ASMMATCHER %s
3+
// RUN: llvm-tblgen -gen-disassembler -I %S -I %p/../../include %s -o - | FileCheck -check-prefix=DISASM %s
4+
// RUN: llvm-tblgen -gen-dag-isel -I %S -I %p/../../include %s -o - | FileCheck -check-prefix=ISEL-SDAG %s
5+
// RUN: llvm-tblgen -gen-global-isel -I %S -I %p/../../include %s -o - | FileCheck -check-prefix=ISEL-GISEL %s
66

7-
include "llvm/Target/Target.td"
7+
include "Common/RegClassByHwModeCommon.td"
88

99
// INSTRINFO: #ifdef GET_INSTRINFO_ENUM
1010
// INSTRINFO-NEXT: #undef GET_INSTRINFO_ENUM
@@ -302,8 +302,6 @@ include "llvm/Target/Target.td"
302302
// ISEL-GISEL-NEXT: GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/GIMT_Encode2(MyTarget::MY_STORE),
303303
// ISEL-GISEL-NEXT: GIR_RootConstrainSelectedInstOperands,
304304

305-
306-
307305
def HasAlignedRegisters : Predicate<"Subtarget->hasAlignedRegisters()">;
308306
def HasUnalignedRegisters : Predicate<"Subtarget->hasUnalignedRegisters()">;
309307
def IsPtr64 : Predicate<"Subtarget->isPtr64()">;
@@ -317,34 +315,6 @@ def EvenMode : HwMode<[HasAlignedRegisters]>;
317315
def OddMode : HwMode<[HasUnalignedRegisters]>;
318316
def Ptr64 : HwMode<[IsPtr64]>;
319317

320-
class MyReg<string n>
321-
: Register<n> {
322-
let Namespace = "MyTarget";
323-
}
324-
325-
class MyClass<int size, list<ValueType> types, dag registers>
326-
: RegisterClass<"MyTarget", types, size, registers> {
327-
let Size = size;
328-
}
329-
330-
def X0 : MyReg<"x0">;
331-
def X1 : MyReg<"x1">;
332-
def X2 : MyReg<"x2">;
333-
def X3 : MyReg<"x3">;
334-
def X4 : MyReg<"x4">;
335-
def X5 : MyReg<"x5">;
336-
def X6 : MyReg<"x6">;
337-
338-
def Y0 : MyReg<"y0">;
339-
def Y1 : MyReg<"y1">;
340-
def Y2 : MyReg<"y2">;
341-
def Y3 : MyReg<"y3">;
342-
def Y4 : MyReg<"y4">;
343-
def Y5 : MyReg<"y5">;
344-
def Y6 : MyReg<"y6">;
345-
346-
347-
348318
def P0_32 : MyReg<"p0">;
349319
def P1_32 : MyReg<"p1">;
350320
def P2_32 : MyReg<"p2">;
@@ -385,23 +355,6 @@ def CustomDecodeYEvenIfRequired : RegisterOperand<YRegs_EvenIfRequired> {
385355
let DecoderMethod = "YEvenIfRequiredCustomDecoder";
386356
}
387357

388-
class TestInstruction : Instruction {
389-
let Size = 2;
390-
let Namespace = "MyTarget";
391-
let hasSideEffects = false;
392-
let hasExtraSrcRegAllocReq = false;
393-
let hasExtraDefRegAllocReq = false;
394-
395-
field bits<16> Inst;
396-
bits<3> dst;
397-
bits<3> src;
398-
bits<3> opcode;
399-
400-
let Inst{2-0} = dst;
401-
let Inst{5-3} = src;
402-
let Inst{7-5} = opcode;
403-
}
404-
405358
def SpecialOperand : RegisterOperand<XRegs_EvenIfRequired>;
406359

407360
def MY_MOV : TestInstruction {
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// RUN: rm -rf %t && split-file %s %t
2+
// RUN: not llvm-tblgen --gen-asm-matcher -I %p/../../include -I %t -I %S \
3+
// RUN: %t/inst-alias-bad-reg.td -o /dev/null 2>&1 | FileCheck %t/inst-alias-bad-reg.td
4+
// RUN: not llvm-tblgen --gen-compress-inst-emitter -I %p/../../include -I %t -I %S \
5+
// RUN: %t/compress-regclass-by-hwmode.td -o /dev/null 2>&1 | FileCheck %t/compress-regclass-by-hwmode.td
6+
7+
//--- Common.td
8+
include "Common/RegClassByHwModeCommon.td"
9+
10+
def IsPtr64 : Predicate<"Subtarget->isPtr64()">;
11+
defvar Ptr32 = DefaultMode;
12+
def Ptr64 : HwMode<[IsPtr64]>;
13+
def PtrRC : RegClassByHwMode<[Ptr32, Ptr64], [XRegs, YRegs]>;
14+
15+
def PTR_MOV : TestInstruction {
16+
let OutOperandList = (outs PtrRC:$dst);
17+
let InOperandList = (ins PtrRC:$src);
18+
let AsmString = "ptr_mov $dst, $src";
19+
let opcode = 0;
20+
}
21+
22+
23+
//--- inst-alias-bad-reg.td
24+
include "Common.td"
25+
// This should fail since X0 is not necessarily part of PtrRC.
26+
def BAD_REG : InstAlias<"ptr_zero $rd", (PTR_MOV PtrRC:$dst, X0)>;
27+
// CHECK: [[#@LINE-1]]:5: error: cannot resolve HwMode for PtrRC
28+
// CHECK: Common.td:6:5: note: PtrRC defined here
29+
def MyTargetISA : InstrInfo;
30+
def MyTarget : Target { let InstructionSet = MyTargetISA; }
31+
32+
//--- compress-regclass-by-hwmode.td
33+
include "Common.td"
34+
def PTR_ZERO_SMALL : TestInstruction {
35+
let OutOperandList = (outs PtrRC:$dst);
36+
let InOperandList = (ins);
37+
let AsmString = "ptr_zero $dst";
38+
let opcode = 1;
39+
let Size = 1;
40+
}
41+
// This should fail since X0 is not necessarily part of PtrRC.
42+
def : CompressPat<(PTR_MOV PtrRC:$dst, X0),
43+
(PTR_ZERO_SMALL PtrRC:$dst)>;
44+
// CHECK: [[#@LINE-2]]:1: error: cannot resolve HwMode for PtrRC
45+
// CHECK: Common.td:6:5: note: PtrRC defined here
46+
def MyTargetISA : InstrInfo;
47+
def MyTarget : Target { let InstructionSet = MyTargetISA; }

llvm/utils/TableGen/Common/CodeGenInstAlias.cpp

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -43,21 +43,20 @@ using ResultOperand = CodeGenInstAlias::ResultOperand;
4343
static Expected<ResultOperand> matchSimpleOperand(const Init *Arg,
4444
const StringInit *ArgName,
4545
const Record *Op,
46-
const CodeGenTarget &T) {
47-
if (Op->isSubClassOf("RegisterClass") ||
48-
Op->isSubClassOf("RegisterOperand")) {
49-
const Record *OpRC =
50-
Op->isSubClassOf("RegisterClass") ? Op : Op->getValueAsDef("RegClass");
51-
46+
const CodeGenTarget &T,
47+
ArrayRef<SMLoc> Loc) {
48+
if (const Record *OpRC = T.getAsRegClassLike(Op)) {
5249
if (const auto *ArgDef = dyn_cast<DefInit>(Arg)) {
5350
const Record *ArgRec = ArgDef->getDef();
5451

5552
// Match 'RegClass:$name' or 'RegOp:$name'.
5653
if (const Record *ArgRC = T.getInitValueAsRegClassLike(Arg)) {
5754
if (ArgRC->isSubClassOf("RegisterClass")) {
58-
if (!T.getRegisterClass(OpRC).hasSubClass(&T.getRegisterClass(ArgRC)))
55+
if (!OpRC->isSubClassOf("RegisterClass") ||
56+
!T.getRegisterClass(OpRC, Loc).hasSubClass(
57+
&T.getRegisterClass(ArgRC, Loc)))
5958
return createStringError(
60-
"argument register class" + ArgRC->getName() +
59+
"argument register class " + ArgRC->getName() +
6160
" is not a subclass of operand register class " +
6261
OpRC->getName());
6362
if (!ArgName)
@@ -73,7 +72,8 @@ static Expected<ResultOperand> matchSimpleOperand(const Init *Arg,
7372

7473
// Match 'Reg'.
7574
if (ArgRec->isSubClassOf("Register")) {
76-
if (!T.getRegisterClass(OpRC).contains(T.getRegBank().getReg(ArgRec)))
75+
if (!T.getRegisterClass(OpRC, Loc).contains(
76+
T.getRegBank().getReg(ArgRec)))
7777
return createStringError(
7878
"register argument " + ArgRec->getName() +
7979
" is not a member of operand register class " + OpRC->getName());
@@ -111,11 +111,9 @@ static Expected<ResultOperand> matchSimpleOperand(const Init *Arg,
111111
return ResultOperand::createRecord(ArgName->getAsUnquotedString(),
112112
ArgDef->getDef());
113113
}
114-
115-
return createStringError("argument must be a subclass of Operand");
116114
}
117-
118-
llvm_unreachable("Unknown operand kind");
115+
return createStringError("argument must be a subclass of 'Operand' but got " +
116+
Op->getName() + " instead");
119117
}
120118

121119
static Expected<ResultOperand> matchComplexOperand(const Init *Arg,
@@ -204,7 +202,8 @@ CodeGenInstAlias::CodeGenInstAlias(const Record *R, const CodeGenTarget &T)
204202
const Record *SubOp =
205203
cast<DefInit>(OpInfo.MIOperandInfo->getArg(SubOpIdx))->getDef();
206204
Expected<ResultOperand> ResOpOrErr = matchSimpleOperand(
207-
ArgDag->getArg(SubOpIdx), ArgDag->getArgName(SubOpIdx), SubOp, T);
205+
ArgDag->getArg(SubOpIdx), ArgDag->getArgName(SubOpIdx), SubOp, T,
206+
R->getLoc());
208207
if (!ResOpOrErr)
209208
PrintFatalError(R, "in argument #" + Twine(ArgIdx) + "." +
210209
Twine(SubOpIdx) + ": " +
@@ -225,8 +224,9 @@ CodeGenInstAlias::CodeGenInstAlias(const Record *R, const CodeGenTarget &T)
225224
} else {
226225
// Simple operand (RegisterClass, RegisterOperand or Operand with empty
227226
// MIOperandInfo).
228-
Expected<ResultOperand> ResOpOrErr = matchSimpleOperand(
229-
Result->getArg(ArgIdx), Result->getArgName(ArgIdx), Op, T);
227+
Expected<ResultOperand> ResOpOrErr =
228+
matchSimpleOperand(Result->getArg(ArgIdx), Result->getArgName(ArgIdx),
229+
Op, T, R->getLoc());
230230
if (!ResOpOrErr)
231231
PrintFatalError(R, "in argument #" + Twine(ArgIdx) + ": " +
232232
toString(ResOpOrErr.takeError()));

llvm/utils/TableGen/Common/CodeGenRegisters.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1316,11 +1316,18 @@ CodeGenRegBank::getOrCreateSubClass(const CodeGenRegisterClass *RC,
13161316
return {&RegClasses.back(), true};
13171317
}
13181318

1319-
CodeGenRegisterClass *CodeGenRegBank::getRegClass(const Record *Def) const {
1319+
CodeGenRegisterClass *CodeGenRegBank::getRegClass(const Record *Def,
1320+
ArrayRef<SMLoc> Loc) const {
13201321
if (CodeGenRegisterClass *RC = Def2RC.lookup(Def))
13211322
return RC;
13221323

1323-
PrintFatalError(Def->getLoc(), "Not a known RegisterClass!");
1324+
ArrayRef<SMLoc> DiagLoc = Loc.empty() ? Def->getLoc() : Loc;
1325+
// TODO: Ideally we should update the API to allow resolving HwMode.
1326+
if (Def->isSubClassOf("RegClassByHwMode"))
1327+
PrintError(DiagLoc, "cannot resolve HwMode for " + Def->getName());
1328+
else
1329+
PrintError(DiagLoc, Def->getName() + " is not a known RegisterClass!");
1330+
PrintFatalNote(Def->getLoc(), Def->getName() + " defined here");
13241331
}
13251332

13261333
CodeGenSubRegIndex *

llvm/utils/TableGen/Common/CodeGenRegisters.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -815,7 +815,8 @@ class CodeGenRegBank {
815815
}
816816

817817
// Find a register class from its def.
818-
CodeGenRegisterClass *getRegClass(const Record *) const;
818+
CodeGenRegisterClass *getRegClass(const Record *,
819+
ArrayRef<SMLoc> Loc = {}) const;
819820

820821
/// getRegisterClassForRegister - Find the register class that contains the
821822
/// specified physical register. If the register is not in a register

llvm/utils/TableGen/Common/CodeGenTarget.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -173,8 +173,8 @@ const CodeGenRegister *CodeGenTarget::getRegisterByName(StringRef Name) const {
173173
}
174174

175175
const CodeGenRegisterClass &
176-
CodeGenTarget::getRegisterClass(const Record *R) const {
177-
return *getRegBank().getRegClass(R);
176+
CodeGenTarget::getRegisterClass(const Record *R, ArrayRef<SMLoc> Loc) const {
177+
return *getRegBank().getRegClass(R, Loc);
178178
}
179179

180180
std::vector<ValueTypeByHwMode>
@@ -227,12 +227,14 @@ const Record *CodeGenTarget::getInitValueAsRegClassLike(const Init *V) const {
227227
const DefInit *VDefInit = dyn_cast<DefInit>(V);
228228
if (!VDefInit)
229229
return nullptr;
230+
return getAsRegClassLike(VDefInit->getDef());
231+
}
230232

231-
const Record *RegClass = VDefInit->getDef();
232-
if (RegClass->isSubClassOf("RegisterOperand"))
233-
return RegClass->getValueAsDef("RegClass");
233+
const Record *CodeGenTarget::getAsRegClassLike(const Record *Rec) const {
234+
if (Rec->isSubClassOf("RegisterOperand"))
235+
return Rec->getValueAsDef("RegClass");
234236

235-
return RegClass->isSubClassOf("RegisterClassLike") ? RegClass : nullptr;
237+
return Rec->isSubClassOf("RegisterClassLike") ? Rec : nullptr;
236238
}
237239

238240
CodeGenSchedModels &CodeGenTarget::getSchedModels() const {

llvm/utils/TableGen/Common/CodeGenTarget.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,8 @@ class CodeGenTarget {
131131
return RegAltNameIndices;
132132
}
133133

134-
const CodeGenRegisterClass &getRegisterClass(const Record *R) const;
134+
const CodeGenRegisterClass &getRegisterClass(const Record *R,
135+
ArrayRef<SMLoc> Loc = {}) const;
135136

136137
/// Convenience wrapper to avoid hardcoding the name of RegClassByHwMode
137138
/// everywhere. This is here instead of CodeGenRegBank to avoid the fatal
@@ -165,6 +166,7 @@ class CodeGenTarget {
165166
/// return the Record. This is used as a convenience function to handle direct
166167
/// RegisterClass references, or those wrapped in a RegisterOperand.
167168
const Record *getInitValueAsRegClassLike(const Init *V) const;
169+
const Record *getAsRegClassLike(const Record *V) const;
168170

169171
CodeGenSchedModels &getSchedModels() const;
170172

llvm/utils/TableGen/CompressInstEmitter.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,8 @@ class CompressInstEmitter {
142142
void emitCompressInstEmitter(raw_ostream &OS, EmitterType EType);
143143
bool validateTypes(const Record *DagOpType, const Record *InstOpType,
144144
bool IsSourceInst);
145-
bool validateRegister(const Record *Reg, const Record *RegClass);
145+
bool validateRegister(const Record *Reg, const Record *RegClass,
146+
ArrayRef<SMLoc> Loc);
146147
void checkDagOperandMapping(const Record *Rec,
147148
const StringMap<ArgData> &DestOperands,
148149
const DagInit *SourceDag, const DagInit *DestDag);
@@ -162,11 +163,12 @@ class CompressInstEmitter {
162163
} // End anonymous namespace.
163164

164165
bool CompressInstEmitter::validateRegister(const Record *Reg,
165-
const Record *RegClass) {
166+
const Record *RegClass,
167+
ArrayRef<SMLoc> Loc) {
166168
assert(Reg->isSubClassOf("Register") && "Reg record should be a Register");
167-
assert(RegClass->isSubClassOf("RegisterClass") &&
168-
"RegClass record should be a RegisterClass");
169-
const CodeGenRegisterClass &RC = Target.getRegisterClass(RegClass);
169+
assert(RegClass->isSubClassOf("RegisterClassLike") &&
170+
"RegClass record should be RegisterClassLike");
171+
const CodeGenRegisterClass &RC = Target.getRegisterClass(RegClass, Loc);
170172
const CodeGenRegister *R = Target.getRegBank().getReg(Reg);
171173
assert(R != nullptr && "Register not defined!!");
172174
return RC.contains(R);
@@ -255,7 +257,7 @@ void CompressInstEmitter::addDagOperandMapping(const Record *Rec,
255257
if (const auto *DI = dyn_cast<DefInit>(Dag->getArg(DAGOpNo))) {
256258
if (DI->getDef()->isSubClassOf("Register")) {
257259
// Check if the fixed register belongs to the Register class.
258-
if (!validateRegister(DI->getDef(), OpndRec))
260+
if (!validateRegister(DI->getDef(), OpndRec, Rec->getLoc()))
259261
PrintFatalError(Rec->getLoc(),
260262
"Error in Dag '" + Dag->getAsString() +
261263
"'Register: '" + DI->getDef()->getName() +

0 commit comments

Comments
 (0)