LLVM 22.0.0git
SparcFrameLowering.cpp
Go to the documentation of this file.
1//===-- SparcFrameLowering.cpp - Sparc Frame Information ------------------===//
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//===----------------------------------------------------------------------===//
8//
9// This file contains the Sparc implementation of TargetFrameLowering class.
10//
11//===----------------------------------------------------------------------===//
12
13#include "SparcFrameLowering.h"
14#include "SparcInstrInfo.h"
16#include "SparcSubtarget.h"
25
26using namespace llvm;
27
28static cl::opt<bool>
29DisableLeafProc("disable-sparc-leaf-proc",
30 cl::init(false),
31 cl::desc("Disable Sparc leaf procedure optimization."),
33
36 ST.is64Bit() ? Align(16) : Align(8), 0,
37 ST.is64Bit() ? Align(16) : Align(8),
38 /*StackRealignable=*/false) {}
39
40void SparcFrameLowering::emitSPAdjustment(MachineFunction &MF,
43 int NumBytes,
44 unsigned ADDrr,
45 unsigned ADDri) const {
46
47 DebugLoc dl;
48 const SparcInstrInfo &TII =
49 *static_cast<const SparcInstrInfo *>(MF.getSubtarget().getInstrInfo());
50
51 if (NumBytes >= -4096 && NumBytes < 4096) {
52 BuildMI(MBB, MBBI, dl, TII.get(ADDri), SP::O6)
53 .addReg(SP::O6).addImm(NumBytes);
54 return;
55 }
56
57 // Emit this the hard way. This clobbers G1 which we always know is
58 // available here.
59 if (NumBytes >= 0) {
60 // Emit nonnegative numbers with sethi + or.
61 // sethi %hi(NumBytes), %g1
62 // or %g1, %lo(NumBytes), %g1
63 // add %sp, %g1, %sp
64 BuildMI(MBB, MBBI, dl, TII.get(SP::SETHIi), SP::G1)
65 .addImm(HI22(NumBytes));
66 BuildMI(MBB, MBBI, dl, TII.get(SP::ORri), SP::G1)
67 .addReg(SP::G1).addImm(LO10(NumBytes));
68 BuildMI(MBB, MBBI, dl, TII.get(ADDrr), SP::O6)
69 .addReg(SP::O6).addReg(SP::G1);
70 return ;
71 }
72
73 // Emit negative numbers with sethi + xor.
74 // sethi %hix(NumBytes), %g1
75 // xor %g1, %lox(NumBytes), %g1
76 // add %sp, %g1, %sp
77 BuildMI(MBB, MBBI, dl, TII.get(SP::SETHIi), SP::G1)
78 .addImm(HIX22(NumBytes));
79 BuildMI(MBB, MBBI, dl, TII.get(SP::XORri), SP::G1)
80 .addReg(SP::G1).addImm(LOX10(NumBytes));
81 BuildMI(MBB, MBBI, dl, TII.get(ADDrr), SP::O6)
82 .addReg(SP::O6).addReg(SP::G1);
83}
84
86 MachineBasicBlock &MBB) const {
88
89 assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported");
91 const SparcSubtarget &Subtarget = MF.getSubtarget<SparcSubtarget>();
93
94 // Get the number of bytes to allocate from the FrameInfo
95 int NumBytes = (int) MFI.getStackSize();
96
97 unsigned SAVEri = SP::SAVEri;
98 unsigned SAVErr = SP::SAVErr;
99 if (FuncInfo->isLeafProc()) {
100 if (NumBytes == 0)
101 return;
102 SAVEri = SP::ADDri;
103 SAVErr = SP::ADDrr;
104 }
105
106 // The SPARC ABI is a bit odd in that it requires a reserved 92-byte
107 // (128 in v9) area in the user's stack, starting at %sp. Thus, the
108 // first part of the stack that can actually be used is located at
109 // %sp + 92.
110 //
111 // We therefore need to add that offset to the total stack size
112 // after all the stack objects are placed by
113 // PrologEpilogInserter calculateFrameObjectOffsets. However, since the stack needs to be
114 // aligned *after* the extra size is added, we need to disable
115 // calculateFrameObjectOffsets's built-in stack alignment, by having
116 // targetHandlesStackFrameRounding return true.
117
118
119 // Add the extra call frame stack size, if needed. (This is the same
120 // code as in PrologEpilogInserter, but also gets disabled by
121 // targetHandlesStackFrameRounding)
122 if (MFI.adjustsStack() && hasReservedCallFrame(MF))
123 NumBytes += MFI.getMaxCallFrameSize();
124
125 // Adds the SPARC subtarget-specific spill area to the stack
126 // size. Also ensures target-required alignment.
127 NumBytes = Subtarget.getAdjustedFrameSize(NumBytes);
128
129 // Finally, ensure that the size is sufficiently aligned for the
130 // data on the stack.
131 NumBytes = alignTo(NumBytes, MFI.getMaxAlign());
132
133 // Update stack size with corrected value.
134 MFI.setStackSize(NumBytes);
135
136 emitSPAdjustment(MF, MBB, MBBI, -NumBytes, SAVErr, SAVEri);
137
138 if (MF.needsFrameMoves()) {
140 CFIBuilder.buildDefCFARegister(SP::I6);
141 CFIBuilder.buildWindowSave();
142 CFIBuilder.buildRegister(SP::O7, SP::I7);
143 }
144}
145
149 if (!hasReservedCallFrame(MF)) {
150 MachineInstr &MI = *I;
151 int Size = MI.getOperand(0).getImm();
152 if (MI.getOpcode() == SP::ADJCALLSTACKDOWN)
153 Size = -Size;
154
155 if (Size)
156 emitSPAdjustment(MF, MBB, I, Size, SP::ADDrr, SP::ADDri);
157 }
158 return MBB.erase(I);
159}
160
161
163 MachineBasicBlock &MBB) const {
166 const SparcInstrInfo &TII =
167 *static_cast<const SparcInstrInfo *>(MF.getSubtarget().getInstrInfo());
168 DebugLoc dl = MBBI->getDebugLoc();
169 assert((MBBI->getOpcode() == SP::RETL || MBBI->getOpcode() == SP::TAIL_CALL ||
170 MBBI->getOpcode() == SP::TAIL_CALLri) &&
171 "Can only put epilog before 'retl' or 'tail_call' instruction!");
172 if (!FuncInfo->isLeafProc()) {
173 BuildMI(MBB, MBBI, dl, TII.get(SP::RESTORErr), SP::G0).addReg(SP::G0)
174 .addReg(SP::G0);
175 return;
176 }
177 MachineFrameInfo &MFI = MF.getFrameInfo();
178
179 int NumBytes = (int) MFI.getStackSize();
180 if (NumBytes != 0)
181 emitSPAdjustment(MF, MBB, MBBI, NumBytes, SP::ADDrr, SP::ADDri);
182
183 // Preserve return address in %o7
184 if (MBBI->getOpcode() == SP::TAIL_CALL) {
185 MBB.addLiveIn(SP::O7);
186 BuildMI(MBB, MBBI, dl, TII.get(SP::ORrr), SP::G1)
187 .addReg(SP::G0)
188 .addReg(SP::O7);
189 BuildMI(MBB, MBBI, dl, TII.get(SP::ORrr), SP::O7)
190 .addReg(SP::G0)
191 .addReg(SP::G1);
192 }
193}
194
196 // Reserve call frame if there are no variable sized objects on the stack.
197 return !MF.getFrameInfo().hasVarSizedObjects();
198}
199
200// hasFPImpl - Return true if the specified function should have a dedicated
201// frame pointer register. This is true if the function has variable sized
202// allocas or if frame pointer elimination is disabled.
204 const MachineFrameInfo &MFI = MF.getFrameInfo();
205 return MF.getTarget().Options.DisableFramePointerElim(MF) ||
207}
208
211 Register &FrameReg) const {
212 const SparcSubtarget &Subtarget = MF.getSubtarget<SparcSubtarget>();
213 const MachineFrameInfo &MFI = MF.getFrameInfo();
214 const SparcRegisterInfo *RegInfo = Subtarget.getRegisterInfo();
216 bool isFixed = MFI.isFixedObjectIndex(FI);
217
218 // Addressable stack objects are accessed using neg. offsets from
219 // %fp, or positive offsets from %sp.
220 bool UseFP;
221
222 // Sparc uses FP-based references in general, even when "hasFP" is
223 // false. That function is rather a misnomer, because %fp is
224 // actually always available, unless isLeafProc.
225 if (FuncInfo->isLeafProc()) {
226 // If there's a leaf proc, all offsets need to be %sp-based,
227 // because we haven't caused %fp to actually point to our frame.
228 UseFP = false;
229 } else if (isFixed) {
230 // Otherwise, argument access should always use %fp.
231 UseFP = true;
232 } else {
233 // Finally, default to using %fp.
234 UseFP = true;
235 }
236
237 int64_t FrameOffset = MF.getFrameInfo().getObjectOffset(FI) +
238 Subtarget.getStackPointerBias();
239
240 if (UseFP) {
241 FrameReg = RegInfo->getFrameRegister(MF);
242 return StackOffset::getFixed(FrameOffset);
243 } else {
244 FrameReg = SP::O6; // %sp
245 return StackOffset::getFixed(FrameOffset + MF.getFrameInfo().getStackSize());
246 }
247}
248
250{
251
252 for (unsigned reg = SP::I0; reg <= SP::I7; ++reg)
253 if (MRI->isPhysRegUsed(reg))
254 return false;
255
256 for (unsigned reg = SP::L0; reg <= SP::L7; ++reg)
257 if (MRI->isPhysRegUsed(reg))
258 return false;
259
260 return true;
261}
262
263bool SparcFrameLowering::isLeafProc(MachineFunction &MF) const
264{
265
267 MachineFrameInfo &MFI = MF.getFrameInfo();
268
269 return !(MFI.hasCalls() // has calls
270 || MRI.isPhysRegUsed(SP::L0) // Too many registers needed
271 || MRI.isPhysRegUsed(SP::O6) // %sp is used
272 || hasFP(MF) // need %fp
273 || MF.hasInlineAsm()); // has inline assembly
274}
275
276void SparcFrameLowering::remapRegsForLeafProc(MachineFunction &MF) const {
278 // Remap %i[0-7] to %o[0-7].
279 for (unsigned reg = SP::I0; reg <= SP::I7; ++reg) {
280 if (!MRI.isPhysRegUsed(reg))
281 continue;
282
283 unsigned mapped_reg = reg - SP::I0 + SP::O0;
284
285 // Replace I register with O register.
286 MRI.replaceRegWith(reg, mapped_reg);
287
288 // Also replace register pair super-registers.
289 if ((reg - SP::I0) % 2 == 0) {
290 unsigned preg = (reg - SP::I0) / 2 + SP::I0_I1;
291 unsigned mapped_preg = preg - SP::I0_I1 + SP::O0_O1;
292 MRI.replaceRegWith(preg, mapped_preg);
293 }
294 }
295
296 // Rewrite MBB's Live-ins.
297 for (MachineBasicBlock &MBB : MF) {
298 for (unsigned reg = SP::I0_I1; reg <= SP::I6_I7; ++reg) {
299 if (!MBB.isLiveIn(reg))
300 continue;
301 MBB.removeLiveIn(reg);
302 MBB.addLiveIn(reg - SP::I0_I1 + SP::O0_O1);
303 }
304 for (unsigned reg = SP::I0; reg <= SP::I7; ++reg) {
305 if (!MBB.isLiveIn(reg))
306 continue;
307 MBB.removeLiveIn(reg);
308 MBB.addLiveIn(reg - SP::I0 + SP::O0);
309 }
310 }
311
313#ifdef EXPENSIVE_CHECKS
314 MF.verify(0, "After LeafProc Remapping");
315#endif
316}
317
319 BitVector &SavedRegs,
320 RegScavenger *RS) const {
322 if (!DisableLeafProc && isLeafProc(MF)) {
324 MFI->setLeafProc(true);
325
326 remapRegsForLeafProc(MF);
327 }
328
329}
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator MBBI
#define LLVM_ATTRIBUTE_UNUSED
Definition: Compiler.h:298
uint64_t Size
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition: MD5.cpp:58
static cl::opt< bool > DisableLeafProc("disable-sparc-leaf-proc", cl::init(false), cl::desc("Disable Sparc leaf procedure optimization."), cl::Hidden)
static bool LLVM_ATTRIBUTE_UNUSED verifyLeafProcRegUse(MachineRegisterInfo *MRI)
static bool is64Bit(const char *name)
Helper class for creating CFI instructions and inserting them into MIR.
void buildWindowSave() const
void buildRegister(MCRegister Reg1, MCRegister Reg2) const
void buildDefCFARegister(MCRegister Reg) const
A debug info location.
Definition: DebugLoc.h:124
LLVM_ABI void removeLiveIn(MCRegister Reg, LaneBitmask LaneMask=LaneBitmask::getAll())
Remove the specified register from the live in set.
LLVM_ABI iterator getLastNonDebugInstr(bool SkipPseudoOp=true)
Returns an iterator to the last non-debug instruction in the basic block, or end().
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
LLVM_ABI instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
LLVM_ABI bool isLiveIn(MCRegister Reg, LaneBitmask LaneMask=LaneBitmask::getAll()) const
Return true if the specified register is in the live in set.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects.
bool adjustsStack() const
Return true if this function adjusts the stack – e.g., when calling another function.
bool hasCalls() const
Return true if the current function has any function calls.
bool isFrameAddressTaken() const
This method may be called any time after instruction selection is complete to determine if there is a...
Align getMaxAlign() const
Return the alignment in bytes that this function must be aligned to, which is greater than the defaul...
uint64_t getMaxCallFrameSize() const
Return the maximum size of a call frame that must be allocated for an outgoing function call.
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
void setStackSize(uint64_t Size)
Set the size of the stack.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
bool hasInlineAsm() const
Returns true if the function contains any inline assembly.
bool needsFrameMoves() const
True if this function needs frame moves for debug or exceptions.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineBasicBlock & front() const
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Representation of each machine instruction.
Definition: MachineInstr.h:72
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override
emitProlog/emitEpilog - These methods insert prolog and epilog code into the function.
SparcFrameLowering(const SparcSubtarget &ST)
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const override
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
bool hasFPImpl(const MachineFunction &MF) const override
StackOffset getFrameIndexReference(const MachineFunction &MF, int FI, Register &FrameReg) const override
getFrameIndexReference - This method should return the base register and offset used to reference a f...
MachineBasicBlock::iterator eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const override
This method is called during prolog/epilog code insertion to eliminate call frame setup and destroy p...
bool hasReservedCallFrame(const MachineFunction &MF) const override
hasReservedCallFrame - Under normal circumstances, when a frame pointer is not required,...
const SparcRegisterInfo * getRegisterInfo() const override
int64_t getStackPointerBias() const
The 64-bit ABI uses biased stack and frame pointers, so the stack frame of the current function is th...
int getAdjustedFrameSize(int stackSize) const
Given a actual stack size as determined by FrameInfo, this function returns adjusted framesize which ...
StackOffset holds a fixed and a scalable offset in bytes.
Definition: TypeSize.h:34
int64_t getFixed() const
Returns the fixed component of the stack.
Definition: TypeSize.h:50
Information about stack frame layout on the target.
bool hasFP(const MachineFunction &MF) const
hasFP - Return true if the specified function should have a dedicated frame pointer register.
virtual void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
TargetOptions Options
LLVM_ABI bool DisableFramePointerElim(const MachineFunction &MF) const
DisableFramePointerElim - This returns true if frame pointer elimination optimization should be disab...
virtual const TargetInstrInfo * getInstrInfo() const
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:444
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
static unsigned HI22(int64_t imm)
Definition: Sparc.h:173
static unsigned HIX22(int64_t imm)
Definition: Sparc.h:181
static unsigned LOX10(int64_t imm)
Definition: Sparc.h:185
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition: Alignment.h:155
static unsigned LO10(int64_t imm)
Definition: Sparc.h:177
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
Register getFrameRegister(const MachineFunction &MF) const override