1*0b57cec5SDimitry Andric //===-- MipsTargetMachine.cpp - Define TargetMachine for Mips -------------===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric // 9*0b57cec5SDimitry Andric // Implements the info about Mips target spec. 10*0b57cec5SDimitry Andric // 11*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 12*0b57cec5SDimitry Andric 13*0b57cec5SDimitry Andric #include "MipsTargetMachine.h" 14*0b57cec5SDimitry Andric #include "MCTargetDesc/MipsABIInfo.h" 15*0b57cec5SDimitry Andric #include "MCTargetDesc/MipsMCTargetDesc.h" 16*0b57cec5SDimitry Andric #include "Mips.h" 17*0b57cec5SDimitry Andric #include "Mips16ISelDAGToDAG.h" 18*0b57cec5SDimitry Andric #include "MipsSEISelDAGToDAG.h" 19*0b57cec5SDimitry Andric #include "MipsSubtarget.h" 20*0b57cec5SDimitry Andric #include "MipsTargetObjectFile.h" 21*0b57cec5SDimitry Andric #include "TargetInfo/MipsTargetInfo.h" 22*0b57cec5SDimitry Andric #include "llvm/ADT/Optional.h" 23*0b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h" 24*0b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 25*0b57cec5SDimitry Andric #include "llvm/Analysis/TargetTransformInfo.h" 26*0b57cec5SDimitry Andric #include "llvm/CodeGen/GlobalISel/IRTranslator.h" 27*0b57cec5SDimitry Andric #include "llvm/CodeGen/GlobalISel/Legalizer.h" 28*0b57cec5SDimitry Andric #include "llvm/CodeGen/GlobalISel/RegBankSelect.h" 29*0b57cec5SDimitry Andric #include "llvm/CodeGen/GlobalISel/InstructionSelect.h" 30*0b57cec5SDimitry Andric #include "llvm/CodeGen/BasicTTIImpl.h" 31*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h" 32*0b57cec5SDimitry Andric #include "llvm/CodeGen/Passes.h" 33*0b57cec5SDimitry Andric #include "llvm/CodeGen/TargetPassConfig.h" 34*0b57cec5SDimitry Andric #include "llvm/IR/Attributes.h" 35*0b57cec5SDimitry Andric #include "llvm/IR/Function.h" 36*0b57cec5SDimitry Andric #include "llvm/Support/CodeGen.h" 37*0b57cec5SDimitry Andric #include "llvm/Support/Debug.h" 38*0b57cec5SDimitry Andric #include "llvm/Support/TargetRegistry.h" 39*0b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 40*0b57cec5SDimitry Andric #include "llvm/Target/TargetOptions.h" 41*0b57cec5SDimitry Andric #include <string> 42*0b57cec5SDimitry Andric 43*0b57cec5SDimitry Andric using namespace llvm; 44*0b57cec5SDimitry Andric 45*0b57cec5SDimitry Andric #define DEBUG_TYPE "mips" 46*0b57cec5SDimitry Andric 47*0b57cec5SDimitry Andric extern "C" void LLVMInitializeMipsTarget() { 48*0b57cec5SDimitry Andric // Register the target. 49*0b57cec5SDimitry Andric RegisterTargetMachine<MipsebTargetMachine> X(getTheMipsTarget()); 50*0b57cec5SDimitry Andric RegisterTargetMachine<MipselTargetMachine> Y(getTheMipselTarget()); 51*0b57cec5SDimitry Andric RegisterTargetMachine<MipsebTargetMachine> A(getTheMips64Target()); 52*0b57cec5SDimitry Andric RegisterTargetMachine<MipselTargetMachine> B(getTheMips64elTarget()); 53*0b57cec5SDimitry Andric 54*0b57cec5SDimitry Andric PassRegistry *PR = PassRegistry::getPassRegistry(); 55*0b57cec5SDimitry Andric initializeGlobalISel(*PR); 56*0b57cec5SDimitry Andric initializeMipsDelaySlotFillerPass(*PR); 57*0b57cec5SDimitry Andric initializeMipsBranchExpansionPass(*PR); 58*0b57cec5SDimitry Andric initializeMicroMipsSizeReducePass(*PR); 59*0b57cec5SDimitry Andric initializeMipsPreLegalizerCombinerPass(*PR); 60*0b57cec5SDimitry Andric } 61*0b57cec5SDimitry Andric 62*0b57cec5SDimitry Andric static std::string computeDataLayout(const Triple &TT, StringRef CPU, 63*0b57cec5SDimitry Andric const TargetOptions &Options, 64*0b57cec5SDimitry Andric bool isLittle) { 65*0b57cec5SDimitry Andric std::string Ret; 66*0b57cec5SDimitry Andric MipsABIInfo ABI = MipsABIInfo::computeTargetABI(TT, CPU, Options.MCOptions); 67*0b57cec5SDimitry Andric 68*0b57cec5SDimitry Andric // There are both little and big endian mips. 69*0b57cec5SDimitry Andric if (isLittle) 70*0b57cec5SDimitry Andric Ret += "e"; 71*0b57cec5SDimitry Andric else 72*0b57cec5SDimitry Andric Ret += "E"; 73*0b57cec5SDimitry Andric 74*0b57cec5SDimitry Andric if (ABI.IsO32()) 75*0b57cec5SDimitry Andric Ret += "-m:m"; 76*0b57cec5SDimitry Andric else 77*0b57cec5SDimitry Andric Ret += "-m:e"; 78*0b57cec5SDimitry Andric 79*0b57cec5SDimitry Andric // Pointers are 32 bit on some ABIs. 80*0b57cec5SDimitry Andric if (!ABI.IsN64()) 81*0b57cec5SDimitry Andric Ret += "-p:32:32"; 82*0b57cec5SDimitry Andric 83*0b57cec5SDimitry Andric // 8 and 16 bit integers only need to have natural alignment, but try to 84*0b57cec5SDimitry Andric // align them to 32 bits. 64 bit integers have natural alignment. 85*0b57cec5SDimitry Andric Ret += "-i8:8:32-i16:16:32-i64:64"; 86*0b57cec5SDimitry Andric 87*0b57cec5SDimitry Andric // 32 bit registers are always available and the stack is at least 64 bit 88*0b57cec5SDimitry Andric // aligned. On N64 64 bit registers are also available and the stack is 89*0b57cec5SDimitry Andric // 128 bit aligned. 90*0b57cec5SDimitry Andric if (ABI.IsN64() || ABI.IsN32()) 91*0b57cec5SDimitry Andric Ret += "-n32:64-S128"; 92*0b57cec5SDimitry Andric else 93*0b57cec5SDimitry Andric Ret += "-n32-S64"; 94*0b57cec5SDimitry Andric 95*0b57cec5SDimitry Andric return Ret; 96*0b57cec5SDimitry Andric } 97*0b57cec5SDimitry Andric 98*0b57cec5SDimitry Andric static Reloc::Model getEffectiveRelocModel(bool JIT, 99*0b57cec5SDimitry Andric Optional<Reloc::Model> RM) { 100*0b57cec5SDimitry Andric if (!RM.hasValue() || JIT) 101*0b57cec5SDimitry Andric return Reloc::Static; 102*0b57cec5SDimitry Andric return *RM; 103*0b57cec5SDimitry Andric } 104*0b57cec5SDimitry Andric 105*0b57cec5SDimitry Andric // On function prologue, the stack is created by decrementing 106*0b57cec5SDimitry Andric // its pointer. Once decremented, all references are done with positive 107*0b57cec5SDimitry Andric // offset from the stack/frame pointer, using StackGrowsUp enables 108*0b57cec5SDimitry Andric // an easier handling. 109*0b57cec5SDimitry Andric // Using CodeModel::Large enables different CALL behavior. 110*0b57cec5SDimitry Andric MipsTargetMachine::MipsTargetMachine(const Target &T, const Triple &TT, 111*0b57cec5SDimitry Andric StringRef CPU, StringRef FS, 112*0b57cec5SDimitry Andric const TargetOptions &Options, 113*0b57cec5SDimitry Andric Optional<Reloc::Model> RM, 114*0b57cec5SDimitry Andric Optional<CodeModel::Model> CM, 115*0b57cec5SDimitry Andric CodeGenOpt::Level OL, bool JIT, 116*0b57cec5SDimitry Andric bool isLittle) 117*0b57cec5SDimitry Andric : LLVMTargetMachine(T, computeDataLayout(TT, CPU, Options, isLittle), TT, 118*0b57cec5SDimitry Andric CPU, FS, Options, getEffectiveRelocModel(JIT, RM), 119*0b57cec5SDimitry Andric getEffectiveCodeModel(CM, CodeModel::Small), OL), 120*0b57cec5SDimitry Andric isLittle(isLittle), TLOF(llvm::make_unique<MipsTargetObjectFile>()), 121*0b57cec5SDimitry Andric ABI(MipsABIInfo::computeTargetABI(TT, CPU, Options.MCOptions)), 122*0b57cec5SDimitry Andric Subtarget(nullptr), DefaultSubtarget(TT, CPU, FS, isLittle, *this, 123*0b57cec5SDimitry Andric Options.StackAlignmentOverride), 124*0b57cec5SDimitry Andric NoMips16Subtarget(TT, CPU, FS.empty() ? "-mips16" : FS.str() + ",-mips16", 125*0b57cec5SDimitry Andric isLittle, *this, Options.StackAlignmentOverride), 126*0b57cec5SDimitry Andric Mips16Subtarget(TT, CPU, FS.empty() ? "+mips16" : FS.str() + ",+mips16", 127*0b57cec5SDimitry Andric isLittle, *this, Options.StackAlignmentOverride) { 128*0b57cec5SDimitry Andric Subtarget = &DefaultSubtarget; 129*0b57cec5SDimitry Andric initAsmInfo(); 130*0b57cec5SDimitry Andric } 131*0b57cec5SDimitry Andric 132*0b57cec5SDimitry Andric MipsTargetMachine::~MipsTargetMachine() = default; 133*0b57cec5SDimitry Andric 134*0b57cec5SDimitry Andric void MipsebTargetMachine::anchor() {} 135*0b57cec5SDimitry Andric 136*0b57cec5SDimitry Andric MipsebTargetMachine::MipsebTargetMachine(const Target &T, const Triple &TT, 137*0b57cec5SDimitry Andric StringRef CPU, StringRef FS, 138*0b57cec5SDimitry Andric const TargetOptions &Options, 139*0b57cec5SDimitry Andric Optional<Reloc::Model> RM, 140*0b57cec5SDimitry Andric Optional<CodeModel::Model> CM, 141*0b57cec5SDimitry Andric CodeGenOpt::Level OL, bool JIT) 142*0b57cec5SDimitry Andric : MipsTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, JIT, false) {} 143*0b57cec5SDimitry Andric 144*0b57cec5SDimitry Andric void MipselTargetMachine::anchor() {} 145*0b57cec5SDimitry Andric 146*0b57cec5SDimitry Andric MipselTargetMachine::MipselTargetMachine(const Target &T, const Triple &TT, 147*0b57cec5SDimitry Andric StringRef CPU, StringRef FS, 148*0b57cec5SDimitry Andric const TargetOptions &Options, 149*0b57cec5SDimitry Andric Optional<Reloc::Model> RM, 150*0b57cec5SDimitry Andric Optional<CodeModel::Model> CM, 151*0b57cec5SDimitry Andric CodeGenOpt::Level OL, bool JIT) 152*0b57cec5SDimitry Andric : MipsTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, JIT, true) {} 153*0b57cec5SDimitry Andric 154*0b57cec5SDimitry Andric const MipsSubtarget * 155*0b57cec5SDimitry Andric MipsTargetMachine::getSubtargetImpl(const Function &F) const { 156*0b57cec5SDimitry Andric Attribute CPUAttr = F.getFnAttribute("target-cpu"); 157*0b57cec5SDimitry Andric Attribute FSAttr = F.getFnAttribute("target-features"); 158*0b57cec5SDimitry Andric 159*0b57cec5SDimitry Andric std::string CPU = !CPUAttr.hasAttribute(Attribute::None) 160*0b57cec5SDimitry Andric ? CPUAttr.getValueAsString().str() 161*0b57cec5SDimitry Andric : TargetCPU; 162*0b57cec5SDimitry Andric std::string FS = !FSAttr.hasAttribute(Attribute::None) 163*0b57cec5SDimitry Andric ? FSAttr.getValueAsString().str() 164*0b57cec5SDimitry Andric : TargetFS; 165*0b57cec5SDimitry Andric bool hasMips16Attr = 166*0b57cec5SDimitry Andric !F.getFnAttribute("mips16").hasAttribute(Attribute::None); 167*0b57cec5SDimitry Andric bool hasNoMips16Attr = 168*0b57cec5SDimitry Andric !F.getFnAttribute("nomips16").hasAttribute(Attribute::None); 169*0b57cec5SDimitry Andric 170*0b57cec5SDimitry Andric bool HasMicroMipsAttr = 171*0b57cec5SDimitry Andric !F.getFnAttribute("micromips").hasAttribute(Attribute::None); 172*0b57cec5SDimitry Andric bool HasNoMicroMipsAttr = 173*0b57cec5SDimitry Andric !F.getFnAttribute("nomicromips").hasAttribute(Attribute::None); 174*0b57cec5SDimitry Andric 175*0b57cec5SDimitry Andric // FIXME: This is related to the code below to reset the target options, 176*0b57cec5SDimitry Andric // we need to know whether or not the soft float flag is set on the 177*0b57cec5SDimitry Andric // function, so we can enable it as a subtarget feature. 178*0b57cec5SDimitry Andric bool softFloat = 179*0b57cec5SDimitry Andric F.hasFnAttribute("use-soft-float") && 180*0b57cec5SDimitry Andric F.getFnAttribute("use-soft-float").getValueAsString() == "true"; 181*0b57cec5SDimitry Andric 182*0b57cec5SDimitry Andric if (hasMips16Attr) 183*0b57cec5SDimitry Andric FS += FS.empty() ? "+mips16" : ",+mips16"; 184*0b57cec5SDimitry Andric else if (hasNoMips16Attr) 185*0b57cec5SDimitry Andric FS += FS.empty() ? "-mips16" : ",-mips16"; 186*0b57cec5SDimitry Andric if (HasMicroMipsAttr) 187*0b57cec5SDimitry Andric FS += FS.empty() ? "+micromips" : ",+micromips"; 188*0b57cec5SDimitry Andric else if (HasNoMicroMipsAttr) 189*0b57cec5SDimitry Andric FS += FS.empty() ? "-micromips" : ",-micromips"; 190*0b57cec5SDimitry Andric if (softFloat) 191*0b57cec5SDimitry Andric FS += FS.empty() ? "+soft-float" : ",+soft-float"; 192*0b57cec5SDimitry Andric 193*0b57cec5SDimitry Andric auto &I = SubtargetMap[CPU + FS]; 194*0b57cec5SDimitry Andric if (!I) { 195*0b57cec5SDimitry Andric // This needs to be done before we create a new subtarget since any 196*0b57cec5SDimitry Andric // creation will depend on the TM and the code generation flags on the 197*0b57cec5SDimitry Andric // function that reside in TargetOptions. 198*0b57cec5SDimitry Andric resetTargetOptions(F); 199*0b57cec5SDimitry Andric I = llvm::make_unique<MipsSubtarget>(TargetTriple, CPU, FS, isLittle, *this, 200*0b57cec5SDimitry Andric Options.StackAlignmentOverride); 201*0b57cec5SDimitry Andric } 202*0b57cec5SDimitry Andric return I.get(); 203*0b57cec5SDimitry Andric } 204*0b57cec5SDimitry Andric 205*0b57cec5SDimitry Andric void MipsTargetMachine::resetSubtarget(MachineFunction *MF) { 206*0b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "resetSubtarget\n"); 207*0b57cec5SDimitry Andric 208*0b57cec5SDimitry Andric Subtarget = &MF->getSubtarget<MipsSubtarget>(); 209*0b57cec5SDimitry Andric } 210*0b57cec5SDimitry Andric 211*0b57cec5SDimitry Andric namespace { 212*0b57cec5SDimitry Andric 213*0b57cec5SDimitry Andric /// Mips Code Generator Pass Configuration Options. 214*0b57cec5SDimitry Andric class MipsPassConfig : public TargetPassConfig { 215*0b57cec5SDimitry Andric public: 216*0b57cec5SDimitry Andric MipsPassConfig(MipsTargetMachine &TM, PassManagerBase &PM) 217*0b57cec5SDimitry Andric : TargetPassConfig(TM, PM) { 218*0b57cec5SDimitry Andric // The current implementation of long branch pass requires a scratch 219*0b57cec5SDimitry Andric // register ($at) to be available before branch instructions. Tail merging 220*0b57cec5SDimitry Andric // can break this requirement, so disable it when long branch pass is 221*0b57cec5SDimitry Andric // enabled. 222*0b57cec5SDimitry Andric EnableTailMerge = !getMipsSubtarget().enableLongBranchPass(); 223*0b57cec5SDimitry Andric } 224*0b57cec5SDimitry Andric 225*0b57cec5SDimitry Andric MipsTargetMachine &getMipsTargetMachine() const { 226*0b57cec5SDimitry Andric return getTM<MipsTargetMachine>(); 227*0b57cec5SDimitry Andric } 228*0b57cec5SDimitry Andric 229*0b57cec5SDimitry Andric const MipsSubtarget &getMipsSubtarget() const { 230*0b57cec5SDimitry Andric return *getMipsTargetMachine().getSubtargetImpl(); 231*0b57cec5SDimitry Andric } 232*0b57cec5SDimitry Andric 233*0b57cec5SDimitry Andric void addIRPasses() override; 234*0b57cec5SDimitry Andric bool addInstSelector() override; 235*0b57cec5SDimitry Andric void addPreEmitPass() override; 236*0b57cec5SDimitry Andric void addPreRegAlloc() override; 237*0b57cec5SDimitry Andric bool addIRTranslator() override; 238*0b57cec5SDimitry Andric void addPreLegalizeMachineIR() override; 239*0b57cec5SDimitry Andric bool addLegalizeMachineIR() override; 240*0b57cec5SDimitry Andric bool addRegBankSelect() override; 241*0b57cec5SDimitry Andric bool addGlobalInstructionSelect() override; 242*0b57cec5SDimitry Andric 243*0b57cec5SDimitry Andric std::unique_ptr<CSEConfigBase> getCSEConfig() const override; 244*0b57cec5SDimitry Andric }; 245*0b57cec5SDimitry Andric 246*0b57cec5SDimitry Andric } // end anonymous namespace 247*0b57cec5SDimitry Andric 248*0b57cec5SDimitry Andric TargetPassConfig *MipsTargetMachine::createPassConfig(PassManagerBase &PM) { 249*0b57cec5SDimitry Andric return new MipsPassConfig(*this, PM); 250*0b57cec5SDimitry Andric } 251*0b57cec5SDimitry Andric 252*0b57cec5SDimitry Andric std::unique_ptr<CSEConfigBase> MipsPassConfig::getCSEConfig() const { 253*0b57cec5SDimitry Andric return getStandardCSEConfigForOpt(TM->getOptLevel()); 254*0b57cec5SDimitry Andric } 255*0b57cec5SDimitry Andric 256*0b57cec5SDimitry Andric void MipsPassConfig::addIRPasses() { 257*0b57cec5SDimitry Andric TargetPassConfig::addIRPasses(); 258*0b57cec5SDimitry Andric addPass(createAtomicExpandPass()); 259*0b57cec5SDimitry Andric if (getMipsSubtarget().os16()) 260*0b57cec5SDimitry Andric addPass(createMipsOs16Pass()); 261*0b57cec5SDimitry Andric if (getMipsSubtarget().inMips16HardFloat()) 262*0b57cec5SDimitry Andric addPass(createMips16HardFloatPass()); 263*0b57cec5SDimitry Andric } 264*0b57cec5SDimitry Andric // Install an instruction selector pass using 265*0b57cec5SDimitry Andric // the ISelDag to gen Mips code. 266*0b57cec5SDimitry Andric bool MipsPassConfig::addInstSelector() { 267*0b57cec5SDimitry Andric addPass(createMipsModuleISelDagPass()); 268*0b57cec5SDimitry Andric addPass(createMips16ISelDag(getMipsTargetMachine(), getOptLevel())); 269*0b57cec5SDimitry Andric addPass(createMipsSEISelDag(getMipsTargetMachine(), getOptLevel())); 270*0b57cec5SDimitry Andric return false; 271*0b57cec5SDimitry Andric } 272*0b57cec5SDimitry Andric 273*0b57cec5SDimitry Andric void MipsPassConfig::addPreRegAlloc() { 274*0b57cec5SDimitry Andric addPass(createMipsOptimizePICCallPass()); 275*0b57cec5SDimitry Andric } 276*0b57cec5SDimitry Andric 277*0b57cec5SDimitry Andric TargetTransformInfo 278*0b57cec5SDimitry Andric MipsTargetMachine::getTargetTransformInfo(const Function &F) { 279*0b57cec5SDimitry Andric if (Subtarget->allowMixed16_32()) { 280*0b57cec5SDimitry Andric LLVM_DEBUG(errs() << "No Target Transform Info Pass Added\n"); 281*0b57cec5SDimitry Andric // FIXME: This is no longer necessary as the TTI returned is per-function. 282*0b57cec5SDimitry Andric return TargetTransformInfo(F.getParent()->getDataLayout()); 283*0b57cec5SDimitry Andric } 284*0b57cec5SDimitry Andric 285*0b57cec5SDimitry Andric LLVM_DEBUG(errs() << "Target Transform Info Pass Added\n"); 286*0b57cec5SDimitry Andric return TargetTransformInfo(BasicTTIImpl(this, F)); 287*0b57cec5SDimitry Andric } 288*0b57cec5SDimitry Andric 289*0b57cec5SDimitry Andric // Implemented by targets that want to run passes immediately before 290*0b57cec5SDimitry Andric // machine code is emitted. return true if -print-machineinstrs should 291*0b57cec5SDimitry Andric // print out the code after the passes. 292*0b57cec5SDimitry Andric void MipsPassConfig::addPreEmitPass() { 293*0b57cec5SDimitry Andric // Expand pseudo instructions that are sensitive to register allocation. 294*0b57cec5SDimitry Andric addPass(createMipsExpandPseudoPass()); 295*0b57cec5SDimitry Andric 296*0b57cec5SDimitry Andric // The microMIPS size reduction pass performs instruction reselection for 297*0b57cec5SDimitry Andric // instructions which can be remapped to a 16 bit instruction. 298*0b57cec5SDimitry Andric addPass(createMicroMipsSizeReducePass()); 299*0b57cec5SDimitry Andric 300*0b57cec5SDimitry Andric // The delay slot filler pass can potientially create forbidden slot hazards 301*0b57cec5SDimitry Andric // for MIPSR6 and therefore it should go before MipsBranchExpansion pass. 302*0b57cec5SDimitry Andric addPass(createMipsDelaySlotFillerPass()); 303*0b57cec5SDimitry Andric 304*0b57cec5SDimitry Andric // This pass expands branches and takes care about the forbidden slot hazards. 305*0b57cec5SDimitry Andric // Expanding branches may potentially create forbidden slot hazards for 306*0b57cec5SDimitry Andric // MIPSR6, and fixing such hazard may potentially break a branch by extending 307*0b57cec5SDimitry Andric // its offset out of range. That's why this pass combine these two tasks, and 308*0b57cec5SDimitry Andric // runs them alternately until one of them finishes without any changes. Only 309*0b57cec5SDimitry Andric // then we can be sure that all branches are expanded properly and no hazards 310*0b57cec5SDimitry Andric // exists. 311*0b57cec5SDimitry Andric // Any new pass should go before this pass. 312*0b57cec5SDimitry Andric addPass(createMipsBranchExpansion()); 313*0b57cec5SDimitry Andric 314*0b57cec5SDimitry Andric addPass(createMipsConstantIslandPass()); 315*0b57cec5SDimitry Andric } 316*0b57cec5SDimitry Andric 317*0b57cec5SDimitry Andric bool MipsPassConfig::addIRTranslator() { 318*0b57cec5SDimitry Andric addPass(new IRTranslator()); 319*0b57cec5SDimitry Andric return false; 320*0b57cec5SDimitry Andric } 321*0b57cec5SDimitry Andric 322*0b57cec5SDimitry Andric void MipsPassConfig::addPreLegalizeMachineIR() { 323*0b57cec5SDimitry Andric addPass(createMipsPreLegalizeCombiner()); 324*0b57cec5SDimitry Andric } 325*0b57cec5SDimitry Andric 326*0b57cec5SDimitry Andric bool MipsPassConfig::addLegalizeMachineIR() { 327*0b57cec5SDimitry Andric addPass(new Legalizer()); 328*0b57cec5SDimitry Andric return false; 329*0b57cec5SDimitry Andric } 330*0b57cec5SDimitry Andric 331*0b57cec5SDimitry Andric bool MipsPassConfig::addRegBankSelect() { 332*0b57cec5SDimitry Andric addPass(new RegBankSelect()); 333*0b57cec5SDimitry Andric return false; 334*0b57cec5SDimitry Andric } 335*0b57cec5SDimitry Andric 336*0b57cec5SDimitry Andric bool MipsPassConfig::addGlobalInstructionSelect() { 337*0b57cec5SDimitry Andric addPass(new InstructionSelect()); 338*0b57cec5SDimitry Andric return false; 339*0b57cec5SDimitry Andric } 340