summaryrefslogtreecommitdiffstats
path: root/llvm/utils/TableGen/GlobalISelEmitter.cpp
diff options
context:
space:
mode:
authorDaniel Sanders <daniel_l_sanders@apple.com>2017-04-29 17:30:09 +0000
committerDaniel Sanders <daniel_l_sanders@apple.com>2017-04-29 17:30:09 +0000
commite9fdba39e005bbb8abb90aacf80e75a477b51208 (patch)
tree1394158ed113cc9e0db54d7c45812b3adb6eed9a /llvm/utils/TableGen/GlobalISelEmitter.cpp
parent96d02f550397c46278924dd1081b5b33da270a05 (diff)
downloadbcm5719-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/GlobalISelEmitter.cpp')
-rw-r--r--llvm/utils/TableGen/GlobalISelEmitter.cpp78
1 files changed, 60 insertions, 18 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) {
OpenPOWER on IntegriCloud