diff options
Diffstat (limited to 'llvm/utils')
-rw-r--r-- | llvm/utils/TableGen/GlobalISelEmitter.cpp | 142 |
1 files changed, 39 insertions, 103 deletions
diff --git a/llvm/utils/TableGen/GlobalISelEmitter.cpp b/llvm/utils/TableGen/GlobalISelEmitter.cpp index 488bf8d312b..b637114a2e0 100644 --- a/llvm/utils/TableGen/GlobalISelEmitter.cpp +++ b/llvm/utils/TableGen/GlobalISelEmitter.cpp @@ -91,52 +91,6 @@ public: }; class InstructionMatcher; -class OperandPlaceholder { -private: - enum PlaceholderKind { - OP_MatchReference, - OP_Temporary, - } Kind; - - struct MatchReferenceData { - InstructionMatcher *InsnMatcher; - StringRef InsnVarName; - StringRef SymbolicName; - }; - - struct TemporaryData { - unsigned OpIdx; - }; - - union { - struct MatchReferenceData MatchReference; - struct TemporaryData Temporary; - }; - - OperandPlaceholder(PlaceholderKind Kind) : Kind(Kind) {} - -public: - ~OperandPlaceholder() {} - - static OperandPlaceholder - CreateMatchReference(InstructionMatcher *InsnMatcher, - StringRef InsnVarName, StringRef SymbolicName) { - OperandPlaceholder Result(OP_MatchReference); - Result.MatchReference.InsnMatcher = InsnMatcher; - Result.MatchReference.InsnVarName = InsnVarName; - Result.MatchReference.SymbolicName = SymbolicName; - return Result; - } - - static OperandPlaceholder CreateTemporary(unsigned OpIdx) { - OperandPlaceholder Result(OP_Temporary); - Result.Temporary.OpIdx = OpIdx; - return Result; - } - - void emitCxxValueExpr(raw_ostream &OS) const; -}; - /// Convert an MVT to an equivalent LLT if possible, or the invalid LLT() for /// MVTs that don't map cleanly to an LLT (e.g., iPTR, *any, ...). static Optional<LLTCodeGen> MVTToLLT(MVT::SimpleValueType SVT) { @@ -256,7 +210,10 @@ public: /// Report the maximum number of temporary operands needed by the rule /// matcher. - unsigned countTemporaryOperands() const; + unsigned countRendererFns() const; + + // FIXME: Remove this as soon as possible + InstructionMatcher &insnmatcher_front() const { return *Matchers.front(); } }; template <class PredicateTy> class PredicateListMatcher { @@ -361,7 +318,7 @@ public: /// Report the maximum number of temporary operands needed by the predicate /// matcher. - virtual unsigned countTemporaryOperands() const { return 0; } + virtual unsigned countRendererFns() const { return 0; } }; /// Generates code to check that an operand is a particular LLT. @@ -391,10 +348,6 @@ protected: const OperandMatcher &Operand; const Record &TheDef; - unsigned getNumOperands() const { - return TheDef.getValueAsDag("Operands")->getNumArgs(); - } - unsigned getAllocatedTemporariesBaseID() const; public: @@ -409,17 +362,13 @@ public: void emitCxxPredicateExpr(raw_ostream &OS, RuleMatcher &Rule, StringRef OperandExpr) const override { - OS << TheDef.getValueAsString("MatcherFn") << "(" << OperandExpr; - for (unsigned I = 0; I < getNumOperands(); ++I) { - OS << ", "; - OperandPlaceholder::CreateTemporary(getAllocatedTemporariesBaseID() + I) - .emitCxxValueExpr(OS); - } - OS << ")"; + unsigned ID = getAllocatedTemporariesBaseID(); + OS << "(Renderer" << ID << " = " << TheDef.getValueAsString("MatcherFn") + << "(" << OperandExpr << "))"; } - unsigned countTemporaryOperands() const override { - return getNumOperands(); + unsigned countRendererFns() const override { + return 1; } }; @@ -488,7 +437,7 @@ protected: /// The index of the first temporary variable allocated to this operand. The /// number of allocated temporaries can be found with - /// countTemporaryOperands(). + /// countRendererFns(). unsigned AllocatedTemporariesBaseID; public: @@ -569,12 +518,12 @@ public: /// Report the maximum number of temporary operands needed by the operand /// matcher. - unsigned countTemporaryOperands() const { + unsigned countRendererFns() const { return std::accumulate( predicates().begin(), predicates().end(), 0, [](unsigned A, const std::unique_ptr<OperandPredicateMatcher> &Predicate) { - return A + Predicate->countTemporaryOperands(); + return A + Predicate->countRendererFns(); }); } @@ -623,7 +572,7 @@ public: /// Report the maximum number of temporary operands needed by the predicate /// matcher. - virtual unsigned countTemporaryOperands() const { return 0; } + virtual unsigned countRendererFns() const { return 0; } }; /// Generates code to check the opcode of an instruction. @@ -780,17 +729,17 @@ public: /// Report the maximum number of temporary operands needed by the instruction /// matcher. - unsigned countTemporaryOperands() const { + unsigned countRendererFns() const { return std::accumulate(predicates().begin(), predicates().end(), 0, [](unsigned A, const std::unique_ptr<InstructionPredicateMatcher> &Predicate) { - return A + Predicate->countTemporaryOperands(); + return A + Predicate->countRendererFns(); }) + std::accumulate( Operands.begin(), Operands.end(), 0, [](unsigned A, const std::unique_ptr<OperandMatcher> &Operand) { - return A + Operand->countTemporaryOperands(); + return A + Operand->countRendererFns(); }); } }; @@ -845,18 +794,6 @@ public: }; //===- Actions ------------------------------------------------------------===// -void OperandPlaceholder::emitCxxValueExpr(raw_ostream &OS) const { - switch (Kind) { - case OP_MatchReference: - OS << MatchReference.InsnMatcher->getOperand(MatchReference.SymbolicName) - .getOperandExpr(MatchReference.InsnVarName); - break; - case OP_Temporary: - OS << "TempOp" << Temporary.OpIdx; - break; - } -} - class OperandRenderer { public: enum RendererKind { OR_Copy, OR_Imm, OR_Register, OR_ComplexPattern }; @@ -942,31 +879,33 @@ public: } }; +/// Adds operands by calling a renderer function supplied by the ComplexPattern +/// matcher function. class RenderComplexPatternOperand : public OperandRenderer { private: const Record &TheDef; - std::vector<OperandPlaceholder> Sources; + /// The name of the operand. + const StringRef SymbolicName; + /// The renderer number. This must be unique within a rule since it's used to + /// identify a temporary variable to hold the renderer function. + unsigned RendererID; unsigned getNumOperands() const { return TheDef.getValueAsDag("Operands")->getNumArgs(); } public: - RenderComplexPatternOperand(const Record &TheDef, - const ArrayRef<OperandPlaceholder> Sources) - : OperandRenderer(OR_ComplexPattern), TheDef(TheDef), Sources(Sources) {} + RenderComplexPatternOperand(const Record &TheDef, StringRef SymbolicName, + unsigned RendererID) + : OperandRenderer(OR_ComplexPattern), TheDef(TheDef), + SymbolicName(SymbolicName), RendererID(RendererID) {} static bool classof(const OperandRenderer *R) { return R->getKind() == OR_ComplexPattern; } void emitCxxRenderStmts(raw_ostream &OS, RuleMatcher &Rule) const override { - assert(Sources.size() == getNumOperands() && "Inconsistent number of operands"); - for (const auto &Source : Sources) { - OS << "MIB.add("; - Source.emitCxxValueExpr(OS); - OS << ");\n"; - } + OS << "Renderer" << RendererID << "(MIB);\n"; } }; @@ -1249,11 +1188,11 @@ bool RuleMatcher::isHigherPriorityThan(const RuleMatcher &B) const { return false; } -unsigned RuleMatcher::countTemporaryOperands() const { +unsigned RuleMatcher::countRendererFns() const { return std::accumulate( Matchers.begin(), Matchers.end(), 0, [](unsigned A, const std::unique_ptr<InstructionMatcher> &Matcher) { - return A + Matcher->countTemporaryOperands(); + return A + Matcher->countRendererFns(); }); } @@ -1452,9 +1391,9 @@ Error GlobalISelEmitter::importChildMatcher(InstructionMatcher &InsnMatcher, return failedImport("SelectionDAG ComplexPattern (" + ChildRec->getName() + ") not mapped to GlobalISel"); - const auto &Predicate = OM.addPredicate<ComplexPatternOperandMatcher>( - OM, *ComplexPattern->second); - TempOpIdx += Predicate.countTemporaryOperands(); + OM.addPredicate<ComplexPatternOperandMatcher>(OM, + *ComplexPattern->second); + TempOpIdx++; return Error::success(); } @@ -1519,13 +1458,10 @@ Error GlobalISelEmitter::importExplicitUseRenderer( return failedImport( "SelectionDAG ComplexPattern not mapped to GlobalISel"); - SmallVector<OperandPlaceholder, 2> RenderedOperands; const OperandMatcher &OM = InsnMatcher.getOperand(DstChild->getName()); - for (unsigned I = 0; I < OM.countTemporaryOperands(); ++I) - RenderedOperands.push_back(OperandPlaceholder::CreateTemporary( - OM.getAllocatedTemporariesBaseID() + I)); DstMIBuilder.addRenderer<RenderComplexPatternOperand>( - *ComplexPattern->second, RenderedOperands); + *ComplexPattern->second, DstChild->getName(), + OM.getAllocatedTemporariesBaseID()); return Error::success(); } @@ -1745,7 +1681,7 @@ void GlobalISelEmitter::run(raw_ostream &OS) { unsigned MaxTemporaries = 0; for (const auto &Rule : Rules) - MaxTemporaries = std::max(MaxTemporaries, Rule.countTemporaryOperands()); + MaxTemporaries = std::max(MaxTemporaries, Rule.countRendererFns()); OS << "#ifdef GET_GLOBALISEL_PREDICATE_BITSET\n" << "const unsigned MAX_SUBTARGET_PREDICATES = " << SubtargetFeatures.size() @@ -1756,12 +1692,12 @@ void GlobalISelEmitter::run(raw_ostream &OS) { OS << "#ifdef GET_GLOBALISEL_TEMPORARIES_DECL\n"; for (unsigned I = 0; I < MaxTemporaries; ++I) - OS << " mutable MachineOperand TempOp" << I << ";\n"; + OS << " mutable ComplexRendererFn Renderer" << I << ";\n"; OS << "#endif // ifdef GET_GLOBALISEL_TEMPORARIES_DECL\n\n"; OS << "#ifdef GET_GLOBALISEL_TEMPORARIES_INIT\n"; for (unsigned I = 0; I < MaxTemporaries; ++I) - OS << ", TempOp" << I << "(MachineOperand::CreatePlaceholder())\n"; + OS << ", Renderer" << I << "(nullptr)\n"; OS << "#endif // ifdef GET_GLOBALISEL_TEMPORARIES_INIT\n\n"; OS << "#ifdef GET_GLOBALISEL_IMPL\n"; |