diff options
Diffstat (limited to 'llvm/utils/TableGen/GlobalISelEmitter.cpp')
-rw-r--r-- | llvm/utils/TableGen/GlobalISelEmitter.cpp | 456 |
1 files changed, 239 insertions, 217 deletions
diff --git a/llvm/utils/TableGen/GlobalISelEmitter.cpp b/llvm/utils/TableGen/GlobalISelEmitter.cpp index 4250b57..3b334ea 100644 --- a/llvm/utils/TableGen/GlobalISelEmitter.cpp +++ b/llvm/utils/TableGen/GlobalISelEmitter.cpp @@ -404,21 +404,34 @@ private: createInstructionRenderer(action_iterator InsertPt, RuleMatcher &M, const TreePatternNode &Dst) const; - Expected<action_iterator> importExplicitDefRenderers( - action_iterator InsertPt, RuleMatcher &M, BuildMIAction &DstMIBuilder, - const TreePatternNode &Dst, unsigned Start = 0) const; + Expected<action_iterator> + importExplicitDefRenderers(action_iterator InsertPt, RuleMatcher &M, + BuildMIAction &DstMIBuilder, + const TreePatternNode &Dst, bool IsRoot) const; Expected<action_iterator> importExplicitUseRenderers(action_iterator InsertPt, RuleMatcher &M, BuildMIAction &DstMIBuilder, const TreePatternNode &Dst) const; - Expected<action_iterator> - importExplicitUseRenderer(action_iterator InsertPt, RuleMatcher &Rule, - BuildMIAction &DstMIBuilder, - const TreePatternNode &Dst) const; - Error importDefaultOperandRenderers(action_iterator InsertPt, RuleMatcher &M, - BuildMIAction &DstMIBuilder, - const DAGDefaultOperand &DefaultOp) const; + + Error importNamedNodeRenderer(RuleMatcher &M, BuildMIAction &MIBuilder, + const TreePatternNode &N) const; + + Error importLeafNodeRenderer(RuleMatcher &M, BuildMIAction &MIBuilder, + const TreePatternNode &N, + action_iterator InsertPt) const; + + Error importXFormNodeRenderer(RuleMatcher &M, BuildMIAction &MIBuilder, + const TreePatternNode &N) const; + + Error importInstructionNodeRenderer(RuleMatcher &M, BuildMIAction &MIBuilder, + const TreePatternNode &N, + action_iterator &InsertPt) const; + + Error importNodeRenderer(RuleMatcher &M, BuildMIAction &MIBuilder, + const TreePatternNode &N, + action_iterator &InsertPt) const; + Error importImplicitDefRenderers(BuildMIAction &DstMIBuilder, ArrayRef<const Record *> ImplicitDefs) const; @@ -992,27 +1005,24 @@ Error GlobalISelEmitter::importChildMatcher( // Check MBB's before the type check since they are not a known type. if (!SrcChild.isLeaf()) { - if (SrcChild.getOperator()->isSubClassOf("SDNode")) { - auto &ChildSDNI = CGP.getSDNodeInfo(SrcChild.getOperator()); - if (ChildSDNI.getSDClassName() == "BasicBlockSDNode") { - OM.addPredicate<MBBOperandMatcher>(); - return Error::success(); - } - if (SrcChild.getOperator()->getName() == "timm") { - OM.addPredicate<ImmOperandMatcher>(); + if (SrcChild.getOperator()->getName() == "bb") { + OM.addPredicate<MBBOperandMatcher>(); + return Error::success(); + } + if (SrcChild.getOperator()->getName() == "timm") { + OM.addPredicate<ImmOperandMatcher>(); - // Add predicates, if any - for (const TreePredicateCall &Call : SrcChild.getPredicateCalls()) { - const TreePredicateFn &Predicate = Call.Fn; + // Add predicates, if any + for (const TreePredicateCall &Call : SrcChild.getPredicateCalls()) { + const TreePredicateFn &Predicate = Call.Fn; - // Only handle immediate patterns for now - if (Predicate.isImmediatePattern()) { - OM.addPredicate<OperandImmPredicateMatcher>(Predicate); - } + // Only handle immediate patterns for now + if (Predicate.isImmediatePattern()) { + OM.addPredicate<OperandImmPredicateMatcher>(Predicate); } - - return Error::success(); } + + return Error::success(); } } else if (auto *ChildDefInit = dyn_cast<DefInit>(SrcChild.getLeafValue())) { auto *ChildRec = ChildDefInit->getDef(); @@ -1192,162 +1202,217 @@ Error GlobalISelEmitter::importChildMatcher( return failedImport("Src pattern child is an unsupported kind"); } -Expected<action_iterator> GlobalISelEmitter::importExplicitUseRenderer( - action_iterator InsertPt, RuleMatcher &Rule, BuildMIAction &DstMIBuilder, - const TreePatternNode &Dst) const { +// Equivalent of MatcherGen::EmitResultOfNamedOperand. +Error GlobalISelEmitter::importNamedNodeRenderer( + RuleMatcher &M, BuildMIAction &MIBuilder, const TreePatternNode &N) const { + StringRef NodeName = N.getName(); - const auto &SubOperand = Rule.getComplexSubOperand(Dst.getName()); - if (SubOperand) { - DstMIBuilder.addRenderer<RenderComplexPatternOperand>( - *std::get<0>(*SubOperand), Dst.getName(), std::get<1>(*SubOperand), - std::get<2>(*SubOperand)); - return InsertPt; + if (auto SubOperand = M.getComplexSubOperand(NodeName)) { + auto [ComplexPatternRec, RendererID, SubOperandIdx] = *SubOperand; + MIBuilder.addRenderer<RenderComplexPatternOperand>( + *ComplexPatternRec, NodeName, RendererID, SubOperandIdx); + 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<CustomOperandRenderer>(*I->second, - Child.getName()); - } else { - DstMIBuilder.addRenderer<CustomRenderer>(*I->second, Child.getName()); - } + if (!N.isLeaf()) { + StringRef OperatorName = N.getOperator()->getName(); - return InsertPt; - } - return failedImport("SDNodeXForm " + Child.getName() + - " has no custom renderer"); + if (OperatorName == "imm") { + MIBuilder.addRenderer<CopyConstantAsImmRenderer>(NodeName); + return Error::success(); } - // We accept 'bb' here. It's an operator because BasicBlockSDNode isn't - // inline, but in MI it's just another operand. - if (Dst.getOperator()->isSubClassOf("SDNode")) { - auto &ChildSDNI = CGP.getSDNodeInfo(Dst.getOperator()); - if (ChildSDNI.getSDClassName() == "BasicBlockSDNode") { - DstMIBuilder.addRenderer<CopyRenderer>(Dst.getName()); - return InsertPt; - } + if (OperatorName == "fpimm") { + MIBuilder.addRenderer<CopyFConstantAsFPImmRenderer>(NodeName); + return Error::success(); } - // 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<CopyRenderer>(Dst.getName()); - return InsertPt; - } - if (Dst.getOperator()->getName() == "tframeindex") { - DstMIBuilder.addRenderer<CopyRenderer>(Dst.getName()); - return InsertPt; - } - if (Dst.getOperator()->getName() == "imm") { - DstMIBuilder.addRenderer<CopyConstantAsImmRenderer>(Dst.getName()); - return InsertPt; - } - if (Dst.getOperator()->getName() == "fpimm") { - DstMIBuilder.addRenderer<CopyFConstantAsFPImmRenderer>(Dst.getName()); - return InsertPt; + // 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<CopyRenderer>(NodeName); + return Error::success(); } - if (Dst.getOperator()->isSubClassOf("Instruction")) { - auto OpTy = getInstResultType(Dst, Target); - if (!OpTy) - return OpTy.takeError(); + return failedImport("node has unsupported operator " + to_string(N)); + } + + if (const auto *DI = dyn_cast<DefInit>(N.getLeafValue())) { + const Record *R = DI->getDef(); - unsigned TempRegID = Rule.allocateTempRegID(); - InsertPt = - Rule.insertAction<MakeTempRegisterAction>(InsertPt, *OpTy, TempRegID); - DstMIBuilder.addRenderer<TempRegRenderer>(TempRegID); + if (N.getNumResults() != 1) + return failedImport("node does not have one result " + to_string(N)); - auto InsertPtOrError = createAndImportSubInstructionRenderer( - ++InsertPt, Rule, Dst, TempRegID); - if (auto Error = InsertPtOrError.takeError()) - return std::move(Error); - return InsertPtOrError.get(); + 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<RenderComplexPatternOperand>( + *I->second, NodeName, OM.getAllocatedTemporariesBaseID()); + return Error::success(); + } + + if (R->isSubClassOf("RegisterOperand") && + !R->isValueUnset("GIZeroRegister")) { + MIBuilder.addRenderer<CopyOrAddZeroRegRenderer>( + NodeName, R->getValueAsDef("GIZeroRegister")); + return Error::success(); } - return failedImport("Dst pattern child isn't a leaf node or an MBB" + - llvm::to_string(Dst)); + // 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<CopyRenderer>(NodeName); + return Error::success(); + } } - // It could be a specific immediate in which case we should just check for - // that immediate. - if (const IntInit *ChildIntInit = dyn_cast<IntInit>(Dst.getLeafValue())) { - DstMIBuilder.addRenderer<ImmRenderer>(ChildIntInit->getValue()); - return InsertPt; + // 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<UnsetInit>(N.getLeafValue())) { + MIBuilder.addRenderer<CopyRenderer>(NodeName); + return Error::success(); } - // Otherwise, we're looking for a bog-standard RegisterClass operand. - if (auto *ChildDefInit = dyn_cast<DefInit>(Dst.getLeafValue())) { - auto *ChildRec = ChildDefInit->getDef(); + return failedImport("unsupported node " + to_string(N)); +} - ArrayRef<TypeSetByHwMode> ChildTypes = Dst.getExtTypes(); - if (ChildTypes.size() != 1) - return failedImport("Dst pattern child has multiple results"); +// Equivalent of MatcherGen::EmitResultLeafAsOperand. +Error GlobalISelEmitter::importLeafNodeRenderer( + RuleMatcher &M, BuildMIAction &MIBuilder, const TreePatternNode &N, + action_iterator InsertPt) const { + if (const auto *II = dyn_cast<IntInit>(N.getLeafValue())) { + MIBuilder.addRenderer<ImmRenderer>(II->getValue()); + return Error::success(); + } - std::optional<LLTCodeGen> OpTyOrNone; - if (ChildTypes.front().isMachineValueType()) - OpTyOrNone = MVTToLLT(ChildTypes.front().getMachineValueType().SimpleTy); - if (!OpTyOrNone) - return failedImport("Dst operand has an unsupported type"); + if (const auto *DI = dyn_cast<DefInit>(N.getLeafValue())) { + const Record *R = DI->getDef(); - if (ChildRec->isSubClassOf("Register")) { - DstMIBuilder.addRenderer<AddRegisterRenderer>(Target, ChildRec); - return InsertPt; + if (R->isSubClassOf("Register") || R->getName() == "zero_reg") { + MIBuilder.addRenderer<AddRegisterRenderer>(Target, R); + return Error::success(); } - if (ChildRec->isSubClassOf("RegisterClass") || - ChildRec->isSubClassOf("RegisterOperand") || - ChildRec->isSubClassOf("ValueType")) { - if (ChildRec->isSubClassOf("RegisterOperand") && - !ChildRec->isValueUnset("GIZeroRegister")) { - DstMIBuilder.addRenderer<CopyOrAddZeroRegRenderer>( - Dst.getName(), ChildRec->getValueAsDef("GIZeroRegister")); - return InsertPt; - } + if (R->getName() == "undef_tied_input") { + std::optional<LLTCodeGen> OpTyOrNone = MVTToLLT(N.getSimpleType(0)); + if (!OpTyOrNone) + return failedImport("unsupported type"); - DstMIBuilder.addRenderer<CopyRenderer>(Dst.getName()); - return InsertPt; - } + unsigned TempRegID = M.allocateTempRegID(); + M.insertAction<MakeTempRegisterAction>(InsertPt, *OpTyOrNone, TempRegID); - if (ChildRec->isSubClassOf("SubRegIndex")) { - CodeGenSubRegIndex *SubIdx = CGRegs.getSubRegIdx(ChildRec); - DstMIBuilder.addRenderer<ImmRenderer>(SubIdx->EnumValue); - return InsertPt; - } + auto I = M.insertAction<BuildMIAction>( + InsertPt, M.allocateOutputInsnID(), + &Target.getInstruction(RK.getDef("IMPLICIT_DEF"))); + auto &ImpDefBuilder = static_cast<BuildMIAction &>(**I); + ImpDefBuilder.addRenderer<TempRegRenderer>(TempRegID, /*IsDef=*/true); - if (ChildRec->isSubClassOf("ComplexPattern")) { - const auto &ComplexPattern = ComplexPatternEquivs.find(ChildRec); - if (ComplexPattern == ComplexPatternEquivs.end()) - return failedImport( - "SelectionDAG ComplexPattern not mapped to GlobalISel"); + MIBuilder.addRenderer<TempRegRenderer>(TempRegID); + return Error::success(); + } - const OperandMatcher &OM = Rule.getOperandMatcher(Dst.getName()); - DstMIBuilder.addRenderer<RenderComplexPatternOperand>( - *ComplexPattern->second, Dst.getName(), - OM.getAllocatedTemporariesBaseID()); - return InsertPt; + if (R->isSubClassOf("SubRegIndex")) { + const CodeGenSubRegIndex *SubRegIndex = CGRegs.getSubRegIdx(R); + MIBuilder.addRenderer<ImmRenderer>(SubRegIndex->EnumValue); + return Error::success(); } - return failedImport( - "Dst pattern child def is an unsupported tablegen class"); + // There are also RegisterClass / RegisterOperand operands of REG_SEQUENCE / + // COPY_TO_REGCLASS, but these instructions are currently handled elsewhere. } - // Handle the case where the MVT/register class is omitted in the dest pattern - // but MVT exists in the source pattern. - if (isa<UnsetInit>(Dst.getLeafValue()) && Rule.hasOperand(Dst.getName())) { - DstMIBuilder.addRenderer<CopyRenderer>(Dst.getName()); - return InsertPt; + 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<CustomOperandRenderer>(*XFormEquivRec, NodeName); + } else { + MIBuilder.addRenderer<CustomRenderer>(*XFormEquivRec, NodeName); } - return failedImport("Dst pattern child is an unsupported kind"); + + return Error::success(); +} + +// Equivalent of MatcherGen::EmitResultInstructionAsOperand. +Error GlobalISelEmitter::importInstructionNodeRenderer( + RuleMatcher &M, BuildMIAction &MIBuilder, const TreePatternNode &N, + action_iterator &InsertPt) const { + Expected<LLTCodeGen> 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<MakeTempRegisterAction>(InsertPt, *OpTy, TempRegID); + MIBuilder.addRenderer<TempRegRenderer>(TempRegID); + + auto InsertPtOrError = + createAndImportSubInstructionRenderer(++InsertPt, M, N, TempRegID); + if (!InsertPtOrError) + return InsertPtOrError.takeError(); + + InsertPt = *InsertPtOrError; + return Error::success(); +} + +// 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 (N.isLeaf()) + return importLeafNodeRenderer(M, MIBuilder, N, InsertPt); + + if (N.getOperator()->isSubClassOf("SDNodeXForm")) + return importXFormNodeRenderer(M, MIBuilder, N); + + if (N.getOperator()->isSubClassOf("Instruction")) + return importInstructionNodeRenderer(M, MIBuilder, N, InsertPt); + + // Should not reach here. + return failedImport("unrecognized node " + llvm::to_string(N)); } /// Generates code that builds the resulting instruction(s) from the destination @@ -1364,18 +1429,19 @@ Expected<BuildMIAction &> GlobalISelEmitter::createAndImportInstructionRenderer( action_iterator InsertPt = InsertPtOrError.get(); BuildMIAction &DstMIBuilder = *static_cast<BuildMIAction *>(InsertPt->get()); - for (auto PhysInput : InsnMatcher.getPhysRegInputs()) { + for (auto PhysOp : M.physoperands()) { InsertPt = M.insertAction<BuildMIAction>( InsertPt, M.allocateOutputInsnID(), &Target.getInstruction(RK.getDef("COPY"))); BuildMIAction &CopyToPhysRegMIBuilder = *static_cast<BuildMIAction *>(InsertPt->get()); - CopyToPhysRegMIBuilder.addRenderer<AddRegisterRenderer>( - Target, PhysInput.first, true); - CopyToPhysRegMIBuilder.addRenderer<CopyPhysRegRenderer>(PhysInput.first); + CopyToPhysRegMIBuilder.addRenderer<AddRegisterRenderer>(Target, + PhysOp.first, true); + CopyToPhysRegMIBuilder.addRenderer<CopyPhysRegRenderer>(PhysOp.first); } - if (auto Error = importExplicitDefRenderers(InsertPt, M, DstMIBuilder, Dst) + if (auto Error = importExplicitDefRenderers(InsertPt, M, DstMIBuilder, Dst, + /*IsRoot=*/true) .takeError()) return std::move(Error); @@ -1404,8 +1470,8 @@ GlobalISelEmitter::createAndImportSubInstructionRenderer( DstMIBuilder.addRenderer<TempRegRenderer>(TempRegID, true); // Handle additional (ignored) results. - InsertPtOrError = importExplicitDefRenderers(std::prev(*InsertPtOrError), M, - DstMIBuilder, Dst, /*Start=*/1); + InsertPtOrError = importExplicitDefRenderers( + std::prev(*InsertPtOrError), M, DstMIBuilder, Dst, /*IsRoot=*/false); if (auto Error = InsertPtOrError.takeError()) return std::move(Error); @@ -1446,16 +1512,16 @@ GlobalISelEmitter::createInstructionRenderer(action_iterator InsertPt, Expected<action_iterator> GlobalISelEmitter::importExplicitDefRenderers( action_iterator InsertPt, RuleMatcher &M, BuildMIAction &DstMIBuilder, - const TreePatternNode &Dst, unsigned Start) const { + const TreePatternNode &Dst, bool IsRoot) const { const CodeGenInstruction *DstI = DstMIBuilder.getCGI(); // Process explicit defs. The caller may have already handled the first def. - for (unsigned I = Start, E = DstI->Operands.NumDefs; I != E; ++I) { + for (unsigned I = IsRoot ? 0 : 1, E = DstI->Operands.NumDefs; I != E; ++I) { const CGIOperandList::OperandInfo &OpInfo = DstI->Operands[I]; std::string OpName = getMangledRootDefName(OpInfo.Name); // If the def is used in the source DAG, forward it. - if (M.hasOperand(OpName)) { + if (IsRoot && M.hasOperand(OpName)) { // CopyRenderer saves a StringRef, so cannot pass OpName itself - // let's use a string with an appropriate lifetime. StringRef PermanentRef = M.getOperandMatcher(OpName).getSymbolicName(); @@ -1601,11 +1667,9 @@ Expected<action_iterator> GlobalISelEmitter::importExplicitUseRenderers( dyn_cast<DefInit>(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<SubRegIndexRenderer>(SubIdx); } } @@ -1660,21 +1724,20 @@ Expected<action_iterator> GlobalISelEmitter::importExplicitUseRenderers( // This is a predicate or optional def operand which the pattern has not // overridden, or which we aren't letting it override; emit the 'default // ops' operands. - - const Record *OperandNode = DstI->Operands[InstOpNo].Rec; - if (auto Error = importDefaultOperandRenderers( - InsertPt, M, DstMIBuilder, CGP.getDefaultOperand(OperandNode))) - return std::move(Error); + for (const TreePatternNode &OpNode : + make_pointee_range(CGP.getDefaultOperand(OperandNode).DefaultOps)) { + if (Error Err = importNodeRenderer(M, DstMIBuilder, OpNode, InsertPt)) + return Err; + } ++NumDefaultOps; 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; } @@ -1688,47 +1751,6 @@ Expected<action_iterator> GlobalISelEmitter::importExplicitUseRenderers( return InsertPt; } -Error GlobalISelEmitter::importDefaultOperandRenderers( - action_iterator InsertPt, RuleMatcher &M, BuildMIAction &DstMIBuilder, - const DAGDefaultOperand &DefaultOp) const { - for (const auto &Op : DefaultOp.DefaultOps) { - const auto &N = *Op; - if (!N.isLeaf()) - return failedImport("Could not add default op"); - - const auto *DefaultOp = N.getLeafValue(); - - if (const DefInit *DefaultDefOp = dyn_cast<DefInit>(DefaultOp)) { - std::optional<LLTCodeGen> OpTyOrNone = MVTToLLT(N.getSimpleType(0)); - auto *Def = DefaultDefOp->getDef(); - if (Def->getName() == "undef_tied_input") { - unsigned TempRegID = M.allocateTempRegID(); - M.insertAction<MakeTempRegisterAction>(InsertPt, *OpTyOrNone, - TempRegID); - InsertPt = M.insertAction<BuildMIAction>( - InsertPt, M.allocateOutputInsnID(), - &Target.getInstruction(RK.getDef("IMPLICIT_DEF"))); - BuildMIAction &IDMIBuilder = - *static_cast<BuildMIAction *>(InsertPt->get()); - IDMIBuilder.addRenderer<TempRegRenderer>(TempRegID); - DstMIBuilder.addRenderer<TempRegRenderer>(TempRegID); - } else { - DstMIBuilder.addRenderer<AddRegisterRenderer>(Target, Def); - } - continue; - } - - if (const IntInit *DefaultIntOp = dyn_cast<IntInit>(DefaultOp)) { - DstMIBuilder.addRenderer<ImmRenderer>(DefaultIntOp->getValue()); - continue; - } - - return failedImport("Could not add default op"); - } - - return Error::success(); -} - Error GlobalISelEmitter::importImplicitDefRenderers( BuildMIAction &DstMIBuilder, ArrayRef<const Record *> ImplicitDefs) const { if (!ImplicitDefs.empty()) |