llvm-project/llvm/lib/Target/BPF/BPFTargetMachine.cpp
David Green ca29c271d2 [Targets] Add errors for tiny and kernel codemodel on targets that don't support them
Adds fatal errors for any target that does not support the Tiny or Kernel
codemodels by rejigging the getEffectiveCodeModel calls.

Differential Revision: https://reviews.llvm.org/D50141

llvm-svn: 348585
2018-12-07 12:10:23 +00:00

118 lines
4.0 KiB
C++

//===-- BPFTargetMachine.cpp - Define TargetMachine for BPF ---------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Implements the info about BPF target spec.
//
//===----------------------------------------------------------------------===//
#include "BPFTargetMachine.h"
#include "BPF.h"
#include "MCTargetDesc/BPFMCAsmInfo.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Target/TargetOptions.h"
using namespace llvm;
static cl::
opt<bool> DisableMIPeephole("disable-bpf-peephole", cl::Hidden,
cl::desc("Disable machine peepholes for BPF"));
extern "C" void LLVMInitializeBPFTarget() {
// Register the target.
RegisterTargetMachine<BPFTargetMachine> X(getTheBPFleTarget());
RegisterTargetMachine<BPFTargetMachine> Y(getTheBPFbeTarget());
RegisterTargetMachine<BPFTargetMachine> Z(getTheBPFTarget());
PassRegistry &PR = *PassRegistry::getPassRegistry();
initializeBPFMIPeepholePass(PR);
}
// DataLayout: little or big endian
static std::string computeDataLayout(const Triple &TT) {
if (TT.getArch() == Triple::bpfeb)
return "E-m:e-p:64:64-i64:64-n32:64-S128";
else
return "e-m:e-p:64:64-i64:64-n32:64-S128";
}
static Reloc::Model getEffectiveRelocModel(Optional<Reloc::Model> RM) {
if (!RM.hasValue())
return Reloc::PIC_;
return *RM;
}
BPFTargetMachine::BPFTargetMachine(const Target &T, const Triple &TT,
StringRef CPU, StringRef FS,
const TargetOptions &Options,
Optional<Reloc::Model> RM,
Optional<CodeModel::Model> CM,
CodeGenOpt::Level OL, bool JIT)
: LLVMTargetMachine(T, computeDataLayout(TT), TT, CPU, FS, Options,
getEffectiveRelocModel(RM),
getEffectiveCodeModel(CM, CodeModel::Small), OL),
TLOF(make_unique<TargetLoweringObjectFileELF>()),
Subtarget(TT, CPU, FS, *this) {
initAsmInfo();
BPFMCAsmInfo *MAI =
static_cast<BPFMCAsmInfo *>(const_cast<MCAsmInfo *>(AsmInfo.get()));
MAI->setDwarfUsesRelocationsAcrossSections(!Subtarget.getUseDwarfRIS());
}
namespace {
// BPF Code Generator Pass Configuration Options.
class BPFPassConfig : public TargetPassConfig {
public:
BPFPassConfig(BPFTargetMachine &TM, PassManagerBase &PM)
: TargetPassConfig(TM, PM) {}
BPFTargetMachine &getBPFTargetMachine() const {
return getTM<BPFTargetMachine>();
}
bool addInstSelector() override;
void addMachineSSAOptimization() override;
void addPreEmitPass() override;
};
}
TargetPassConfig *BPFTargetMachine::createPassConfig(PassManagerBase &PM) {
return new BPFPassConfig(*this, PM);
}
// Install an instruction selector pass using
// the ISelDag to gen BPF code.
bool BPFPassConfig::addInstSelector() {
addPass(createBPFISelDag(getBPFTargetMachine()));
return false;
}
void BPFPassConfig::addMachineSSAOptimization() {
// The default implementation must be called first as we want eBPF
// Peephole ran at last.
TargetPassConfig::addMachineSSAOptimization();
const BPFSubtarget *Subtarget = getBPFTargetMachine().getSubtargetImpl();
if (Subtarget->getHasAlu32() && !DisableMIPeephole)
addPass(createBPFMIPeepholePass());
}
void BPFPassConfig::addPreEmitPass() {
const BPFSubtarget *Subtarget = getBPFTargetMachine().getSubtargetImpl();
addPass(createBPFMIPreEmitCheckingPass());
if (getOptLevel() != CodeGenOpt::None)
if (Subtarget->getHasAlu32() && !DisableMIPeephole)
addPass(createBPFMIPreEmitPeepholePass());
}