MipsTargetMachine.cpp revision ebe69fe11e48d322045d5949c83283927a0d790b
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 "Mips16HardFloat.h" 18#include "Mips16ISelDAGToDAG.h" 19#include "Mips16ISelLowering.h" 20#include "Mips16InstrInfo.h" 21#include "MipsFrameLowering.h" 22#include "MipsInstrInfo.h" 23#include "MipsModuleISelDAGToDAG.h" 24#include "MipsOs16.h" 25#include "MipsSEFrameLowering.h" 26#include "MipsSEISelDAGToDAG.h" 27#include "MipsSEISelLowering.h" 28#include "MipsSEInstrInfo.h" 29#include "MipsTargetObjectFile.h" 30#include "llvm/Analysis/TargetTransformInfo.h" 31#include "llvm/CodeGen/Passes.h" 32#include "llvm/IR/LegacyPassManager.h" 33#include "llvm/Support/Debug.h" 34#include "llvm/Support/TargetRegistry.h" 35#include "llvm/Support/raw_ostream.h" 36#include "llvm/Transforms/Scalar.h" 37using namespace llvm; 38 39#define DEBUG_TYPE "mips" 40 41extern "C" void LLVMInitializeMipsTarget() { 42 // Register the target. 43 RegisterTargetMachine<MipsebTargetMachine> X(TheMipsTarget); 44 RegisterTargetMachine<MipselTargetMachine> Y(TheMipselTarget); 45 RegisterTargetMachine<MipsebTargetMachine> A(TheMips64Target); 46 RegisterTargetMachine<MipselTargetMachine> B(TheMips64elTarget); 47} 48 49static std::string computeDataLayout(bool isLittle, MipsABIInfo &ABI) { 50 std::string Ret = ""; 51 52 // There are both little and big endian mips. 53 if (isLittle) 54 Ret += "e"; 55 else 56 Ret += "E"; 57 58 Ret += "-m:m"; 59 60 // Pointers are 32 bit on some ABIs. 61 if (!ABI.IsN64()) 62 Ret += "-p:32:32"; 63 64 // 8 and 16 bit integers only need no have natural alignment, but try to 65 // align them to 32 bits. 64 bit integers have natural alignment. 66 Ret += "-i8:8:32-i16:16:32-i64:64"; 67 68 // 32 bit registers are always available and the stack is at least 64 bit 69 // aligned. On N64 64 bit registers are also available and the stack is 70 // 128 bit aligned. 71 if (ABI.IsN64() || ABI.IsN32()) 72 Ret += "-n32:64-S128"; 73 else 74 Ret += "-n32-S64"; 75 76 return Ret; 77} 78 79// On function prologue, the stack is created by decrementing 80// its pointer. Once decremented, all references are done with positive 81// offset from the stack/frame pointer, using StackGrowsUp enables 82// an easier handling. 83// Using CodeModel::Large enables different CALL behavior. 84MipsTargetMachine::MipsTargetMachine(const Target &T, StringRef TT, 85 StringRef CPU, StringRef FS, 86 const TargetOptions &Options, 87 Reloc::Model RM, CodeModel::Model CM, 88 CodeGenOpt::Level OL, bool isLittle) 89 : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL), 90 isLittle(isLittle), TLOF(make_unique<MipsTargetObjectFile>()), 91 ABI(MipsABIInfo::computeTargetABI(Triple(TT), CPU, Options.MCOptions)), 92 DL(computeDataLayout(isLittle, ABI)), Subtarget(nullptr), 93 DefaultSubtarget(TT, CPU, FS, isLittle, *this), 94 NoMips16Subtarget(TT, CPU, FS.empty() ? "-mips16" : FS.str() + ",-mips16", 95 isLittle, *this), 96 Mips16Subtarget(TT, CPU, FS.empty() ? "+mips16" : FS.str() + ",+mips16", 97 isLittle, *this) { 98 Subtarget = &DefaultSubtarget; 99 initAsmInfo(); 100} 101 102MipsTargetMachine::~MipsTargetMachine() {} 103 104void MipsebTargetMachine::anchor() { } 105 106MipsebTargetMachine:: 107MipsebTargetMachine(const Target &T, StringRef TT, 108 StringRef CPU, StringRef FS, const TargetOptions &Options, 109 Reloc::Model RM, CodeModel::Model CM, 110 CodeGenOpt::Level OL) 111 : MipsTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, false) {} 112 113void MipselTargetMachine::anchor() { } 114 115MipselTargetMachine:: 116MipselTargetMachine(const Target &T, StringRef TT, 117 StringRef CPU, StringRef FS, const TargetOptions &Options, 118 Reloc::Model RM, CodeModel::Model CM, 119 CodeGenOpt::Level OL) 120 : MipsTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) {} 121 122const MipsSubtarget * 123MipsTargetMachine::getSubtargetImpl(const Function &F) const { 124 Attribute CPUAttr = F.getFnAttribute("target-cpu"); 125 Attribute FSAttr = F.getFnAttribute("target-features"); 126 127 std::string CPU = !CPUAttr.hasAttribute(Attribute::None) 128 ? CPUAttr.getValueAsString().str() 129 : TargetCPU; 130 std::string FS = !FSAttr.hasAttribute(Attribute::None) 131 ? FSAttr.getValueAsString().str() 132 : TargetFS; 133 bool hasMips16Attr = 134 !F.getFnAttribute("mips16").hasAttribute(Attribute::None); 135 bool hasNoMips16Attr = 136 !F.getFnAttribute("nomips16").hasAttribute(Attribute::None); 137 138 // FIXME: This is related to the code below to reset the target options, 139 // we need to know whether or not the soft float flag is set on the 140 // function before we can generate a subtarget. We also need to use 141 // it as a key for the subtarget since that can be the only difference 142 // between two functions. 143 Attribute SFAttr = F.getFnAttribute("use-soft-float"); 144 bool softFloat = !SFAttr.hasAttribute(Attribute::None) 145 ? SFAttr.getValueAsString() == "true" 146 : Options.UseSoftFloat; 147 148 if (hasMips16Attr) 149 FS += FS.empty() ? "+mips16" : ",+mips16"; 150 else if (hasNoMips16Attr) 151 FS += FS.empty() ? "-mips16" : ",-mips16"; 152 153 auto &I = SubtargetMap[CPU + FS + (softFloat ? "use-soft-float=true" 154 : "use-soft-float=false")]; 155 if (!I) { 156 // This needs to be done before we create a new subtarget since any 157 // creation will depend on the TM and the code generation flags on the 158 // function that reside in TargetOptions. 159 resetTargetOptions(F); 160 I = llvm::make_unique<MipsSubtarget>(TargetTriple, CPU, FS, isLittle, *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(createMipsOs16(getMipsTargetMachine())); 213 if (getMipsSubtarget().inMips16HardFloat()) 214 addPass(createMips16HardFloat(getMipsTargetMachine())); 215} 216// Install an instruction selector pass using 217// the ISelDag to gen Mips code. 218bool MipsPassConfig::addInstSelector() { 219 addPass(createMipsModuleISelDag(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(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