mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-28 06:00:28 +00:00
Revert r300964 + r300970 - [globalisel][tablegen] Import SelectionDAG's rule predicates and support the equivalent in GIRule.
It's causing llvm-clang-x86_64-expensive-checks-win to fail to compile and I haven't worked out why. Reverting to make it green while I figure it out. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@300978 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
bd1b03d467
commit
9eb6db17b6
@ -18,50 +18,20 @@
|
||||
|
||||
#include "llvm/ADT/Optional.h"
|
||||
#include <cstdint>
|
||||
#include <bitset>
|
||||
|
||||
namespace llvm {
|
||||
class MachineInstr;
|
||||
class MachineFunction;
|
||||
class MachineOperand;
|
||||
class MachineRegisterInfo;
|
||||
class RegisterBankInfo;
|
||||
class TargetInstrInfo;
|
||||
class TargetRegisterInfo;
|
||||
|
||||
/// Container class for CodeGen predicate results.
|
||||
/// This is convenient because std::bitset does not have a constructor
|
||||
/// with an initializer list of set bits.
|
||||
///
|
||||
/// Each InstructionSelector subclass should define a PredicateBitset class with:
|
||||
/// const unsigned MAX_SUBTARGET_PREDICATES = 192;
|
||||
/// using PredicateBitset = PredicateBitsetImpl<MAX_SUBTARGET_PREDICATES>;
|
||||
/// and updating the constant to suit the target. Tablegen provides a suitable
|
||||
/// definition for the predicates in use in <Target>GenGlobalISel.inc when
|
||||
/// GET_GLOBALISEL_PREDICATE_BITSET is defined.
|
||||
template <std::size_t MaxPredicates>
|
||||
class PredicateBitsetImpl : public std::bitset<MaxPredicates> {
|
||||
public:
|
||||
// Cannot inherit constructors because it's not supported by VC++..
|
||||
PredicateBitsetImpl() = default;
|
||||
|
||||
PredicateBitsetImpl(const std::bitset<MaxPredicates> &B)
|
||||
: std::bitset<MaxPredicates>(B) {}
|
||||
|
||||
PredicateBitsetImpl(std::initializer_list<unsigned> Init) {
|
||||
for (auto I : Init)
|
||||
std::bitset<MaxPredicates>::set(I);
|
||||
}
|
||||
};
|
||||
|
||||
/// Provides the logic to select generic machine instructions.
|
||||
class InstructionSelector {
|
||||
public:
|
||||
virtual ~InstructionSelector() {}
|
||||
|
||||
/// This is executed before selecting a function.
|
||||
virtual void beginFunction(const MachineFunction &MF) {}
|
||||
|
||||
/// Select the (possibly generic) instruction \p I to only use target-specific
|
||||
/// opcodes. It is OK to insert multiple instructions, but they cannot be
|
||||
/// generic pre-isel instructions.
|
||||
|
@ -41,17 +41,12 @@ using namespace llvm;
|
||||
|
||||
namespace {
|
||||
|
||||
#define GET_GLOBALISEL_PREDICATE_BITSET
|
||||
#include "AArch64GenGlobalISel.inc"
|
||||
#undef GET_GLOBALISEL_PREDICATE_BITSET
|
||||
|
||||
class AArch64InstructionSelector : public InstructionSelector {
|
||||
public:
|
||||
AArch64InstructionSelector(const AArch64TargetMachine &TM,
|
||||
const AArch64Subtarget &STI,
|
||||
const AArch64RegisterBankInfo &RBI);
|
||||
|
||||
void beginFunction(const MachineFunction &MF) override;
|
||||
bool select(MachineInstr &I) const override;
|
||||
|
||||
private:
|
||||
@ -75,12 +70,6 @@ private:
|
||||
const AArch64InstrInfo &TII;
|
||||
const AArch64RegisterInfo &TRI;
|
||||
const AArch64RegisterBankInfo &RBI;
|
||||
bool ForCodeSize;
|
||||
|
||||
PredicateBitset AvailableFeatures;
|
||||
PredicateBitset
|
||||
computeAvailableFeatures(const MachineFunction *MF,
|
||||
const AArch64Subtarget *Subtarget) const;
|
||||
|
||||
// We declare the temporaries used by selectImpl() in the class to minimize the
|
||||
// cost of constructing placeholder values.
|
||||
@ -99,7 +88,7 @@ AArch64InstructionSelector::AArch64InstructionSelector(
|
||||
const AArch64TargetMachine &TM, const AArch64Subtarget &STI,
|
||||
const AArch64RegisterBankInfo &RBI)
|
||||
: InstructionSelector(), TM(TM), STI(STI), TII(*STI.getInstrInfo()),
|
||||
TRI(*STI.getRegisterInfo()), RBI(RBI), ForCodeSize(), AvailableFeatures()
|
||||
TRI(*STI.getRegisterInfo()), RBI(RBI)
|
||||
#define GET_GLOBALISEL_TEMPORARIES_INIT
|
||||
#include "AArch64GenGlobalISel.inc"
|
||||
#undef GET_GLOBALISEL_TEMPORARIES_INIT
|
||||
@ -578,12 +567,6 @@ bool AArch64InstructionSelector::selectVaStartDarwin(
|
||||
return true;
|
||||
}
|
||||
|
||||
void AArch64InstructionSelector::beginFunction(
|
||||
const MachineFunction &MF) {
|
||||
ForCodeSize = MF.getFunction()->optForSize();
|
||||
AvailableFeatures = computeAvailableFeatures(&MF, &STI);
|
||||
}
|
||||
|
||||
bool AArch64InstructionSelector::select(MachineInstr &I) const {
|
||||
assert(I.getParent() && "Instruction should be in a basic block!");
|
||||
assert(I.getParent()->getParent() && "Instruction should be in a function!");
|
||||
|
@ -95,8 +95,7 @@ void initializeFixupBWInstPassPass(PassRegistry &);
|
||||
/// encoding when possible in order to reduce code size.
|
||||
FunctionPass *createX86EvexToVexInsts();
|
||||
|
||||
InstructionSelector *createX86InstructionSelector(const X86TargetMachine &TM,
|
||||
X86Subtarget &,
|
||||
InstructionSelector *createX86InstructionSelector(X86Subtarget &,
|
||||
X86RegisterBankInfo &);
|
||||
|
||||
void initializeEvexToVexInstPassPass(PassRegistry &);
|
||||
|
@ -39,16 +39,11 @@ using namespace llvm;
|
||||
|
||||
namespace {
|
||||
|
||||
#define GET_GLOBALISEL_PREDICATE_BITSET
|
||||
#include "X86GenGlobalISel.inc"
|
||||
#undef GET_GLOBALISEL_PREDICATE_BITSET
|
||||
|
||||
class X86InstructionSelector : public InstructionSelector {
|
||||
public:
|
||||
X86InstructionSelector(const X86TargetMachine &TM, const X86Subtarget &STI,
|
||||
X86InstructionSelector(const X86Subtarget &STI,
|
||||
const X86RegisterBankInfo &RBI);
|
||||
|
||||
void beginFunction(const MachineFunction &MF) override;
|
||||
bool select(MachineInstr &I) const override;
|
||||
|
||||
private:
|
||||
@ -75,17 +70,10 @@ private:
|
||||
bool selectTrunc(MachineInstr &I, MachineRegisterInfo &MRI,
|
||||
MachineFunction &MF) const;
|
||||
|
||||
const X86TargetMachine &TM;
|
||||
const X86Subtarget &STI;
|
||||
const X86InstrInfo &TII;
|
||||
const X86RegisterInfo &TRI;
|
||||
const X86RegisterBankInfo &RBI;
|
||||
bool OptForSize;
|
||||
bool OptForMinSize;
|
||||
|
||||
PredicateBitset AvailableFeatures;
|
||||
PredicateBitset computeAvailableFeatures(const MachineFunction *MF,
|
||||
const X86Subtarget *Subtarget) const;
|
||||
|
||||
#define GET_GLOBALISEL_TEMPORARIES_DECL
|
||||
#include "X86GenGlobalISel.inc"
|
||||
@ -98,12 +86,10 @@ private:
|
||||
#include "X86GenGlobalISel.inc"
|
||||
#undef GET_GLOBALISEL_IMPL
|
||||
|
||||
X86InstructionSelector::X86InstructionSelector(const X86TargetMachine &TM,
|
||||
const X86Subtarget &STI,
|
||||
X86InstructionSelector::X86InstructionSelector(const X86Subtarget &STI,
|
||||
const X86RegisterBankInfo &RBI)
|
||||
: InstructionSelector(), TM(TM), STI(STI), TII(*STI.getInstrInfo()),
|
||||
TRI(*STI.getRegisterInfo()), RBI(RBI), OptForSize(false),
|
||||
OptForMinSize(false), AvailableFeatures()
|
||||
: InstructionSelector(), STI(STI), TII(*STI.getInstrInfo()),
|
||||
TRI(*STI.getRegisterInfo()), RBI(RBI)
|
||||
#define GET_GLOBALISEL_TEMPORARIES_INIT
|
||||
#include "X86GenGlobalISel.inc"
|
||||
#undef GET_GLOBALISEL_TEMPORARIES_INIT
|
||||
@ -195,12 +181,6 @@ static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII,
|
||||
return true;
|
||||
}
|
||||
|
||||
void X86InstructionSelector::beginFunction(const MachineFunction &MF) {
|
||||
OptForSize = MF.getFunction()->optForSize();
|
||||
OptForMinSize = MF.getFunction()->optForMinSize();
|
||||
AvailableFeatures = computeAvailableFeatures(&MF, &STI);
|
||||
}
|
||||
|
||||
bool X86InstructionSelector::select(MachineInstr &I) const {
|
||||
assert(I.getParent() && "Instruction should be in a basic block!");
|
||||
assert(I.getParent()->getParent() && "Instruction should be in a function!");
|
||||
@ -591,8 +571,7 @@ bool X86InstructionSelector::selectTrunc(MachineInstr &I,
|
||||
}
|
||||
|
||||
InstructionSelector *
|
||||
llvm::createX86InstructionSelector(const X86TargetMachine &TM,
|
||||
X86Subtarget &Subtarget,
|
||||
llvm::createX86InstructionSelector(X86Subtarget &Subtarget,
|
||||
X86RegisterBankInfo &RBI) {
|
||||
return new X86InstructionSelector(TM, Subtarget, RBI);
|
||||
return new X86InstructionSelector(Subtarget, RBI);
|
||||
}
|
||||
|
@ -286,7 +286,7 @@ X86TargetMachine::getSubtargetImpl(const Function &F) const {
|
||||
|
||||
auto *RBI = new X86RegisterBankInfo(*I->getRegisterInfo());
|
||||
GISel->RegBankInfo.reset(RBI);
|
||||
GISel->InstSelector.reset(createX86InstructionSelector(*this, *I, *RBI));
|
||||
GISel->InstSelector.reset(createX86InstructionSelector(*I, *RBI));
|
||||
#endif
|
||||
I->setGISelAccessor(*GISel);
|
||||
}
|
||||
|
@ -29,31 +29,7 @@ def m1 : OperandWithDefaultOps <i32, (ops (i32 -1))>;
|
||||
def Z : OperandWithDefaultOps <i32, (ops R0)>;
|
||||
def m1Z : OperandWithDefaultOps <i32, (ops (i32 -1), R0)>;
|
||||
|
||||
def HasA : Predicate<"Subtarget->hasA()">;
|
||||
def HasB : Predicate<"Subtarget->hasB()">;
|
||||
|
||||
//===- Test the function boilerplate. -------------------------------------===//
|
||||
|
||||
// CHECK-LABEL: enum SubtargetFeatureBits : uint8_t {
|
||||
// CHECK-NEXT: Feature_HasABit = 0,
|
||||
// CHECK-NEXT: Feature_HasBBit = 1,
|
||||
// CHECK-NEXT: };
|
||||
|
||||
// CHECK-LABEL: static const char *SubtargetFeatureNames[] = {
|
||||
// CHECK-NEXT: "Feature_HasA",
|
||||
// CHECK-NEXT: "Feature_HasB",
|
||||
// CHECK-NEXT: nullptr
|
||||
// CHECK-NEXT: };
|
||||
|
||||
// CHECK-LABEL: PredicateBitset MyTargetInstructionSelector::
|
||||
// CHECK-NEXT: computeAvailableFeatures(const MachineFunction *MF, const MyTargetSubtarget *Subtarget) const {
|
||||
// CHECK-NEXT: PredicateBitset Features;
|
||||
// CHECK-NEXT: if (Subtarget->hasA())
|
||||
// CHECK-NEXT: Features[Feature_HasABit] = 1;
|
||||
// CHECK-NEXT: if (Subtarget->hasB())
|
||||
// CHECK-NEXT: Features[Feature_HasBBit] = 1;
|
||||
// CHECK-NEXT: return Features;
|
||||
// CHECK-NEXT: }
|
||||
//===- Test the function definition boilerplate. --------------------------===//
|
||||
|
||||
// CHECK: bool MyTargetInstructionSelector::selectImpl(MachineInstr &I) const {
|
||||
// CHECK: MachineFunction &MF = *I.getParent()->getParent();
|
||||
@ -127,9 +103,6 @@ def ADD : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2),
|
||||
//===- Test a nested instruction match. -----------------------------------===//
|
||||
|
||||
// CHECK-LABEL: if ([&]() {
|
||||
// CHECK-NEXT: PredicateBitset ExpectedFeatures = {Feature_HasABit};
|
||||
// CHECK-NEXT: if ((AvailableFeatures & ExpectedFeatures) != ExpectedFeatures)
|
||||
// CHECK-NEXT: return false;
|
||||
// CHECK-NEXT: MachineInstr &MI0 = I;
|
||||
// CHECK-NEXT: if (MI0.getNumOperands() < 3)
|
||||
// CHECK-NEXT: return false;
|
||||
@ -169,9 +142,6 @@ def ADD : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2),
|
||||
|
||||
// We also get a second rule by commutativity.
|
||||
// CHECK-LABEL: if ([&]() {
|
||||
// CHECK-NEXT: PredicateBitset ExpectedFeatures = {Feature_HasABit};
|
||||
// CHECK-NEXT: if ((AvailableFeatures & ExpectedFeatures) != ExpectedFeatures)
|
||||
// CHECK-NEXT: return false;
|
||||
// CHECK-NEXT: MachineInstr &MI0 = I;
|
||||
// CHECK-NEXT: if (MI0.getNumOperands() < 3)
|
||||
// CHECK-NEXT: return false;
|
||||
@ -211,15 +181,11 @@ def ADD : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2),
|
||||
|
||||
def MULADD : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2, GPR32:$src3),
|
||||
[(set GPR32:$dst,
|
||||
(mul (add GPR32:$src1, GPR32:$src2), GPR32:$src3))]>,
|
||||
Requires<[HasA]>;
|
||||
(mul (add GPR32:$src1, GPR32:$src2), GPR32:$src3))]>;
|
||||
|
||||
//===- Test another simple pattern with regclass operands. ----------------===//
|
||||
|
||||
// CHECK-LABEL: if ([&]() {
|
||||
// CHECK-NEXT: PredicateBitset ExpectedFeatures = {Feature_HasABit, Feature_HasBBit};
|
||||
// CHECK-NEXT: if ((AvailableFeatures & ExpectedFeatures) != ExpectedFeatures)
|
||||
// CHECK-NEXT: return false;
|
||||
// CHECK-NEXT: MachineInstr &MI0 = I;
|
||||
// CHECK-NEXT: if (MI0.getNumOperands() < 3)
|
||||
// CHECK-NEXT: return false;
|
||||
@ -247,8 +213,7 @@ def MULADD : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2, GPR32:$src3),
|
||||
// CHECK-NEXT: }()) { return true; }
|
||||
|
||||
def MUL : I<(outs GPR32:$dst), (ins GPR32:$src2, GPR32:$src1),
|
||||
[(set GPR32:$dst, (mul GPR32:$src1, GPR32:$src2))]>,
|
||||
Requires<[HasA, HasB]>;
|
||||
[(set GPR32:$dst, (mul GPR32:$src1, GPR32:$src2))]>;
|
||||
|
||||
//===- Test a pattern with ComplexPattern operands. -----------------------===//
|
||||
//
|
||||
|
@ -2861,7 +2861,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
|
||||
emitValidateOperandClass(Info, OS);
|
||||
|
||||
// Emit the available features compute function.
|
||||
SubtargetFeatureInfo::emitComputeAssemblerAvailableFeatures(
|
||||
SubtargetFeatureInfo::emitComputeAvailableFeatures(
|
||||
Info.Target.getName(), ClassName, "ComputeAvailableFeatures",
|
||||
Info.SubtargetFeatures, OS);
|
||||
|
||||
|
@ -336,7 +336,7 @@ void CodeEmitterGen::run(raw_ostream &o) {
|
||||
o << "#endif // NDEBUG\n";
|
||||
|
||||
// Emit the available features compute function.
|
||||
SubtargetFeatureInfo::emitComputeAssemblerAvailableFeatures(
|
||||
SubtargetFeatureInfo::emitComputeAvailableFeatures(
|
||||
Target.getName(), "MCCodeEmitter", "computeAvailableFeatures",
|
||||
SubtargetFeatures, o);
|
||||
|
||||
|
@ -31,7 +31,6 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "CodeGenDAGPatterns.h"
|
||||
#include "SubtargetFeatureInfo.h"
|
||||
#include "llvm/ADT/Optional.h"
|
||||
#include "llvm/ADT/SmallSet.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
@ -162,6 +161,20 @@ static std::string explainPredicates(const TreePatternNode *N) {
|
||||
return Explanation;
|
||||
}
|
||||
|
||||
static std::string explainRulePredicates(const ArrayRef<Init *> Predicates) {
|
||||
std::string Explanation = "";
|
||||
StringRef Separator = "";
|
||||
for (const auto *P : Predicates) {
|
||||
Explanation += Separator;
|
||||
|
||||
if (const DefInit *PDef = dyn_cast<DefInit>(P)) {
|
||||
Explanation += PDef->getDef()->getName();
|
||||
} else
|
||||
Explanation += "<unknown>";
|
||||
}
|
||||
return Explanation;
|
||||
}
|
||||
|
||||
std::string explainOperator(Record *Operator) {
|
||||
if (Operator->isSubClassOf("SDNode"))
|
||||
return " (" + Operator->getValueAsString("Opcode") + ")";
|
||||
@ -225,8 +238,6 @@ class RuleMatcher {
|
||||
/// ID for the next instruction variable defined with defineInsnVar()
|
||||
unsigned NextInsnVarID;
|
||||
|
||||
std::vector<Record *> RequiredFeatures;
|
||||
|
||||
public:
|
||||
RuleMatcher()
|
||||
: Matchers(), Actions(), InsnVariableNames(), NextInsnVarID(0) {}
|
||||
@ -234,7 +245,6 @@ public:
|
||||
RuleMatcher &operator=(RuleMatcher &&Other) = default;
|
||||
|
||||
InstructionMatcher &addInstructionMatcher();
|
||||
void addRequiredFeature(Record *Feature);
|
||||
|
||||
template <class Kind, class... Args> Kind &addAction(Args &&... args);
|
||||
|
||||
@ -245,9 +255,7 @@ public:
|
||||
void emitCxxCapturedInsnList(raw_ostream &OS);
|
||||
void emitCxxCaptureStmts(raw_ostream &OS, StringRef Expr);
|
||||
|
||||
void emit(raw_ostream &OS,
|
||||
std::map<Record *, SubtargetFeatureInfo, LessRecordByID>
|
||||
SubtargetFeatures);
|
||||
void emit(raw_ostream &OS);
|
||||
|
||||
/// Compare the priority of this object and B.
|
||||
///
|
||||
@ -1084,10 +1092,6 @@ InstructionMatcher &RuleMatcher::addInstructionMatcher() {
|
||||
return *Matchers.back();
|
||||
}
|
||||
|
||||
void RuleMatcher::addRequiredFeature(Record *Feature) {
|
||||
RequiredFeatures.push_back(Feature);
|
||||
}
|
||||
|
||||
template <class Kind, class... Args>
|
||||
Kind &RuleMatcher::addAction(Args &&... args) {
|
||||
Actions.emplace_back(llvm::make_unique<Kind>(std::forward<Args>(args)...));
|
||||
@ -1131,9 +1135,7 @@ void RuleMatcher::emitCxxCaptureStmts(raw_ostream &OS, StringRef Expr) {
|
||||
Matchers.front()->emitCxxCaptureStmts(OS, *this, InsnVarName);
|
||||
}
|
||||
|
||||
void RuleMatcher::emit(raw_ostream &OS,
|
||||
std::map<Record *, SubtargetFeatureInfo, LessRecordByID>
|
||||
SubtargetFeatures) {
|
||||
void RuleMatcher::emit(raw_ostream &OS) {
|
||||
if (Matchers.empty())
|
||||
llvm_unreachable("Unexpected empty matcher!");
|
||||
|
||||
@ -1147,22 +1149,7 @@ void RuleMatcher::emit(raw_ostream &OS,
|
||||
// %elt0(s32), %elt1(s32) = TGT_LOAD_PAIR %ptr
|
||||
// on some targets but we don't need to make use of that yet.
|
||||
assert(Matchers.size() == 1 && "Cannot handle multi-root matchers yet");
|
||||
|
||||
OS << "if (";
|
||||
OS << "[&]() {\n";
|
||||
if (!RequiredFeatures.empty()) {
|
||||
OS << " PredicateBitset ExpectedFeatures = {";
|
||||
StringRef Separator = "";
|
||||
for (const auto &Predicate : RequiredFeatures) {
|
||||
const auto &I = SubtargetFeatures.find(Predicate);
|
||||
assert(I != SubtargetFeatures.end() && "Didn't import predicate?");
|
||||
OS << Separator << I->second.getEnumBitName();
|
||||
Separator = ", ";
|
||||
}
|
||||
OS << "};\n";
|
||||
OS << "if ((AvailableFeatures & ExpectedFeatures) != ExpectedFeatures)\n"
|
||||
<< " return false;\n";
|
||||
}
|
||||
OS << "if ([&]() {\n";
|
||||
|
||||
emitCxxCaptureStmts(OS, "I");
|
||||
|
||||
@ -1277,13 +1264,10 @@ private:
|
||||
/// GIComplexPatternEquiv.
|
||||
DenseMap<const Record *, const Record *> ComplexPatternEquivs;
|
||||
|
||||
// Map of predicates to their subtarget features.
|
||||
std::map<Record *, SubtargetFeatureInfo, LessRecordByID> SubtargetFeatures;
|
||||
|
||||
void gatherNodeEquivs();
|
||||
const CodeGenInstruction *findNodeEquiv(Record *N) const;
|
||||
|
||||
Error importRulePredicates(RuleMatcher &M, ArrayRef<Init *> Predicates);
|
||||
Error importRulePredicates(RuleMatcher &M, ArrayRef<Init *> Predicates) const;
|
||||
Expected<InstructionMatcher &>
|
||||
createAndImportSelDAGMatcher(InstructionMatcher &InsnMatcher,
|
||||
const TreePatternNode *Src) const;
|
||||
@ -1303,8 +1287,6 @@ private:
|
||||
/// Analyze pattern \p P, returning a matcher for it if possible.
|
||||
/// Otherwise, return an Error explaining why we don't support it.
|
||||
Expected<RuleMatcher> runOnPattern(const PatternToMatch &P);
|
||||
|
||||
void declareSubtargetFeature(Record *Predicate);
|
||||
};
|
||||
|
||||
void GlobalISelEmitter::gatherNodeEquivs() {
|
||||
@ -1333,13 +1315,10 @@ GlobalISelEmitter::GlobalISelEmitter(RecordKeeper &RK)
|
||||
|
||||
Error
|
||||
GlobalISelEmitter::importRulePredicates(RuleMatcher &M,
|
||||
ArrayRef<Init *> Predicates) {
|
||||
for (const Init *Predicate : Predicates) {
|
||||
const DefInit *PredicateDef = static_cast<const DefInit *>(Predicate);
|
||||
declareSubtargetFeature(PredicateDef->getDef());
|
||||
M.addRequiredFeature(PredicateDef->getDef());
|
||||
}
|
||||
|
||||
ArrayRef<Init *> Predicates) const {
|
||||
if (!Predicates.empty())
|
||||
return failedImport("Pattern has a rule predicate (" +
|
||||
explainRulePredicates(Predicates) + ")");
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
@ -1746,13 +1725,6 @@ void GlobalISelEmitter::run(raw_ostream &OS) {
|
||||
for (const auto &Rule : Rules)
|
||||
MaxTemporaries = std::max(MaxTemporaries, Rule.countTemporaryOperands());
|
||||
|
||||
OS << "#ifdef GET_GLOBALISEL_PREDICATE_BITSET\n"
|
||||
<< "const unsigned MAX_SUBTARGET_PREDICATES = " << SubtargetFeatures.size()
|
||||
<< ";\n"
|
||||
<< "using PredicateBitset = "
|
||||
"llvm::PredicateBitsetImpl<MAX_SUBTARGET_PREDICATES>;\n"
|
||||
<< "#endif // ifdef GET_GLOBALISEL_PREDICATE_BITSET\n\n";
|
||||
|
||||
OS << "#ifdef GET_GLOBALISEL_TEMPORARIES_DECL\n";
|
||||
for (unsigned I = 0; I < MaxTemporaries; ++I)
|
||||
OS << " mutable MachineOperand TempOp" << I << ";\n";
|
||||
@ -1763,21 +1735,14 @@ void GlobalISelEmitter::run(raw_ostream &OS) {
|
||||
OS << ", TempOp" << I << "(MachineOperand::CreatePlaceholder())\n";
|
||||
OS << "#endif // ifdef GET_GLOBALISEL_TEMPORARIES_INIT\n\n";
|
||||
|
||||
OS << "#ifdef GET_GLOBALISEL_IMPL\n";
|
||||
SubtargetFeatureInfo::emitSubtargetFeatureBitEnumeration(SubtargetFeatures,
|
||||
OS);
|
||||
SubtargetFeatureInfo::emitNameTable(SubtargetFeatures, OS);
|
||||
SubtargetFeatureInfo::emitComputeAvailableFeatures(
|
||||
Target.getName(), "InstructionSelector", "computeAvailableFeatures",
|
||||
SubtargetFeatures, OS);
|
||||
|
||||
OS << "bool " << Target.getName()
|
||||
OS << "#ifdef GET_GLOBALISEL_IMPL\n"
|
||||
<< "bool " << Target.getName()
|
||||
<< "InstructionSelector::selectImpl(MachineInstr &I) const {\n"
|
||||
<< " MachineFunction &MF = *I.getParent()->getParent();\n"
|
||||
<< " const MachineRegisterInfo &MRI = MF.getRegInfo();\n";
|
||||
|
||||
for (auto &Rule : Rules) {
|
||||
Rule.emit(OS, SubtargetFeatures);
|
||||
Rule.emit(OS);
|
||||
++NumPatternEmitted;
|
||||
}
|
||||
|
||||
@ -1786,12 +1751,6 @@ void GlobalISelEmitter::run(raw_ostream &OS) {
|
||||
<< "#endif // ifdef GET_GLOBALISEL_IMPL\n";
|
||||
}
|
||||
|
||||
void GlobalISelEmitter::declareSubtargetFeature(Record *Predicate) {
|
||||
if (SubtargetFeatures.count(Predicate) == 0)
|
||||
SubtargetFeatures.emplace(
|
||||
Predicate, SubtargetFeatureInfo(Predicate, SubtargetFeatures.size()));
|
||||
}
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -59,20 +59,6 @@ void SubtargetFeatureInfo::emitSubtargetFeatureFlagEnumeration(
|
||||
OS << "};\n\n";
|
||||
}
|
||||
|
||||
void SubtargetFeatureInfo::emitSubtargetFeatureBitEnumeration(
|
||||
std::map<Record *, SubtargetFeatureInfo, LessRecordByID> &SubtargetFeatures,
|
||||
raw_ostream &OS) {
|
||||
OS << "// Bits for subtarget features that participate in "
|
||||
<< "instruction matching.\n";
|
||||
OS << "enum SubtargetFeatureBits : "
|
||||
<< getMinimalTypeForRange(SubtargetFeatures.size()) << " {\n";
|
||||
for (const auto &SF : SubtargetFeatures) {
|
||||
const SubtargetFeatureInfo &SFI = SF.second;
|
||||
OS << " " << SFI.getEnumBitName() << " = " << SFI.Index << ",\n";
|
||||
}
|
||||
OS << "};\n\n";
|
||||
}
|
||||
|
||||
void SubtargetFeatureInfo::emitNameTable(
|
||||
std::map<Record *, SubtargetFeatureInfo, LessRecordByID> &SubtargetFeatures,
|
||||
raw_ostream &OS) {
|
||||
@ -104,24 +90,6 @@ void SubtargetFeatureInfo::emitComputeAvailableFeatures(
|
||||
StringRef TargetName, StringRef ClassName, StringRef FuncName,
|
||||
std::map<Record *, SubtargetFeatureInfo, LessRecordByID> &SubtargetFeatures,
|
||||
raw_ostream &OS) {
|
||||
OS << "PredicateBitset " << TargetName << ClassName << "::\n"
|
||||
<< FuncName << "(const MachineFunction *MF, const " << TargetName
|
||||
<< "Subtarget *Subtarget) const {\n";
|
||||
OS << " PredicateBitset Features;\n";
|
||||
for (const auto &SF : SubtargetFeatures) {
|
||||
const SubtargetFeatureInfo &SFI = SF.second;
|
||||
|
||||
OS << " if (" << SFI.TheDef->getValueAsString("CondString") << ")\n";
|
||||
OS << " Features[" << SFI.getEnumBitName() << "] = 1;\n";
|
||||
}
|
||||
OS << " return Features;\n";
|
||||
OS << "}\n\n";
|
||||
}
|
||||
|
||||
void SubtargetFeatureInfo::emitComputeAssemblerAvailableFeatures(
|
||||
StringRef TargetName, StringRef ClassName, StringRef FuncName,
|
||||
std::map<Record *, SubtargetFeatureInfo, LessRecordByID> &SubtargetFeatures,
|
||||
raw_ostream &OS) {
|
||||
OS << "uint64_t " << TargetName << ClassName << "::\n"
|
||||
<< FuncName << "(const FeatureBitset& FB) const {\n";
|
||||
OS << " uint64_t Features = 0;\n";
|
||||
|
@ -37,34 +37,16 @@ struct SubtargetFeatureInfo {
|
||||
return "Feature_" + TheDef->getName().str();
|
||||
}
|
||||
|
||||
/// \brief The name of the enumerated constant identifying the bitnumber for
|
||||
/// this feature.
|
||||
std::string getEnumBitName() const {
|
||||
return "Feature_" + TheDef->getName().str() + "Bit";
|
||||
}
|
||||
|
||||
void dump() const;
|
||||
static std::vector<std::pair<Record *, SubtargetFeatureInfo>>
|
||||
getAll(const RecordKeeper &Records);
|
||||
|
||||
/// Emit the subtarget feature flag definitions.
|
||||
///
|
||||
/// This version emits the bit value for the feature and is therefore limited
|
||||
/// to 64 feature bits.
|
||||
static void emitSubtargetFeatureFlagEnumeration(
|
||||
std::map<Record *, SubtargetFeatureInfo, LessRecordByID>
|
||||
&SubtargetFeatures,
|
||||
raw_ostream &OS);
|
||||
|
||||
/// Emit the subtarget feature flag definitions.
|
||||
///
|
||||
/// This version emits the bit index for the feature and can therefore support
|
||||
/// more than 64 feature bits.
|
||||
static void emitSubtargetFeatureBitEnumeration(
|
||||
std::map<Record *, SubtargetFeatureInfo, LessRecordByID>
|
||||
&SubtargetFeatures,
|
||||
raw_ostream &OS);
|
||||
|
||||
static void emitNameTable(std::map<Record *, SubtargetFeatureInfo,
|
||||
LessRecordByID> &SubtargetFeatures,
|
||||
raw_ostream &OS);
|
||||
@ -72,9 +54,6 @@ struct SubtargetFeatureInfo {
|
||||
/// Emit the function to compute the list of available features given a
|
||||
/// subtarget.
|
||||
///
|
||||
/// This version is used for subtarget features defined using Predicate<>
|
||||
/// and supports more than 64 feature bits.
|
||||
///
|
||||
/// \param TargetName The name of the target as used in class prefixes (e.g.
|
||||
/// <TargetName>Subtarget)
|
||||
/// \param ClassName The name of the class (without the <Target> prefix)
|
||||
@ -87,25 +66,6 @@ struct SubtargetFeatureInfo {
|
||||
std::map<Record *, SubtargetFeatureInfo, LessRecordByID>
|
||||
&SubtargetFeatures,
|
||||
raw_ostream &OS);
|
||||
|
||||
/// Emit the function to compute the list of available features given a
|
||||
/// subtarget.
|
||||
///
|
||||
/// This version is used for subtarget features defined using
|
||||
/// AssemblerPredicate<> and supports up to 64 feature bits.
|
||||
///
|
||||
/// \param TargetName The name of the target as used in class prefixes (e.g.
|
||||
/// <TargetName>Subtarget)
|
||||
/// \param ClassName The name of the class (without the <Target> prefix)
|
||||
/// that will contain the generated functions.
|
||||
/// \param FuncName The name of the function to emit.
|
||||
/// \param SubtargetFeatures A map of TableGen records to the
|
||||
/// SubtargetFeatureInfo equivalent.
|
||||
static void emitComputeAssemblerAvailableFeatures(
|
||||
StringRef TargetName, StringRef ClassName, StringRef FuncName,
|
||||
std::map<Record *, SubtargetFeatureInfo, LessRecordByID>
|
||||
&SubtargetFeatures,
|
||||
raw_ostream &OS);
|
||||
};
|
||||
} // end namespace llvm
|
||||
|
||||
|
@ -40,6 +40,5 @@ const char *llvm::getMinimalTypeForEnumBitfield(uint64_t Size) {
|
||||
uint64_t MaxIndex = Size;
|
||||
if (MaxIndex > 0)
|
||||
MaxIndex--;
|
||||
assert(MaxIndex <= 64 && "Too many bits");
|
||||
return getMinimalTypeForRange(1ULL << MaxIndex);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user