From 7655b54d234c2d5164bb7edad005d8e6d850a2f4 Mon Sep 17 00:00:00 2001 From: Sergei Barannikov Date: Wed, 25 Dec 2024 01:16:22 +0300 Subject: [PATCH 1/5] importNamedNodeRenderer --- llvm/utils/TableGen/GlobalISelEmitter.cpp | 182 ++++++++++++---------- 1 file changed, 103 insertions(+), 79 deletions(-) diff --git a/llvm/utils/TableGen/GlobalISelEmitter.cpp b/llvm/utils/TableGen/GlobalISelEmitter.cpp index 5038be7b24fbc..4ec69c37d5766 100644 --- a/llvm/utils/TableGen/GlobalISelEmitter.cpp +++ b/llvm/utils/TableGen/GlobalISelEmitter.cpp @@ -412,6 +412,10 @@ class GlobalISelEmitter final : public GlobalISelMatchTableExecutorEmitter { importExplicitUseRenderers(action_iterator InsertPt, RuleMatcher &M, BuildMIAction &DstMIBuilder, const TreePatternNode &Dst) const; + + Error importNamedNodeRenderer(RuleMatcher &M, BuildMIAction &MIBuilder, + const TreePatternNode &N) const; + Expected importExplicitUseRenderer(action_iterator InsertPt, RuleMatcher &Rule, BuildMIAction &DstMIBuilder, @@ -1189,15 +1193,106 @@ Error GlobalISelEmitter::importChildMatcher( return failedImport("Src pattern child is an unsupported kind"); } +// Equivalent of MatcherGen::EmitResultOfNamedOperand. +Error GlobalISelEmitter::importNamedNodeRenderer( + RuleMatcher &M, BuildMIAction &MIBuilder, const TreePatternNode &N) const { + StringRef NodeName = N.getName(); + + if (auto SubOperand = M.getComplexSubOperand(NodeName)) { + auto [ComplexPatternRec, RendererID, SubOperandIdx] = *SubOperand; + MIBuilder.addRenderer( + *ComplexPatternRec, NodeName, RendererID, SubOperandIdx); + return Error::success(); + } + + if (!N.isLeaf()) { + StringRef OperatorName = N.getOperator()->getName(); + + if (OperatorName == "imm") { + MIBuilder.addRenderer(NodeName); + return Error::success(); + } + + if (OperatorName == "fpimm") { + MIBuilder.addRenderer(NodeName); + return Error::success(); + } + + // TODO: 'imm' and 'fpimm' are the only nodes that need special treatment. + // Remove this check and add CopyRenderer unconditionally for other nodes. + if (OperatorName == "bb" || OperatorName == "timm" || + OperatorName == "tframeindex") { + MIBuilder.addRenderer(NodeName); + return Error::success(); + } + + return failedImport("node has unsupported operator " + to_string(N)); + } + + if (const auto *DI = dyn_cast(N.getLeafValue())) { + const Record *R = DI->getDef(); + + if (N.getNumResults() != 1) + return failedImport("node does not have one result " + to_string(N)); + + std::optional OpTyOrNone; + ArrayRef ChildTypes = N.getExtTypes(); + if (ChildTypes.front().isMachineValueType()) + OpTyOrNone = MVTToLLT(ChildTypes.front().getMachineValueType().SimpleTy); + + // TODO: Remove this check. Types in the destination DAG should not matter. + if (!OpTyOrNone) + return failedImport("node has unsupported type " + to_string(N)); + + if (R->isSubClassOf("ComplexPattern")) { + auto I = ComplexPatternEquivs.find(R); + if (I == ComplexPatternEquivs.end()) + return failedImport("ComplexPattern " + R->getName() + + " does not have GISel equivalent"); + + const OperandMatcher &OM = M.getOperandMatcher(NodeName); + MIBuilder.addRenderer( + *I->second, NodeName, OM.getAllocatedTemporariesBaseID()); + return Error::success(); + } + + if (R->isSubClassOf("RegisterOperand") && + !R->isValueUnset("GIZeroRegister")) { + MIBuilder.addRenderer( + NodeName, R->getValueAsDef("GIZeroRegister")); + return Error::success(); + } + + // TODO: All special cases are handled above. Remove this check and add + // CopyRenderer unconditionally. + if (R->isSubClassOf("RegisterClass") || + R->isSubClassOf("RegisterOperand") || R->isSubClassOf("ValueType")) { + MIBuilder.addRenderer(NodeName); + return Error::success(); + } + } + + // TODO: Change this to assert and move to the beginning of the function. + if (!M.hasOperand(NodeName)) + return failedImport("could not find node $" + NodeName + + " in the source DAG"); + + // TODO: Remove this check and add CopyRenderer unconditionally. + // TODO: Handle nodes with multiple results (provided they can reach here). + if (isa(N.getLeafValue())) { + MIBuilder.addRenderer(NodeName); + return Error::success(); + } + + return failedImport("unsupported node " + to_string(N)); +} + Expected GlobalISelEmitter::importExplicitUseRenderer( action_iterator InsertPt, RuleMatcher &Rule, BuildMIAction &DstMIBuilder, const TreePatternNode &Dst) const { - - const auto &SubOperand = Rule.getComplexSubOperand(Dst.getName()); - if (SubOperand) { - DstMIBuilder.addRenderer( - *std::get<0>(*SubOperand), Dst.getName(), std::get<1>(*SubOperand), - std::get<2>(*SubOperand)); + if (Dst.hasName()) { + if (Error Err = importNamedNodeRenderer(Rule, DstMIBuilder, Dst)) + return Err; return InsertPt; } @@ -1223,34 +1318,6 @@ Expected GlobalISelEmitter::importExplicitUseRenderer( " has no custom renderer"); } - // We accept 'bb' here. It's an operator because BasicBlockSDNode isn't - // inline, but in MI it's just another operand. - if (Dst.getOperator()->getName() == "bb") { - DstMIBuilder.addRenderer(Dst.getName()); - return InsertPt; - } - - // Similarly, imm is an operator in TreePatternNode's view but must be - // rendered as operands. - // FIXME: The target should be able to choose sign-extended when appropriate - // (e.g. on Mips). - if (Dst.getOperator()->getName() == "timm") { - DstMIBuilder.addRenderer(Dst.getName()); - return InsertPt; - } - if (Dst.getOperator()->getName() == "tframeindex") { - DstMIBuilder.addRenderer(Dst.getName()); - return InsertPt; - } - if (Dst.getOperator()->getName() == "imm") { - DstMIBuilder.addRenderer(Dst.getName()); - return InsertPt; - } - if (Dst.getOperator()->getName() == "fpimm") { - DstMIBuilder.addRenderer(Dst.getName()); - return InsertPt; - } - if (Dst.getOperator()->isSubClassOf("Instruction")) { auto OpTy = getInstResultType(Dst, Target); if (!OpTy) @@ -1268,8 +1335,8 @@ Expected GlobalISelEmitter::importExplicitUseRenderer( return InsertPtOrError.get(); } - return failedImport("Dst pattern child isn't a leaf node or an MBB" + - llvm::to_string(Dst)); + // Should not reach here. + return failedImport("unrecognized node " + llvm::to_string(Dst)); } // It could be a specific immediate in which case we should just check for @@ -1283,64 +1350,21 @@ Expected GlobalISelEmitter::importExplicitUseRenderer( if (auto *ChildDefInit = dyn_cast(Dst.getLeafValue())) { auto *ChildRec = ChildDefInit->getDef(); - ArrayRef ChildTypes = Dst.getExtTypes(); - if (ChildTypes.size() != 1) - return failedImport("Dst pattern child has multiple results"); - - std::optional OpTyOrNone; - if (ChildTypes.front().isMachineValueType()) - OpTyOrNone = MVTToLLT(ChildTypes.front().getMachineValueType().SimpleTy); - if (!OpTyOrNone) - return failedImport("Dst operand has an unsupported type"); - if (ChildRec->isSubClassOf("Register")) { DstMIBuilder.addRenderer(Target, ChildRec); return InsertPt; } - if (ChildRec->isSubClassOf("RegisterClass") || - ChildRec->isSubClassOf("RegisterOperand") || - ChildRec->isSubClassOf("ValueType")) { - if (ChildRec->isSubClassOf("RegisterOperand") && - !ChildRec->isValueUnset("GIZeroRegister")) { - DstMIBuilder.addRenderer( - Dst.getName(), ChildRec->getValueAsDef("GIZeroRegister")); - return InsertPt; - } - - DstMIBuilder.addRenderer(Dst.getName()); - return InsertPt; - } - if (ChildRec->isSubClassOf("SubRegIndex")) { CodeGenSubRegIndex *SubIdx = CGRegs.getSubRegIdx(ChildRec); DstMIBuilder.addRenderer(SubIdx->EnumValue); return InsertPt; } - if (ChildRec->isSubClassOf("ComplexPattern")) { - const auto &ComplexPattern = ComplexPatternEquivs.find(ChildRec); - if (ComplexPattern == ComplexPatternEquivs.end()) - return failedImport( - "SelectionDAG ComplexPattern not mapped to GlobalISel"); - - const OperandMatcher &OM = Rule.getOperandMatcher(Dst.getName()); - DstMIBuilder.addRenderer( - *ComplexPattern->second, Dst.getName(), - OM.getAllocatedTemporariesBaseID()); - return InsertPt; - } - return failedImport( "Dst pattern child def is an unsupported tablegen class"); } - // Handle the case where the MVT/register class is omitted in the dest pattern - // but MVT exists in the source pattern. - if (isa(Dst.getLeafValue()) && Rule.hasOperand(Dst.getName())) { - DstMIBuilder.addRenderer(Dst.getName()); - return InsertPt; - } return failedImport("Dst pattern child is an unsupported kind"); } From 91743debc60e86999b36fe991b91478013daf136 Mon Sep 17 00:00:00 2001 From: Sergei Barannikov Date: Wed, 25 Dec 2024 01:32:05 +0300 Subject: [PATCH 2/5] importLeafNodeRenderer --- llvm/utils/TableGen/GlobalISelEmitter.cpp | 126 ++++++++++++---------- 1 file changed, 67 insertions(+), 59 deletions(-) diff --git a/llvm/utils/TableGen/GlobalISelEmitter.cpp b/llvm/utils/TableGen/GlobalISelEmitter.cpp index 4ec69c37d5766..600b934bbfa8e 100644 --- a/llvm/utils/TableGen/GlobalISelEmitter.cpp +++ b/llvm/utils/TableGen/GlobalISelEmitter.cpp @@ -416,6 +416,9 @@ class GlobalISelEmitter final : public GlobalISelMatchTableExecutorEmitter { Error importNamedNodeRenderer(RuleMatcher &M, BuildMIAction &MIBuilder, const TreePatternNode &N) const; + Error importLeafNodeRenderer(RuleMatcher &M, BuildMIAction &MIBuilder, + const TreePatternNode &N) const; + Expected importExplicitUseRenderer(action_iterator InsertPt, RuleMatcher &Rule, BuildMIAction &DstMIBuilder, @@ -1287,85 +1290,90 @@ Error GlobalISelEmitter::importNamedNodeRenderer( return failedImport("unsupported node " + to_string(N)); } -Expected GlobalISelEmitter::importExplicitUseRenderer( - action_iterator InsertPt, RuleMatcher &Rule, BuildMIAction &DstMIBuilder, - const TreePatternNode &Dst) const { - if (Dst.hasName()) { - if (Error Err = importNamedNodeRenderer(Rule, DstMIBuilder, Dst)) - return Err; - return InsertPt; +// Equivalent of MatcherGen::EmitResultLeafAsOperand. +Error GlobalISelEmitter::importLeafNodeRenderer( + RuleMatcher &M, BuildMIAction &MIBuilder, const TreePatternNode &N) const { + if (const auto *II = dyn_cast(N.getLeafValue())) { + MIBuilder.addRenderer(II->getValue()); + return Error::success(); } - if (!Dst.isLeaf()) { - if (Dst.getOperator()->isSubClassOf("SDNodeXForm")) { - auto &Child = Dst.getChild(0); - auto I = SDNodeXFormEquivs.find(Dst.getOperator()); - if (I != SDNodeXFormEquivs.end()) { - const Record *XFormOpc = Dst.getOperator()->getValueAsDef("Opcode"); - if (XFormOpc->getName() == "timm") { - // If this is a TargetConstant, there won't be a corresponding - // instruction to transform. Instead, this will refer directly to an - // operand in an instruction's operand list. - DstMIBuilder.addRenderer(*I->second, - Child.getName()); - } else { - DstMIBuilder.addRenderer(*I->second, Child.getName()); - } + if (const auto *DI = dyn_cast(N.getLeafValue())) { + const Record *R = DI->getDef(); - return InsertPt; - } - return failedImport("SDNodeXForm " + Child.getName() + - " has no custom renderer"); + if (R->isSubClassOf("Register")) { + MIBuilder.addRenderer(Target, R); + return Error::success(); } - if (Dst.getOperator()->isSubClassOf("Instruction")) { - auto OpTy = getInstResultType(Dst, Target); - if (!OpTy) - return OpTy.takeError(); + if (R->isSubClassOf("SubRegIndex")) { + const CodeGenSubRegIndex *SubRegIndex = CGRegs.getSubRegIdx(R); + MIBuilder.addRenderer(SubRegIndex->EnumValue); + return Error::success(); + } - unsigned TempRegID = Rule.allocateTempRegID(); - InsertPt = - Rule.insertAction(InsertPt, *OpTy, TempRegID); - DstMIBuilder.addRenderer(TempRegID); + // There are also RegisterClass / RegisterOperand operands of REG_SEQUENCE / + // COPY_TO_REGCLASS, but these instructions are currently handled elsewhere. + } - auto InsertPtOrError = createAndImportSubInstructionRenderer( - ++InsertPt, Rule, Dst, TempRegID); - if (auto Error = InsertPtOrError.takeError()) - return std::move(Error); - return InsertPtOrError.get(); - } + return failedImport("unrecognized node " + to_string(N)); +} - // Should not reach here. - return failedImport("unrecognized node " + llvm::to_string(Dst)); +Expected GlobalISelEmitter::importExplicitUseRenderer( + action_iterator InsertPt, RuleMatcher &Rule, BuildMIAction &DstMIBuilder, + const TreePatternNode &Dst) const { + if (Dst.hasName()) { + if (Error Err = importNamedNodeRenderer(Rule, DstMIBuilder, Dst)) + return Err; + return InsertPt; } - // It could be a specific immediate in which case we should just check for - // that immediate. - if (const IntInit *ChildIntInit = dyn_cast(Dst.getLeafValue())) { - DstMIBuilder.addRenderer(ChildIntInit->getValue()); + if (Dst.isLeaf()) { + if (Error Err = importLeafNodeRenderer(Rule, DstMIBuilder, Dst)) + return Err; return InsertPt; } - // Otherwise, we're looking for a bog-standard RegisterClass operand. - if (auto *ChildDefInit = dyn_cast(Dst.getLeafValue())) { - auto *ChildRec = ChildDefInit->getDef(); + if (Dst.getOperator()->isSubClassOf("SDNodeXForm")) { + auto &Child = Dst.getChild(0); + auto I = SDNodeXFormEquivs.find(Dst.getOperator()); + if (I != SDNodeXFormEquivs.end()) { + const Record *XFormOpc = Dst.getOperator()->getValueAsDef("Opcode"); + if (XFormOpc->getName() == "timm") { + // If this is a TargetConstant, there won't be a corresponding + // instruction to transform. Instead, this will refer directly to an + // operand in an instruction's operand list. + DstMIBuilder.addRenderer(*I->second, + Child.getName()); + } else { + DstMIBuilder.addRenderer(*I->second, Child.getName()); + } - if (ChildRec->isSubClassOf("Register")) { - DstMIBuilder.addRenderer(Target, ChildRec); return InsertPt; } + return failedImport("SDNodeXForm " + Child.getName() + + " has no custom renderer"); + } - if (ChildRec->isSubClassOf("SubRegIndex")) { - CodeGenSubRegIndex *SubIdx = CGRegs.getSubRegIdx(ChildRec); - DstMIBuilder.addRenderer(SubIdx->EnumValue); - return InsertPt; - } + if (Dst.getOperator()->isSubClassOf("Instruction")) { + auto OpTy = getInstResultType(Dst, Target); + if (!OpTy) + return OpTy.takeError(); - return failedImport( - "Dst pattern child def is an unsupported tablegen class"); + unsigned TempRegID = Rule.allocateTempRegID(); + InsertPt = + Rule.insertAction(InsertPt, *OpTy, TempRegID); + DstMIBuilder.addRenderer(TempRegID); + + auto InsertPtOrError = + createAndImportSubInstructionRenderer(++InsertPt, Rule, Dst, TempRegID); + if (auto Error = InsertPtOrError.takeError()) + return std::move(Error); + return InsertPtOrError.get(); } - return failedImport("Dst pattern child is an unsupported kind"); + // Should not reach here. + return failedImport("unrecognized node " + llvm::to_string(Dst)); } /// Generates code that builds the resulting instruction(s) from the destination From e7a645d48892a8c660a620265912b2f241b14514 Mon Sep 17 00:00:00 2001 From: Sergei Barannikov Date: Wed, 25 Dec 2024 01:40:23 +0300 Subject: [PATCH 3/5] importXFormNodeRenderer --- llvm/utils/TableGen/GlobalISelEmitter.cpp | 59 ++++++++++++++++------- 1 file changed, 41 insertions(+), 18 deletions(-) diff --git a/llvm/utils/TableGen/GlobalISelEmitter.cpp b/llvm/utils/TableGen/GlobalISelEmitter.cpp index 600b934bbfa8e..9a865af07e6ce 100644 --- a/llvm/utils/TableGen/GlobalISelEmitter.cpp +++ b/llvm/utils/TableGen/GlobalISelEmitter.cpp @@ -419,6 +419,9 @@ class GlobalISelEmitter final : public GlobalISelMatchTableExecutorEmitter { Error importLeafNodeRenderer(RuleMatcher &M, BuildMIAction &MIBuilder, const TreePatternNode &N) const; + Error importXFormNodeRenderer(RuleMatcher &M, BuildMIAction &MIBuilder, + const TreePatternNode &N) const; + Expected importExplicitUseRenderer(action_iterator InsertPt, RuleMatcher &Rule, BuildMIAction &DstMIBuilder, @@ -1319,6 +1322,41 @@ Error GlobalISelEmitter::importLeafNodeRenderer( return failedImport("unrecognized node " + to_string(N)); } +// Equivalent of MatcherGen::EmitResultSDNodeXFormAsOperand. +Error GlobalISelEmitter::importXFormNodeRenderer( + RuleMatcher &M, BuildMIAction &MIBuilder, const TreePatternNode &N) const { + const Record *XFormRec = N.getOperator(); + auto I = SDNodeXFormEquivs.find(XFormRec); + if (I == SDNodeXFormEquivs.end()) + return failedImport("SDNodeXForm " + XFormRec->getName() + + " does not have GISel equivalent"); + + // TODO: Fail to import if GISDNodeXForm does not have RendererFn. + // This currently results in a fatal error in emitRenderOpcodes. + const Record *XFormEquivRec = I->second; + + // The node to apply the transformation function to. + // FIXME: The node may not have a name and may be a leaf. It should be + // rendered first, like any other nodes. This may or may not require + // introducing a temporary register, and we can't tell that without + // inspecting the node (possibly recursively). This is a general drawback + // of appending renderers directly to BuildMIAction. + const TreePatternNode &Node = N.getChild(0); + StringRef NodeName = Node.getName(); + + const Record *XFormOpc = CGP.getSDNodeTransform(XFormRec).first; + if (XFormOpc->getName() == "timm") { + // If this is a TargetConstant, there won't be a corresponding + // instruction to transform. Instead, this will refer directly to an + // operand in an instruction's operand list. + MIBuilder.addRenderer(*XFormEquivRec, NodeName); + } else { + MIBuilder.addRenderer(*XFormEquivRec, NodeName); + } + + return Error::success(); +} + Expected GlobalISelEmitter::importExplicitUseRenderer( action_iterator InsertPt, RuleMatcher &Rule, BuildMIAction &DstMIBuilder, const TreePatternNode &Dst) const { @@ -1335,24 +1373,9 @@ Expected GlobalISelEmitter::importExplicitUseRenderer( } if (Dst.getOperator()->isSubClassOf("SDNodeXForm")) { - auto &Child = Dst.getChild(0); - auto I = SDNodeXFormEquivs.find(Dst.getOperator()); - if (I != SDNodeXFormEquivs.end()) { - const Record *XFormOpc = Dst.getOperator()->getValueAsDef("Opcode"); - if (XFormOpc->getName() == "timm") { - // If this is a TargetConstant, there won't be a corresponding - // instruction to transform. Instead, this will refer directly to an - // operand in an instruction's operand list. - DstMIBuilder.addRenderer(*I->second, - Child.getName()); - } else { - DstMIBuilder.addRenderer(*I->second, Child.getName()); - } - - return InsertPt; - } - return failedImport("SDNodeXForm " + Child.getName() + - " has no custom renderer"); + if (Error Err = importXFormNodeRenderer(Rule, DstMIBuilder, Dst)) + return Err; + return InsertPt; } if (Dst.getOperator()->isSubClassOf("Instruction")) { From 5ee3665f9281bad7ebdfba57ad9ddda0731a6187 Mon Sep 17 00:00:00 2001 From: Sergei Barannikov Date: Wed, 25 Dec 2024 01:45:31 +0300 Subject: [PATCH 4/5] importInstructionNodeRenderer --- llvm/utils/TableGen/GlobalISelEmitter.cpp | 46 ++++++++++++++++------- 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/llvm/utils/TableGen/GlobalISelEmitter.cpp b/llvm/utils/TableGen/GlobalISelEmitter.cpp index 9a865af07e6ce..2a075bdf0da86 100644 --- a/llvm/utils/TableGen/GlobalISelEmitter.cpp +++ b/llvm/utils/TableGen/GlobalISelEmitter.cpp @@ -422,6 +422,10 @@ class GlobalISelEmitter final : public GlobalISelMatchTableExecutorEmitter { Error importXFormNodeRenderer(RuleMatcher &M, BuildMIAction &MIBuilder, const TreePatternNode &N) const; + Error importInstructionNodeRenderer(RuleMatcher &M, BuildMIAction &MIBuilder, + const TreePatternNode &N, + action_iterator &InsertPt) const; + Expected importExplicitUseRenderer(action_iterator InsertPt, RuleMatcher &Rule, BuildMIAction &DstMIBuilder, @@ -1357,6 +1361,30 @@ Error GlobalISelEmitter::importXFormNodeRenderer( return Error::success(); } +// Equivalent of MatcherGen::EmitResultInstructionAsOperand. +Error GlobalISelEmitter::importInstructionNodeRenderer( + RuleMatcher &M, BuildMIAction &MIBuilder, const TreePatternNode &N, + action_iterator &InsertPt) const { + Expected OpTy = getInstResultType(N, Target); + if (!OpTy) + return OpTy.takeError(); + + // TODO: See the comment in importXFormNodeRenderer. We rely on the node + // requiring a temporary register, which prevents us from using this + // function on the root of the destination DAG. + unsigned TempRegID = M.allocateTempRegID(); + InsertPt = M.insertAction(InsertPt, *OpTy, TempRegID); + MIBuilder.addRenderer(TempRegID); + + auto InsertPtOrError = + createAndImportSubInstructionRenderer(++InsertPt, M, N, TempRegID); + if (!InsertPtOrError) + return InsertPtOrError.takeError(); + + InsertPt = *InsertPtOrError; + return Error::success(); +} + Expected GlobalISelEmitter::importExplicitUseRenderer( action_iterator InsertPt, RuleMatcher &Rule, BuildMIAction &DstMIBuilder, const TreePatternNode &Dst) const { @@ -1379,20 +1407,10 @@ Expected GlobalISelEmitter::importExplicitUseRenderer( } if (Dst.getOperator()->isSubClassOf("Instruction")) { - auto OpTy = getInstResultType(Dst, Target); - if (!OpTy) - return OpTy.takeError(); - - unsigned TempRegID = Rule.allocateTempRegID(); - InsertPt = - Rule.insertAction(InsertPt, *OpTy, TempRegID); - DstMIBuilder.addRenderer(TempRegID); - - auto InsertPtOrError = - createAndImportSubInstructionRenderer(++InsertPt, Rule, Dst, TempRegID); - if (auto Error = InsertPtOrError.takeError()) - return std::move(Error); - return InsertPtOrError.get(); + if (Error Err = + importInstructionNodeRenderer(Rule, DstMIBuilder, Dst, InsertPt)) + return Err; + return InsertPt; } // Should not reach here. From 847faddf6422b21adb5389329e61d84073da755e Mon Sep 17 00:00:00 2001 From: Sergei Barannikov Date: Wed, 25 Dec 2024 01:53:52 +0300 Subject: [PATCH 5/5] Simplify interface --- llvm/utils/TableGen/GlobalISelEmitter.cpp | 64 +++++++++-------------- 1 file changed, 25 insertions(+), 39 deletions(-) diff --git a/llvm/utils/TableGen/GlobalISelEmitter.cpp b/llvm/utils/TableGen/GlobalISelEmitter.cpp index 2a075bdf0da86..606cff6bc167c 100644 --- a/llvm/utils/TableGen/GlobalISelEmitter.cpp +++ b/llvm/utils/TableGen/GlobalISelEmitter.cpp @@ -426,10 +426,10 @@ class GlobalISelEmitter final : public GlobalISelMatchTableExecutorEmitter { const TreePatternNode &N, action_iterator &InsertPt) const; - Expected - importExplicitUseRenderer(action_iterator InsertPt, RuleMatcher &Rule, - BuildMIAction &DstMIBuilder, - const TreePatternNode &Dst) const; + Error importNodeRenderer(RuleMatcher &M, BuildMIAction &MIBuilder, + const TreePatternNode &N, + action_iterator &InsertPt) const; + Error importDefaultOperandRenderers(action_iterator InsertPt, RuleMatcher &M, BuildMIAction &DstMIBuilder, const DAGDefaultOperand &DefaultOp) const; @@ -1385,36 +1385,25 @@ Error GlobalISelEmitter::importInstructionNodeRenderer( return Error::success(); } -Expected GlobalISelEmitter::importExplicitUseRenderer( - action_iterator InsertPt, RuleMatcher &Rule, BuildMIAction &DstMIBuilder, - const TreePatternNode &Dst) const { - if (Dst.hasName()) { - if (Error Err = importNamedNodeRenderer(Rule, DstMIBuilder, Dst)) - return Err; - return InsertPt; - } +// Equivalent of MatcherGen::EmitResultOperand. +Error GlobalISelEmitter::importNodeRenderer(RuleMatcher &M, + BuildMIAction &MIBuilder, + const TreePatternNode &N, + action_iterator &InsertPt) const { + if (N.hasName()) + return importNamedNodeRenderer(M, MIBuilder, N); - if (Dst.isLeaf()) { - if (Error Err = importLeafNodeRenderer(Rule, DstMIBuilder, Dst)) - return Err; - return InsertPt; - } + if (N.isLeaf()) + return importLeafNodeRenderer(M, MIBuilder, N); - if (Dst.getOperator()->isSubClassOf("SDNodeXForm")) { - if (Error Err = importXFormNodeRenderer(Rule, DstMIBuilder, Dst)) - return Err; - return InsertPt; - } + if (N.getOperator()->isSubClassOf("SDNodeXForm")) + return importXFormNodeRenderer(M, MIBuilder, N); - if (Dst.getOperator()->isSubClassOf("Instruction")) { - if (Error Err = - importInstructionNodeRenderer(Rule, DstMIBuilder, Dst, InsertPt)) - return Err; - return InsertPt; - } + if (N.getOperator()->isSubClassOf("Instruction")) + return importInstructionNodeRenderer(M, MIBuilder, N, InsertPt); // Should not reach here. - return failedImport("unrecognized node " + llvm::to_string(Dst)); + return failedImport("unrecognized node " + llvm::to_string(N)); } /// Generates code that builds the resulting instruction(s) from the destination @@ -1668,11 +1657,9 @@ Expected GlobalISelEmitter::importExplicitUseRenderers( dyn_cast(SubRegChild.getLeafValue())) { CodeGenSubRegIndex *SubIdx = CGRegs.getSubRegIdx(SubRegInit->getDef()); - auto InsertPtOrError = - importExplicitUseRenderer(InsertPt, M, DstMIBuilder, ValChild); - if (auto Error = InsertPtOrError.takeError()) - return std::move(Error); - InsertPt = InsertPtOrError.get(); + if (Error Err = importNodeRenderer(M, DstMIBuilder, ValChild, InsertPt)) + return Err; + DstMIBuilder.addRenderer(SubIdx); } } @@ -1737,11 +1724,10 @@ Expected GlobalISelEmitter::importExplicitUseRenderers( continue; } - auto InsertPtOrError = importExplicitUseRenderer(InsertPt, M, DstMIBuilder, - Dst.getChild(Child)); - if (auto Error = InsertPtOrError.takeError()) - return std::move(Error); - InsertPt = InsertPtOrError.get(); + if (Error Err = + importNodeRenderer(M, DstMIBuilder, Dst.getChild(Child), InsertPt)) + return Err; + ++Child; }