Skip to content

Commit 63edd24

Browse files
committed
[AIEX] Make all tables in AIEXGenFormats.inc constexpr
We needed to make the tables constexpr to avoid a huge static constructor routine that was blowing up the compilation time of the compiler.
1 parent bc22c70 commit 63edd24

File tree

6 files changed

+96
-48
lines changed

6 files changed

+96
-48
lines changed

llvm/lib/Target/AIE/MCTargetDesc/AIEMCFormats.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,8 @@ unsigned AIEInstFormat::getSlotOffsetHiBit() const {
4848
const MCSlotKind AIEInstFormat::getSlot() const {
4949
// NOTE: for a regular instruction (not packet), the map contains only 1
5050
// value.
51-
// NOTE: so... Overkill to use a map in this case?
5251
assert(hasSingleSlot());
53-
return SlotsMap.begin()->first;
52+
return SlotsMap.begin()->SlotKind;
5453
}
5554

5655

llvm/lib/Target/AIE/MCTargetDesc/AIEMCFormats.h

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,12 @@ class MCFormatField {
160160
MCSlotKind getSlotKind() const { return SlotKind; }
161161
};
162162

163+
class SlotFieldPair {
164+
public:
165+
const MCSlotKind SlotKind;
166+
const MCFormatField *FormatField;
167+
};
168+
163169
} // end namespace llvm
164170

