Home | History | Annotate | Download | only in Mips
      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 
     35 using namespace llvm;
     36 
     37 #define DEBUG_TYPE "mips"
     38 
     39 extern "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 
     47 static 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.
     85 MipsTargetMachine::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 
    103 MipsTargetMachine::~MipsTargetMachine() {}
    104 
    105 void MipsebTargetMachine::anchor() { }
    106 
    107 MipsebTargetMachine::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 
    114 void MipselTargetMachine::anchor() { }
    115 
    116 MipselTargetMachine::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 
    123 const MipsSubtarget *
    124 MipsTargetMachine::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 
    165 void 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 
    173 namespace {
    174 /// Mips Code Generator Pass Configuration Options.
    175 class MipsPassConfig : public TargetPassConfig {
    176 public:
    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 
    204 TargetPassConfig *MipsTargetMachine::createPassConfig(PassManagerBase &PM) {
    205   return new MipsPassConfig(this, PM);
    206 }
    207 
    208 void 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.
    218 bool MipsPassConfig::addInstSelector() {
    219   addPass(createMipsModuleISelDagPass(getMipsTargetMachine()));
    220   addPass(createMips16ISelDag(getMipsTargetMachine()));
    221   addPass(createMipsSEISelDag(getMipsTargetMachine()));
    222   return false;
    223 }
    224 
    225 void MipsPassConfig::addMachineSSAOptimization() {
    226   addPass(createMipsOptimizePICCallPass(getMipsTargetMachine()));
    227   TargetPassConfig::addMachineSSAOptimization();
    228 }
    229 
    230 void MipsPassConfig::addPreRegAlloc() {
    231   if (getOptLevel() == CodeGenOpt::None)
    232     addPass(createMipsOptimizePICCallPass(getMipsTargetMachine()));
    233 }
    234 
    235 TargetIRAnalysis MipsTargetMachine::getTargetIRAnalysis() {
    236   return TargetIRAnalysis([this](const 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.
    251 void MipsPassConfig::addPreEmitPass() {
    252   MipsTargetMachine &TM = getMipsTargetMachine();
    253   addPass(createMipsDelaySlotFillerPass(TM));
    254   addPass(createMipsLongBranchPass(TM));
    255   addPass(createMipsConstantIslandPass(TM));
    256 }
    257