1f22ef01cSRoman Divacky //===-- MipsTargetMachine.cpp - Define TargetMachine for Mips -------------===//
2f22ef01cSRoman Divacky //
3f22ef01cSRoman Divacky //                     The LLVM Compiler Infrastructure
4f22ef01cSRoman Divacky //
5f22ef01cSRoman Divacky // This file is distributed under the University of Illinois Open Source
6f22ef01cSRoman Divacky // License. See LICENSE.TXT for details.
7f22ef01cSRoman Divacky //
8f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
9f22ef01cSRoman Divacky //
10f22ef01cSRoman Divacky // Implements the info about Mips target spec.
11f22ef01cSRoman Divacky //
12f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
13f22ef01cSRoman Divacky 
14db17bf38SDimitry Andric #include "MipsTargetMachine.h"
157a7e6055SDimitry Andric #include "MCTargetDesc/MipsABIInfo.h"
167a7e6055SDimitry Andric #include "MCTargetDesc/MipsMCTargetDesc.h"
17dff0c46cSDimitry Andric #include "Mips.h"
1891bc56edSDimitry Andric #include "Mips16ISelDAGToDAG.h"
19284c1978SDimitry Andric #include "MipsSEISelDAGToDAG.h"
207a7e6055SDimitry Andric #include "MipsSubtarget.h"
2139d628a0SDimitry Andric #include "MipsTargetObjectFile.h"
227a7e6055SDimitry Andric #include "llvm/ADT/Optional.h"
237a7e6055SDimitry Andric #include "llvm/ADT/STLExtras.h"
247a7e6055SDimitry Andric #include "llvm/ADT/StringRef.h"
25284c1978SDimitry Andric #include "llvm/Analysis/TargetTransformInfo.h"
264ba319b5SDimitry Andric #include "llvm/CodeGen/GlobalISel/IRTranslator.h"
274ba319b5SDimitry Andric #include "llvm/CodeGen/GlobalISel/Legalizer.h"
284ba319b5SDimitry Andric #include "llvm/CodeGen/GlobalISel/RegBankSelect.h"
294ba319b5SDimitry Andric #include "llvm/CodeGen/GlobalISel/InstructionSelect.h"
307a7e6055SDimitry Andric #include "llvm/CodeGen/BasicTTIImpl.h"
317a7e6055SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
32dff0c46cSDimitry Andric #include "llvm/CodeGen/Passes.h"
333ca95b02SDimitry Andric #include "llvm/CodeGen/TargetPassConfig.h"
347a7e6055SDimitry Andric #include "llvm/IR/Attributes.h"
357a7e6055SDimitry Andric #include "llvm/IR/Function.h"
367a7e6055SDimitry Andric #include "llvm/Support/CodeGen.h"
37284c1978SDimitry Andric #include "llvm/Support/Debug.h"
386122f3e6SDimitry Andric #include "llvm/Support/TargetRegistry.h"
3991bc56edSDimitry Andric #include "llvm/Support/raw_ostream.h"
407a7e6055SDimitry Andric #include "llvm/Target/TargetOptions.h"
417a7e6055SDimitry Andric #include <string>
42ff0cc061SDimitry Andric 
43f22ef01cSRoman Divacky using namespace llvm;
44f22ef01cSRoman Divacky 
4591bc56edSDimitry Andric #define DEBUG_TYPE "mips"
46284c1978SDimitry Andric 
LLVMInitializeMipsTarget()47f22ef01cSRoman Divacky extern "C" void LLVMInitializeMipsTarget() {
48f22ef01cSRoman Divacky   // Register the target.
49d88c1a5aSDimitry Andric   RegisterTargetMachine<MipsebTargetMachine> X(getTheMipsTarget());
50d88c1a5aSDimitry Andric   RegisterTargetMachine<MipselTargetMachine> Y(getTheMipselTarget());
51d88c1a5aSDimitry Andric   RegisterTargetMachine<MipsebTargetMachine> A(getTheMips64Target());
52d88c1a5aSDimitry Andric   RegisterTargetMachine<MipselTargetMachine> B(getTheMips64elTarget());
534ba319b5SDimitry Andric 
544ba319b5SDimitry Andric   PassRegistry *PR = PassRegistry::getPassRegistry();
554ba319b5SDimitry Andric   initializeGlobalISel(*PR);
564ba319b5SDimitry Andric   initializeMipsDelaySlotFillerPass(*PR);
574ba319b5SDimitry Andric   initializeMipsBranchExpansionPass(*PR);
584ba319b5SDimitry Andric   initializeMicroMipsSizeReducePass(*PR);
59*b5893f02SDimitry Andric   initializeMipsPreLegalizerCombinerPass(*PR);
60f22ef01cSRoman Divacky }
61f22ef01cSRoman Divacky 
computeDataLayout(const Triple & TT,StringRef CPU,const TargetOptions & Options,bool isLittle)628f0fd8f6SDimitry Andric static std::string computeDataLayout(const Triple &TT, StringRef CPU,
63ff0cc061SDimitry Andric                                      const TargetOptions &Options,
64ff0cc061SDimitry Andric                                      bool isLittle) {
657a7e6055SDimitry Andric   std::string Ret;
668f0fd8f6SDimitry Andric   MipsABIInfo ABI = MipsABIInfo::computeTargetABI(TT, CPU, Options.MCOptions);
67ff0cc061SDimitry Andric 
68ff0cc061SDimitry Andric   // There are both little and big endian mips.
69ff0cc061SDimitry Andric   if (isLittle)
70ff0cc061SDimitry Andric     Ret += "e";
71ff0cc061SDimitry Andric   else
72ff0cc061SDimitry Andric     Ret += "E";
73ff0cc061SDimitry Andric 
746c4bc1bdSDimitry Andric   if (ABI.IsO32())
75ff0cc061SDimitry Andric     Ret += "-m:m";
766c4bc1bdSDimitry Andric   else
776c4bc1bdSDimitry Andric     Ret += "-m:e";
78ff0cc061SDimitry Andric 
79ff0cc061SDimitry Andric   // Pointers are 32 bit on some ABIs.
80ff0cc061SDimitry Andric   if (!ABI.IsN64())
81ff0cc061SDimitry Andric     Ret += "-p:32:32";
82ff0cc061SDimitry Andric 
83875ed548SDimitry Andric   // 8 and 16 bit integers only need to have natural alignment, but try to
84ff0cc061SDimitry Andric   // align them to 32 bits. 64 bit integers have natural alignment.
85ff0cc061SDimitry Andric   Ret += "-i8:8:32-i16:16:32-i64:64";
86ff0cc061SDimitry Andric 
87ff0cc061SDimitry Andric   // 32 bit registers are always available and the stack is at least 64 bit
88ff0cc061SDimitry Andric   // aligned. On N64 64 bit registers are also available and the stack is
89ff0cc061SDimitry Andric   // 128 bit aligned.
90ff0cc061SDimitry Andric   if (ABI.IsN64() || ABI.IsN32())
91ff0cc061SDimitry Andric     Ret += "-n32:64-S128";
92ff0cc061SDimitry Andric   else
93ff0cc061SDimitry Andric     Ret += "-n32-S64";
94ff0cc061SDimitry Andric 
95ff0cc061SDimitry Andric   return Ret;
96ff0cc061SDimitry Andric }
97ff0cc061SDimitry Andric 
getEffectiveRelocModel(bool JIT,Optional<Reloc::Model> RM)982cab237bSDimitry Andric static Reloc::Model getEffectiveRelocModel(bool JIT,
993ca95b02SDimitry Andric                                            Optional<Reloc::Model> RM) {
1002cab237bSDimitry Andric   if (!RM.hasValue() || JIT)
1013ca95b02SDimitry Andric     return Reloc::Static;
1023ca95b02SDimitry Andric   return *RM;
1033ca95b02SDimitry Andric }
1043ca95b02SDimitry Andric 
105f22ef01cSRoman Divacky // On function prologue, the stack is created by decrementing
106f22ef01cSRoman Divacky // its pointer. Once decremented, all references are done with positive
107f22ef01cSRoman Divacky // offset from the stack/frame pointer, using StackGrowsUp enables
108f22ef01cSRoman Divacky // an easier handling.
109f22ef01cSRoman Divacky // Using CodeModel::Large enables different CALL behavior.
MipsTargetMachine(const Target & T,const Triple & TT,StringRef CPU,StringRef FS,const TargetOptions & Options,Optional<Reloc::Model> RM,Optional<CodeModel::Model> CM,CodeGenOpt::Level OL,bool JIT,bool isLittle)1108f0fd8f6SDimitry Andric MipsTargetMachine::MipsTargetMachine(const Target &T, const Triple &TT,
11191bc56edSDimitry Andric                                      StringRef CPU, StringRef FS,
11291bc56edSDimitry Andric                                      const TargetOptions &Options,
1133ca95b02SDimitry Andric                                      Optional<Reloc::Model> RM,
1142cab237bSDimitry Andric                                      Optional<CodeModel::Model> CM,
1152cab237bSDimitry Andric                                      CodeGenOpt::Level OL, bool JIT,
1163ca95b02SDimitry Andric                                      bool isLittle)
117ff0cc061SDimitry Andric     : LLVMTargetMachine(T, computeDataLayout(TT, CPU, Options, isLittle), TT,
1182cab237bSDimitry Andric                         CPU, FS, Options, getEffectiveRelocModel(JIT, RM),
119*b5893f02SDimitry Andric                         getEffectiveCodeModel(CM, CodeModel::Small), OL),
1207a7e6055SDimitry Andric       isLittle(isLittle), TLOF(llvm::make_unique<MipsTargetObjectFile>()),
1218f0fd8f6SDimitry Andric       ABI(MipsABIInfo::computeTargetABI(TT, CPU, Options.MCOptions)),
1222cab237bSDimitry Andric       Subtarget(nullptr), DefaultSubtarget(TT, CPU, FS, isLittle, *this,
1232cab237bSDimitry Andric                                            Options.StackAlignmentOverride),
12491bc56edSDimitry Andric       NoMips16Subtarget(TT, CPU, FS.empty() ? "-mips16" : FS.str() + ",-mips16",
1252cab237bSDimitry Andric                         isLittle, *this, Options.StackAlignmentOverride),
12691bc56edSDimitry Andric       Mips16Subtarget(TT, CPU, FS.empty() ? "+mips16" : FS.str() + ",+mips16",
1272cab237bSDimitry Andric                       isLittle, *this, Options.StackAlignmentOverride) {
12891bc56edSDimitry Andric   Subtarget = &DefaultSubtarget;
129f785676fSDimitry Andric   initAsmInfo();
130f22ef01cSRoman Divacky }
131f22ef01cSRoman Divacky 
1327a7e6055SDimitry Andric MipsTargetMachine::~MipsTargetMachine() = default;
13339d628a0SDimitry Andric 
anchor()134dff0c46cSDimitry Andric void MipsebTargetMachine::anchor() {}
135dff0c46cSDimitry Andric 
MipsebTargetMachine(const Target & T,const Triple & TT,StringRef CPU,StringRef FS,const TargetOptions & Options,Optional<Reloc::Model> RM,Optional<CodeModel::Model> CM,CodeGenOpt::Level OL,bool JIT)1368f0fd8f6SDimitry Andric MipsebTargetMachine::MipsebTargetMachine(const Target &T, const Triple &TT,
1378f0fd8f6SDimitry Andric                                          StringRef CPU, StringRef FS,
1388f0fd8f6SDimitry Andric                                          const TargetOptions &Options,
1393ca95b02SDimitry Andric                                          Optional<Reloc::Model> RM,
1402cab237bSDimitry Andric                                          Optional<CodeModel::Model> CM,
1412cab237bSDimitry Andric                                          CodeGenOpt::Level OL, bool JIT)
1422cab237bSDimitry Andric     : MipsTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, JIT, false) {}
143dff0c46cSDimitry Andric 
anchor()144dff0c46cSDimitry Andric void MipselTargetMachine::anchor() {}
1456122f3e6SDimitry Andric 
MipselTargetMachine(const Target & T,const Triple & TT,StringRef CPU,StringRef FS,const TargetOptions & Options,Optional<Reloc::Model> RM,Optional<CodeModel::Model> CM,CodeGenOpt::Level OL,bool JIT)1468f0fd8f6SDimitry Andric MipselTargetMachine::MipselTargetMachine(const Target &T, const Triple &TT,
1478f0fd8f6SDimitry Andric                                          StringRef CPU, StringRef FS,
1488f0fd8f6SDimitry Andric                                          const TargetOptions &Options,
1493ca95b02SDimitry Andric                                          Optional<Reloc::Model> RM,
1502cab237bSDimitry Andric                                          Optional<CodeModel::Model> CM,
1512cab237bSDimitry Andric                                          CodeGenOpt::Level OL, bool JIT)
1522cab237bSDimitry Andric     : MipsTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, JIT, true) {}
153dff0c46cSDimitry Andric 
15439d628a0SDimitry Andric const MipsSubtarget *
getSubtargetImpl(const Function & F) const15539d628a0SDimitry Andric MipsTargetMachine::getSubtargetImpl(const Function &F) const {
156ff0cc061SDimitry Andric   Attribute CPUAttr = F.getFnAttribute("target-cpu");
157ff0cc061SDimitry Andric   Attribute FSAttr = F.getFnAttribute("target-features");
15839d628a0SDimitry Andric 
15939d628a0SDimitry Andric   std::string CPU = !CPUAttr.hasAttribute(Attribute::None)
16039d628a0SDimitry Andric                         ? CPUAttr.getValueAsString().str()
16139d628a0SDimitry Andric                         : TargetCPU;
16239d628a0SDimitry Andric   std::string FS = !FSAttr.hasAttribute(Attribute::None)
16339d628a0SDimitry Andric                        ? FSAttr.getValueAsString().str()
16439d628a0SDimitry Andric                        : TargetFS;
16539d628a0SDimitry Andric   bool hasMips16Attr =
166ff0cc061SDimitry Andric       !F.getFnAttribute("mips16").hasAttribute(Attribute::None);
16739d628a0SDimitry Andric   bool hasNoMips16Attr =
168ff0cc061SDimitry Andric       !F.getFnAttribute("nomips16").hasAttribute(Attribute::None);
16939d628a0SDimitry Andric 
170d8866befSDimitry Andric   bool HasMicroMipsAttr =
171d8866befSDimitry Andric       !F.getFnAttribute("micromips").hasAttribute(Attribute::None);
172d8866befSDimitry Andric   bool HasNoMicroMipsAttr =
173d8866befSDimitry Andric       !F.getFnAttribute("nomicromips").hasAttribute(Attribute::None);
174d8866befSDimitry Andric 
17539d628a0SDimitry Andric   // FIXME: This is related to the code below to reset the target options,
17639d628a0SDimitry Andric   // we need to know whether or not the soft float flag is set on the
177ff0cc061SDimitry Andric   // function, so we can enable it as a subtarget feature.
178ff0cc061SDimitry Andric   bool softFloat =
179ff0cc061SDimitry Andric       F.hasFnAttribute("use-soft-float") &&
180ff0cc061SDimitry Andric       F.getFnAttribute("use-soft-float").getValueAsString() == "true";
18139d628a0SDimitry Andric 
18239d628a0SDimitry Andric   if (hasMips16Attr)
18339d628a0SDimitry Andric     FS += FS.empty() ? "+mips16" : ",+mips16";
18439d628a0SDimitry Andric   else if (hasNoMips16Attr)
18539d628a0SDimitry Andric     FS += FS.empty() ? "-mips16" : ",-mips16";
186d8866befSDimitry Andric   if (HasMicroMipsAttr)
187d8866befSDimitry Andric     FS += FS.empty() ? "+micromips" : ",+micromips";
188d8866befSDimitry Andric   else if (HasNoMicroMipsAttr)
189d8866befSDimitry Andric     FS += FS.empty() ? "-micromips" : ",-micromips";
190ff0cc061SDimitry Andric   if (softFloat)
191ff0cc061SDimitry Andric     FS += FS.empty() ? "+soft-float" : ",+soft-float";
19239d628a0SDimitry Andric 
193ff0cc061SDimitry Andric   auto &I = SubtargetMap[CPU + FS];
19439d628a0SDimitry Andric   if (!I) {
19539d628a0SDimitry Andric     // This needs to be done before we create a new subtarget since any
19639d628a0SDimitry Andric     // creation will depend on the TM and the code generation flags on the
19739d628a0SDimitry Andric     // function that reside in TargetOptions.
19839d628a0SDimitry Andric     resetTargetOptions(F);
1992cab237bSDimitry Andric     I = llvm::make_unique<MipsSubtarget>(TargetTriple, CPU, FS, isLittle, *this,
2002cab237bSDimitry Andric                                          Options.StackAlignmentOverride);
20139d628a0SDimitry Andric   }
20239d628a0SDimitry Andric   return I.get();
20339d628a0SDimitry Andric }
20439d628a0SDimitry Andric 
resetSubtarget(MachineFunction * MF)20591bc56edSDimitry Andric void MipsTargetMachine::resetSubtarget(MachineFunction *MF) {
2064ba319b5SDimitry Andric   LLVM_DEBUG(dbgs() << "resetSubtarget\n");
20739d628a0SDimitry Andric 
2082cab237bSDimitry Andric   Subtarget = const_cast<MipsSubtarget *>(getSubtargetImpl(MF->getFunction()));
20939d628a0SDimitry Andric   MF->setSubtarget(Subtarget);
21091bc56edSDimitry Andric }
21191bc56edSDimitry Andric 
212dff0c46cSDimitry Andric namespace {
2137a7e6055SDimitry Andric 
214dff0c46cSDimitry Andric /// Mips Code Generator Pass Configuration Options.
215dff0c46cSDimitry Andric class MipsPassConfig : public TargetPassConfig {
216dff0c46cSDimitry Andric public:
MipsPassConfig(MipsTargetMachine & TM,PassManagerBase & PM)217f9448bf3SDimitry Andric   MipsPassConfig(MipsTargetMachine &TM, PassManagerBase &PM)
218f785676fSDimitry Andric       : TargetPassConfig(TM, PM) {
219f785676fSDimitry Andric     // The current implementation of long branch pass requires a scratch
220f785676fSDimitry Andric     // register ($at) to be available before branch instructions. Tail merging
221f785676fSDimitry Andric     // can break this requirement, so disable it when long branch pass is
222f785676fSDimitry Andric     // enabled.
223f785676fSDimitry Andric     EnableTailMerge = !getMipsSubtarget().enableLongBranchPass();
224f785676fSDimitry Andric   }
225dff0c46cSDimitry Andric 
getMipsTargetMachine() const226dff0c46cSDimitry Andric   MipsTargetMachine &getMipsTargetMachine() const {
227dff0c46cSDimitry Andric     return getTM<MipsTargetMachine>();
228dff0c46cSDimitry Andric   }
229dff0c46cSDimitry Andric 
getMipsSubtarget() const230dff0c46cSDimitry Andric   const MipsSubtarget &getMipsSubtarget() const {
231dff0c46cSDimitry Andric     return *getMipsTargetMachine().getSubtargetImpl();
232dff0c46cSDimitry Andric   }
233dff0c46cSDimitry Andric 
23491bc56edSDimitry Andric   void addIRPasses() override;
23591bc56edSDimitry Andric   bool addInstSelector() override;
23639d628a0SDimitry Andric   void addPreEmitPass() override;
23739d628a0SDimitry Andric   void addPreRegAlloc() override;
2384ba319b5SDimitry Andric   bool addIRTranslator() override;
239*b5893f02SDimitry Andric   void addPreLegalizeMachineIR() override;
2404ba319b5SDimitry Andric   bool addLegalizeMachineIR() override;
2414ba319b5SDimitry Andric   bool addRegBankSelect() override;
2424ba319b5SDimitry Andric   bool addGlobalInstructionSelect() override;
243dff0c46cSDimitry Andric };
2447a7e6055SDimitry Andric 
2457a7e6055SDimitry Andric } // end anonymous namespace
246dff0c46cSDimitry Andric 
createPassConfig(PassManagerBase & PM)247dff0c46cSDimitry Andric TargetPassConfig *MipsTargetMachine::createPassConfig(PassManagerBase &PM) {
248f9448bf3SDimitry Andric   return new MipsPassConfig(*this, PM);
249dff0c46cSDimitry Andric }
250f22ef01cSRoman Divacky 
addIRPasses()251284c1978SDimitry Andric void MipsPassConfig::addIRPasses() {
252284c1978SDimitry Andric   TargetPassConfig::addIRPasses();
253d8866befSDimitry Andric   addPass(createAtomicExpandPass());
254284c1978SDimitry Andric   if (getMipsSubtarget().os16())
255d8866befSDimitry Andric     addPass(createMipsOs16Pass());
256f785676fSDimitry Andric   if (getMipsSubtarget().inMips16HardFloat())
257d8866befSDimitry Andric     addPass(createMips16HardFloatPass());
258284c1978SDimitry Andric }
259f22ef01cSRoman Divacky // Install an instruction selector pass using
260f22ef01cSRoman Divacky // the ISelDag to gen Mips code.
addInstSelector()261cb4dff85SDimitry Andric bool MipsPassConfig::addInstSelector() {
262d8866befSDimitry Andric   addPass(createMipsModuleISelDagPass());
2633ca95b02SDimitry Andric   addPass(createMips16ISelDag(getMipsTargetMachine(), getOptLevel()));
2643ca95b02SDimitry Andric   addPass(createMipsSEISelDag(getMipsTargetMachine(), getOptLevel()));
26591bc56edSDimitry Andric   return false;
266284c1978SDimitry Andric }
26791bc56edSDimitry Andric 
addPreRegAlloc()26839d628a0SDimitry Andric void MipsPassConfig::addPreRegAlloc() {
269d8866befSDimitry Andric   addPass(createMipsOptimizePICCallPass());
270f22ef01cSRoman Divacky }
271f22ef01cSRoman Divacky 
272da09e106SDimitry Andric TargetTransformInfo
getTargetTransformInfo(const Function & F)273da09e106SDimitry Andric MipsTargetMachine::getTargetTransformInfo(const Function &F) {
27491bc56edSDimitry Andric   if (Subtarget->allowMixed16_32()) {
2754ba319b5SDimitry Andric     LLVM_DEBUG(errs() << "No Target Transform Info Pass Added\n");
276ff0cc061SDimitry Andric     // FIXME: This is no longer necessary as the TTI returned is per-function.
277875ed548SDimitry Andric     return TargetTransformInfo(F.getParent()->getDataLayout());
278ff0cc061SDimitry Andric   }
279ff0cc061SDimitry Andric 
2804ba319b5SDimitry Andric   LLVM_DEBUG(errs() << "Target Transform Info Pass Added\n");
281ff0cc061SDimitry Andric   return TargetTransformInfo(BasicTTIImpl(this, F));
282284c1978SDimitry Andric }
283284c1978SDimitry Andric 
284f22ef01cSRoman Divacky // Implemented by targets that want to run passes immediately before
285f22ef01cSRoman Divacky // machine code is emitted. return true if -print-machineinstrs should
286f22ef01cSRoman Divacky // print out the code after the passes.
addPreEmitPass()28739d628a0SDimitry Andric void MipsPassConfig::addPreEmitPass() {
2884ba319b5SDimitry Andric   // Expand pseudo instructions that are sensitive to register allocation.
2894ba319b5SDimitry Andric   addPass(createMipsExpandPseudoPass());
2903ca95b02SDimitry Andric 
2914ba319b5SDimitry Andric   // The microMIPS size reduction pass performs instruction reselection for
2924ba319b5SDimitry Andric   // instructions which can be remapped to a 16 bit instruction.
2934ba319b5SDimitry Andric   addPass(createMicroMipsSizeReducePass());
2944ba319b5SDimitry Andric 
2954ba319b5SDimitry Andric   // The delay slot filler pass can potientially create forbidden slot hazards
2964ba319b5SDimitry Andric   // for MIPSR6 and therefore it should go before MipsBranchExpansion pass.
297d8866befSDimitry Andric   addPass(createMipsDelaySlotFillerPass());
2984ba319b5SDimitry Andric 
2994ba319b5SDimitry Andric   // This pass expands branches and takes care about the forbidden slot hazards.
3004ba319b5SDimitry Andric   // Expanding branches may potentially create forbidden slot hazards for
3014ba319b5SDimitry Andric   // MIPSR6, and fixing such hazard may potentially break a branch by extending
3024ba319b5SDimitry Andric   // its offset out of range. That's why this pass combine these two tasks, and
3034ba319b5SDimitry Andric   // runs them alternately until one of them finishes without any changes. Only
3044ba319b5SDimitry Andric   // then we can be sure that all branches are expanded properly and no hazards
3054ba319b5SDimitry Andric   // exists.
3064ba319b5SDimitry Andric   // Any new pass should go before this pass.
3074ba319b5SDimitry Andric   addPass(createMipsBranchExpansion());
3084ba319b5SDimitry Andric 
3093ca95b02SDimitry Andric   addPass(createMipsConstantIslandPass());
3106122f3e6SDimitry Andric }
3114ba319b5SDimitry Andric 
addIRTranslator()3124ba319b5SDimitry Andric bool MipsPassConfig::addIRTranslator() {
3134ba319b5SDimitry Andric   addPass(new IRTranslator());
3144ba319b5SDimitry Andric   return false;
3154ba319b5SDimitry Andric }
3164ba319b5SDimitry Andric 
addPreLegalizeMachineIR()317*b5893f02SDimitry Andric void MipsPassConfig::addPreLegalizeMachineIR() {
318*b5893f02SDimitry Andric   addPass(createMipsPreLegalizeCombiner());
319*b5893f02SDimitry Andric }
320*b5893f02SDimitry Andric 
addLegalizeMachineIR()3214ba319b5SDimitry Andric bool MipsPassConfig::addLegalizeMachineIR() {
3224ba319b5SDimitry Andric   addPass(new Legalizer());
3234ba319b5SDimitry Andric   return false;
3244ba319b5SDimitry Andric }
3254ba319b5SDimitry Andric 
addRegBankSelect()3264ba319b5SDimitry Andric bool MipsPassConfig::addRegBankSelect() {
3274ba319b5SDimitry Andric   addPass(new RegBankSelect());
3284ba319b5SDimitry Andric   return false;
3294ba319b5SDimitry Andric }
3304ba319b5SDimitry Andric 
addGlobalInstructionSelect()3314ba319b5SDimitry Andric bool MipsPassConfig::addGlobalInstructionSelect() {
3324ba319b5SDimitry Andric   addPass(new InstructionSelect());
3334ba319b5SDimitry Andric   return false;
3344ba319b5SDimitry Andric }
335