diff options
| -rw-r--r-- | llvm/utils/TableGen/GlobalISelEmitter.cpp | 116 |
1 files changed, 73 insertions, 43 deletions
diff --git a/llvm/utils/TableGen/GlobalISelEmitter.cpp b/llvm/utils/TableGen/GlobalISelEmitter.cpp index 85739bbab4a..daa958e211f 100644 --- a/llvm/utils/TableGen/GlobalISelEmitter.cpp +++ b/llvm/utils/TableGen/GlobalISelEmitter.cpp @@ -527,12 +527,19 @@ class RuleMatcher { /// have succeeded. std::vector<std::unique_ptr<MatchAction>> Actions; - typedef std::map<const InstructionMatcher *, unsigned> - DefinedInsnVariablesMap; + using DefinedInsnVariablesMap = + std::map<const InstructionMatcher *, unsigned>; + /// A map of instruction matchers to the local variables created by /// emitCaptureOpcodes(). DefinedInsnVariablesMap InsnVariableIDs; + using MutatableInsnSet = SmallPtrSet<const InstructionMatcher *, 4>; + + // The set of instruction matchers that have not yet been claimed for mutation + // by a BuildMI. + MutatableInsnSet MutatableInsns; + /// A map of named operands defined by the matchers that may be referenced by /// the renderers. StringMap<OperandMatcher *> DefinedOperands; @@ -553,8 +560,9 @@ class RuleMatcher { public: RuleMatcher(ArrayRef<SMLoc> SrcLoc) - : Matchers(), Actions(), InsnVariableIDs(), DefinedOperands(), - NextInsnVarID(0), SrcLoc(SrcLoc), ComplexSubOperands() {} + : Matchers(), Actions(), InsnVariableIDs(), MutatableInsns(), + DefinedOperands(), NextInsnVarID(0), SrcLoc(SrcLoc), + ComplexSubOperands() {} RuleMatcher(RuleMatcher &&Other) = default; RuleMatcher &operator=(RuleMatcher &&Other) = default; @@ -582,6 +590,22 @@ public: return make_range(defined_insn_vars_begin(), defined_insn_vars_end()); } + MutatableInsnSet::const_iterator mutatable_insns_begin() const { + return MutatableInsns.begin(); + } + MutatableInsnSet::const_iterator mutatable_insns_end() const { + return MutatableInsns.end(); + } + iterator_range<typename MutatableInsnSet::const_iterator> + mutatable_insns() const { + return make_range(mutatable_insns_begin(), mutatable_insns_end()); + } + void reserveInsnMatcherForMutation(const InstructionMatcher *InsnMatcher) { + bool R = MutatableInsns.erase(InsnMatcher); + assert(R && "Reserving a mutatable insn that isn't available"); + (void)R; + } + void defineOperand(StringRef SymbolicName, OperandMatcher &OM); void defineComplexSubOperand(StringRef SymbolicName, Record *ComplexPattern, @@ -1723,12 +1747,8 @@ public: virtual ~MatchAction() {} /// Emit the MatchTable opcodes to implement the action. - /// - /// \param RecycleInsnID If given, it's an instruction to recycle. The - /// requirements on the instruction vary from action to - /// action. - virtual void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule, - unsigned RecycleInsnID) const = 0; + virtual void emitActionOpcodes(MatchTable &Table, + RuleMatcher &Rule) const = 0; }; /// Generates a comment describing the matched rule being acted upon. @@ -1739,8 +1759,7 @@ private: public: DebugCommentAction(StringRef S) : S(S) {} - void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule, - unsigned RecycleInsnID) const override { + void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override { Table << MatchTable::Comment(S) << MatchTable::LineBreak; } }; @@ -1755,17 +1774,17 @@ private: std::vector<std::unique_ptr<OperandRenderer>> OperandRenderers; /// True if the instruction can be built solely by mutating the opcode. - bool canMutate(RuleMatcher &Rule) const { - if (!Matched) + bool canMutate(RuleMatcher &Rule, const InstructionMatcher *Insn) const { + if (!Insn) return false; - if (OperandRenderers.size() != Matched->getNumOperands()) + if (OperandRenderers.size() != Insn->getNumOperands()) return false; for (const auto &Renderer : enumerate(OperandRenderers)) { if (const auto *Copy = dyn_cast<CopyRenderer>(&*Renderer.value())) { const OperandMatcher &OM = Rule.getOperandMatcher(Copy->getSymbolicName()); - if (Matched != &OM.getInstructionMatcher() || + if (Insn != &OM.getInstructionMatcher() || OM.getOperandIndex() != Renderer.index()) return false; } else @@ -1776,9 +1795,19 @@ private: } public: - BuildMIAction(unsigned InsnID, const CodeGenInstruction *I, - const InstructionMatcher *Matched) - : InsnID(InsnID), I(I), Matched(Matched) {} + BuildMIAction(unsigned InsnID, const CodeGenInstruction *I) + : InsnID(InsnID), I(I), Matched(nullptr) {} + + void chooseInsnToMutate(RuleMatcher &Rule) { + for (const auto *MutateCandidate : Rule.mutatable_insns()) { + if (canMutate(Rule, MutateCandidate)) { + // Take the first one we're offered that we're able to mutate. + Rule.reserveInsnMatcherForMutation(MutateCandidate); + Matched = MutateCandidate; + return; + } + } + } template <class Kind, class... Args> Kind &addRenderer(Args&&... args) { @@ -1787,9 +1816,12 @@ public: return *static_cast<Kind *>(OperandRenderers.back().get()); } - void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule, - unsigned RecycleInsnID) const override { - if (canMutate(Rule)) { + void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override { + if (Matched) { + assert(canMutate(Rule, Matched) && + "Arranged to mutate an insn that isn't mutatable"); + + unsigned RecycleInsnID = Rule.getInsnVarID(*Matched); Table << MatchTable::Opcode("GIR_MutateOpcode") << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID) << MatchTable::Comment("RecycleInsnID") @@ -1853,8 +1885,8 @@ public: } Table << MatchTable::Opcode("GIR_EraseFromParent") - << MatchTable::Comment("InsnID") - << MatchTable::IntValue(RecycleInsnID) << MatchTable::LineBreak; + << MatchTable::Comment("InsnID") << MatchTable::IntValue(0) + << MatchTable::LineBreak; } }; @@ -1866,8 +1898,7 @@ class ConstrainOperandsToDefinitionAction : public MatchAction { public: ConstrainOperandsToDefinitionAction(unsigned InsnID) : InsnID(InsnID) {} - void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule, - unsigned RecycleInsnID) const override { + void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override { Table << MatchTable::Opcode("GIR_ConstrainSelectedInstOperands") << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID) << MatchTable::LineBreak; @@ -1886,8 +1917,7 @@ public: const CodeGenRegisterClass &RC) : InsnID(InsnID), OpIdx(OpIdx), RC(RC) {} - void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule, - unsigned RecycleInsnID) const override { + void emitActionOpcodes(MatchTable &Table, RuleMatcher &Rule) const override { Table << MatchTable::Opcode("GIR_ConstrainOperandRC") << MatchTable::Comment("InsnID") << MatchTable::IntValue(InsnID) << MatchTable::Comment("Op") << MatchTable::IntValue(OpIdx) @@ -1898,6 +1928,7 @@ public: InstructionMatcher &RuleMatcher::addInstructionMatcher(StringRef SymbolicName) { Matchers.emplace_back(new InstructionMatcher(*this, SymbolicName)); + MutatableInsns.insert(Matchers.back().get()); return *Matchers.back(); } @@ -2069,7 +2100,7 @@ void RuleMatcher::emit(MatchTable &Table) { } for (const auto &MA : Actions) - MA->emitActionOpcodes(Table, *this, 0); + MA->emitActionOpcodes(Table, *this); Table << MatchTable::Opcode("GIR_Done", -1) << MatchTable::LineBreak << MatchTable::Label(LabelID); } @@ -2189,12 +2220,11 @@ private: bool OperandIsAPointer, unsigned OpIdx, unsigned &TempOpIdx) const; Expected<BuildMIAction &> - createAndImportInstructionRenderer(RuleMatcher &M, const TreePatternNode *Dst, - const InstructionMatcher &InsnMatcher); + createAndImportInstructionRenderer(RuleMatcher &M, + const TreePatternNode *Dst); Error importExplicitUseRenderer(RuleMatcher &Rule, BuildMIAction &DstMIBuilder, - TreePatternNode *DstChild, - const InstructionMatcher &InsnMatcher) const; + TreePatternNode *DstChild) const; Error importDefaultOperandRenderers(BuildMIAction &DstMIBuilder, DagInit *DefaultOps) const; Error @@ -2525,8 +2555,8 @@ Error GlobalISelEmitter::importChildMatcher(RuleMatcher &Rule, } Error GlobalISelEmitter::importExplicitUseRenderer( - RuleMatcher &Rule, BuildMIAction &DstMIBuilder, TreePatternNode *DstChild, - const InstructionMatcher &InsnMatcher) const { + RuleMatcher &Rule, BuildMIAction &DstMIBuilder, + TreePatternNode *DstChild) const { if (DstChild->getTransformFn() != nullptr) { return failedImport("Dst pattern child has transform fn " + DstChild->getTransformFn()->getName()); @@ -2626,8 +2656,7 @@ Error GlobalISelEmitter::importExplicitUseRenderer( } Expected<BuildMIAction &> GlobalISelEmitter::createAndImportInstructionRenderer( - RuleMatcher &M, const TreePatternNode *Dst, - const InstructionMatcher &InsnMatcher) { + RuleMatcher &M, const TreePatternNode *Dst) { Record *DstOp = Dst->getOperator(); if (!DstOp->isSubClassOf("Instruction")) { if (DstOp->isSubClassOf("ValueType")) @@ -2652,7 +2681,7 @@ Expected<BuildMIAction &> GlobalISelEmitter::createAndImportInstructionRenderer( IsExtractSubReg = true; } - auto &DstMIBuilder = M.addAction<BuildMIAction>(0, DstI, &InsnMatcher); + auto &DstMIBuilder = M.addAction<BuildMIAction>(0, DstI); // Render the explicit defs. for (unsigned I = 0; I < DstI->Operands.NumDefs; ++I) { @@ -2707,8 +2736,8 @@ Expected<BuildMIAction &> GlobalISelEmitter::createAndImportInstructionRenderer( continue; } - if (auto Error = importExplicitUseRenderer( - M, DstMIBuilder, Dst->getChild(Child), InsnMatcher)) + if (auto Error = + importExplicitUseRenderer(M, DstMIBuilder, Dst->getChild(Child))) return std::move(Error); ++Child; } @@ -2805,7 +2834,7 @@ Expected<RuleMatcher> GlobalISelEmitter::runOnPattern(const PatternToMatch &P) { M.defineOperand(OM0.getSymbolicName(), OM0); OM0.addPredicate<RegisterBankOperandMatcher>(RC); - auto &DstMIBuilder = M.addAction<BuildMIAction>(0, &DstI, &InsnMatcher); + auto &DstMIBuilder = M.addAction<BuildMIAction>(0, &DstI); DstMIBuilder.addRenderer<CopyRenderer>(0, DstIOperand.Name); DstMIBuilder.addRenderer<CopyRenderer>(0, Dst->getName()); M.addAction<ConstrainOperandToRegClassAction>(0, 0, RC); @@ -2869,8 +2898,7 @@ Expected<RuleMatcher> GlobalISelEmitter::runOnPattern(const PatternToMatch &P) { ++OpIdx; } - auto DstMIBuilderOrError = - createAndImportInstructionRenderer(M, Dst, InsnMatcher); + auto DstMIBuilderOrError = createAndImportInstructionRenderer(M, Dst); if (auto Error = DstMIBuilderOrError.takeError()) return std::move(Error); BuildMIAction &DstMIBuilder = DstMIBuilderOrError.get(); @@ -2880,6 +2908,8 @@ Expected<RuleMatcher> GlobalISelEmitter::runOnPattern(const PatternToMatch &P) { if (auto Error = importImplicitDefRenderers(DstMIBuilder, P.getDstRegs())) return std::move(Error); + DstMIBuilder.chooseInsnToMutate(M); + // Constrain the registers to classes. This is normally derived from the // emitted instruction but a few instructions require special handling. if (DstI.TheDef->getName() == "COPY_TO_REGCLASS") { |

