Skip to content

[TableGen] Add CodeGenIntrinsicsMap for on-demand intrinsic creation #107100

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 19 additions & 9 deletions llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,20 @@ using namespace llvm;
// CodeGenIntrinsic Implementation
//===----------------------------------------------------------------------===//

CodeGenIntrinsicTable::CodeGenIntrinsicTable(const RecordKeeper &RC) {
std::vector<Record *> IntrProperties =
RC.getAllDerivedDefinitions("IntrinsicProperty");

std::vector<const Record *> DefaultProperties;
for (const Record *Rec : IntrProperties)
CodeGenIntrinsicContext::CodeGenIntrinsicContext(const RecordKeeper &RC) {
for (const Record *Rec : RC.getAllDerivedDefinitions("IntrinsicProperty"))
if (Rec->getValueAsBit("IsDefault"))
DefaultProperties.push_back(Rec);
}

CodeGenIntrinsicTable::CodeGenIntrinsicTable(const RecordKeeper &RC) {
CodeGenIntrinsicContext Ctx(RC);

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

for (const Record *Def : Defs)
Intrinsics.push_back(CodeGenIntrinsic(Def, DefaultProperties));
Intrinsics.push_back(CodeGenIntrinsic(Def, Ctx));

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

CodeGenIntrinsic &CodeGenIntrinsicMap::operator[](const Record *Record) {
if (!Record->isSubClassOf("Intrinsic"))
PrintFatalError("Intrinsic defs should be subclass of 'Intrinsic' class");

auto [Iter, Inserted] = Map.try_emplace(Record);
if (Inserted)
Iter->second = std::make_unique<CodeGenIntrinsic>(Record, Ctx);
return *Iter->second;
}

CodeGenIntrinsic::CodeGenIntrinsic(const Record *R,
ArrayRef<const Record *> DefaultProperties)
const CodeGenIntrinsicContext &Ctx)
: TheDef(R) {
StringRef DefName = TheDef->getName();
ArrayRef<SMLoc> DefLoc = R->getLoc();
Expand Down Expand Up @@ -119,7 +129,7 @@ CodeGenIntrinsic::CodeGenIntrinsic(const Record *R,
}

// Set default properties to true.
setDefaultProperties(DefaultProperties);
setDefaultProperties(Ctx.DefaultProperties);

// Also record the SDPatternOperator Properties.
Properties = parseSDPatternOperatorProperties(R);
Expand Down
22 changes: 19 additions & 3 deletions llvm/utils/TableGen/Basic/CodeGenIntrinsics.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

#include "SDNodeProperties.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/ModRef.h"
#include <string>
Expand All @@ -25,6 +26,12 @@ namespace llvm {
class Record;
class RecordKeeper;

// Global information needed to build intrinsics.
struct CodeGenIntrinsicContext {
explicit CodeGenIntrinsicContext(const RecordKeeper &RC);
std::vector<const Record *> DefaultProperties;
};

struct CodeGenIntrinsic {
const Record *TheDef; // The actual record defining this intrinsic.
std::string Name; // The name of the LLVM function "llvm.bswap.i32"
Expand Down Expand Up @@ -155,8 +162,7 @@ struct CodeGenIntrinsic {

bool isParamImmArg(unsigned ParamIdx) const;

CodeGenIntrinsic(const Record *R,
ArrayRef<const Record *> DefaultProperties = {});
CodeGenIntrinsic(const Record *R, const CodeGenIntrinsicContext &Ctx);
};

class CodeGenIntrinsicTable {
Expand All @@ -171,7 +177,6 @@ class CodeGenIntrinsicTable {
std::vector<TargetSet> Targets;

explicit CodeGenIntrinsicTable(const RecordKeeper &RC);
CodeGenIntrinsicTable() = default;

bool empty() const { return Intrinsics.empty(); }
size_t size() const { return Intrinsics.size(); }
Expand All @@ -182,6 +187,17 @@ class CodeGenIntrinsicTable {
return Intrinsics[Pos];
}
};

// This class builds `CodeGenIntrinsic` on demand for a given Def.
class CodeGenIntrinsicMap {
DenseMap<const Record *, std::unique_ptr<CodeGenIntrinsic>> Map;
const CodeGenIntrinsicContext Ctx;

public:
explicit CodeGenIntrinsicMap(const RecordKeeper &RC) : Ctx(RC) {}
CodeGenIntrinsic &operator[](const Record *Def);
};

} // namespace llvm

#endif // LLVM_UTILS_TABLEGEN_BASIC_CODEGENINTRINSICS_H
6 changes: 2 additions & 4 deletions llvm/utils/TableGen/Common/CodeGenDAGPatterns.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3160,10 +3160,8 @@ void TreePattern::dump() const { print(errs()); }

CodeGenDAGPatterns::CodeGenDAGPatterns(RecordKeeper &R,
PatternRewriterFn PatternRewriter)
: Records(R), Target(R), LegalVTS(Target.getLegalValueTypes()),
PatternRewriter(PatternRewriter) {

Intrinsics = CodeGenIntrinsicTable(Records);
: Records(R), Target(R), Intrinsics(R),
LegalVTS(Target.getLegalValueTypes()), PatternRewriter(PatternRewriter) {
ParseNodeInfo();
ParseNodeTransforms();
ParseComplexPatterns();
Expand Down
11 changes: 4 additions & 7 deletions llvm/utils/TableGen/Common/GlobalISel/PatternParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,13 +107,10 @@ getInstrForIntrinsic(const CodeGenTarget &CGT, const CodeGenIntrinsic *I) {
static const CodeGenIntrinsic *getCodeGenIntrinsic(Record *R) {
// Intrinsics need to have a static lifetime because the match table keeps
// references to CodeGenIntrinsic objects.
static DenseMap<const Record *, std::unique_ptr<CodeGenIntrinsic>>
AllIntrinsics;

auto &Ptr = AllIntrinsics[R];
if (!Ptr)
Ptr = std::make_unique<CodeGenIntrinsic>(R);
return Ptr.get();
static CodeGenIntrinsicMap *AllIntrinsics;
if (!AllIntrinsics)
AllIntrinsics = new CodeGenIntrinsicMap(R->getRecords());
return &(*AllIntrinsics)[R];
}

std::unique_ptr<Pattern>
Expand Down
13 changes: 8 additions & 5 deletions llvm/utils/TableGen/SearchableTableEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ struct GenericTable {
class SearchableTableEmitter {
RecordKeeper &Records;
std::unique_ptr<CodeGenTarget> Target;
DenseMap<Init *, std::unique_ptr<CodeGenIntrinsic>> Intrinsics;
std::unique_ptr<CodeGenIntrinsicMap> Intrinsics;
std::vector<std::unique_ptr<GenericEnum>> Enums;
DenseMap<Record *, GenericEnum *> EnumMap;
std::set<std::string> PreprocessorGuards;
Expand Down Expand Up @@ -146,10 +146,13 @@ class SearchableTableEmitter {
}

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

bool compareBy(Record *LHS, Record *RHS, const SearchIndex &Index);
Expand Down
Loading