10b57cec5SDimitry Andric //===-- MipsTargetMachine.cpp - Define TargetMachine for Mips -------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // Implements the info about Mips target spec. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #include "MipsTargetMachine.h" 140b57cec5SDimitry Andric #include "MCTargetDesc/MipsABIInfo.h" 150b57cec5SDimitry Andric #include "MCTargetDesc/MipsMCTargetDesc.h" 160b57cec5SDimitry Andric #include "Mips.h" 170b57cec5SDimitry Andric #include "Mips16ISelDAGToDAG.h" 18bdd1243dSDimitry Andric #include "MipsMachineFunction.h" 190b57cec5SDimitry Andric #include "MipsSEISelDAGToDAG.h" 200b57cec5SDimitry Andric #include "MipsSubtarget.h" 210b57cec5SDimitry Andric #include "MipsTargetObjectFile.h" 2281ad6265SDimitry Andric #include "MipsTargetTransformInfo.h" 230b57cec5SDimitry Andric #include "TargetInfo/MipsTargetInfo.h" 240b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h" 250b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 260b57cec5SDimitry Andric #include "llvm/Analysis/TargetTransformInfo.h" 27480093f4SDimitry Andric #include "llvm/CodeGen/BasicTTIImpl.h" 2881ad6265SDimitry Andric #include "llvm/CodeGen/GlobalISel/CSEInfo.h" 290b57cec5SDimitry Andric #include "llvm/CodeGen/GlobalISel/IRTranslator.h" 30480093f4SDimitry Andric #include "llvm/CodeGen/GlobalISel/InstructionSelect.h" 310b57cec5SDimitry Andric #include "llvm/CodeGen/GlobalISel/Legalizer.h" 320b57cec5SDimitry Andric #include "llvm/CodeGen/GlobalISel/RegBankSelect.h" 330b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h" 340b57cec5SDimitry Andric #include "llvm/CodeGen/Passes.h" 350b57cec5SDimitry Andric #include "llvm/CodeGen/TargetPassConfig.h" 360b57cec5SDimitry Andric #include "llvm/IR/Attributes.h" 370b57cec5SDimitry Andric #include "llvm/IR/Function.h" 38480093f4SDimitry Andric #include "llvm/InitializePasses.h" 39349cc55cSDimitry Andric #include "llvm/MC/TargetRegistry.h" 400b57cec5SDimitry Andric #include "llvm/Support/CodeGen.h" 410b57cec5SDimitry Andric #include "llvm/Support/Debug.h" 420b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 430b57cec5SDimitry Andric #include "llvm/Target/TargetOptions.h" 44bdd1243dSDimitry Andric #include <optional> 450b57cec5SDimitry Andric #include <string> 460b57cec5SDimitry Andric 470b57cec5SDimitry Andric using namespace llvm; 480b57cec5SDimitry Andric 490b57cec5SDimitry Andric #define DEBUG_TYPE "mips" 500b57cec5SDimitry Andric 5104eeddc0SDimitry Andric static cl::opt<bool> 5204eeddc0SDimitry Andric EnableMulMulFix("mfix4300", cl::init(false), 5304eeddc0SDimitry Andric cl::desc("Enable the VR4300 mulmul bug fix."), cl::Hidden); 5404eeddc0SDimitry Andric 55480093f4SDimitry Andric extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeMipsTarget() { 560b57cec5SDimitry Andric // Register the target. 570b57cec5SDimitry Andric RegisterTargetMachine<MipsebTargetMachine> X(getTheMipsTarget()); 580b57cec5SDimitry Andric RegisterTargetMachine<MipselTargetMachine> Y(getTheMipselTarget()); 590b57cec5SDimitry Andric RegisterTargetMachine<MipsebTargetMachine> A(getTheMips64Target()); 600b57cec5SDimitry Andric RegisterTargetMachine<MipselTargetMachine> B(getTheMips64elTarget()); 610b57cec5SDimitry Andric 620b57cec5SDimitry Andric PassRegistry *PR = PassRegistry::getPassRegistry(); 630b57cec5SDimitry Andric initializeGlobalISel(*PR); 640b57cec5SDimitry Andric initializeMipsDelaySlotFillerPass(*PR); 650b57cec5SDimitry Andric initializeMipsBranchExpansionPass(*PR); 660b57cec5SDimitry Andric initializeMicroMipsSizeReducePass(*PR); 670b57cec5SDimitry Andric initializeMipsPreLegalizerCombinerPass(*PR); 6881ad6265SDimitry Andric initializeMipsPostLegalizerCombinerPass(*PR); 6904eeddc0SDimitry Andric initializeMipsMulMulBugFixPass(*PR); 70*0fca6ea1SDimitry Andric initializeMipsDAGToDAGISelLegacyPass(*PR); 710b57cec5SDimitry Andric } 720b57cec5SDimitry Andric 730b57cec5SDimitry Andric static std::string computeDataLayout(const Triple &TT, StringRef CPU, 740b57cec5SDimitry Andric const TargetOptions &Options, 750b57cec5SDimitry Andric bool isLittle) { 760b57cec5SDimitry Andric std::string Ret; 770b57cec5SDimitry Andric MipsABIInfo ABI = MipsABIInfo::computeTargetABI(TT, CPU, Options.MCOptions); 780b57cec5SDimitry Andric 790b57cec5SDimitry Andric // There are both little and big endian mips. 800b57cec5SDimitry Andric if (isLittle) 810b57cec5SDimitry Andric Ret += "e"; 820b57cec5SDimitry Andric else 830b57cec5SDimitry Andric Ret += "E"; 840b57cec5SDimitry Andric 850b57cec5SDimitry Andric if (ABI.IsO32()) 860b57cec5SDimitry Andric Ret += "-m:m"; 870b57cec5SDimitry Andric else 880b57cec5SDimitry Andric Ret += "-m:e"; 890b57cec5SDimitry Andric 900b57cec5SDimitry Andric // Pointers are 32 bit on some ABIs. 910b57cec5SDimitry Andric if (!ABI.IsN64()) 920b57cec5SDimitry Andric Ret += "-p:32:32"; 930b57cec5SDimitry Andric 940b57cec5SDimitry Andric // 8 and 16 bit integers only need to have natural alignment, but try to 950b57cec5SDimitry Andric // align them to 32 bits. 64 bit integers have natural alignment. 960b57cec5SDimitry Andric Ret += "-i8:8:32-i16:16:32-i64:64"; 970b57cec5SDimitry Andric 980b57cec5SDimitry Andric // 32 bit registers are always available and the stack is at least 64 bit 990b57cec5SDimitry Andric // aligned. On N64 64 bit registers are also available and the stack is 1000b57cec5SDimitry Andric // 128 bit aligned. 1010b57cec5SDimitry Andric if (ABI.IsN64() || ABI.IsN32()) 1020b57cec5SDimitry Andric Ret += "-n32:64-S128"; 1030b57cec5SDimitry Andric else 1040b57cec5SDimitry Andric Ret += "-n32-S64"; 1050b57cec5SDimitry Andric 1060b57cec5SDimitry Andric return Ret; 1070b57cec5SDimitry Andric } 1080b57cec5SDimitry Andric 1090b57cec5SDimitry Andric static Reloc::Model getEffectiveRelocModel(bool JIT, 110bdd1243dSDimitry Andric std::optional<Reloc::Model> RM) { 11181ad6265SDimitry Andric if (!RM || JIT) 1120b57cec5SDimitry Andric return Reloc::Static; 1130b57cec5SDimitry Andric return *RM; 1140b57cec5SDimitry Andric } 1150b57cec5SDimitry Andric 1160b57cec5SDimitry Andric // On function prologue, the stack is created by decrementing 1170b57cec5SDimitry Andric // its pointer. Once decremented, all references are done with positive 1180b57cec5SDimitry Andric // offset from the stack/frame pointer, using StackGrowsUp enables 1190b57cec5SDimitry Andric // an easier handling. 1200b57cec5SDimitry Andric // Using CodeModel::Large enables different CALL behavior. 1210b57cec5SDimitry Andric MipsTargetMachine::MipsTargetMachine(const Target &T, const Triple &TT, 1220b57cec5SDimitry Andric StringRef CPU, StringRef FS, 1230b57cec5SDimitry Andric const TargetOptions &Options, 124bdd1243dSDimitry Andric std::optional<Reloc::Model> RM, 125bdd1243dSDimitry Andric std::optional<CodeModel::Model> CM, 1265f757f3fSDimitry Andric CodeGenOptLevel OL, bool JIT, 1270b57cec5SDimitry Andric bool isLittle) 1280b57cec5SDimitry Andric : LLVMTargetMachine(T, computeDataLayout(TT, CPU, Options, isLittle), TT, 1290b57cec5SDimitry Andric CPU, FS, Options, getEffectiveRelocModel(JIT, RM), 1300b57cec5SDimitry Andric getEffectiveCodeModel(CM, CodeModel::Small), OL), 1318bcb0991SDimitry Andric isLittle(isLittle), TLOF(std::make_unique<MipsTargetObjectFile>()), 1320b57cec5SDimitry Andric ABI(MipsABIInfo::computeTargetABI(TT, CPU, Options.MCOptions)), 133bdd1243dSDimitry Andric Subtarget(nullptr), 134bdd1243dSDimitry Andric DefaultSubtarget(TT, CPU, FS, isLittle, *this, std::nullopt), 1350b57cec5SDimitry Andric NoMips16Subtarget(TT, CPU, FS.empty() ? "-mips16" : FS.str() + ",-mips16", 136bdd1243dSDimitry Andric isLittle, *this, std::nullopt), 1370b57cec5SDimitry Andric Mips16Subtarget(TT, CPU, FS.empty() ? "+mips16" : FS.str() + ",+mips16", 138bdd1243dSDimitry Andric isLittle, *this, std::nullopt) { 1390b57cec5SDimitry Andric Subtarget = &DefaultSubtarget; 1400b57cec5SDimitry Andric initAsmInfo(); 1415ffd83dbSDimitry Andric 1425ffd83dbSDimitry Andric // Mips supports the debug entry values. 1435ffd83dbSDimitry Andric setSupportsDebugEntryValues(true); 1440b57cec5SDimitry Andric } 1450b57cec5SDimitry Andric 1460b57cec5SDimitry Andric MipsTargetMachine::~MipsTargetMachine() = default; 1470b57cec5SDimitry Andric 1480b57cec5SDimitry Andric void MipsebTargetMachine::anchor() {} 1490b57cec5SDimitry Andric 1500b57cec5SDimitry Andric MipsebTargetMachine::MipsebTargetMachine(const Target &T, const Triple &TT, 1510b57cec5SDimitry Andric StringRef CPU, StringRef FS, 1520b57cec5SDimitry Andric const TargetOptions &Options, 153bdd1243dSDimitry Andric std::optional<Reloc::Model> RM, 154bdd1243dSDimitry Andric std::optional<CodeModel::Model> CM, 1555f757f3fSDimitry Andric CodeGenOptLevel OL, bool JIT) 1560b57cec5SDimitry Andric : MipsTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, JIT, false) {} 1570b57cec5SDimitry Andric 1580b57cec5SDimitry Andric void MipselTargetMachine::anchor() {} 1590b57cec5SDimitry Andric 1600b57cec5SDimitry Andric MipselTargetMachine::MipselTargetMachine(const Target &T, const Triple &TT, 1610b57cec5SDimitry Andric StringRef CPU, StringRef FS, 1620b57cec5SDimitry Andric const TargetOptions &Options, 163bdd1243dSDimitry Andric std::optional<Reloc::Model> RM, 164bdd1243dSDimitry Andric std::optional<CodeModel::Model> CM, 1655f757f3fSDimitry Andric CodeGenOptLevel OL, bool JIT) 1660b57cec5SDimitry Andric : MipsTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, JIT, true) {} 1670b57cec5SDimitry Andric 1680b57cec5SDimitry Andric const MipsSubtarget * 1690b57cec5SDimitry Andric MipsTargetMachine::getSubtargetImpl(const Function &F) const { 1700b57cec5SDimitry Andric Attribute CPUAttr = F.getFnAttribute("target-cpu"); 1710b57cec5SDimitry Andric Attribute FSAttr = F.getFnAttribute("target-features"); 1720b57cec5SDimitry Andric 173e8d8bef9SDimitry Andric std::string CPU = 174e8d8bef9SDimitry Andric CPUAttr.isValid() ? CPUAttr.getValueAsString().str() : TargetCPU; 175e8d8bef9SDimitry Andric std::string FS = 176e8d8bef9SDimitry Andric FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS; 177e8d8bef9SDimitry Andric bool hasMips16Attr = F.getFnAttribute("mips16").isValid(); 178e8d8bef9SDimitry Andric bool hasNoMips16Attr = F.getFnAttribute("nomips16").isValid(); 1790b57cec5SDimitry Andric 180e8d8bef9SDimitry Andric bool HasMicroMipsAttr = F.getFnAttribute("micromips").isValid(); 181e8d8bef9SDimitry Andric bool HasNoMicroMipsAttr = F.getFnAttribute("nomicromips").isValid(); 1820b57cec5SDimitry Andric 1830b57cec5SDimitry Andric // FIXME: This is related to the code below to reset the target options, 1840b57cec5SDimitry Andric // we need to know whether or not the soft float flag is set on the 1850b57cec5SDimitry Andric // function, so we can enable it as a subtarget feature. 186fe6060f1SDimitry Andric bool softFloat = F.getFnAttribute("use-soft-float").getValueAsBool(); 1870b57cec5SDimitry Andric 1880b57cec5SDimitry Andric if (hasMips16Attr) 1890b57cec5SDimitry Andric FS += FS.empty() ? "+mips16" : ",+mips16"; 1900b57cec5SDimitry Andric else if (hasNoMips16Attr) 1910b57cec5SDimitry Andric FS += FS.empty() ? "-mips16" : ",-mips16"; 1920b57cec5SDimitry Andric if (HasMicroMipsAttr) 1930b57cec5SDimitry Andric FS += FS.empty() ? "+micromips" : ",+micromips"; 1940b57cec5SDimitry Andric else if (HasNoMicroMipsAttr) 1950b57cec5SDimitry Andric FS += FS.empty() ? "-micromips" : ",-micromips"; 1960b57cec5SDimitry Andric if (softFloat) 1970b57cec5SDimitry Andric FS += FS.empty() ? "+soft-float" : ",+soft-float"; 1980b57cec5SDimitry Andric 1990b57cec5SDimitry Andric auto &I = SubtargetMap[CPU + FS]; 2000b57cec5SDimitry Andric if (!I) { 2010b57cec5SDimitry Andric // This needs to be done before we create a new subtarget since any 2020b57cec5SDimitry Andric // creation will depend on the TM and the code generation flags on the 2030b57cec5SDimitry Andric // function that reside in TargetOptions. 2040b57cec5SDimitry Andric resetTargetOptions(F); 2058bcb0991SDimitry Andric I = std::make_unique<MipsSubtarget>( 2068bcb0991SDimitry Andric TargetTriple, CPU, FS, isLittle, *this, 207fe6060f1SDimitry Andric MaybeAlign(F.getParent()->getOverrideStackAlignment())); 2080b57cec5SDimitry Andric } 2090b57cec5SDimitry Andric return I.get(); 2100b57cec5SDimitry Andric } 2110b57cec5SDimitry Andric 2120b57cec5SDimitry Andric void MipsTargetMachine::resetSubtarget(MachineFunction *MF) { 2130b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "resetSubtarget\n"); 2140b57cec5SDimitry Andric 2150b57cec5SDimitry Andric Subtarget = &MF->getSubtarget<MipsSubtarget>(); 2160b57cec5SDimitry Andric } 2170b57cec5SDimitry Andric 2180b57cec5SDimitry Andric namespace { 2190b57cec5SDimitry Andric 2200b57cec5SDimitry Andric /// Mips Code Generator Pass Configuration Options. 2210b57cec5SDimitry Andric class MipsPassConfig : public TargetPassConfig { 2220b57cec5SDimitry Andric public: 2230b57cec5SDimitry Andric MipsPassConfig(MipsTargetMachine &TM, PassManagerBase &PM) 2240b57cec5SDimitry Andric : TargetPassConfig(TM, PM) { 2250b57cec5SDimitry Andric // The current implementation of long branch pass requires a scratch 2260b57cec5SDimitry Andric // register ($at) to be available before branch instructions. Tail merging 2270b57cec5SDimitry Andric // can break this requirement, so disable it when long branch pass is 2280b57cec5SDimitry Andric // enabled. 2290b57cec5SDimitry Andric EnableTailMerge = !getMipsSubtarget().enableLongBranchPass(); 2300b57cec5SDimitry Andric } 2310b57cec5SDimitry Andric 2320b57cec5SDimitry Andric MipsTargetMachine &getMipsTargetMachine() const { 2330b57cec5SDimitry Andric return getTM<MipsTargetMachine>(); 2340b57cec5SDimitry Andric } 2350b57cec5SDimitry Andric 2360b57cec5SDimitry Andric const MipsSubtarget &getMipsSubtarget() const { 2370b57cec5SDimitry Andric return *getMipsTargetMachine().getSubtargetImpl(); 2380b57cec5SDimitry Andric } 2390b57cec5SDimitry Andric 2400b57cec5SDimitry Andric void addIRPasses() override; 2410b57cec5SDimitry Andric bool addInstSelector() override; 2420b57cec5SDimitry Andric void addPreEmitPass() override; 2430b57cec5SDimitry Andric void addPreRegAlloc() override; 2440b57cec5SDimitry Andric bool addIRTranslator() override; 2450b57cec5SDimitry Andric void addPreLegalizeMachineIR() override; 2460b57cec5SDimitry Andric bool addLegalizeMachineIR() override; 24781ad6265SDimitry Andric void addPreRegBankSelect() override; 2480b57cec5SDimitry Andric bool addRegBankSelect() override; 2490b57cec5SDimitry Andric bool addGlobalInstructionSelect() override; 2500b57cec5SDimitry Andric 2510b57cec5SDimitry Andric std::unique_ptr<CSEConfigBase> getCSEConfig() const override; 2520b57cec5SDimitry Andric }; 2530b57cec5SDimitry Andric 2540b57cec5SDimitry Andric } // end anonymous namespace 2550b57cec5SDimitry Andric 2560b57cec5SDimitry Andric TargetPassConfig *MipsTargetMachine::createPassConfig(PassManagerBase &PM) { 2570b57cec5SDimitry Andric return new MipsPassConfig(*this, PM); 2580b57cec5SDimitry Andric } 2590b57cec5SDimitry Andric 2600b57cec5SDimitry Andric std::unique_ptr<CSEConfigBase> MipsPassConfig::getCSEConfig() const { 2610b57cec5SDimitry Andric return getStandardCSEConfigForOpt(TM->getOptLevel()); 2620b57cec5SDimitry Andric } 2630b57cec5SDimitry Andric 2640b57cec5SDimitry Andric void MipsPassConfig::addIRPasses() { 2650b57cec5SDimitry Andric TargetPassConfig::addIRPasses(); 266*0fca6ea1SDimitry Andric addPass(createAtomicExpandLegacyPass()); 2670b57cec5SDimitry Andric if (getMipsSubtarget().os16()) 2680b57cec5SDimitry Andric addPass(createMipsOs16Pass()); 2690b57cec5SDimitry Andric if (getMipsSubtarget().inMips16HardFloat()) 2700b57cec5SDimitry Andric addPass(createMips16HardFloatPass()); 2710b57cec5SDimitry Andric } 2720b57cec5SDimitry Andric // Install an instruction selector pass using 2730b57cec5SDimitry Andric // the ISelDag to gen Mips code. 2740b57cec5SDimitry Andric bool MipsPassConfig::addInstSelector() { 2750b57cec5SDimitry Andric addPass(createMipsModuleISelDagPass()); 2760b57cec5SDimitry Andric addPass(createMips16ISelDag(getMipsTargetMachine(), getOptLevel())); 2770b57cec5SDimitry Andric addPass(createMipsSEISelDag(getMipsTargetMachine(), getOptLevel())); 2780b57cec5SDimitry Andric return false; 2790b57cec5SDimitry Andric } 2800b57cec5SDimitry Andric 2810b57cec5SDimitry Andric void MipsPassConfig::addPreRegAlloc() { 2820b57cec5SDimitry Andric addPass(createMipsOptimizePICCallPass()); 2830b57cec5SDimitry Andric } 2840b57cec5SDimitry Andric 2850b57cec5SDimitry Andric TargetTransformInfo 28681ad6265SDimitry Andric MipsTargetMachine::getTargetTransformInfo(const Function &F) const { 2870b57cec5SDimitry Andric if (Subtarget->allowMixed16_32()) { 2880b57cec5SDimitry Andric LLVM_DEBUG(errs() << "No Target Transform Info Pass Added\n"); 2890b57cec5SDimitry Andric // FIXME: This is no longer necessary as the TTI returned is per-function. 290*0fca6ea1SDimitry Andric return TargetTransformInfo(F.getDataLayout()); 2910b57cec5SDimitry Andric } 2920b57cec5SDimitry Andric 2930b57cec5SDimitry Andric LLVM_DEBUG(errs() << "Target Transform Info Pass Added\n"); 29481ad6265SDimitry Andric return TargetTransformInfo(MipsTTIImpl(this, F)); 2950b57cec5SDimitry Andric } 2960b57cec5SDimitry Andric 297bdd1243dSDimitry Andric MachineFunctionInfo *MipsTargetMachine::createMachineFunctionInfo( 298bdd1243dSDimitry Andric BumpPtrAllocator &Allocator, const Function &F, 299bdd1243dSDimitry Andric const TargetSubtargetInfo *STI) const { 300bdd1243dSDimitry Andric return MipsFunctionInfo::create<MipsFunctionInfo>(Allocator, F, STI); 301bdd1243dSDimitry Andric } 302bdd1243dSDimitry Andric 3030b57cec5SDimitry Andric // Implemented by targets that want to run passes immediately before 304e8d8bef9SDimitry Andric // machine code is emitted. 3050b57cec5SDimitry Andric void MipsPassConfig::addPreEmitPass() { 3060b57cec5SDimitry Andric // Expand pseudo instructions that are sensitive to register allocation. 3070b57cec5SDimitry Andric addPass(createMipsExpandPseudoPass()); 3080b57cec5SDimitry Andric 3090b57cec5SDimitry Andric // The microMIPS size reduction pass performs instruction reselection for 3100b57cec5SDimitry Andric // instructions which can be remapped to a 16 bit instruction. 3110b57cec5SDimitry Andric addPass(createMicroMipsSizeReducePass()); 3120b57cec5SDimitry Andric 31304eeddc0SDimitry Andric // This pass inserts a nop instruction between two back-to-back multiplication 31404eeddc0SDimitry Andric // instructions when the "mfix4300" flag is passed. 31504eeddc0SDimitry Andric if (EnableMulMulFix) 31604eeddc0SDimitry Andric addPass(createMipsMulMulBugPass()); 31704eeddc0SDimitry Andric 3180b57cec5SDimitry Andric // The delay slot filler pass can potientially create forbidden slot hazards 3190b57cec5SDimitry Andric // for MIPSR6 and therefore it should go before MipsBranchExpansion pass. 3200b57cec5SDimitry Andric addPass(createMipsDelaySlotFillerPass()); 3210b57cec5SDimitry Andric 3220b57cec5SDimitry Andric // This pass expands branches and takes care about the forbidden slot hazards. 3230b57cec5SDimitry Andric // Expanding branches may potentially create forbidden slot hazards for 3240b57cec5SDimitry Andric // MIPSR6, and fixing such hazard may potentially break a branch by extending 3250b57cec5SDimitry Andric // its offset out of range. That's why this pass combine these two tasks, and 3260b57cec5SDimitry Andric // runs them alternately until one of them finishes without any changes. Only 3270b57cec5SDimitry Andric // then we can be sure that all branches are expanded properly and no hazards 3280b57cec5SDimitry Andric // exists. 3290b57cec5SDimitry Andric // Any new pass should go before this pass. 3300b57cec5SDimitry Andric addPass(createMipsBranchExpansion()); 3310b57cec5SDimitry Andric 3320b57cec5SDimitry Andric addPass(createMipsConstantIslandPass()); 3330b57cec5SDimitry Andric } 3340b57cec5SDimitry Andric 3350b57cec5SDimitry Andric bool MipsPassConfig::addIRTranslator() { 336e8d8bef9SDimitry Andric addPass(new IRTranslator(getOptLevel())); 3370b57cec5SDimitry Andric return false; 3380b57cec5SDimitry Andric } 3390b57cec5SDimitry Andric 3400b57cec5SDimitry Andric void MipsPassConfig::addPreLegalizeMachineIR() { 3410b57cec5SDimitry Andric addPass(createMipsPreLegalizeCombiner()); 3420b57cec5SDimitry Andric } 3430b57cec5SDimitry Andric 3440b57cec5SDimitry Andric bool MipsPassConfig::addLegalizeMachineIR() { 3450b57cec5SDimitry Andric addPass(new Legalizer()); 3460b57cec5SDimitry Andric return false; 3470b57cec5SDimitry Andric } 3480b57cec5SDimitry Andric 34981ad6265SDimitry Andric void MipsPassConfig::addPreRegBankSelect() { 3505f757f3fSDimitry Andric bool IsOptNone = getOptLevel() == CodeGenOptLevel::None; 35181ad6265SDimitry Andric addPass(createMipsPostLegalizeCombiner(IsOptNone)); 35281ad6265SDimitry Andric } 35381ad6265SDimitry Andric 3540b57cec5SDimitry Andric bool MipsPassConfig::addRegBankSelect() { 3550b57cec5SDimitry Andric addPass(new RegBankSelect()); 3560b57cec5SDimitry Andric return false; 3570b57cec5SDimitry Andric } 3580b57cec5SDimitry Andric 3590b57cec5SDimitry Andric bool MipsPassConfig::addGlobalInstructionSelect() { 360fe6060f1SDimitry Andric addPass(new InstructionSelect(getOptLevel())); 3610b57cec5SDimitry Andric return false; 3620b57cec5SDimitry Andric } 363