165171
namespace llvm {
@@ -168,9 +174,31 @@ class MCFormatDesc {
168174
public:
169175
enum MCFormatKind { FK_Packet, FK_Instr };
170176

171-
using SlotsFieldsMap =
172-
std::unordered_map<const MCSlotKind, const MCFormatField *,
173-
MCSlotKind::Hasher>;
177+
/// This stores a slice of a lookup table of SlotFieldPairs and emulates a
178+
/// map.
179+
class SlotsFieldsMap {
180+
public:
181+
constexpr SlotsFieldsMap() : ValueSlice({}) {};
182+
constexpr SlotsFieldsMap(const llvm::ArrayRef<SlotFieldPair> Values)
183+
: ValueSlice(Values) {};
184+
185+
SlotFieldPair const &at(const MCSlotKind &Key) const {
186+
auto Pair =
187+
llvm::find_if(ValueSlice, [Key](SlotFieldPair const &SlotField) {
188+
return SlotField.SlotKind == Key;
189+
});
190+
assert(Pair != ValueSlice.end());
191+
return *Pair;
192+
}
193+
194+
SlotFieldPair const *begin() const { return ValueSlice.begin(); }
195+
196+
size_t size() const { return ValueSlice.size(); }
197+
198+
private:
199+
const llvm::ArrayRef<SlotFieldPair> ValueSlice;
200+
};
201+
174202
/// This behaves like an array of variable sized arrays.
175203
/// All elements are consecutive in memory. The outer dimension
176204
/// is an array of pointers into that memory array, which is passed
@@ -219,9 +247,11 @@ class MCFormatDesc {
219247
const MCFormatField *const BaseField;
220248

221249
public:
222-
MCFormatDesc(unsigned Opcode, bool IsComposite, bool HasMultipleSlotOptions,
223-
const SlotsFieldsMap &Slots, OperandsFieldsMap OpFormatMapper,
224-
const MCFormatField *BaseField)
250+
constexpr MCFormatDesc(unsigned Opcode, bool IsComposite,
251+
bool HasMultipleSlotOptions,
252+
const SlotsFieldsMap Slots,
253+
OperandsFieldsMap OpFormatMapper,
254+
const MCFormatField *BaseField)
225255
: Kind(IsComposite ? FK_Packet : FK_Instr),
226256
HasMultipleSlotOptions(HasMultipleSlotOptions), Opcode(Opcode),
227257
SlotsMap(Slots), OpFormatMapper(OpFormatMapper), BaseField(BaseField) {
@@ -259,8 +289,7 @@ class MCFormatDesc {
259289
MCFormatField::GlobalOffsets
260290
getSlotOffsetsHiBit(const MCSlotKind &Kind) const {
261291
assert(!HasMultipleSlotOptions);
262-
assert(SlotsMap.find(Kind) != SlotsMap.end());
263-
return SlotsMap.at(Kind)->getOffsets();
292+
return SlotsMap.at(Kind).FormatField->getOffsets();
264293
}
265294

266295
/// Returns a pair of Offset of the Slot Kind, indexed on the Low bits:
@@ -276,7 +305,9 @@ class MCFormatDesc {
276305
getSlotOffsetsLoBit(const MCSlotKind &Kind) const {
277306
assert(!HasMultipleSlotOptions);
278307
using GlobalOffsets = typename MCFormatField::GlobalOffsets;
279-
GlobalOffsets HiOffsets = SlotsMap.at(Kind)->getOffsets();
308+
309+
GlobalOffsets HiOffsets = SlotsMap.at(Kind).FormatField->getOffsets();
310+
280311
// Offsets are stored as big-endian indexes.
281312
// We need to make a transformation:
282313
GlobalOffsets LoOffsets;
@@ -313,7 +344,6 @@ class AIEPacketFormat : public MCFormatDesc {
313344
/// This is based on the ordering of the operands in the TableGen definition.
314345
const MCSlotKind getSlot(unsigned Idx) const;
315346

316-
317347
/// Returns the number of slots in the Packet Format
318348
inline unsigned getNumberOfSlot() const;
319349

llvm/test/TableGen/CodeGenFormat/FormatTests/MCOperandIndex.td

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,6 @@ def MOV_U20 : TEST_mov20<(outs mMv0Cg20:$reg), (ins uimm20:$imm), [], "mov.u20",
105105
// CHECK-LABEL: FieldRanges[] = {
106106
// CHECK: I128_LDA_LDB_NOP_ALU_LNG_NOP_VEC_ALL [[#RANGE0:]]
107107
// CHECK: // MOV_U20 [[#RANGE1:]]
108-
// CHECK: // Sentinel [[#RANGE2:]]
109108

110109
// We check below two things:
111110
// - the (good) mapping between the slots Kinds and the MCOperand Index
@@ -116,13 +115,17 @@ def MOV_U20 : TEST_mov20<(outs mMv0Cg20:$reg), (ins uimm20:$imm), [], "mov.u20",
116115
// - op: alu, MI.getOperand(2)
117116
// - op: lng, MI.getOperand(3)
118117

119-
// CHECK-LABEL: static MCFormatDesc const Formats[] = {
118+
// CHECK-LABEL: static constexpr SlotFieldPair const SlotsFields[] = {
119+
// CHECK: I128_LDA_LDB_NOP_ALU_LNG_NOP_VEC_ALL [[#I128_INDEX]]
120+
// CHECK-NEXT: { TESTSlotKind::TEST_SLOT_LDA, &FieldsHierarchyTables[[[#%,I128_LDAINDEX:]]] },
121+
// CHECK-NEXT: { TESTSlotKind::TEST_SLOT_LDB, &FieldsHierarchyTables[[[#%,I128_LDBINDEX:]]] },
122+
// CHECK-NEXT: { TESTSlotKind::TEST_SLOT_ALU, &FieldsHierarchyTables[[[#%,I128_ALUINDEX:]]] },
123+
// CHECK-NEXT: { TESTSlotKind::TEST_SLOT_LNG, &FieldsHierarchyTables[[[#%,I128_LNGINDEX:]]] },
124+
// CHECK-NEXT: { TESTSlotKind::TEST_SLOT_VECA, &FieldsHierarchyTables[[[#%,I128_VECAINDEX:]]] },
125+
126+
// CHECK-LABEL: static constexpr MCFormatDesc const Formats[] = {
120127
// CHECK: TEST::I128_LDA_LDB_NOP_ALU_LNG_NOP_VEC_ALL - Index : [[#I128_INDEX]]
121128
// CHECK: /* Slots - Fields mapper */
122-
// CHECK: TESTSlotKind::TEST_SLOT_LDA, &FieldsHierarchyTables[[[#%,I128_LDAINDEX:]]] },
123-
// CHECK-SAME: { TESTSlotKind::TEST_SLOT_LDB, &FieldsHierarchyTables[[[#%,I128_LDBINDEX:]]] },
124-
// CHECK-SAME: { TESTSlotKind::TEST_SLOT_ALU, &FieldsHierarchyTables[[[#%,I128_ALUINDEX:]]] },
125-
// CHECK-SAME: { TESTSlotKind::TEST_SLOT_LNG, &FieldsHierarchyTables[[[#%,I128_LNGINDEX:]]] },
126-
// CHECK-SAME: { TESTSlotKind::TEST_SLOT_VECA, &FieldsHierarchyTables[[[#%,I128_VECAINDEX:]]] }}
129+
// CHECK: llvm::ArrayRef<SlotFieldPair>(&SlotsFields[0], 5),
127130
// CHECK: /* MCOperand - Slots mapper */
128131
// CHECK: {&FieldRanges[[[#RANGE0]]], [[#RANGE1]]},

llvm/test/TableGen/CodeGenFormat/FormatTests/SlotMapping.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ def VMUL80_S32_S32_BM : TEST_vec_acm_bm_zero
4949
// CHECK: TESTSlotKind::TEST_SLOT_VECA
5050
// CHECK-NOT: TESTSlotKind::TEST_SLOT_VECA
5151

52+
// CHECK: SlotFieldPair
53+
// CHECK: TESTSlotKind::TEST_SLOT_ALUAAA
54+
// CHECK: TESTSlotKind::TEST_SLOT_VECA
55+
5256
def MultiSlotPseudo : TESTMultiSlot_Pseudo<[ADD,VMUL80_S32_S32_BM]>;
5357

5458
// CHECK: TEST::MultiSlotPseudo - Index : 0

llvm/utils/TableGen/CodeGenFormat.cpp

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -192,20 +192,22 @@ void CodeGenFormat::run(raw_ostream &o) {
192192
{
193193
ConstTable OpFields("const MCFormatField *", "OpFields");
194194
ConstTable FieldRanges("const MCFormatField * const *", "FieldRanges");
195+
ConstTable SlotsFields("SlotFieldPair", "SlotsFields");
195196
ConstTable Formats(FormatClassEmitted, "Formats");
196197
for (const TGInstrLayout &Inst : InstFormats) {
197-
Inst.emitFormat(FieldsHierarchy, Formats, OpFields, FieldRanges);
198+
Inst.emitFormat(FieldsHierarchy, Formats, OpFields, FieldRanges,
199+
SlotsFields);
198200
Formats.next();
199201
}
200202

201203
Formats.finish();
202204
OpFields.finish();
203-
FieldRanges.mark("Sentinel");
204-
FieldRanges << OpFields.refNext();
205+
SlotsFields.finish();
205206
FieldRanges.finish();
206207

207208
o << OpFields;
208209
o << FieldRanges;
210+
o << SlotsFields;
209211
o << Formats;
210212
o << "#endif // GET_FORMATS_FORMATS_DEFS\n\n";
211213
}
@@ -672,8 +674,8 @@ void TGInstrLayout::emitOpcodeFormatIndex(raw_ostream &o) const {
672674
}
673675

674676
void TGInstrLayout::emitFormat(ConstTable &FieldsHierarchy, ConstTable &o,
675-
ConstTable &OpFields,
676-
ConstTable &FieldRanges) const {
677+
ConstTable &OpFields, ConstTable &FieldRanges,
678+
ConstTable &SlotsFields) const {
677679
o << " // " << Target << "::" << InstrName
678680
<< " - Index : " << std::to_string(InstrID) << "\n"
679681
<< " {\n"
@@ -682,51 +684,49 @@ void TGInstrLayout::emitFormat(ConstTable &FieldsHierarchy, ConstTable &o,
682684
<< " " << (IsComposite ? "true" : "false") << " /* isComposite */,\n"
683685
<< " " << (IsMultipleSlotOptions ? "true" : "false")
684686
<< " /* hasMultipleSlotOptions */,\n"
685-
<< " " << "/* Slots - Fields mapper */\n"
686-
<< " {";
687+
<< " /* Slots - Fields mapper */\n";
687688

688689
const std::string TargetClassName = Target + SlotsRegistry.GenSlotKindName;
690+
SlotsFields.mark(InstrName.c_str());
689691

690-
bool firstIter = true;
691692
for (const auto &SlotField : slots()) {
692-
if (!firstIter)
693-
o << ", ";
694-
else
695-
firstIter = false;
696-
o << "{ ";
697-
o << TargetClassName << "::" << SlotField->SlotClass->getEnumerationString()
698-
<< ", ";
699-
o << FieldsHierarchy.absRef(SlotField->EmissionID);
700-
o << " }";
693+
SlotsFields << "{ ";
694+
SlotsFields << TargetClassName
695+
<< "::" << SlotField->SlotClass->getEnumerationString() << ", ";
696+
SlotsFields << FieldsHierarchy.absRef(SlotField->EmissionID);
697+
SlotsFields << " }";
698+
SlotsFields.next();
701699
}
702-
o << "},\n";
700+
o << " " << SlotsFields.arrayRef() << ",\n";
703701

704702
// Group every field by their operand index (if they have one)
705703
// i.e. { 0 : {field0, field1}, 1 : {field2}}...
706704
std::map<unsigned, SmallVector<TGFieldLayout *>> FieldOpIndexMap;
707705
// Keep track of the maximum operand index
708-
unsigned MaxIdx = 0;
706+
unsigned NumOperands = 0;
709707
for (auto *OperandField : operands()) {
710-
unsigned Idx = OperandField->getMCOperandIndex();
711-
FieldOpIndexMap[Idx].push_back(OperandField);
712-
MaxIdx = std::max(MaxIdx, Idx);
708+
unsigned OperandIdx = OperandField->getMCOperandIndex();
709+
FieldOpIndexMap[OperandIdx].push_back(OperandField);
710+
NumOperands = std::max(NumOperands, OperandIdx);
713711
}
714712

715713
o << " /* MCOperand - Slots mapper */\n";
716714
OpFields.mark(InstrName.c_str());
717715
FieldRanges.mark(InstrName.c_str());
718-
for (unsigned Idx = 0; Idx <= MaxIdx; Idx++) {
719-
FieldRanges << OpFields.ref(Idx);
716+
unsigned OpFieldIdx = 0;
717+
for (unsigned OperandIdx = 0; OperandIdx <= NumOperands; OperandIdx++) {
718+
FieldRanges << OpFields.ref(OpFieldIdx);
720719
FieldRanges.next();
721-
auto It = FieldOpIndexMap.find(Idx);
720+
auto It = FieldOpIndexMap.find(OperandIdx);
722721
if (It != FieldOpIndexMap.end()) {
723722
for (auto &MO : It->second) {
724723
OpFields << " " << FieldsHierarchy.absRef(MO->EmissionID);
725724
OpFields.next();
725+
OpFieldIdx++;
726726
}
727727
}
728728
}
729-
o << " {" << FieldRanges.ref(0) << ", " << MaxIdx + 1 << "},\n";
729+
o << " {" << FieldRanges.ref(0) << ", " << NumOperands + 1 << "},\n";
730730

731731
auto *RootField = *fields().begin();
732732
o << " " << FieldsHierarchy.absRef(RootField->EmissionID) << "\n"

llvm/utils/TableGen/CodeGenFormat.h

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,16 +57,18 @@ class TGFieldIterator;
5757
// Helper class to create flat tables and some corresponding utilities
5858
class ConstTable {
5959
std::stringstream Text;
60+
std::string Type;
6061
std::string Name;
6162
unsigned Mark = 0;
6263
unsigned Size = 0;
6364

6465
public:
65-
ConstTable(std::string Type, std::string Name) : Name(Name) {
66-
Text << "static " << Type << " const " << Name << "[] = {\n";
66+
ConstTable(std::string Type, std::string Name) : Type(Type), Name(Name) {
67+
Text << "static constexpr " << Type << " const " << Name << "[] = {\n";
6768
}
6869
const std::stringstream &text() const { return Text; }
6970
std::stringstream &text() { return Text; }
71+
unsigned size() { return Size; }
7072

7173
// Mark the start of a block of items
7274
unsigned mark(const char *Comment = nullptr) {
@@ -85,6 +87,15 @@ class ConstTable {
8587
std::string ref(unsigned Idx) const { return absRef(Mark + Idx); }
8688
// Make a reference to the next entry
8789
std::string refNext() const { return absRef(Size); }
90+
// Return an ArrayRef of the entries since the last marked block
91+
std::string arrayRef() const {
92+
unsigned NumElements = Size - Mark;
93+
if (NumElements == 0) {
94+
return "{}";
95+
}
96+
return "llvm::ArrayRef<" + Type + ">(" + ref(0) + ", " +
97+
std::to_string(NumElements) + ")";
98+
}
8899

89100
// Move to the next entry
90101
void next() {
@@ -207,7 +218,8 @@ class TGInstrLayout {
207218
void emitFlatTree(ConstTable &o, unsigned &BaseIndex) const;
208219
/// Emit the Format entries.
209220
void emitFormat(ConstTable &FieldHierarcht, ConstTable &Formats,
210-
ConstTable &OpFields, ConstTable &FieldRanges) const;
221+
ConstTable &OpFields, ConstTable &FieldRanges,
222+
ConstTable &SlotsFields) const;
211223
/// Emit a case table to get InstrID based of InstrName.
212224
void emitOpcodeFormatIndex(raw_ostream &o) const;
213225
/// Emit a set array to get AlternateInsts refs based of

0 commit comments

Comments
 (0)