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