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