MipsTargetMachine.cpp revision 288943
1//===-- MipsTargetMachine.cpp - Define TargetMachine for Mips -------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// Implements the info about Mips target spec. 11// 12//===----------------------------------------------------------------------===// 13 14#include "MipsTargetMachine.h" 15#include "Mips.h" 16#include "Mips16FrameLowering.h" 17#include "Mips16ISelDAGToDAG.h" 18#include "Mips16ISelLowering.h" 19#include "Mips16InstrInfo.h" 20#include "MipsFrameLowering.h" 21#include "MipsInstrInfo.h" 22#include "MipsSEFrameLowering.h" 23#include "MipsSEISelDAGToDAG.h" 24#include "MipsSEISelLowering.h" 25#include "MipsSEInstrInfo.h" 26#include "MipsTargetObjectFile.h" 27#include "llvm/Analysis/TargetTransformInfo.h" 28#include "llvm/CodeGen/Passes.h" 29#include "llvm/IR/LegacyPassManager.h" 30#include "llvm/Support/Debug.h" 31#include "llvm/Support/TargetRegistry.h" 32#include "llvm/Support/raw_ostream.h" 33#include "llvm/Transforms/Scalar.h" 34 35using namespace llvm; 36 37#define DEBUG_TYPE "mips" 38 39extern "C" void LLVMInitializeMipsTarget() { 40 // Register the target. 41 RegisterTargetMachine<MipsebTargetMachine> X(TheMipsTarget); 42 RegisterTargetMachine<MipselTargetMachine> Y(TheMipselTarget); 43 RegisterTargetMachine<MipsebTargetMachine> A(TheMips64Target); 44 RegisterTargetMachine<MipselTargetMachine> B(TheMips64elTarget); 45} 46 47static std::string computeDataLayout(const Triple &TT, StringRef CPU, 48 const TargetOptions &Options, 49 bool isLittle) { 50 std::string Ret = ""; 51 MipsABIInfo ABI = MipsABIInfo::computeTargetABI(TT, CPU, Options.MCOptions); 52 53 // There are both little and big endian mips. 54 if (isLittle) 55 Ret += "e"; 56 else 57 Ret += "E"; 58 59 Ret += "-m:m"; 60 61 // Pointers are 32 bit on some ABIs. 62 if (!ABI.IsN64()) 63 Ret += "-p:32:32"; 64 65 // 8 and 16 bit integers only need to have natural alignment, but try to 66 // align them to 32 bits. 64 bit integers have natural alignment. 67 Ret += "-i8:8:32-i16:16:32-i64:64"; 68 69 // 32 bit registers are always available and the stack is at least 64 bit 70 // aligned. On N64 64 bit registers are also available and the stack is 71 // 128 bit aligned. 72 if (ABI.IsN64() || ABI.IsN32()) 73 Ret += "-n32:64-S128"; 74 else 75 Ret += "-n32-S64"; 76 77 return Ret; 78} 79 80// On function prologue, the stack is created by decrementing 81// its pointer. Once decremented, all references are done with positive 82// offset from the stack/frame pointer, using StackGrowsUp enables 83// an easier handling. 84// Using CodeModel::Large enables different CALL behavior. 85MipsTargetMachine::MipsTargetMachine(const Target &T, const Triple &TT, 86 StringRef CPU, StringRef FS, 87 const TargetOptions &Options, 88 Reloc::Model RM, CodeModel::Model CM, 89 CodeGenOpt::Level OL, bool isLittle) 90 : LLVMTargetMachine(T, computeDataLayout(TT, CPU, Options, isLittle), TT, 91 CPU, FS, Options, RM, CM, OL), 92 isLittle(isLittle), TLOF(make_unique<MipsTargetObjectFile>()), 93 ABI(MipsABIInfo::computeTargetABI(TT, CPU, Options.MCOptions)), 94 Subtarget(nullptr), DefaultSubtarget(TT, CPU, FS, isLittle, *this), 95 NoMips16Subtarget(TT, CPU, FS.empty() ? "-mips16" : FS.str() + ",-mips16", 96 isLittle, *this), 97 Mips16Subtarget(TT, CPU, FS.empty() ? "+mips16" : FS.str() + ",+mips16", 98 isLittle, *this) { 99 Subtarget = &DefaultSubtarget; 100 initAsmInfo(); 101} 102 103MipsTargetMachine::~MipsTargetMachine() {} 104 105void MipsebTargetMachine::anchor() { } 106 107MipsebTargetMachine::MipsebTargetMachine(const Target &T, const Triple &TT, 108 StringRef CPU, StringRef FS, 109 const TargetOptions &Options, 110 Reloc::Model RM, CodeModel::Model CM, 111 CodeGenOpt::Level OL) 112 : MipsTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, false) {} 113 114void MipselTargetMachine::anchor() { } 115 116MipselTargetMachine::MipselTargetMachine(const Target &T, const Triple &TT, 117 StringRef CPU, StringRef FS, 118 const TargetOptions &Options, 119 Reloc::Model RM, CodeModel::Model CM, 120 CodeGenOpt::Level OL) 121 : MipsTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) {} 122 123const MipsSubtarget * 124MipsTargetMachine::getSubtargetImpl(const Function &F) const { 125 Attribute CPUAttr = F.getFnAttribute("target-cpu"); 126 Attribute FSAttr = F.getFnAttribute("target-features"); 127 128 std::string CPU = !CPUAttr.hasAttribute(Attribute::None) 129 ? CPUAttr.getValueAsString().str() 130 : TargetCPU; 131 std::string FS = !FSAttr.hasAttribute(Attribute::None) 132 ? FSAttr.getValueAsString().str() 133 : TargetFS; 134 bool hasMips16Attr = 135 !F.getFnAttribute("mips16").hasAttribute(Attribute::None); 136 bool hasNoMips16Attr = 137 !F.getFnAttribute("nomips16").hasAttribute(Attribute::None); 138 139 // FIXME: This is related to the code below to reset the target options, 140 // we need to know whether or not the soft float flag is set on the 141 // function, so we can enable it as a subtarget feature. 142 bool softFloat = 143 F.hasFnAttribute("use-soft-float") && 144 F.getFnAttribute("use-soft-float").getValueAsString() == "true"; 145 146 if (hasMips16Attr) 147 FS += FS.empty() ? "+mips16" : ",+mips16"; 148 else if (hasNoMips16Attr) 149 FS += FS.empty() ? "-mips16" : ",-mips16"; 150 if (softFloat) 151 FS += FS.empty() ? "+soft-float" : ",+soft-float"; 152 153 auto &I = SubtargetMap[CPU + FS]; 154 if (!I) { 155 // This needs to be done before we create a new subtarget since any 156 // creation will depend on the TM and the code generation flags on the 157 // function that reside in TargetOptions. 158 resetTargetOptions(F); 159 I = llvm::make_unique<MipsSubtarget>(TargetTriple, CPU, FS, isLittle, 160 *this); 161 } 162 return I.get(); 163} 164 165void MipsTargetMachine::resetSubtarget(MachineFunction *MF) { 166 DEBUG(dbgs() << "resetSubtarget\n"); 167 168 Subtarget = const_cast<MipsSubtarget *>(getSubtargetImpl(*MF->getFunction())); 169 MF->setSubtarget(Subtarget); 170 return; 171} 172 173namespace { 174/// Mips Code Generator Pass Configuration Options. 175class MipsPassConfig : public TargetPassConfig { 176public: 177 MipsPassConfig(MipsTargetMachine *TM, PassManagerBase &PM) 178 : TargetPassConfig(TM, PM) { 179 // The current implementation of long branch pass requires a scratch 180 // register ($at) to be available before branch instructions. Tail merging 181 // can break this requirement, so disable it when long branch pass is 182 // enabled. 183 EnableTailMerge = !getMipsSubtarget().enableLongBranchPass(); 184 } 185 186 MipsTargetMachine &getMipsTargetMachine() const { 187 return getTM<MipsTargetMachine>(); 188 } 189 190 const MipsSubtarget &getMipsSubtarget() const { 191 return *getMipsTargetMachine().getSubtargetImpl(); 192 } 193 194 void addIRPasses() override; 195 bool addInstSelector() override; 196 void addMachineSSAOptimization() override; 197 void addPreEmitPass() override; 198 199 void addPreRegAlloc() override; 200 201}; 202} // namespace 203 204TargetPassConfig *MipsTargetMachine::createPassConfig(PassManagerBase &PM) { 205 return new MipsPassConfig(this, PM); 206} 207 208void MipsPassConfig::addIRPasses() { 209 TargetPassConfig::addIRPasses(); 210 addPass(createAtomicExpandPass(&getMipsTargetMachine())); 211 if (getMipsSubtarget().os16()) 212 addPass(createMipsOs16Pass(getMipsTargetMachine())); 213 if (getMipsSubtarget().inMips16HardFloat()) 214 addPass(createMips16HardFloatPass(getMipsTargetMachine())); 215} 216// Install an instruction selector pass using 217// the ISelDag to gen Mips code. 218bool MipsPassConfig::addInstSelector() { 219 addPass(createMipsModuleISelDagPass(getMipsTargetMachine())); 220 addPass(createMips16ISelDag(getMipsTargetMachine())); 221 addPass(createMipsSEISelDag(getMipsTargetMachine())); 222 return false; 223} 224 225void MipsPassConfig::addMachineSSAOptimization() { 226 addPass(createMipsOptimizePICCallPass(getMipsTargetMachine())); 227 TargetPassConfig::addMachineSSAOptimization(); 228} 229 230void MipsPassConfig::addPreRegAlloc() { 231 if (getOptLevel() == CodeGenOpt::None) 232 addPass(createMipsOptimizePICCallPass(getMipsTargetMachine())); 233} 234 235TargetIRAnalysis MipsTargetMachine::getTargetIRAnalysis() { 236 return TargetIRAnalysis([this](Function &F) { 237 if (Subtarget->allowMixed16_32()) { 238 DEBUG(errs() << "No Target Transform Info Pass Added\n"); 239 // FIXME: This is no longer necessary as the TTI returned is per-function. 240 return TargetTransformInfo(F.getParent()->getDataLayout()); 241 } 242 243 DEBUG(errs() << "Target Transform Info Pass Added\n"); 244 return TargetTransformInfo(BasicTTIImpl(this, F)); 245 }); 246} 247 248// Implemented by targets that want to run passes immediately before 249// machine code is emitted. return true if -print-machineinstrs should 250// print out the code after the passes. 251void MipsPassConfig::addPreEmitPass() { 252 MipsTargetMachine &TM = getMipsTargetMachine(); 253 addPass(createMipsDelaySlotFillerPass(TM)); 254 addPass(createMipsLongBranchPass(TM)); 255 addPass(createMipsConstantIslandPass(TM)); 256} 257