Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / llvm / lib / Target / Mips / MipsMachineFunction.cpp
blob7d9824aaf8ec36c2cdc02bba73af9349a941d441
1 //===-- MipsMachineFunctionInfo.cpp - Private data used for Mips ----------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #include "MipsMachineFunction.h"
10 #include "MCTargetDesc/MipsABIInfo.h"
11 #include "MipsSubtarget.h"
12 #include "MipsTargetMachine.h"
13 #include "llvm/CodeGen/MachineFrameInfo.h"
14 #include "llvm/CodeGen/MachineRegisterInfo.h"
15 #include "llvm/CodeGen/PseudoSourceValue.h"
16 #include "llvm/CodeGen/TargetRegisterInfo.h"
17 #include "llvm/Support/CommandLine.h"
19 using namespace llvm;
21 static cl::opt<bool>
22 FixGlobalBaseReg("mips-fix-global-base-reg", cl::Hidden, cl::init(true),
23 cl::desc("Always use $gp as the global base register."));
25 MachineFunctionInfo *
26 MipsFunctionInfo::clone(BumpPtrAllocator &Allocator, MachineFunction &DestMF,
27 const DenseMap<MachineBasicBlock *, MachineBasicBlock *>
28 &Src2DstMBB) const {
29 return DestMF.cloneInfo<MipsFunctionInfo>(*this);
32 MipsFunctionInfo::~MipsFunctionInfo() = default;
34 bool MipsFunctionInfo::globalBaseRegSet() const {
35 return GlobalBaseReg;
38 static const TargetRegisterClass &getGlobalBaseRegClass(MachineFunction &MF) {
39 auto &STI = MF.getSubtarget<MipsSubtarget>();
40 auto &TM = static_cast<const MipsTargetMachine &>(MF.getTarget());
42 if (STI.inMips16Mode())
43 return Mips::CPU16RegsRegClass;
45 if (STI.inMicroMipsMode())
46 return Mips::GPRMM16RegClass;
48 if (TM.getABI().IsN64())
49 return Mips::GPR64RegClass;
51 return Mips::GPR32RegClass;
54 Register MipsFunctionInfo::getGlobalBaseReg(MachineFunction &MF) {
55 if (!GlobalBaseReg)
56 GlobalBaseReg =
57 MF.getRegInfo().createVirtualRegister(&getGlobalBaseRegClass(MF));
58 return GlobalBaseReg;
61 Register MipsFunctionInfo::getGlobalBaseRegForGlobalISel(MachineFunction &MF) {
62 if (!GlobalBaseReg) {
63 getGlobalBaseReg(MF);
64 initGlobalBaseReg(MF);
66 return GlobalBaseReg;
69 void MipsFunctionInfo::initGlobalBaseReg(MachineFunction &MF) {
70 if (!GlobalBaseReg)
71 return;
73 MachineBasicBlock &MBB = MF.front();
74 MachineBasicBlock::iterator I = MBB.begin();
75 MachineRegisterInfo &RegInfo = MF.getRegInfo();
76 const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
77 DebugLoc DL;
78 const TargetRegisterClass *RC;
79 const MipsABIInfo &ABI =
80 static_cast<const MipsTargetMachine &>(MF.getTarget()).getABI();
81 RC = (ABI.IsN64()) ? &Mips::GPR64RegClass : &Mips::GPR32RegClass;
83 Register V0 = RegInfo.createVirtualRegister(RC);
84 Register V1 = RegInfo.createVirtualRegister(RC);
86 if (ABI.IsN64()) {
87 MF.getRegInfo().addLiveIn(Mips::T9_64);
88 MBB.addLiveIn(Mips::T9_64);
90 // lui $v0, %hi(%neg(%gp_rel(fname)))
91 // daddu $v1, $v0, $t9
92 // daddiu $globalbasereg, $v1, %lo(%neg(%gp_rel(fname)))
93 const GlobalValue *FName = &MF.getFunction();
94 BuildMI(MBB, I, DL, TII.get(Mips::LUi64), V0)
95 .addGlobalAddress(FName, 0, MipsII::MO_GPOFF_HI);
96 BuildMI(MBB, I, DL, TII.get(Mips::DADDu), V1).addReg(V0)
97 .addReg(Mips::T9_64);
98 BuildMI(MBB, I, DL, TII.get(Mips::DADDiu), GlobalBaseReg).addReg(V1)
99 .addGlobalAddress(FName, 0, MipsII::MO_GPOFF_LO);
100 return;
103 if (!MF.getTarget().isPositionIndependent()) {
104 // Set global register to __gnu_local_gp.
106 // lui $v0, %hi(__gnu_local_gp)
107 // addiu $globalbasereg, $v0, %lo(__gnu_local_gp)
108 BuildMI(MBB, I, DL, TII.get(Mips::LUi), V0)
109 .addExternalSymbol("__gnu_local_gp", MipsII::MO_ABS_HI);
110 BuildMI(MBB, I, DL, TII.get(Mips::ADDiu), GlobalBaseReg).addReg(V0)
111 .addExternalSymbol("__gnu_local_gp", MipsII::MO_ABS_LO);
112 return;
115 MF.getRegInfo().addLiveIn(Mips::T9);
116 MBB.addLiveIn(Mips::T9);
118 if (ABI.IsN32()) {
119 // lui $v0, %hi(%neg(%gp_rel(fname)))
120 // addu $v1, $v0, $t9
121 // addiu $globalbasereg, $v1, %lo(%neg(%gp_rel(fname)))
122 const GlobalValue *FName = &MF.getFunction();
123 BuildMI(MBB, I, DL, TII.get(Mips::LUi), V0)
124 .addGlobalAddress(FName, 0, MipsII::MO_GPOFF_HI);
125 BuildMI(MBB, I, DL, TII.get(Mips::ADDu), V1).addReg(V0).addReg(Mips::T9);
126 BuildMI(MBB, I, DL, TII.get(Mips::ADDiu), GlobalBaseReg).addReg(V1)
127 .addGlobalAddress(FName, 0, MipsII::MO_GPOFF_LO);
128 return;
131 assert(ABI.IsO32());
133 // For O32 ABI, the following instruction sequence is emitted to initialize
134 // the global base register:
136 // 0. lui $2, %hi(_gp_disp)
137 // 1. addiu $2, $2, %lo(_gp_disp)
138 // 2. addu $globalbasereg, $2, $t9
140 // We emit only the last instruction here.
142 // GNU linker requires that the first two instructions appear at the beginning
143 // of a function and no instructions be inserted before or between them.
144 // The two instructions are emitted during lowering to MC layer in order to
145 // avoid any reordering.
147 // Register $2 (Mips::V0) is added to the list of live-in registers to ensure
148 // the value instruction 1 (addiu) defines is valid when instruction 2 (addu)
149 // reads it.
150 MF.getRegInfo().addLiveIn(Mips::V0);
151 MBB.addLiveIn(Mips::V0);
152 BuildMI(MBB, I, DL, TII.get(Mips::ADDu), GlobalBaseReg)
153 .addReg(Mips::V0).addReg(Mips::T9);
156 void MipsFunctionInfo::createEhDataRegsFI(MachineFunction &MF) {
157 const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo();
158 for (int &I : EhDataRegFI) {
159 const TargetRegisterClass &RC =
160 static_cast<const MipsTargetMachine &>(MF.getTarget()).getABI().IsN64()
161 ? Mips::GPR64RegClass
162 : Mips::GPR32RegClass;
164 I = MF.getFrameInfo().CreateStackObject(TRI.getSpillSize(RC),
165 TRI.getSpillAlign(RC), false);
169 void MipsFunctionInfo::createISRRegFI(MachineFunction &MF) {
170 // ISRs require spill slots for Status & ErrorPC Coprocessor 0 registers.
171 // The current implementation only supports Mips32r2+ not Mips64rX. Status
172 // is always 32 bits, ErrorPC is 32 or 64 bits dependent on architecture,
173 // however Mips32r2+ is the supported architecture.
174 const TargetRegisterClass &RC = Mips::GPR32RegClass;
175 const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo();
177 for (int &I : ISRDataRegFI)
178 I = MF.getFrameInfo().CreateStackObject(TRI.getSpillSize(RC),
179 TRI.getSpillAlign(RC), false);
182 bool MipsFunctionInfo::isEhDataRegFI(int FI) const {
183 return CallsEhReturn && (FI == EhDataRegFI[0] || FI == EhDataRegFI[1]
184 || FI == EhDataRegFI[2] || FI == EhDataRegFI[3]);
187 bool MipsFunctionInfo::isISRRegFI(int FI) const {
188 return IsISR && (FI == ISRDataRegFI[0] || FI == ISRDataRegFI[1]);
190 MachinePointerInfo MipsFunctionInfo::callPtrInfo(MachineFunction &MF,
191 const char *ES) {
192 return MachinePointerInfo(MF.getPSVManager().getExternalSymbolCallEntry(ES));
195 MachinePointerInfo MipsFunctionInfo::callPtrInfo(MachineFunction &MF,
196 const GlobalValue *GV) {
197 return MachinePointerInfo(MF.getPSVManager().getGlobalValueCallEntry(GV));
200 int MipsFunctionInfo::getMoveF64ViaSpillFI(MachineFunction &MF,
201 const TargetRegisterClass *RC) {
202 const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo();
203 if (MoveF64ViaSpillFI == -1) {
204 MoveF64ViaSpillFI = MF.getFrameInfo().CreateStackObject(
205 TRI.getSpillSize(*RC), TRI.getSpillAlign(*RC), false);
207 return MoveF64ViaSpillFI;
210 void MipsFunctionInfo::anchor() {}