diff options
Diffstat (limited to 'utils/TableGen/GlobalISelEmitter.cpp')
-rw-r--r-- | utils/TableGen/GlobalISelEmitter.cpp | 115 |
1 files changed, 70 insertions, 45 deletions
diff --git a/utils/TableGen/GlobalISelEmitter.cpp b/utils/TableGen/GlobalISelEmitter.cpp index b80f023550622..c7d662db5a2fe 100644 --- a/utils/TableGen/GlobalISelEmitter.cpp +++ b/utils/TableGen/GlobalISelEmitter.cpp @@ -574,6 +574,7 @@ class Matcher { public: virtual ~Matcher() = default; virtual void emit(MatchTable &Table) = 0; + virtual std::unique_ptr<PredicateMatcher> forgetFirstCondition() = 0; }; class GroupMatcher : public Matcher { @@ -595,6 +596,15 @@ public: Rules.clear(); } void emit(MatchTable &Table) override; + + std::unique_ptr<PredicateMatcher> forgetFirstCondition() override { + // We shouldn't need to mess up with groups, since we + // should have merged everything shareable upfront. + // If we start to look into reordering predicates, + // we may want to reconsider this. + assert(0 && "Groups should be formed maximal for now"); + llvm_unreachable("No need for this for now"); + } }; /// Generates code to check that a match rule matches. @@ -749,7 +759,7 @@ public: /// matcher. unsigned countRendererFns() const; - std::unique_ptr<PredicateMatcher> forgetFirstCondition(); + std::unique_ptr<PredicateMatcher> forgetFirstCondition() override; // FIXME: Remove this as soon as possible InstructionMatcher &insnmatchers_front() const { return *Matchers.front(); } @@ -921,7 +931,7 @@ class SameOperandMatcher : public OperandPredicateMatcher { std::string MatchingName; public: - SameOperandMatcher(StringRef MatchingName, unsigned InsnVarID, unsigned OpIdx) + SameOperandMatcher(unsigned InsnVarID, unsigned OpIdx, StringRef MatchingName) : OperandPredicateMatcher(OPM_SameOperand, InsnVarID, OpIdx), MatchingName(MatchingName) {} @@ -941,7 +951,7 @@ protected: public: static std::set<LLTCodeGen> KnownTypes; - LLTOperandMatcher(const LLTCodeGen &Ty, unsigned InsnVarID, unsigned OpIdx) + LLTOperandMatcher(unsigned InsnVarID, unsigned OpIdx, const LLTCodeGen &Ty) : OperandPredicateMatcher(OPM_LLT, InsnVarID, OpIdx), Ty(Ty) { KnownTypes.insert(Ty); } @@ -981,8 +991,8 @@ protected: unsigned SizeInBits; public: - PointerToAnyOperandMatcher(unsigned SizeInBits, unsigned InsnVarID, - unsigned OpIdx) + PointerToAnyOperandMatcher(unsigned InsnVarID, unsigned OpIdx, + unsigned SizeInBits) : OperandPredicateMatcher(OPM_PointerToAny, InsnVarID, OpIdx), SizeInBits(SizeInBits) {} @@ -1011,9 +1021,9 @@ protected: public: bool isIdentical(const PredicateMatcher &B) const override { return false; } - ComplexPatternOperandMatcher(const OperandMatcher &Operand, - const Record &TheDef, unsigned InsnVarID, - unsigned OpIdx) + ComplexPatternOperandMatcher(unsigned InsnVarID, unsigned OpIdx, + const OperandMatcher &Operand, + const Record &TheDef) : OperandPredicateMatcher(OPM_ComplexPattern, InsnVarID, OpIdx), Operand(Operand), TheDef(TheDef) {} @@ -1043,8 +1053,8 @@ protected: const CodeGenRegisterClass &RC; public: - RegisterBankOperandMatcher(const CodeGenRegisterClass &RC, unsigned InsnVarID, - unsigned OpIdx) + RegisterBankOperandMatcher(unsigned InsnVarID, unsigned OpIdx, + const CodeGenRegisterClass &RC) : OperandPredicateMatcher(OPM_RegBank, InsnVarID, OpIdx), RC(RC) {} bool isIdentical(const PredicateMatcher &B) const override { @@ -1092,7 +1102,7 @@ protected: int64_t Value; public: - ConstantIntOperandMatcher(int64_t Value, unsigned InsnVarID, unsigned OpIdx) + ConstantIntOperandMatcher(unsigned InsnVarID, unsigned OpIdx, int64_t Value) : OperandPredicateMatcher(OPM_Int, InsnVarID, OpIdx), Value(Value) {} bool isIdentical(const PredicateMatcher &B) const override { @@ -1120,7 +1130,7 @@ protected: int64_t Value; public: - LiteralIntOperandMatcher(int64_t Value, unsigned InsnVarID, unsigned OpIdx) + LiteralIntOperandMatcher(unsigned InsnVarID, unsigned OpIdx, int64_t Value) : OperandPredicateMatcher(OPM_LiteralInt, InsnVarID, OpIdx), Value(Value) {} @@ -1148,8 +1158,8 @@ protected: const CodeGenIntrinsic *II; public: - IntrinsicIDOperandMatcher(const CodeGenIntrinsic *II, unsigned InsnVarID, - unsigned OpIdx) + IntrinsicIDOperandMatcher(unsigned InsnVarID, unsigned OpIdx, + const CodeGenIntrinsic *II) : OperandPredicateMatcher(OPM_IntrinsicID, InsnVarID, OpIdx), II(II) {} bool isIdentical(const PredicateMatcher &B) const override { @@ -1284,9 +1294,9 @@ PredicateListMatcher<OperandPredicateMatcher>::addPredicate(Args &&... args) { auto *OpMatcher = static_cast<OperandMatcher *>(this); if (static_cast<OperandMatcher *>(this)->isSameAsAnotherOperand()) return None; - Predicates.emplace_back(llvm::make_unique<Kind>( - std::forward<Args>(args)..., OpMatcher->getInsnVarID(), - OpMatcher->getOperandIndex())); + Predicates.emplace_back(llvm::make_unique<Kind>(OpMatcher->getInsnVarID(), + OpMatcher->getOperandIndex(), + std::forward<Args>(args)...)); return static_cast<Kind *>(Predicates.back().get()); } @@ -1658,8 +1668,8 @@ protected: std::unique_ptr<InstructionMatcher> InsnMatcher; public: - InstructionOperandMatcher(RuleMatcher &Rule, StringRef SymbolicName, - unsigned InsnVarID, unsigned OpIdx) + InstructionOperandMatcher(unsigned InsnVarID, unsigned OpIdx, + RuleMatcher &Rule, StringRef SymbolicName) : OperandPredicateMatcher(OPM_Instruction, InsnVarID, OpIdx), InsnMatcher(new InstructionMatcher(Rule, SymbolicName)) {} @@ -2336,6 +2346,10 @@ void RuleMatcher::emit(MatchTable &Table) { if (Matchers.empty()) llvm_unreachable("Unexpected empty matcher!"); + // Reset the ID generation so that the emitted IDs match the ones + // we set while building the InstructionMatcher and such. + clearImplicitMap(); + // The representation supports rules that require multiple roots such as: // %ptr(p0) = ... // %elt0(s32) = G_LOAD %ptr @@ -2615,7 +2629,7 @@ private: /// # predicate C /// \endverbatim std::vector<Matcher *> optimizeRules( - std::vector<RuleMatcher> &Rules, + const std::vector<Matcher *> &Rules, std::vector<std::unique_ptr<GroupMatcher>> &StorageGroupMatcher); }; @@ -3342,9 +3356,6 @@ Expected<RuleMatcher> GlobalISelEmitter::runOnPattern(const PatternToMatch &P) { unsigned TempOpIdx = 0; auto InsnMatcherOrError = createAndImportSelDAGMatcher(M, InsnMatcherTemp, Src, TempOpIdx); - // Reset the ID generation so that the emitted IDs match the ones - // in the InstructionMatcher and such. - M.clearImplicitMap(); if (auto Error = InsnMatcherOrError.takeError()) return std::move(Error); InstructionMatcher &InsnMatcher = InsnMatcherOrError.get(); @@ -3539,28 +3550,36 @@ void GlobalISelEmitter::emitImmPredicates( OS << "};\n"; } - for (const auto *Record : MatchedRecords) - OS << "static bool Predicate_" << Record->getName() << "(" << Type - << " Imm) {" << Record->getValueAsString("ImmediateCode") << "}\n"; - - OS << "static InstructionSelector::" << TypeIdentifier - << "ImmediatePredicateFn " << TypeIdentifier << "ImmPredicateFns[] = {\n" - << " nullptr,\n"; - for (const auto *Record : MatchedRecords) - OS << " Predicate_" << Record->getName() << ",\n"; - OS << "};\n"; + OS << "bool " << Target.getName() << "InstructionSelector::testImmPredicate_" + << TypeIdentifier << "(unsigned PredicateID, " << Type + << " Imm) const {\n"; + if (!MatchedRecords.empty()) + OS << " switch (PredicateID) {\n"; + for (const auto *Record : MatchedRecords) { + OS << " case GIPFP_" << TypeIdentifier << "_Predicate_" + << Record->getName() << ": {\n" + << " " << Record->getValueAsString("ImmediateCode") << "\n" + << " llvm_unreachable(\"ImmediateCode should have returned\");\n" + << " return false;\n" + << " }\n"; + } + if (!MatchedRecords.empty()) + OS << " }\n"; + OS << " llvm_unreachable(\"Unknown predicate\");\n" + << " return false;\n" + << "}\n"; } std::vector<Matcher *> GlobalISelEmitter::optimizeRules( - std::vector<RuleMatcher> &Rules, + const std::vector<Matcher *> &Rules, std::vector<std::unique_ptr<GroupMatcher>> &StorageGroupMatcher) { std::vector<Matcher *> OptRules; // Start with a stupid grouping for now. std::unique_ptr<GroupMatcher> CurrentGroup = make_unique<GroupMatcher>(); assert(CurrentGroup->conditions_empty()); unsigned NbGroup = 0; - for (RuleMatcher &Rule : Rules) { - std::unique_ptr<PredicateMatcher> Predicate = Rule.forgetFirstCondition(); + for (Matcher *Rule : Rules) { + std::unique_ptr<PredicateMatcher> Predicate = Rule->forgetFirstCondition(); if (!CurrentGroup->conditions_empty() && !CurrentGroup->lastConditionMatches(*Predicate)) { // Start a new group. @@ -3572,7 +3591,7 @@ std::vector<Matcher *> GlobalISelEmitter::optimizeRules( } if (CurrentGroup->conditions_empty()) CurrentGroup->addCondition(std::move(Predicate)); - CurrentGroup->addRule(Rule); + CurrentGroup->addRule(*Rule); } if (!CurrentGroup->conditions_empty()) { ++NbGroup; @@ -3662,12 +3681,17 @@ void GlobalISelEmitter::run(raw_ostream &OS) { "MatcherInfo;\n" << " static " << Target.getName() << "InstructionSelector::ComplexMatcherMemFn ComplexPredicateFns[];\n" + << "bool testImmPredicate_I64(unsigned PredicateID, int64_t Imm) const " + "override;\n" + << "bool testImmPredicate_APInt(unsigned PredicateID, const APInt &Imm) " + "const override;\n" + << "bool testImmPredicate_APFloat(unsigned PredicateID, const APFloat " + "&Imm) const override;\n" << "#endif // ifdef GET_GLOBALISEL_TEMPORARIES_DECL\n\n"; OS << "#ifdef GET_GLOBALISEL_TEMPORARIES_INIT\n" << ", State(" << MaxTemporaries << "),\n" - << "MatcherInfo({TypeObjects, FeatureBitsets, I64ImmPredicateFns, " - "APIntImmPredicateFns, APFloatImmPredicateFns, ComplexPredicateFns})\n" + << "MatcherInfo({TypeObjects, FeatureBitsets, ComplexPredicateFns})\n" << "#endif // ifdef GET_GLOBALISEL_TEMPORARIES_INIT\n\n"; OS << "#ifdef GET_GLOBALISEL_IMPL\n"; @@ -3823,12 +3847,13 @@ void GlobalISelEmitter::run(raw_ostream &OS) { }); std::vector<std::unique_ptr<GroupMatcher>> StorageGroupMatcher; - std::vector<Matcher *> OptRules; - if (OptimizeMatchTable) - OptRules = optimizeRules(Rules, StorageGroupMatcher); - else - for (Matcher &Rule : Rules) - OptRules.push_back(&Rule); + std::vector<Matcher *> InputRules; + for (Matcher &Rule : Rules) + InputRules.push_back(&Rule); + + std::vector<Matcher *> OptRules = + OptimizeMatchTable ? optimizeRules(InputRules, StorageGroupMatcher) + : InputRules; MatchTable Table(0); for (Matcher *Rule : OptRules) { |