forked from OSchip/llvm-project
Revert r311546 as it breaks build
http://lab.llvm.org:8011/builders/llvm-clang-x86_64-expensive-checks-win/builds/4394 llvm-svn: 311560
This commit is contained in:
parent
7f7c3dc0aa
commit
3697ebe25f
|
@ -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<ComplexMatcherMemFn> ComplexPredicates;
|
||||
};
|
||||
|
||||
|
|
|
@ -17,12 +17,6 @@
|
|||
#define LLVM_CODEGEN_GLOBALISEL_INSTRUCTIONSELECTORIMPL_H
|
||||
|
||||
namespace llvm {
|
||||
|
||||
/// GlobalISel PatFrag Predicates
|
||||
enum {
|
||||
GIPFP_Invalid,
|
||||
};
|
||||
|
||||
template <class TgtInstructionSelector, class PredicateBitset,
|
||||
class ComplexMatcherMemFn>
|
||||
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++];
|
||||
|
|
|
@ -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)
|
||||
...
|
|
@ -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. -------===//
|
||||
//===- Test a simple pattern with just a leaf immediate. ------------------===//
|
||||
|
||||
// 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)<<P:Predicate_simm8>>:$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<i32, [{ return isInt<8>(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_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)]>;
|
||||
|
|
|
@ -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<std::unique_ptr<PredicateTy>> 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 <class Kind, class... Args>
|
||||
|
@ -555,8 +541,7 @@ public:
|
|||
template <class... Args>
|
||||
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<OperandPredicateMatcher>::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<InstructionPredicateMatcher>::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)<<P:Predicate_simm8>>:$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<LLTOperandMatcher>(*OpTyOrNone);
|
||||
}
|
||||
|
||||
for (const auto &Predicate : Src->getPredicateFns()) {
|
||||
if (Predicate.isAlwaysTrue())
|
||||
continue;
|
||||
|
||||
if (Predicate.isImmediatePattern()) {
|
||||
InsnMatcher.addPredicate<InstructionImmPredicateMatcher>(Predicate);
|
||||
continue;
|
||||
}
|
||||
|
||||
return failedImport("Src pattern child has predicate (" +
|
||||
explainPredicates(Src) + ")");
|
||||
}
|
||||
|
||||
if (Src->isLeaf()) {
|
||||
Init *SrcInit = Src->getLeafValue();
|
||||
if (IntInit *SrcIntInit = dyn_cast<IntInit>(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<EEVT::TypeSet> 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<DefInit>(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"
|
||||
|
|
Loading…
Reference in New Issue