blob: 35b5351d6f36472cae70dc77a5ae28813fcdcf95 [file] [edit]
// Add a few Bogus backend classes so we can create MachineInstrs without
// depending on a real target.
class BogusTargetLowering : public TargetLowering {
public:
BogusTargetLowering(const TargetMachine &TM, const TargetSubtargetInfo &STI)
: TargetLowering(TM, STI) {}
};
class BogusFrameLowering : public TargetFrameLowering {
public:
BogusFrameLowering()
: TargetFrameLowering(TargetFrameLowering::StackGrowsDown, Align(4), 4) {}
void emitPrologue(MachineFunction &MF,
MachineBasicBlock &MBB) const override {}
void emitEpilogue(MachineFunction &MF,
MachineBasicBlock &MBB) const override {}
protected:
bool hasFPImpl(const MachineFunction &MF) const override { return false; }
};
class BogusRegisterInfo : public TargetRegisterInfo {
public:
BogusRegisterInfo()
: TargetRegisterInfo(nullptr, nullptr, {}, nullptr, nullptr,
LaneBitmask(~0u), nullptr, nullptr) {
InitMCRegisterInfo(nullptr, 0, 0, 0, nullptr, 0, nullptr, 0, nullptr,
nullptr, nullptr, nullptr, nullptr, 0, nullptr);
}
const MCPhysReg *
getCalleeSavedRegs(const MachineFunction *MF) const override {
return nullptr;
}
ArrayRef<const uint32_t *> getRegMasks() const override { return {}; }
ArrayRef<const char *> getRegMaskNames() const override { return {}; }
BitVector getReservedRegs(const MachineFunction &MF) const override {
return BitVector();
}
const RegClassWeight &
getRegClassWeight(const TargetRegisterClass *RC) const override {
static RegClassWeight Bogus{1, 16};
return Bogus;
}
unsigned getRegUnitWeight(MCRegUnit RegUnit) const override { return 1; }
unsigned getNumRegPressureSets() const override { return 0; }
const char *getRegPressureSetName(unsigned Idx) const override {
return "bogus";
}
unsigned getRegPressureSetLimit(const MachineFunction &MF,
unsigned Idx) const override {
return 0;
}
const TargetRegisterClass *
getLargestRegClassForRegPressureSet(unsigned Idx) const override {
return nullptr;
}
const int *
getRegClassPressureSets(const TargetRegisterClass *RC) const override {
static const int Bogus[] = {0, -1};
return &Bogus[0];
}
const int *getRegUnitPressureSets(MCRegUnit RegUnit) const override {
static const int Bogus[] = {0, -1};
return &Bogus[0];
}
const TargetRegisterClass *
getMinimalPhysRegClass(MCRegister Reg) const override {
return nullptr;
}
Register getFrameRegister(const MachineFunction &MF) const override {
return 0;
}
bool eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj,
unsigned FIOperandNum,
RegScavenger *RS = nullptr) const override {
return false;
}
};
class BogusTargetInstrInfo : public TargetInstrInfo {
BogusRegisterInfo RegInfo;
public:
BogusTargetInstrInfo() : TargetInstrInfo(RegInfo) {}
};
class BogusSubtarget : public TargetSubtargetInfo {
public:
BogusSubtarget(TargetMachine &TM)
: TargetSubtargetInfo(Triple(""), "", "", "", "", {}, {}, {}, nullptr,
nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr),
FL(), TL(TM, *this) {}
~BogusSubtarget() override = default;
const TargetFrameLowering *getFrameLowering() const override { return &FL; }
const TargetLowering *getTargetLowering() const override { return &TL; }
const TargetInstrInfo *getInstrInfo() const override { return &TII; }
const TargetRegisterInfo *getRegisterInfo() const override { return &TRI; }
const FeatureBitset &getInlineIgnoreFeatures() const override {
static constexpr FeatureBitset Features;
return Features;
}
const FeatureBitset &getInlineInverseFeatures() const override {
static constexpr FeatureBitset Features;
return Features;
}
const FeatureBitset &getInlineMustMatchFeatures() const override {
static constexpr FeatureBitset Features;
return Features;
}
private:
BogusFrameLowering FL;
BogusRegisterInfo TRI;
BogusTargetLowering TL;
BogusTargetInstrInfo TII;
};
static TargetOptions getTargetOptionsForBogusMachine() {
TargetOptions Opts;
Opts.EmitCallSiteInfo = true;
return Opts;
}
class BogusTargetMachine : public CodeGenTargetMachineImpl {
public:
BogusTargetMachine()
: CodeGenTargetMachineImpl(
Target(), "", Triple(""), "", "", getTargetOptionsForBogusMachine(),
Reloc::Static, CodeModel::Small, CodeGenOptLevel::Default),
ST(*this) {
// With an empty Triple, `initAsmInfo` cannot be called. Provide
// default MC{AsmInfo,RegisterInfo,SubtargetInfo} so MCContext can be
// created.
AsmInfo = std::make_unique<MCAsmInfo>(Options.MCOptions);
MRI = std::make_unique<MCRegisterInfo>();
STI = std::make_unique<MCSubtargetInfo>(
Triple(""), "", "", "", StringTable{""}, ArrayRef<SubtargetFeatureKV>{},
ArrayRef<SubtargetSubTypeKV>{}, ArrayRef<SubtargetSubTypeAliasKV>{},
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr);
}
~BogusTargetMachine() override = default;
const TargetSubtargetInfo *getSubtargetImpl(const Function &) const override {
return &ST;
}
private:
BogusSubtarget ST;
};
BogusTargetMachine *createTargetMachine() {
static BogusTargetMachine BogusTM;
return &BogusTM;
}
std::unique_ptr<MachineFunction>
createMachineFunction(LLVMContext &Ctx, Module &M, const Twine &Name = "Test") {
auto Type = FunctionType::get(Type::getVoidTy(Ctx), false);
auto F = Function::Create(Type, GlobalValue::ExternalLinkage, Name, &M);
auto TM = createTargetMachine();
unsigned FunctionNum = 42;
MachineModuleInfo MMI(TM);
const TargetSubtargetInfo &STI = *TM->getSubtargetImpl(*F);
return std::make_unique<MachineFunction>(*F, *TM, STI, MMI.getContext(),
FunctionNum);
}