diff options
author | Daniel Sanders <daniel_l_sanders@apple.com> | 2017-04-29 17:30:09 +0000 |
---|---|---|
committer | Daniel Sanders <daniel_l_sanders@apple.com> | 2017-04-29 17:30:09 +0000 |
commit | e9fdba39e005bbb8abb90aacf80e75a477b51208 (patch) | |
tree | 1394158ed113cc9e0db54d7c45812b3adb6eed9a /llvm/utils/TableGen | |
parent | 96d02f550397c46278924dd1081b5b33da270a05 (diff) | |
download | bcm5719-llvm-e9fdba39e005bbb8abb90aacf80e75a477b51208.tar.gz bcm5719-llvm-e9fdba39e005bbb8abb90aacf80e75a477b51208.zip |
[globalisel][tablegen] Compute available feature bits correctly.
Summary:
Predicate<> now has a field to indicate how often it must be recomputed.
Currently, there are two frequencies, per-module (RecomputePerFunction==0)
and per-function (RecomputePerFunction==1). Per-function predicates are
currently recomputed more frequently than necessary since the only predicate
in this category is cheap to test. Per-module predicates are now computed in
getSubtargetImpl() while per-function predicates are computed in selectImpl().
Tablegen now manages the PredicateBitset internally. It should only be
necessary to add the required includes.
Also fixed a problem revealed by the test case where
constrainSelectedInstRegOperands() would attempt to tie operands that
BuildMI had already tied.
Reviewers: ab, qcolombet, t.p.northover, rovka, aditya_nandakumar
Reviewed By: rovka
Subscribers: kristof.beyls, igorb, llvm-commits
Differential Revision: https://reviews.llvm.org/D32491
llvm-svn: 301750
Diffstat (limited to 'llvm/utils/TableGen')
-rw-r--r-- | llvm/utils/TableGen/GlobalISelEmitter.cpp | 78 | ||||
-rw-r--r-- | llvm/utils/TableGen/SubtargetFeatureInfo.cpp | 22 | ||||
-rw-r--r-- | llvm/utils/TableGen/SubtargetFeatureInfo.h | 36 |
3 files changed, 89 insertions, 47 deletions
diff --git a/llvm/utils/TableGen/GlobalISelEmitter.cpp b/llvm/utils/TableGen/GlobalISelEmitter.cpp index dcf10ab511d..f0b7c436fb5 100644 --- a/llvm/utils/TableGen/GlobalISelEmitter.cpp +++ b/llvm/utils/TableGen/GlobalISelEmitter.cpp @@ -199,21 +199,19 @@ public: void emitCxxCapturedInsnList(raw_ostream &OS); void emitCxxCaptureStmts(raw_ostream &OS, StringRef Expr); - void emit(raw_ostream &OS, - std::map<Record *, SubtargetFeatureInfo, LessRecordByID> - SubtargetFeatures); +void emit(raw_ostream &OS, SubtargetFeatureInfoMap SubtargetFeatures); - /// Compare the priority of this object and B. - /// - /// Returns true if this object is more important than B. - bool isHigherPriorityThan(const RuleMatcher &B) const; +/// Compare the priority of this object and B. +/// +/// Returns true if this object is more important than B. +bool isHigherPriorityThan(const RuleMatcher &B) const; - /// Report the maximum number of temporary operands needed by the rule - /// matcher. - unsigned countRendererFns() const; +/// Report the maximum number of temporary operands needed by the rule +/// matcher. +unsigned countRendererFns() const; - // FIXME: Remove this as soon as possible - InstructionMatcher &insnmatcher_front() const { return *Matchers.front(); } +// FIXME: Remove this as soon as possible +InstructionMatcher &insnmatcher_front() const { return *Matchers.front(); } }; template <class PredicateTy> class PredicateListMatcher { @@ -951,6 +949,9 @@ private: /// True if the instruction can be built solely by mutating the opcode. bool canMutate() const { + if (OperandRenderers.size() != Matched.getNumOperands()) + return false; + for (const auto &Renderer : enumerate(OperandRenderers)) { if (const auto *Copy = dyn_cast<CopyRenderer>(&*Renderer.value())) { const OperandMatcher &OM = Matched.getOperand(Copy->getSymbolicName()); @@ -1072,8 +1073,7 @@ void RuleMatcher::emitCxxCaptureStmts(raw_ostream &OS, StringRef Expr) { } void RuleMatcher::emit(raw_ostream &OS, - std::map<Record *, SubtargetFeatureInfo, LessRecordByID> - SubtargetFeatures) { + SubtargetFeatureInfoMap SubtargetFeatures) { if (Matchers.empty()) llvm_unreachable("Unexpected empty matcher!"); @@ -1218,7 +1218,7 @@ private: DenseMap<const Record *, const Record *> ComplexPatternEquivs; // Map of predicates to their subtarget features. - std::map<Record *, SubtargetFeatureInfo, LessRecordByID> SubtargetFeatures; + SubtargetFeatureInfoMap SubtargetFeatures; void gatherNodeEquivs(); const CodeGenInstruction *findNodeEquiv(Record *N) const; @@ -1713,14 +1713,36 @@ void GlobalISelEmitter::run(raw_ostream &OS) { SubtargetFeatureInfo::emitSubtargetFeatureBitEnumeration(SubtargetFeatures, OS); SubtargetFeatureInfo::emitNameTable(SubtargetFeatures, OS); + + // Separate subtarget features by how often they must be recomputed. + SubtargetFeatureInfoMap ModuleFeatures; + std::copy_if(SubtargetFeatures.begin(), SubtargetFeatures.end(), + std::inserter(ModuleFeatures, ModuleFeatures.end()), + [](const SubtargetFeatureInfoMap::value_type &X) { + return !X.second.mustRecomputePerFunction(); + }); + SubtargetFeatureInfoMap FunctionFeatures; + std::copy_if(SubtargetFeatures.begin(), SubtargetFeatures.end(), + std::inserter(FunctionFeatures, FunctionFeatures.end()), + [](const SubtargetFeatureInfoMap::value_type &X) { + return X.second.mustRecomputePerFunction(); + }); + SubtargetFeatureInfo::emitComputeAvailableFeatures( - Target.getName(), "InstructionSelector", "computeAvailableFeatures", - SubtargetFeatures, OS); + Target.getName(), "InstructionSelector", "computeAvailableModuleFeatures", + ModuleFeatures, OS); + SubtargetFeatureInfo::emitComputeAvailableFeatures( + Target.getName(), "InstructionSelector", + "computeAvailableFunctionFeatures", FunctionFeatures, OS, + "const MachineFunction *MF"); OS << "bool " << Target.getName() << "InstructionSelector::selectImpl(MachineInstr &I) const {\n" << " MachineFunction &MF = *I.getParent()->getParent();\n" - << " const MachineRegisterInfo &MRI = MF.getRegInfo();\n"; + << " const MachineRegisterInfo &MRI = MF.getRegInfo();\n" + << " // FIXME: This should be computed on a per-function basis rather than per-insn.\n" + << " AvailableFunctionFeatures = computeAvailableFunctionFeatures(&STI, &MF);\n" + << " const PredicateBitset AvailableFeatures = getAvailableFeatures();\n"; for (auto &Rule : Rules) { Rule.emit(OS, SubtargetFeatures); @@ -1730,6 +1752,26 @@ void GlobalISelEmitter::run(raw_ostream &OS) { OS << " return false;\n" << "}\n" << "#endif // ifdef GET_GLOBALISEL_IMPL\n"; + + OS << "#ifdef GET_GLOBALISEL_PREDICATES_DECL\n" + << "PredicateBitset AvailableModuleFeatures;\n" + << "mutable PredicateBitset AvailableFunctionFeatures;\n" + << "PredicateBitset getAvailableFeatures() const {\n" + << " return AvailableModuleFeatures | AvailableFunctionFeatures;\n" + << "}\n" + << "PredicateBitset\n" + << "computeAvailableModuleFeatures(const " << Target.getName() + << "Subtarget *Subtarget) const;\n" + << "PredicateBitset\n" + << "computeAvailableFunctionFeatures(const " << Target.getName() + << "Subtarget *Subtarget,\n" + << " const MachineFunction *MF) const;\n" + << "#endif // ifdef GET_GLOBALISEL_PREDICATES_DECL\n"; + + OS << "#ifdef GET_GLOBALISEL_PREDICATES_INIT\n" + << "AvailableModuleFeatures(computeAvailableModuleFeatures(&STI)),\n" + << "AvailableFunctionFeatures()\n" + << "#endif // ifdef GET_GLOBALISEL_PREDICATES_INIT\n"; } void GlobalISelEmitter::declareSubtargetFeature(Record *Predicate) { diff --git a/llvm/utils/TableGen/SubtargetFeatureInfo.cpp b/llvm/utils/TableGen/SubtargetFeatureInfo.cpp index 96418dc77d5..5153c35b126 100644 --- a/llvm/utils/TableGen/SubtargetFeatureInfo.cpp +++ b/llvm/utils/TableGen/SubtargetFeatureInfo.cpp @@ -45,8 +45,7 @@ SubtargetFeatureInfo::getAll(const RecordKeeper &Records) { } void SubtargetFeatureInfo::emitSubtargetFeatureFlagEnumeration( - std::map<Record *, SubtargetFeatureInfo, LessRecordByID> &SubtargetFeatures, - raw_ostream &OS) { + SubtargetFeatureInfoMap &SubtargetFeatures, raw_ostream &OS) { OS << "// Flags for subtarget features that participate in " << "instruction matching.\n"; OS << "enum SubtargetFeatureFlag : " @@ -60,8 +59,7 @@ void SubtargetFeatureInfo::emitSubtargetFeatureFlagEnumeration( } void SubtargetFeatureInfo::emitSubtargetFeatureBitEnumeration( - std::map<Record *, SubtargetFeatureInfo, LessRecordByID> &SubtargetFeatures, - raw_ostream &OS) { + SubtargetFeatureInfoMap &SubtargetFeatures, raw_ostream &OS) { OS << "// Bits for subtarget features that participate in " << "instruction matching.\n"; OS << "enum SubtargetFeatureBits : " @@ -74,8 +72,7 @@ void SubtargetFeatureInfo::emitSubtargetFeatureBitEnumeration( } void SubtargetFeatureInfo::emitNameTable( - std::map<Record *, SubtargetFeatureInfo, LessRecordByID> &SubtargetFeatures, - raw_ostream &OS) { + SubtargetFeatureInfoMap &SubtargetFeatures, raw_ostream &OS) { // Need to sort the name table so that lookup by the log of the enum value // gives the proper name. More specifically, for a feature of value 1<<n, // SubtargetFeatureNames[n] should be the name of the feature. @@ -102,11 +99,13 @@ void SubtargetFeatureInfo::emitNameTable( void SubtargetFeatureInfo::emitComputeAvailableFeatures( StringRef TargetName, StringRef ClassName, StringRef FuncName, - std::map<Record *, SubtargetFeatureInfo, LessRecordByID> &SubtargetFeatures, - raw_ostream &OS) { + SubtargetFeatureInfoMap &SubtargetFeatures, raw_ostream &OS, + StringRef ExtraParams) { OS << "PredicateBitset " << TargetName << ClassName << "::\n" - << FuncName << "(const MachineFunction *MF, const " << TargetName - << "Subtarget *Subtarget) const {\n"; + << FuncName << "(const " << TargetName << "Subtarget *Subtarget"; + if (!ExtraParams.empty()) + OS << ", " << ExtraParams; + OS << ") const {\n"; OS << " PredicateBitset Features;\n"; for (const auto &SF : SubtargetFeatures) { const SubtargetFeatureInfo &SFI = SF.second; @@ -120,8 +119,7 @@ void SubtargetFeatureInfo::emitComputeAvailableFeatures( void SubtargetFeatureInfo::emitComputeAssemblerAvailableFeatures( StringRef TargetName, StringRef ClassName, StringRef FuncName, - std::map<Record *, SubtargetFeatureInfo, LessRecordByID> &SubtargetFeatures, - raw_ostream &OS) { + SubtargetFeatureInfoMap &SubtargetFeatures, raw_ostream &OS) { OS << "uint64_t " << TargetName << ClassName << "::\n" << FuncName << "(const FeatureBitset& FB) const {\n"; OS << " uint64_t Features = 0;\n"; diff --git a/llvm/utils/TableGen/SubtargetFeatureInfo.h b/llvm/utils/TableGen/SubtargetFeatureInfo.h index bbaf4525960..c55c16a4031 100644 --- a/llvm/utils/TableGen/SubtargetFeatureInfo.h +++ b/llvm/utils/TableGen/SubtargetFeatureInfo.h @@ -21,6 +21,9 @@ namespace llvm { class Record; class RecordKeeper; +struct SubtargetFeatureInfo; +using SubtargetFeatureInfoMap = std::map<Record *, SubtargetFeatureInfo, LessRecordByID>; + /// Helper class for storing information on a subtarget feature which /// participates in instruction matching. struct SubtargetFeatureInfo { @@ -43,6 +46,10 @@ struct SubtargetFeatureInfo { return "Feature_" + TheDef->getName().str() + "Bit"; } + bool mustRecomputePerFunction() const { + return TheDef->getValueAsBit("RecomputePerFunction"); + } + void dump() const; static std::vector<std::pair<Record *, SubtargetFeatureInfo>> getAll(const RecordKeeper &Records); @@ -52,21 +59,17 @@ struct SubtargetFeatureInfo { /// This version emits the bit value for the feature and is therefore limited /// to 64 feature bits. static void emitSubtargetFeatureFlagEnumeration( - std::map<Record *, SubtargetFeatureInfo, LessRecordByID> - &SubtargetFeatures, - raw_ostream &OS); + SubtargetFeatureInfoMap &SubtargetFeatures, raw_ostream &OS); /// Emit the subtarget feature flag definitions. /// /// This version emits the bit index for the feature and can therefore support /// more than 64 feature bits. - static void emitSubtargetFeatureBitEnumeration( - std::map<Record *, SubtargetFeatureInfo, LessRecordByID> - &SubtargetFeatures, - raw_ostream &OS); + static void + emitSubtargetFeatureBitEnumeration(SubtargetFeatureInfoMap &SubtargetFeatures, + raw_ostream &OS); - static void emitNameTable(std::map<Record *, SubtargetFeatureInfo, - LessRecordByID> &SubtargetFeatures, + static void emitNameTable(SubtargetFeatureInfoMap &SubtargetFeatures, raw_ostream &OS); /// Emit the function to compute the list of available features given a @@ -82,11 +85,12 @@ struct SubtargetFeatureInfo { /// \param FuncName The name of the function to emit. /// \param SubtargetFeatures A map of TableGen records to the /// SubtargetFeatureInfo equivalent. - static void emitComputeAvailableFeatures( - StringRef TargetName, StringRef ClassName, StringRef FuncName, - std::map<Record *, SubtargetFeatureInfo, LessRecordByID> - &SubtargetFeatures, - raw_ostream &OS); + /// \param ExtraParams Additional arguments to the generated function. + static void + emitComputeAvailableFeatures(StringRef TargetName, StringRef ClassName, + StringRef FuncName, + SubtargetFeatureInfoMap &SubtargetFeatures, + raw_ostream &OS, StringRef ExtraParams = ""); /// Emit the function to compute the list of available features given a /// subtarget. @@ -103,9 +107,7 @@ struct SubtargetFeatureInfo { /// SubtargetFeatureInfo equivalent. static void emitComputeAssemblerAvailableFeatures( StringRef TargetName, StringRef ClassName, StringRef FuncName, - std::map<Record *, SubtargetFeatureInfo, LessRecordByID> - &SubtargetFeatures, - raw_ostream &OS); + SubtargetFeatureInfoMap &SubtargetFeatures, raw_ostream &OS); }; } // end namespace llvm |