From: Daniel Sanders Date: Tue, 31 Oct 2017 19:09:29 +0000 (+0000) Subject: [globalisel][tablegen] Factor out implicit def/use renderers from createAndImportInst... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d619fda3f460e82442aad33673bb1fef85d7bffa;p=llvm [globalisel][tablegen] Factor out implicit def/use renderers from createAndImportInstructionRenderer(). NFC Multi-instruction emission will require that we have separate handling for the defs between the implicitly created temporaries and the rule outputs. The former require new temporary vregs while the latter should copy existing operands. Factor out the implicit def/use renderers to minimize the code duplication when we implement that. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@317025 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/utils/TableGen/GlobalISelEmitter.cpp b/utils/TableGen/GlobalISelEmitter.cpp index daa958e211f..9a38d925278 100644 --- a/utils/TableGen/GlobalISelEmitter.cpp +++ b/utils/TableGen/GlobalISelEmitter.cpp @@ -1798,6 +1798,8 @@ public: BuildMIAction(unsigned InsnID, const CodeGenInstruction *I) : InsnID(InsnID), I(I), Matched(nullptr) {} + const CodeGenInstruction *getCGI() const { return I; } + void chooseInsnToMutate(RuleMatcher &Rule) { for (const auto *MutateCandidate : Rule.mutatable_insns()) { if (canMutate(Rule, MutateCandidate)) { @@ -2219,9 +2221,16 @@ private: const TreePatternNode *SrcChild, bool OperandIsAPointer, unsigned OpIdx, unsigned &TempOpIdx) const; + Expected createAndImportInstructionRenderer(RuleMatcher &M, const TreePatternNode *Dst); + Expected + createInstructionRenderer(RuleMatcher &M, const TreePatternNode *Dst); + void importExplicitDefRenderers(BuildMIAction &DstMIBuilder); + Expected + importExplicitUseRenderers(RuleMatcher &M, BuildMIAction &DstMIBuilder, + const llvm::TreePatternNode *Dst); Error importExplicitUseRenderer(RuleMatcher &Rule, BuildMIAction &DstMIBuilder, TreePatternNode *DstChild) const; @@ -2657,6 +2666,22 @@ Error GlobalISelEmitter::importExplicitUseRenderer( Expected GlobalISelEmitter::createAndImportInstructionRenderer( RuleMatcher &M, const TreePatternNode *Dst) { + auto DstMIBuilderOrError = createInstructionRenderer(M, Dst); + if (auto Error = DstMIBuilderOrError.takeError()) + return std::move(Error); + + BuildMIAction &DstMIBuilder = DstMIBuilderOrError.get(); + + importExplicitDefRenderers(DstMIBuilder); + + if (auto Error = importExplicitUseRenderers(M, DstMIBuilder, Dst).takeError()) + return std::move(Error); + + return DstMIBuilder; +} + +Expected GlobalISelEmitter::createInstructionRenderer( + RuleMatcher &M, const TreePatternNode *Dst) { Record *DstOp = Dst->getOperator(); if (!DstOp->isSubClassOf("Instruction")) { if (DstOp->isSubClassOf("ValueType")) @@ -2666,31 +2691,35 @@ Expected GlobalISelEmitter::createAndImportInstructionRenderer( } CodeGenInstruction *DstI = &Target.getInstruction(DstOp); - unsigned DstINumUses = DstI->Operands.size() - DstI->Operands.NumDefs; - unsigned ExpectedDstINumUses = Dst->getNumChildren(); - bool IsExtractSubReg = false; - // COPY_TO_REGCLASS is just a copy with a ConstrainOperandToRegClassAction // attached. Similarly for EXTRACT_SUBREG except that's a subregister copy. - if (DstI->TheDef->getName() == "COPY_TO_REGCLASS") { + if (DstI->TheDef->getName() == "COPY_TO_REGCLASS") DstI = &Target.getInstruction(RK.getDef("COPY")); - DstINumUses--; // Ignore the class constraint. - ExpectedDstINumUses--; - } else if (DstI->TheDef->getName() == "EXTRACT_SUBREG") { + else if (DstI->TheDef->getName() == "EXTRACT_SUBREG") DstI = &Target.getInstruction(RK.getDef("COPY")); - IsExtractSubReg = true; - } auto &DstMIBuilder = M.addAction(0, DstI); - // Render the explicit defs. + return DstMIBuilder; +} + +void GlobalISelEmitter::importExplicitDefRenderers( + BuildMIAction &DstMIBuilder) { + const CodeGenInstruction *DstI = DstMIBuilder.getCGI(); for (unsigned I = 0; I < DstI->Operands.NumDefs; ++I) { const CGIOperandList::OperandInfo &DstIOperand = DstI->Operands[I]; DstMIBuilder.addRenderer(0, DstIOperand.Name); } +} + +Expected GlobalISelEmitter::importExplicitUseRenderers( + RuleMatcher &M, BuildMIAction &DstMIBuilder, + const llvm::TreePatternNode *Dst) { + const CodeGenInstruction *DstI = DstMIBuilder.getCGI(); + CodeGenInstruction *OrigDstI = &Target.getInstruction(Dst->getOperator()); // EXTRACT_SUBREG needs to use a subregister COPY. - if (IsExtractSubReg) { + if (OrigDstI->TheDef->getName() == "EXTRACT_SUBREG") { if (!Dst->getChild(0)->isLeaf()) return failedImport("EXTRACT_SUBREG child #1 is not a leaf"); @@ -2717,6 +2746,13 @@ Expected GlobalISelEmitter::createAndImportInstructionRenderer( } // Render the explicit uses. + unsigned DstINumUses = OrigDstI->Operands.size() - OrigDstI->Operands.NumDefs; + unsigned ExpectedDstINumUses = Dst->getNumChildren(); + if (OrigDstI->TheDef->getName() == "COPY_TO_REGCLASS") { + DstINumUses--; // Ignore the class constraint. + ExpectedDstINumUses--; + } + unsigned Child = 0; unsigned NumDefaultOps = 0; for (unsigned I = 0; I != DstINumUses; ++I) {