From: Victor Leschuk Date: Wed, 23 Aug 2017 15:21:10 +0000 (+0000) Subject: Revert r311546 as it breaks build X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0e75cf0e235f441b59ac5db76e66590b8b1fb231;p=llvm Revert r311546 as it breaks build http://lab.llvm.org:8011/builders/llvm-clang-x86_64-expensive-checks-win/builds/4394 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@311560 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/CodeGen/GlobalISel/InstructionSelector.h b/include/llvm/CodeGen/GlobalISel/InstructionSelector.h index 4ab6ceb35a7..5033668d660 100644 --- a/include/llvm/CodeGen/GlobalISel/InstructionSelector.h +++ b/include/llvm/CodeGen/GlobalISel/InstructionSelector.h @@ -93,10 +93,6 @@ enum { /// - InsnID - Instruction ID /// - Expected number of operands GIM_CheckNumOperands, - /// Check an immediate predicate on the specified instruction - /// - InsnID - Instruction ID - /// - The predicate to test - GIM_CheckImmPredicate, /// Check the type for the specified operand /// - InsnID - Instruction ID @@ -226,8 +222,6 @@ enum { /// Provides the logic to select generic machine instructions. class InstructionSelector { public: - typedef bool(*ImmediatePredicateFn)(int64_t); - virtual ~InstructionSelector() = default; /// Select the (possibly generic) instruction \p I to only use target-specific @@ -260,7 +254,6 @@ public: struct MatcherInfoTy { const LLT *TypeObjects; const PredicateBitset *FeatureBitsets; - const ImmediatePredicateFn *ImmPredicateFns; const std::vector ComplexPredicates; }; diff --git a/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h b/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h index 72de9815eb5..d805326359f 100644 --- a/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h +++ b/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h @@ -17,12 +17,6 @@ #define LLVM_CODEGEN_GLOBALISEL_INSTRUCTIONSELECTORIMPL_H namespace llvm { - -/// GlobalISel PatFrag Predicates -enum { - GIPFP_Invalid, -}; - template bool InstructionSelector::executeMatchTable( @@ -132,28 +126,6 @@ bool InstructionSelector::executeMatchTable( } break; } - case GIM_CheckImmPredicate: { - int64_t InsnID = MatchTable[CurrentIdx++]; - int64_t Predicate = MatchTable[CurrentIdx++]; - DEBUG(dbgs() << CurrentIdx << ": GIM_CheckImmPredicate(MIs[" << InsnID - << "], Predicate=" << Predicate << ")\n"); - assert(State.MIs[InsnID] != nullptr && "Used insn before defined"); - assert(State.MIs[InsnID]->getOpcode() == TargetOpcode::G_CONSTANT && - "Expected G_CONSTANT"); - assert(Predicate > GIPFP_Invalid && "Expected a valid predicate"); - int64_t Value = 0; - if (State.MIs[InsnID]->getOperand(1).isCImm()) - Value = State.MIs[InsnID]->getOperand(1).getCImm()->getSExtValue(); - else if (State.MIs[InsnID]->getOperand(1).isImm()) - Value = State.MIs[InsnID]->getOperand(1).getImm(); - else - llvm_unreachable("Expected Imm or CImm operand"); - - if (!MatcherInfo.ImmPredicateFns[Predicate](Value)) - if (handleReject() == RejectAndGiveUp) - return false; - break; - } case GIM_CheckType: { int64_t InsnID = MatchTable[CurrentIdx++]; diff --git a/test/CodeGen/AArch64/GlobalISel/select-neon-vcvtfxu2fp.mir b/test/CodeGen/AArch64/GlobalISel/select-neon-vcvtfxu2fp.mir deleted file mode 100644 index a7a33acab25..00000000000 --- a/test/CodeGen/AArch64/GlobalISel/select-neon-vcvtfxu2fp.mir +++ /dev/null @@ -1,37 +0,0 @@ -# RUN: llc -mtriple=aarch64-- -mattr=+neon,+fullfp16 -run-pass=instruction-select -verify-machineinstrs -global-isel %s -o - | FileCheck %s - ---- | - target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128" - - define void @vcvtfxu2fp_s64_fpr() { ret void } -... - ---- -# Check that we select a 64-bit FPR vcvtfxu2fp intrinsic into UCVTFd for FPR64. -# CHECK-LABEL: name: vcvtfxu2fp_s64_fpr -name: vcvtfxu2fp_s64_fpr -legalized: true -regBankSelected: true - -# CHECK: registers: -# CHECK-NEXT: - { id: 0, class: fpr64, preferred-register: '' } -# CHECK-NEXT: - { id: 1, class: gpr, preferred-register: '' } -# CHECK-NEXT: - { id: 2, class: fpr64, preferred-register: '' } -registers: - - { id: 0, class: fpr } - - { id: 1, class: gpr } - - { id: 2, class: fpr } - -# CHECK: body: -# CHECK: %0 = COPY %d0 -# CHECK: %2 = UCVTFd %0, 12 -# CHECK: %d1 = COPY %2 -body: | - bb.0: - liveins: %d0 - - %0(s64) = COPY %d0 - %1(s32) = G_CONSTANT i32 12 - %2(s64) = G_INTRINSIC intrinsic(@llvm.aarch64.neon.vcvtfxu2fp.f64), %0, %1 - %d1 = COPY %2(s64) -... diff --git a/test/TableGen/GlobalISelEmitter.td b/test/TableGen/GlobalISelEmitter.td index ddfb4f8744a..cb3974a1cf1 100644 --- a/test/TableGen/GlobalISelEmitter.td +++ b/test/TableGen/GlobalISelEmitter.td @@ -53,7 +53,7 @@ def HasC : Predicate<"Subtarget->hasC()"> { let RecomputePerFunction = 1; } // CHECK-LABEL: #ifdef GET_GLOBALISEL_TEMPORARIES_INIT // CHECK-NEXT: , State(2), -// CHECK-NEXT: MatcherInfo({TypeObjects, FeatureBitsets, ImmPredicateFns, { +// CHECK-NEXT: MatcherInfo({TypeObjects, FeatureBitsets, { // CHECK-NEXT: nullptr, // GICP_Invalid // CHECK-NEXT: &MyTargetInstructionSelector::selectComplexPattern, // gi_complex // CHECK-NEXT: }}) @@ -109,15 +109,6 @@ def HasC : Predicate<"Subtarget->hasC()"> { let RecomputePerFunction = 1; } // CHECK-NEXT: GICP_gi_complex, // CHECK-NEXT: }; -// CHECK-LABEL: // PatFrag predicates. -// CHECK-NEXT: enum { -// CHECK-NEXT: GIPFP_Predicate_simm8 = GIPFP_Invalid, -// CHECK-NEXT: }; -// CHECK-NEXT: static bool Predicate_simm8(int64_t Imm) { return isInt<8>(Imm); } -// CHECK-NEXT: static InstructionSelector::ImmediatePredicateFn ImmPredicateFns[] = { -// CHECK-NEXT: Predicate_simm8, -// CHECK-NEXT: }; - // CHECK: bool MyTargetInstructionSelector::selectImpl(MachineInstr &I) const { // CHECK-NEXT: MachineFunction &MF = *I.getParent()->getParent(); // CHECK-NEXT: MachineRegisterInfo &MRI = MF.getRegInfo(); @@ -644,39 +635,16 @@ def : Pat<(i32 (bitconvert FPR32:$src1)), def MOV1 : I<(outs GPR32:$dst), (ins), [(set GPR32:$dst, 1)]>; -//===- Test a simple pattern with a leaf immediate and a predicate. -------===// - -// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 16*/ [[LABEL:[0-9]+]], -// CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2, -// CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_CONSTANT, -// CHECK-NEXT: GIM_CheckImmPredicate, /*MI*/0, /*Predicate*/GIPFP_Predicate_simm8, -// CHECK-NEXT: // MIs[0] dst -// CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, -// CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID, -// CHECK-NEXT: // MIs[0] Operand 1 -// CHECK-NEXT: // No operand predicates -// CHECK-NEXT: // (imm:i32)<>:$imm => (MOVimm8:i32 (imm:i32):$imm) -// CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MOVimm8, -// CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst -// CHECK-NEXT: GIR_CopyConstantAsSImm, /*NewInsnID*/0, /*OldInsnID*/0, // imm -// CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0, -// CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, -// CHECK-NEXT: GIR_Done, -// CHECK-NEXT: // Label 16: @[[LABEL]] - -def simm8 : ImmLeaf(Imm); }]>; -def MOVimm8 : I<(outs GPR32:$dst), (ins i32imm:$imm), [(set GPR32:$dst, simm8:$imm)]>; - //===- Test a simple pattern with just a leaf immediate. ------------------===// -// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 17*/ [[LABEL:[0-9]+]], +// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 16*/ [[LABEL:[0-9]+]], // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/2, // CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_CONSTANT, // CHECK-NEXT: // MIs[0] dst // CHECK-NEXT: GIM_CheckType, /*MI*/0, /*Op*/0, /*Type*/GILLT_s32, // CHECK-NEXT: GIM_CheckRegBankForClass, /*MI*/0, /*Op*/0, /*RC*/MyTarget::GPR32RegClassID, // CHECK-NEXT: // MIs[0] Operand 1 -// CHECK-NEXT: // No operand predicates +// CHECK-NEXT: // No predicates // CHECK-NEXT: // (imm:i32):$imm => (MOVimm:i32 (imm:i32):$imm) // CHECK-NEXT: GIR_BuildMI, /*InsnID*/0, /*Opcode*/MyTarget::MOVimm, // CHECK-NEXT: GIR_Copy, /*NewInsnID*/0, /*OldInsnID*/0, /*OpIdx*/0, // dst @@ -684,13 +652,13 @@ def MOVimm8 : I<(outs GPR32:$dst), (ins i32imm:$imm), [(set GPR32:$dst, simm8:$i // CHECK-NEXT: GIR_EraseFromParent, /*InsnID*/0, // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, // CHECK-NEXT: GIR_Done, -// CHECK-NEXT: // Label 17: @[[LABEL]] +// CHECK-NEXT: // Label 16: @[[LABEL]] def MOVimm : I<(outs GPR32:$dst), (ins i32imm:$imm), [(set GPR32:$dst, imm:$imm)]>; //===- Test a pattern with an MBB operand. --------------------------------===// -// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 18*/ [[LABEL:[0-9]+]], +// CHECK-NEXT: GIM_Try, /*On fail goto*//*Label 17*/ [[LABEL:[0-9]+]], // CHECK-NEXT: GIM_CheckNumOperands, /*MI*/0, /*Expected*/1, // CHECK-NEXT: GIM_CheckOpcode, /*MI*/0, TargetOpcode::G_BR, // CHECK-NEXT: // MIs[0] target @@ -699,7 +667,7 @@ def MOVimm : I<(outs GPR32:$dst), (ins i32imm:$imm), [(set GPR32:$dst, imm:$imm) // CHECK-NEXT: GIR_MutateOpcode, /*InsnID*/0, /*RecycleInsnID*/0, /*Opcode*/MyTarget::BR, // CHECK-NEXT: GIR_ConstrainSelectedInstOperands, /*InsnID*/0, // CHECK-NEXT: GIR_Done, -// CHECK-NEXT: // Label 18: @[[LABEL]] +// CHECK-NEXT: // Label 17: @[[LABEL]] def BR : I<(outs), (ins unknown:$target), [(br bb:$target)]>; diff --git a/utils/TableGen/GlobalISelEmitter.cpp b/utils/TableGen/GlobalISelEmitter.cpp index 17898beb7de..9f53ac40e3a 100644 --- a/utils/TableGen/GlobalISelEmitter.cpp +++ b/utils/TableGen/GlobalISelEmitter.cpp @@ -180,19 +180,9 @@ static Error failedImport(const Twine &Reason) { static Error isTrivialOperatorNode(const TreePatternNode *N) { std::string Explanation = ""; std::string Separator = ""; - - bool HasUnsupportedPredicate = false; - for (const auto &Predicate : N->getPredicateFns()) { - if (Predicate.isAlwaysTrue()) - continue; - - if (Predicate.isImmediatePattern()) - continue; - - HasUnsupportedPredicate = true; + if (N->hasAnyPredicate()) { Explanation = Separator + "Has a predicate (" + explainPredicates(N) + ")"; Separator = ", "; - break; } if (N->getTransformFn()) { @@ -200,7 +190,7 @@ static Error isTrivialOperatorNode(const TreePatternNode *N) { Separator = ", "; } - if (!HasUnsupportedPredicate && !N->getTransformFn()) + if (!N->hasAnyPredicate() && !N->getTransformFn()) return Error::success(); return failedImport(Explanation); @@ -525,10 +515,6 @@ private: typedef std::vector> PredicateVec; PredicateVec Predicates; - /// Template instantiations should specialize this to return a string to use - /// for the comment emitted when there are no predicates. - std::string getNoPredicateComment() const; - public: /// Construct a new operand predicate and add it to the matcher. template @@ -555,8 +541,7 @@ public: template void emitPredicateListOpcodes(MatchTable &Table, Args &&... args) const { if (Predicates.empty()) { - Table << MatchTable::Comment(getNoPredicateComment()) - << MatchTable::LineBreak; + Table << MatchTable::Comment("No predicates") << MatchTable::LineBreak; return; } @@ -633,12 +618,6 @@ public: virtual unsigned countRendererFns() const { return 0; } }; -template <> -std::string -PredicateListMatcher::getNoPredicateComment() const { - return "No operand predicates"; -} - /// Generates code to check that an operand is a particular LLT. class LLTOperandMatcher : public OperandPredicateMatcher { protected: @@ -936,7 +915,6 @@ protected: /// must be tested first. enum PredicateKind { IPM_Opcode, - IPM_ImmPredicate, }; PredicateKind Kind; @@ -965,12 +943,6 @@ public: virtual unsigned countRendererFns() const { return 0; } }; -template <> -std::string -PredicateListMatcher::getNoPredicateComment() const { - return "No instruction predicates"; -} - /// Generates code to check the opcode of an instruction. class InstructionOpcodeMatcher : public InstructionPredicateMatcher { protected: @@ -1017,54 +989,6 @@ public: } }; -/// Generates code to check that this instruction is a constant whose value -/// meets an immediate predicate. -/// -/// Immediates are slightly odd since they are typically used like an operand -/// but are represented as an operator internally. We typically write simm8:$src -/// in a tablegen pattern, but this is just syntactic sugar for -/// (imm:i32)<>:$imm which more directly describes the nodes -/// that will be matched and the predicate (which is attached to the imm -/// operator) that will be tested. In SelectionDAG this describes a -/// ConstantSDNode whose internal value will be tested using the simm8 predicate. -/// -/// The corresponding GlobalISel representation is %1 = G_CONSTANT iN Value. In -/// this representation, the immediate could be tested with an -/// InstructionMatcher, InstructionOpcodeMatcher, OperandMatcher, and a -/// OperandPredicateMatcher-subclass to check the Value meets the predicate but -/// there are two implementation issues with producing that matcher -/// configuration from the SelectionDAG pattern: -/// * ImmLeaf is a PatFrag whose root is an InstructionMatcher. This means that -/// were we to sink the immediate predicate to the operand we would have to -/// have two partial implementations of PatFrag support, one for immediates -/// and one for non-immediates. -/// * At the point we handle the predicate, the OperandMatcher hasn't been -/// created yet. If we were to sink the predicate to the OperandMatcher we -/// would also have to complicate (or duplicate) the code that descends and -/// creates matchers for the subtree. -/// Overall, it's simpler to handle it in the place it was found. -class InstructionImmPredicateMatcher : public InstructionPredicateMatcher { -protected: - TreePredicateFn Predicate; - -public: - InstructionImmPredicateMatcher(const TreePredicateFn &Predicate) - : InstructionPredicateMatcher(IPM_ImmPredicate), Predicate(Predicate) {} - - static bool classof(const InstructionPredicateMatcher *P) { - return P->getKind() == IPM_ImmPredicate; - } - - void emitPredicateOpcodes(MatchTable &Table, RuleMatcher &Rule, - unsigned InsnVarID) const override { - Table << MatchTable::Opcode("GIM_CheckImmPredicate") - << MatchTable::Comment("MI") << MatchTable::IntValue(InsnVarID) - << MatchTable::Comment("Predicate") - << MatchTable::NamedValue("GIPFP_" + Predicate.getFnName()) - << MatchTable::LineBreak; - } -}; - /// Generates code to check that a set of predicates and operands match for a /// particular instruction. /// @@ -1999,19 +1923,6 @@ GlobalISelEmitter::createAndImportSelDAGMatcher(InstructionMatcher &InsnMatcher, OM.addPredicate(*OpTyOrNone); } - for (const auto &Predicate : Src->getPredicateFns()) { - if (Predicate.isAlwaysTrue()) - continue; - - if (Predicate.isImmediatePattern()) { - InsnMatcher.addPredicate(Predicate); - continue; - } - - return failedImport("Src pattern child has predicate (" + - explainPredicates(Src) + ")"); - } - if (Src->isLeaf()) { Init *SrcInit = Src->getLeafValue(); if (IntInit *SrcIntInit = dyn_cast(SrcInit)) { @@ -2064,6 +1975,10 @@ Error GlobalISelEmitter::importChildMatcher(InstructionMatcher &InsnMatcher, OperandMatcher &OM = InsnMatcher.addOperand(OpIdx, SrcChild->getName(), TempOpIdx); + if (SrcChild->hasAnyPredicate()) + return failedImport("Src pattern child has predicate (" + + explainPredicates(SrcChild) + ")"); + ArrayRef ChildTypes = SrcChild->getExtTypes(); if (ChildTypes.size() != 1) return failedImport("Src pattern child has multiple results"); @@ -2143,11 +2058,6 @@ Error GlobalISelEmitter::importChildMatcher(InstructionMatcher &InsnMatcher, Error GlobalISelEmitter::importExplicitUseRenderer( BuildMIAction &DstMIBuilder, TreePatternNode *DstChild, const InstructionMatcher &InsnMatcher) const { - if (DstChild->getTransformFn() != nullptr) { - return failedImport("Dst pattern child has transform fn " + - DstChild->getTransformFn()->getName()); - } - if (!DstChild->isLeaf()) { // We accept 'bb' here. It's an operator because BasicBlockSDNode isn't // inline, but in MI it's just another operand. @@ -2170,10 +2080,14 @@ Error GlobalISelEmitter::importExplicitUseRenderer( return Error::success(); } - return failedImport("Dst pattern child isn't a leaf node or an MBB" + llvm::to_string(*DstChild)); + return failedImport("Dst pattern child isn't a leaf node or an MBB"); } // Otherwise, we're looking for a bog-standard RegisterClass operand. + if (DstChild->hasAnyPredicate()) + return failedImport("Dst pattern child has predicate (" + + explainPredicates(DstChild) + ")"); + if (auto *ChildDefInit = dyn_cast(DstChild->getLeafValue())) { auto *ChildRec = ChildDefInit->getDef(); @@ -2612,7 +2526,7 @@ void GlobalISelEmitter::run(raw_ostream &OS) { OS << "#ifdef GET_GLOBALISEL_TEMPORARIES_INIT\n" << ", State(" << MaxTemporaries << "),\n" - << "MatcherInfo({TypeObjects, FeatureBitsets, ImmPredicateFns, {\n" + << "MatcherInfo({TypeObjects, FeatureBitsets, {\n" << " nullptr, // GICP_Invalid\n"; for (const auto &Record : ComplexPredicates) OS << " &" << Target.getName() @@ -2725,31 +2639,6 @@ void GlobalISelEmitter::run(raw_ostream &OS) { OS << "};\n" << "// See constructor for table contents\n\n"; - // Emit imm predicate table and an enum to reference them with. - // The 'Predicate_' part of the name is redundant but eliminating it is more - // trouble than it's worth. - { - OS << "// PatFrag predicates.\n" - << "enum {\n"; - StringRef EnumeratorSeparator = " = GIPFP_Invalid,\n"; - for (const auto *Record : RK.getAllDerivedDefinitions("PatFrag")) { - if (!Record->getValueAsString("ImmediateCode").empty()) { - OS << " GIPFP_Predicate_" << Record->getName() << EnumeratorSeparator; - EnumeratorSeparator = ",\n"; - } - } - OS << "};\n"; - } - for (const auto *Record : RK.getAllDerivedDefinitions("PatFrag")) - if (!Record->getValueAsString("ImmediateCode").empty()) - OS << " static bool Predicate_" << Record->getName() << "(int64_t Imm) {" - << Record->getValueAsString("ImmediateCode") << " }\n"; - OS << "static InstructionSelector::ImmediatePredicateFn ImmPredicateFns[] = {\n"; - for (const auto *Record : RK.getAllDerivedDefinitions("PatFrag")) - if (!Record->getValueAsString("ImmediateCode").empty()) - OS << " Predicate_" << Record->getName() << ",\n"; - OS << "};\n"; - OS << "bool " << Target.getName() << "InstructionSelector::selectImpl(MachineInstr &I) const {\n" << " MachineFunction &MF = *I.getParent()->getParent();\n"