MipsTargetMachine.cpp [plain text]
#include "MipsTargetMachine.h"
#include "Mips.h"
#include "Mips16FrameLowering.h"
#include "Mips16HardFloat.h"
#include "Mips16ISelDAGToDAG.h"
#include "Mips16ISelLowering.h"
#include "Mips16InstrInfo.h"
#include "MipsFrameLowering.h"
#include "MipsInstrInfo.h"
#include "MipsModuleISelDAGToDAG.h"
#include "MipsOs16.h"
#include "MipsSEFrameLowering.h"
#include "MipsSEISelDAGToDAG.h"
#include "MipsSEISelLowering.h"
#include "MipsSEInstrInfo.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/PassManager.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Scalar.h"
using namespace llvm;
extern "C" void LLVMInitializeMipsTarget() {
RegisterTargetMachine<MipsebTargetMachine> X(TheMipsTarget);
RegisterTargetMachine<MipselTargetMachine> Y(TheMipselTarget);
RegisterTargetMachine<MipsebTargetMachine> A(TheMips64Target);
RegisterTargetMachine<MipselTargetMachine> B(TheMips64elTarget);
}
static std::string computeDataLayout(const MipsSubtarget &ST) {
std::string Ret = "";
if (ST.isLittle())
Ret += "e";
else
Ret += "E";
Ret += "-m:m";
if (!ST.isABI_N64())
Ret += "-p:32:32";
Ret += "-i8:8:32-i16:16:32-i64:64";
if (ST.isABI_N64() || ST.isABI_N32())
Ret += "-n32:64-S128";
else
Ret += "-n32-S64";
return Ret;
}
MipsTargetMachine::
MipsTargetMachine(const Target &T, StringRef TT,
StringRef CPU, StringRef FS, const TargetOptions &Options,
Reloc::Model RM, CodeModel::Model CM,
CodeGenOpt::Level OL,
bool isLittle)
: LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL),
Subtarget(TT, CPU, FS, isLittle, RM, this),
DL(computeDataLayout(Subtarget)),
InstrInfo(MipsInstrInfo::create(*this)),
FrameLowering(MipsFrameLowering::create(*this, Subtarget)),
TLInfo(MipsTargetLowering::create(*this)), TSInfo(*this),
InstrItins(Subtarget.getInstrItineraryData()), JITInfo() {
initAsmInfo();
}
void MipsTargetMachine::setHelperClassesMips16() {
InstrInfoSE.swap(InstrInfo);
FrameLoweringSE.swap(FrameLowering);
TLInfoSE.swap(TLInfo);
if (!InstrInfo16) {
InstrInfo.reset(MipsInstrInfo::create(*this));
FrameLowering.reset(MipsFrameLowering::create(*this, Subtarget));
TLInfo.reset(MipsTargetLowering::create(*this));
} else {
InstrInfo16.swap(InstrInfo);
FrameLowering16.swap(FrameLowering);
TLInfo16.swap(TLInfo);
}
assert(TLInfo && "null target lowering 16");
assert(InstrInfo && "null instr info 16");
assert(FrameLowering && "null frame lowering 16");
}
void MipsTargetMachine::setHelperClassesMipsSE() {
InstrInfo16.swap(InstrInfo);
FrameLowering16.swap(FrameLowering);
TLInfo16.swap(TLInfo);
if (!InstrInfoSE) {
InstrInfo.reset(MipsInstrInfo::create(*this));
FrameLowering.reset(MipsFrameLowering::create(*this, Subtarget));
TLInfo.reset(MipsTargetLowering::create(*this));
} else {
InstrInfoSE.swap(InstrInfo);
FrameLoweringSE.swap(FrameLowering);
TLInfoSE.swap(TLInfo);
}
assert(TLInfo && "null target lowering in SE");
assert(InstrInfo && "null instr info SE");
assert(FrameLowering && "null frame lowering SE");
}
void MipsebTargetMachine::anchor() { }
MipsebTargetMachine::
MipsebTargetMachine(const Target &T, StringRef TT,
StringRef CPU, StringRef FS, const TargetOptions &Options,
Reloc::Model RM, CodeModel::Model CM,
CodeGenOpt::Level OL)
: MipsTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, false) {}
void MipselTargetMachine::anchor() { }
MipselTargetMachine::
MipselTargetMachine(const Target &T, StringRef TT,
StringRef CPU, StringRef FS, const TargetOptions &Options,
Reloc::Model RM, CodeModel::Model CM,
CodeGenOpt::Level OL)
: MipsTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) {}
namespace {
class MipsPassConfig : public TargetPassConfig {
public:
MipsPassConfig(MipsTargetMachine *TM, PassManagerBase &PM)
: TargetPassConfig(TM, PM) {
EnableTailMerge = !getMipsSubtarget().enableLongBranchPass();
}
MipsTargetMachine &getMipsTargetMachine() const {
return getTM<MipsTargetMachine>();
}
const MipsSubtarget &getMipsSubtarget() const {
return *getMipsTargetMachine().getSubtargetImpl();
}
virtual void addIRPasses();
virtual bool addInstSelector();
virtual void addMachineSSAOptimization();
virtual bool addPreEmitPass();
};
}
TargetPassConfig *MipsTargetMachine::createPassConfig(PassManagerBase &PM) {
return new MipsPassConfig(this, PM);
}
void MipsPassConfig::addIRPasses() {
TargetPassConfig::addIRPasses();
if (getMipsSubtarget().os16())
addPass(createMipsOs16(getMipsTargetMachine()));
if (getMipsSubtarget().inMips16HardFloat())
addPass(createMips16HardFloat(getMipsTargetMachine()));
addPass(createPartiallyInlineLibCallsPass());
}
bool MipsPassConfig::addInstSelector() {
if (getMipsSubtarget().allowMixed16_32()) {
addPass(createMipsModuleISelDag(getMipsTargetMachine()));
addPass(createMips16ISelDag(getMipsTargetMachine()));
addPass(createMipsSEISelDag(getMipsTargetMachine()));
} else {
addPass(createMipsISelDag(getMipsTargetMachine()));
}
return false;
}
void MipsPassConfig::addMachineSSAOptimization() {
addPass(createMipsOptimizePICCallPass(getMipsTargetMachine()));
TargetPassConfig::addMachineSSAOptimization();
}
void MipsTargetMachine::addAnalysisPasses(PassManagerBase &PM) {
if (Subtarget.allowMixed16_32()) {
DEBUG(errs() << "No ");
PM.add(createNoTargetTransformInfoPass());
} else
LLVMTargetMachine::addAnalysisPasses(PM);
DEBUG(errs() << "Target Transform Info Pass Added\n");
}
bool MipsPassConfig::addPreEmitPass() {
MipsTargetMachine &TM = getMipsTargetMachine();
const MipsSubtarget &Subtarget = TM.getSubtarget<MipsSubtarget>();
addPass(createMipsDelaySlotFillerPass(TM));
if (Subtarget.enableLongBranchPass())
addPass(createMipsLongBranchPass(TM));
if (Subtarget.inMips16Mode() ||
Subtarget.allowMixed16_32())
addPass(createMipsConstantIslandPass(TM));
return true;
}
bool MipsTargetMachine::addCodeEmitter(PassManagerBase &PM,
JITCodeEmitter &JCE) {
PM.add(createMipsJITCodeEmitterPass(*this, JCE));
return false;
}