[llvm] r321176 - [globalisel][tablegen] Allow ImmLeaf predicates to use InstructionSelector members
Daniel Sanders via llvm-commits
llvm-commits at lists.llvm.org
Wed Dec 20 06:41:51 PST 2017
Author: dsanders
Date: Wed Dec 20 06:41:51 2017
New Revision: 321176
URL: http://llvm.org/viewvc/llvm-project?rev=321176&view=rev
Log:
[globalisel][tablegen] Allow ImmLeaf predicates to use InstructionSelector members
NFC for currently supported targets. This resolves a problem encountered by
targets such as RISCV that reference `Subtarget` in ImmLeaf predicates.
Modified:
llvm/trunk/include/llvm/CodeGen/GlobalISel/InstructionSelector.h
llvm/trunk/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h
llvm/trunk/test/TableGen/GlobalISelEmitter.td
llvm/trunk/utils/TableGen/GlobalISelEmitter.cpp
Modified: llvm/trunk/include/llvm/CodeGen/GlobalISel/InstructionSelector.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/GlobalISel/InstructionSelector.h?rev=321176&r1=321175&r2=321176&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/GlobalISel/InstructionSelector.h (original)
+++ llvm/trunk/include/llvm/CodeGen/GlobalISel/InstructionSelector.h Wed Dec 20 06:41:51 2017
@@ -282,10 +282,6 @@ enum {
/// Provides the logic to select generic machine instructions.
class InstructionSelector {
public:
- using I64ImmediatePredicateFn = bool (*)(int64_t);
- using APIntImmediatePredicateFn = bool (*)(const APInt &);
- using APFloatImmediatePredicateFn = bool (*)(const APFloat &);
-
virtual ~InstructionSelector() = default;
/// Select the (possibly generic) instruction \p I to only use target-specific
@@ -319,9 +315,6 @@ public:
struct MatcherInfoTy {
const LLT *TypeObjects;
const PredicateBitset *FeatureBitsets;
- const I64ImmediatePredicateFn *I64ImmPredicateFns;
- const APIntImmediatePredicateFn *APIntImmPredicateFns;
- const APFloatImmediatePredicateFn *APFloatImmPredicateFns;
const ComplexMatcherMemFn *ComplexPredicates;
};
@@ -340,6 +333,16 @@ protected:
const RegisterBankInfo &RBI, const PredicateBitset &AvailableFeatures,
CodeGenCoverage &CoverageInfo) const;
+ virtual bool testImmPredicate_I64(unsigned, int64_t) const {
+ llvm_unreachable("Subclasses must override this to use tablegen");
+ }
+ virtual bool testImmPredicate_APInt(unsigned, const APInt &) const {
+ llvm_unreachable("Subclasses must override this to use tablegen");
+ }
+ virtual bool testImmPredicate_APFloat(unsigned, const APFloat &) const {
+ llvm_unreachable("Subclasses must override this to use tablegen");
+ }
+
/// Constrain a register operand of an instruction \p I to a specified
/// register class. This could involve inserting COPYs before (for uses) or
/// after (for defs) and may replace the operand of \p I.
Modified: llvm/trunk/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h?rev=321176&r1=321175&r2=321176&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h (original)
+++ llvm/trunk/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h Wed Dec 20 06:41:51 2017
@@ -181,7 +181,7 @@ bool InstructionSelector::executeMatchTa
else
llvm_unreachable("Expected Imm or CImm operand");
- if (!MatcherInfo.I64ImmPredicateFns[Predicate](Value))
+ if (!testImmPredicate_I64(Predicate, Value))
if (handleReject() == RejectAndGiveUp)
return false;
break;
@@ -202,7 +202,7 @@ bool InstructionSelector::executeMatchTa
else
llvm_unreachable("Expected Imm or CImm operand");
- if (!MatcherInfo.APIntImmPredicateFns[Predicate](Value))
+ if (!testImmPredicate_APInt(Predicate, Value))
if (handleReject() == RejectAndGiveUp)
return false;
break;
@@ -221,7 +221,7 @@ bool InstructionSelector::executeMatchTa
assert(Predicate > GIPFP_APFloat_Invalid && "Expected a valid predicate");
APFloat Value = State.MIs[InsnID]->getOperand(1).getFPImm()->getValueAPF();
- if (!MatcherInfo.APFloatImmPredicateFns[Predicate](Value))
+ if (!testImmPredicate_APFloat(Predicate, Value))
if (handleReject() == RejectAndGiveUp)
return false;
break;
Modified: llvm/trunk/test/TableGen/GlobalISelEmitter.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/TableGen/GlobalISelEmitter.td?rev=321176&r1=321175&r2=321176&view=diff
==============================================================================
--- llvm/trunk/test/TableGen/GlobalISelEmitter.td (original)
+++ llvm/trunk/test/TableGen/GlobalISelEmitter.td Wed Dec 20 06:41:51 2017
@@ -63,11 +63,14 @@ def HasC : Predicate<"Subtarget->hasC()"
// CHECK-NEXT: typedef ComplexRendererFns(MyTargetInstructionSelector::*ComplexMatcherMemFn)(MachineOperand &) const;
// CHECK-NEXT: const MatcherInfoTy<PredicateBitset, ComplexMatcherMemFn> MatcherInfo;
// CHECK-NEXT: static MyTargetInstructionSelector::ComplexMatcherMemFn ComplexPredicateFns[];
+// CHECK-NEXT: bool testImmPredicate_I64(unsigned PredicateID, int64_t Imm) const override;
+// CHECK-NEXT: bool testImmPredicate_APInt(unsigned PredicateID, const APInt &Imm) const override;
+// CHECK-NEXT: bool testImmPredicate_APFloat(unsigned PredicateID, const APFloat &Imm) const override;
// CHECK-NEXT: #endif // ifdef GET_GLOBALISEL_TEMPORARIES_DECL
// CHECK-LABEL: #ifdef GET_GLOBALISEL_TEMPORARIES_INIT
// CHECK-NEXT: , State(2),
-// CHECK-NEXT: MatcherInfo({TypeObjects, FeatureBitsets, I64ImmPredicateFns, APIntImmPredicateFns, APFloatImmPredicateFns, ComplexPredicateFns})
+// CHECK-NEXT: MatcherInfo({TypeObjects, FeatureBitsets, ComplexPredicateFns})
// CHECK-NEXT: #endif // ifdef GET_GLOBALISEL_TEMPORARIES_INIT
// CHECK-LABEL: enum SubtargetFeatureBits : uint8_t {
@@ -127,31 +130,49 @@ def HasC : Predicate<"Subtarget->hasC()"
// CHECK-NEXT: enum {
// CHECK-NEXT: GIPFP_I64_Predicate_simm8 = GIPFP_I64_Invalid + 1,
// CHECK-NEXT: };
-// CHECK-NEXT: static bool Predicate_simm8(int64_t Imm) { return isInt<8>(Imm); }
-// CHECK-NEXT: static InstructionSelector::I64ImmediatePredicateFn I64ImmPredicateFns[] = {
-// CHECK-NEXT: nullptr,
-// CHECK-NEXT: Predicate_simm8,
-// CHECK-NEXT: };
+// CHECK-NEXT: bool MyTargetInstructionSelector::testImmPredicate_I64(unsigned PredicateID, int64_t Imm) const {
+// CHECK-NEXT: switch (PredicateID) {
+// CHECK-NEXT: case GIPFP_I64_Predicate_simm8: {
+// CHECK-NEXT: return isInt<8>(Imm);
+// CHECK-NEXT: llvm_unreachable("ImmediateCode should have returned");
+// CHECK-NEXT: return false;
+// CHECK-NEXT: }
+// CHECK-NEXT: }
+// CHECK-NEXT: llvm_unreachable("Unknown predicate");
+// CHECK-NEXT: return false;
+// CHECK-NEXT: }
// CHECK-LABEL: // PatFrag predicates.
// CHECK-NEXT: enum {
// CHECK-NEXT: GIPFP_APFloat_Predicate_fpimmz = GIPFP_APFloat_Invalid + 1,
// CHECK-NEXT: };
-// CHECK-NEXT: static bool Predicate_fpimmz(const APFloat & Imm) { return Imm->isExactlyValue(0.0); }
-// CHECK-NEXT: static InstructionSelector::APFloatImmediatePredicateFn APFloatImmPredicateFns[] = {
-// CHECK-NEXT: nullptr,
-// CHECK-NEXT: Predicate_fpimmz,
-// CHECK-NEXT: };
+// CHECK-NEXT: bool MyTargetInstructionSelector::testImmPredicate_APFloat(unsigned PredicateID, const APFloat & Imm) const {
+// CHECK-NEXT: switch (PredicateID) {
+// CHECK-NEXT: case GIPFP_APFloat_Predicate_fpimmz: {
+// CHECK-NEXT: return Imm->isExactlyValue(0.0);
+// CHECK-NEXT: llvm_unreachable("ImmediateCode should have returned");
+// CHECK-NEXT: return false;
+// CHECK-NEXT: }
+// CHECK-NEXT: }
+// CHECK-NEXT: llvm_unreachable("Unknown predicate");
+// CHECK-NEXT: return false;
+// CHECK-NEXT: }
// CHECK-LABEL: // PatFrag predicates.
// CHECK-NEXT: enum {
// CHECK-NEXT: GIPFP_APInt_Predicate_simm9 = GIPFP_APInt_Invalid + 1,
// CHECK-NEXT: };
-// CHECK-NEXT: static bool Predicate_simm9(const APInt & Imm) { return isInt<9>(Imm->getSExtValue()); }
-// CHECK-NEXT: static InstructionSelector::APIntImmediatePredicateFn APIntImmPredicateFns[] = {
-// CHECK-NEXT: nullptr,
-// CHECK-NEXT: Predicate_simm9,
-// CHECK-NEXT: };
+// CHECK-NEXT: bool MyTargetInstructionSelector::testImmPredicate_APInt(unsigned PredicateID, const APInt & Imm) const {
+// CHECK-NEXT: switch (PredicateID) {
+// CHECK-NEXT: case GIPFP_APInt_Predicate_simm9: {
+// CHECK-NEXT: return isInt<9>(Imm->getSExtValue());
+// CHECK-NEXT: llvm_unreachable("ImmediateCode should have returned");
+// CHECK-NEXT: return false;
+// CHECK-NEXT: }
+// CHECK-NEXT: }
+// CHECK-NEXT: llvm_unreachable("Unknown predicate");
+// CHECK-NEXT: return false;
+// CHECK-NEXT: }
// CHECK-LABEL: MyTargetInstructionSelector::ComplexMatcherMemFn
// CHECK-NEXT: MyTargetInstructionSelector::ComplexPredicateFns[] = {
Modified: llvm/trunk/utils/TableGen/GlobalISelEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/GlobalISelEmitter.cpp?rev=321176&r1=321175&r2=321176&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/GlobalISelEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/GlobalISelEmitter.cpp Wed Dec 20 06:41:51 2017
@@ -3550,16 +3550,21 @@ void GlobalISelEmitter::emitImmPredicate
OS << "};\n";
}
- for (const auto *Record : MatchedRecords)
- OS << "static bool Predicate_" << Record->getName() << "(" << Type
- << " Imm) {" << Record->getValueAsString("ImmediateCode") << "}\n";
-
- OS << "static InstructionSelector::" << TypeIdentifier
- << "ImmediatePredicateFn " << TypeIdentifier << "ImmPredicateFns[] = {\n"
- << " nullptr,\n";
- for (const auto *Record : MatchedRecords)
- OS << " Predicate_" << Record->getName() << ",\n";
- OS << "};\n";
+ OS << "bool " << Target.getName() << "InstructionSelector::testImmPredicate_"
+ << TypeIdentifier << "(unsigned PredicateID, " << Type << " Imm) const {\n"
+ << " switch (PredicateID) {\n";
+ for (const auto *Record : MatchedRecords) {
+ OS << " case GIPFP_" << TypeIdentifier << "_Predicate_"
+ << Record->getName() << ": {\n"
+ << " " << Record->getValueAsString("ImmediateCode") << "\n"
+ << " llvm_unreachable(\"ImmediateCode should have returned\");\n"
+ << " return false;\n"
+ << " }\n";
+ }
+ OS << " }\n"
+ << " llvm_unreachable(\"Unknown predicate\");\n"
+ << " return false;\n"
+ << "}\n";
}
std::vector<Matcher *> GlobalISelEmitter::optimizeRules(
@@ -3673,12 +3678,17 @@ void GlobalISelEmitter::run(raw_ostream
"MatcherInfo;\n"
<< " static " << Target.getName()
<< "InstructionSelector::ComplexMatcherMemFn ComplexPredicateFns[];\n"
+ << "bool testImmPredicate_I64(unsigned PredicateID, int64_t Imm) const "
+ "override;\n"
+ << "bool testImmPredicate_APInt(unsigned PredicateID, const APInt &Imm) "
+ "const override;\n"
+ << "bool testImmPredicate_APFloat(unsigned PredicateID, const APFloat "
+ "&Imm) const override;\n"
<< "#endif // ifdef GET_GLOBALISEL_TEMPORARIES_DECL\n\n";
OS << "#ifdef GET_GLOBALISEL_TEMPORARIES_INIT\n"
<< ", State(" << MaxTemporaries << "),\n"
- << "MatcherInfo({TypeObjects, FeatureBitsets, I64ImmPredicateFns, "
- "APIntImmPredicateFns, APFloatImmPredicateFns, ComplexPredicateFns})\n"
+ << "MatcherInfo({TypeObjects, FeatureBitsets, ComplexPredicateFns})\n"
<< "#endif // ifdef GET_GLOBALISEL_TEMPORARIES_INIT\n\n";
OS << "#ifdef GET_GLOBALISEL_IMPL\n";
More information about the llvm-commits
mailing list