Skip to content

Commit 660cc98

Browse files
authored
[TableGen] Add CodeGenIntrinsicsMap for on-demand intrinsic creation (#107100)
- Add class `CodeGenIntrinsicMap` for on-demand creation of `CodeGenIntrinsic`. - Add class `CodeGenIntrinsicContext` to capture global information required to build `CodeGenIntrinsic` objects. - Adopt GlobalISel PatternParser and SearchableTableEmitter to use it.
1 parent dcf0160 commit 660cc98

File tree

5 files changed

+52
-28
lines changed

5 files changed

+52
-28
lines changed

llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,20 +25,20 @@ using namespace llvm;
2525
// CodeGenIntrinsic Implementation
2626
//===----------------------------------------------------------------------===//
2727

28-
CodeGenIntrinsicTable::CodeGenIntrinsicTable(const RecordKeeper &RC) {
29-
std::vector<Record *> IntrProperties =
30-
RC.getAllDerivedDefinitions("IntrinsicProperty");
31-
32-
std::vector<const Record *> DefaultProperties;
33-
for (const Record *Rec : IntrProperties)
28+
CodeGenIntrinsicContext::CodeGenIntrinsicContext(const RecordKeeper &RC) {
29+
for (const Record *Rec : RC.getAllDerivedDefinitions("IntrinsicProperty"))
3430
if (Rec->getValueAsBit("IsDefault"))
3531
DefaultProperties.push_back(Rec);
32+
}
33+
34+
CodeGenIntrinsicTable::CodeGenIntrinsicTable(const RecordKeeper &RC) {
35+
CodeGenIntrinsicContext Ctx(RC);
3636

3737
std::vector<Record *> Defs = RC.getAllDerivedDefinitions("Intrinsic");
3838
Intrinsics.reserve(Defs.size());
3939

4040
for (const Record *Def : Defs)
41-
Intrinsics.push_back(CodeGenIntrinsic(Def, DefaultProperties));
41+
Intrinsics.push_back(CodeGenIntrinsic(Def, Ctx));
4242

4343
llvm::sort(Intrinsics,
4444
[](const CodeGenIntrinsic &LHS, const CodeGenIntrinsic &RHS) {
@@ -54,8 +54,18 @@ CodeGenIntrinsicTable::CodeGenIntrinsicTable(const RecordKeeper &RC) {
5454
Targets.back().Count = Intrinsics.size() - Targets.back().Offset;
5555
}
5656

57+
CodeGenIntrinsic &CodeGenIntrinsicMap::operator[](const Record *Record) {
58+
if (!Record->isSubClassOf("Intrinsic"))
59+
PrintFatalError("Intrinsic defs should be subclass of 'Intrinsic' class");
60+
61+
auto [Iter, Inserted] = Map.try_emplace(Record);
62+
if (Inserted)
63+
Iter->second = std::make_unique<CodeGenIntrinsic>(Record, Ctx);
64+
return *Iter->second;
65+
}
66+
5767
CodeGenIntrinsic::CodeGenIntrinsic(const Record *R,
58-
ArrayRef<const Record *> DefaultProperties)
68+
const CodeGenIntrinsicContext &Ctx)
5969
: TheDef(R) {
6070
StringRef DefName = TheDef->getName();
6171
ArrayRef<SMLoc> DefLoc = R->getLoc();
@@ -119,7 +129,7 @@ CodeGenIntrinsic::CodeGenIntrinsic(const Record *R,
119129
}
120130

121131
// Set default properties to true.
122-
setDefaultProperties(DefaultProperties);
132+
setDefaultProperties(Ctx.DefaultProperties);
123133

124134
// Also record the SDPatternOperator Properties.
125135
Properties = parseSDPatternOperatorProperties(R);

llvm/utils/TableGen/Basic/CodeGenIntrinsics.h

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
#include "SDNodeProperties.h"
1717
#include "llvm/ADT/ArrayRef.h"
18+
#include "llvm/ADT/DenseMap.h"
1819
#include "llvm/ADT/SmallVector.h"
1920
#include "llvm/Support/ModRef.h"
2021
#include <string>
@@ -25,6 +26,12 @@ namespace llvm {
2526
class Record;
2627
class RecordKeeper;
2728

29+
// Global information needed to build intrinsics.
30+
struct CodeGenIntrinsicContext {
31+
explicit CodeGenIntrinsicContext(const RecordKeeper &RC);
32+
std::vector<const Record *> DefaultProperties;
33+
};
34+
2835
struct CodeGenIntrinsic {
2936
const Record *TheDef; // The actual record defining this intrinsic.
3037
std::string Name; // The name of the LLVM function "llvm.bswap.i32"
@@ -155,8 +162,7 @@ struct CodeGenIntrinsic {
155162

156163
bool isParamImmArg(unsigned ParamIdx) const;
157164

158-
CodeGenIntrinsic(const Record *R,
159-
ArrayRef<const Record *> DefaultProperties = {});
165+
CodeGenIntrinsic(const Record *R, const CodeGenIntrinsicContext &Ctx);
160166
};
161167

162168
class CodeGenIntrinsicTable {
@@ -171,7 +177,6 @@ class CodeGenIntrinsicTable {
171177
std::vector<TargetSet> Targets;
172178

173179
explicit CodeGenIntrinsicTable(const RecordKeeper &RC);
174-
CodeGenIntrinsicTable() = default;
175180

176181
bool empty() const { return Intrinsics.empty(); }
177182
size_t size() const { return Intrinsics.size(); }
@@ -182,6 +187,17 @@ class CodeGenIntrinsicTable {
182187
return Intrinsics[Pos];
183188
}
184189
};
190+
191+
// This class builds `CodeGenIntrinsic` on demand for a given Def.
192+
class CodeGenIntrinsicMap {
193+
DenseMap<const Record *, std::unique_ptr<CodeGenIntrinsic>> Map;
194+
const CodeGenIntrinsicContext Ctx;
195+
196+
public:
197+
explicit CodeGenIntrinsicMap(const RecordKeeper &RC) : Ctx(RC) {}
198+
CodeGenIntrinsic &operator[](const Record *Def);
199+
};
200+
185201
} // namespace llvm
186202

187203
#endif // LLVM_UTILS_TABLEGEN_BASIC_CODEGENINTRINSICS_H

llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3160,10 +3160,8 @@ void TreePattern::dump() const { print(errs()); }
31603160

31613161
CodeGenDAGPatterns::CodeGenDAGPatterns(RecordKeeper &R,
31623162
PatternRewriterFn PatternRewriter)
3163-
: Records(R), Target(R), LegalVTS(Target.getLegalValueTypes()),
3164-
PatternRewriter(PatternRewriter) {
3165-
3166-
Intrinsics = CodeGenIntrinsicTable(Records);
3163+
: Records(R), Target(R), Intrinsics(R),
3164+
LegalVTS(Target.getLegalValueTypes()), PatternRewriter(PatternRewriter) {
31673165
ParseNodeInfo();
31683166
ParseNodeTransforms();
31693167
ParseComplexPatterns();

llvm/utils/TableGen/Common/GlobalISel/PatternParser.cpp

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -107,13 +107,10 @@ getInstrForIntrinsic(const CodeGenTarget &CGT, const CodeGenIntrinsic *I) {
107107
static const CodeGenIntrinsic *getCodeGenIntrinsic(Record *R) {
108108
// Intrinsics need to have a static lifetime because the match table keeps
109109
// references to CodeGenIntrinsic objects.
110-
static DenseMap<const Record *, std::unique_ptr<CodeGenIntrinsic>>
111-
AllIntrinsics;
112-
113-
auto &Ptr = AllIntrinsics[R];
114-
if (!Ptr)
115-
Ptr = std::make_unique<CodeGenIntrinsic>(R);
116-
return Ptr.get();
110+
static CodeGenIntrinsicMap *AllIntrinsics;
111+
if (!AllIntrinsics)
112+
AllIntrinsics = new CodeGenIntrinsicMap(R->getRecords());
113+
return &(*AllIntrinsics)[R];
117114
}
118115

119116
std::unique_ptr<Pattern>

llvm/utils/TableGen/SearchableTableEmitter.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ struct GenericTable {
9494
class SearchableTableEmitter {
9595
RecordKeeper &Records;
9696
std::unique_ptr<CodeGenTarget> Target;
97-
DenseMap<Init *, std::unique_ptr<CodeGenIntrinsic>> Intrinsics;
97+
std::unique_ptr<CodeGenIntrinsicMap> Intrinsics;
9898
std::vector<std::unique_ptr<GenericEnum>> Enums;
9999
DenseMap<Record *, GenericEnum *> EnumMap;
100100
std::set<std::string> PreprocessorGuards;
@@ -146,10 +146,13 @@ class SearchableTableEmitter {
146146
}
147147

148148
CodeGenIntrinsic &getIntrinsic(Init *I) {
149-
std::unique_ptr<CodeGenIntrinsic> &Intr = Intrinsics[I];
150-
if (!Intr)
151-
Intr = std::make_unique<CodeGenIntrinsic>(cast<DefInit>(I)->getDef());
152-
return *Intr;
149+
const Record *Def = cast<DefInit>(I)->getDef();
150+
// Build the Intrinsics map on demand. If we instantiate one in the
151+
// constructor, we may get errors if the TableGen file being processed does
152+
// not include Intrinsics.td and does not do anything with intrinsics.
153+
if (!Intrinsics)
154+
Intrinsics = std::make_unique<CodeGenIntrinsicMap>(Records);
155+
return (*Intrinsics)[Def];
153156
}
154157

155158
bool compareBy(Record *LHS, Record *RHS, const SearchIndex &Index);

0 commit comments

Comments
 (0)