From e2d7eae2972943fb0be2aa2e4319513c558695b2 Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Wed, 4 Sep 2019 16:19:34 +0000 Subject: [PATCH] GlobalISel/TableGen: Don't skip REG_SEQUENCE based on patterns This partially adds support for patterns with REG_SEQUENCE. The source patterns are now accepted, but the pattern is still rejected due to missing support for the instruction renderer. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@370920 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/GlobalISelEmitter.cpp | 56 +++++++++++++++------------- 1 file changed, 31 insertions(+), 25 deletions(-) diff --git a/utils/TableGen/GlobalISelEmitter.cpp b/utils/TableGen/GlobalISelEmitter.cpp index 774c4ef818d..899ad5ed298 100644 --- a/utils/TableGen/GlobalISelEmitter.cpp +++ b/utils/TableGen/GlobalISelEmitter.cpp @@ -3931,8 +3931,8 @@ GlobalISelEmitter::createAndImportSubInstructionRenderer( // We need to make sure that when we import an INSERT_SUBREG as a // subinstruction that it ends up being constrained to the correct super // register and subregister classes. - if (Target.getInstruction(Dst->getOperator()).TheDef->getName() == - "INSERT_SUBREG") { + auto OpName = Target.getInstruction(Dst->getOperator()).TheDef->getName(); + if (OpName == "INSERT_SUBREG") { auto SubClass = inferRegClassFromPattern(Dst->getChild(1)); if (!SubClass) return failedImport( @@ -3956,23 +3956,22 @@ GlobalISelEmitter::createAndImportSubInstructionRenderer( // Similar to INSERT_SUBREG, we also have to handle SUBREG_TO_REG as a // subinstruction. - if (Target.getInstruction(Dst->getOperator()).TheDef->getName() == - "SUBREG_TO_REG") { - auto SubClass = inferRegClassFromPattern(Dst->getChild(1)); - if (!SubClass) - return failedImport( + if (OpName == "SUBREG_TO_REG") { + auto SubClass = inferRegClassFromPattern(Dst->getChild(1)); + if (!SubClass) + return failedImport( "Cannot infer register class from SUBREG_TO_REG child #1"); - auto SuperClass = inferSuperRegisterClass(Dst->getExtType(0), - Dst->getChild(2)); - if (!SuperClass) - return failedImport( + auto SuperClass = inferSuperRegisterClass(Dst->getExtType(0), + Dst->getChild(2)); + if (!SuperClass) + return failedImport( "Cannot infer register class for SUBREG_TO_REG operand #0"); - M.insertAction( + M.insertAction( InsertPt, DstMIBuilder.getInsnID(), 0, **SuperClass); - M.insertAction( + M.insertAction( InsertPt, DstMIBuilder.getInsnID(), 2, **SubClass); - return InsertPtOrError.get(); -} + return InsertPtOrError.get(); + } M.insertAction(InsertPt, DstMIBuilder.getInsnID()); @@ -4193,10 +4192,11 @@ GlobalISelEmitter::inferRegClassFromPattern(TreePatternNode *N) { // Handle any special-case instructions which we can safely infer register // classes from. StringRef InstName = Inst.TheDef->getName(); - if (InstName == "COPY_TO_REGCLASS") { + bool IsRegSequence = InstName == "REG_SEQUENCE"; + if (IsRegSequence || InstName == "COPY_TO_REGCLASS") { // If we have a COPY_TO_REGCLASS, then we need to handle it specially. It // has the desired register class as the first child. - TreePatternNode *RCChild = N->getChild(1); + TreePatternNode *RCChild = N->getChild(IsRegSequence ? 0 : 1); if (!RCChild->isLeaf()) return None; return getRegClassFromLeaf(RCChild); @@ -4349,6 +4349,8 @@ Expected GlobalISelEmitter::runOnPattern(const PatternToMatch &P) { return failedImport("Pattern operator isn't an instruction"); auto &DstI = Target.getInstruction(DstOp); + StringRef DstIName = DstI.TheDef->getName(); + if (DstI.Operands.NumDefs != Src->getExtTypes().size()) return failedImport("Src pattern results and dst MI defs are different (" + to_string(Src->getExtTypes().size()) + " def(s) vs " + @@ -4362,13 +4364,17 @@ Expected GlobalISelEmitter::runOnPattern(const PatternToMatch &P) { const auto &DstIOperand = DstI.Operands[OpIdx]; Record *DstIOpRec = DstIOperand.Rec; - if (DstI.TheDef->getName() == "COPY_TO_REGCLASS") { + if (DstIName == "COPY_TO_REGCLASS") { DstIOpRec = getInitValueAsRegClass(Dst->getChild(1)->getLeafValue()); if (DstIOpRec == nullptr) return failedImport( "COPY_TO_REGCLASS operand #1 isn't a register class"); - } else if (DstI.TheDef->getName() == "EXTRACT_SUBREG") { + } else if (DstIName == "REG_SEQUENCE") { + DstIOpRec = getInitValueAsRegClass(Dst->getChild(0)->getLeafValue()); + if (DstIOpRec == nullptr) + return failedImport("REG_SEQUENCE operand #0 isn't a register class"); + } else if (DstIName == "EXTRACT_SUBREG") { if (!Dst->getChild(0)->isLeaf()) return failedImport("EXTRACT_SUBREG operand #0 isn't a leaf"); @@ -4378,7 +4384,7 @@ Expected GlobalISelEmitter::runOnPattern(const PatternToMatch &P) { if (DstIOpRec == nullptr) return failedImport("EXTRACT_SUBREG operand #0 isn't a register class"); - } else if (DstI.TheDef->getName() == "INSERT_SUBREG") { + } else if (DstIName == "INSERT_SUBREG") { auto MaybeSuperClass = inferSuperRegisterClassForNode( VTy, Dst->getChild(0), Dst->getChild(2)); if (!MaybeSuperClass) @@ -4393,7 +4399,7 @@ Expected GlobalISelEmitter::runOnPattern(const PatternToMatch &P) { OM.addPredicate(**MaybeSuperClass); ++OpIdx; continue; - } else if (DstI.TheDef->getName() == "SUBREG_TO_REG") { + } else if (DstIName == "SUBREG_TO_REG") { auto MaybeRegClass = inferSuperRegisterClass(VTy, Dst->getChild(2)); if (!MaybeRegClass) return failedImport( @@ -4432,7 +4438,7 @@ Expected GlobalISelEmitter::runOnPattern(const PatternToMatch &P) { // 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") { + if (DstIName == "COPY_TO_REGCLASS") { // COPY_TO_REGCLASS does not provide operand constraints itself but the // result is constrained to the class given by the second child. Record *DstIOpRec = @@ -4450,7 +4456,7 @@ Expected GlobalISelEmitter::runOnPattern(const PatternToMatch &P) { return std::move(M); } - if (DstI.TheDef->getName() == "EXTRACT_SUBREG") { + if (DstIName == "EXTRACT_SUBREG") { // EXTRACT_SUBREG selects into a subregister COPY but unlike most // instructions, the result register class is controlled by the // subregisters of the operand. As a result, we must constrain the result @@ -4493,7 +4499,7 @@ Expected GlobalISelEmitter::runOnPattern(const PatternToMatch &P) { return std::move(M); } - if (DstI.TheDef->getName() == "INSERT_SUBREG") { + if (DstIName == "INSERT_SUBREG") { assert(Src->getExtTypes().size() == 1 && "Expected Src of INSERT_SUBREG to have one result type"); // We need to constrain the destination, a super regsister source, and a @@ -4514,7 +4520,7 @@ Expected GlobalISelEmitter::runOnPattern(const PatternToMatch &P) { return std::move(M); } - if (DstI.TheDef->getName() == "SUBREG_TO_REG") { + if (DstIName == "SUBREG_TO_REG") { // We need to constrain the destination and subregister source. assert(Src->getExtTypes().size() == 1 && "Expected Src of SUBREG_TO_REG to have one result type"); -- 2.40.0