LLVM 20.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"
22#include "llvm/IR/DataLayout.h"
23#include "llvm/IR/Function.h"
26
27using namespace llvm;
28
29static cl::opt<bool>
30DisableLeafProc("disable-sparc-leaf-proc",
31 cl::init(false),
32 cl::desc("Disable Sparc leaf procedure optimization."),
34
37 ST.is64Bit() ? Align(16) : Align(8), 0,
38 ST.is64Bit() ? Align(16) : Align(8)) {}
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>();
92 const SparcInstrInfo &TII =
93 *static_cast<const SparcInstrInfo *>(Subtarget.getInstrInfo());
94 const SparcRegisterInfo &RegInfo =
95 *static_cast<const SparcRegisterInfo *>(Subtarget.getRegisterInfo());
97 // Debug location must be unknown since the first debug location is used
98 // to determine the end of the prologue.
99 DebugLoc dl;
100 bool NeedsStackRealignment = RegInfo.shouldRealignStack(MF);
101
102 if (NeedsStackRealignment && !RegInfo.canRealignStack(MF))
103 report_fatal_error("Function \"" + Twine(MF.getName()) + "\" required "
104 "stack re-alignment, but LLVM couldn't handle it "
105 "(probably because it has a dynamic alloca).");
106
107 // Get the number of bytes to allocate from the FrameInfo
108 int NumBytes = (int) MFI.getStackSize();
109
110 unsigned SAVEri = SP::SAVEri;
111 unsigned SAVErr = SP::SAVErr;
112 if (FuncInfo->isLeafProc()) {
113 if (NumBytes == 0)
114 return;
115 SAVEri = SP::ADDri;
116 SAVErr = SP::ADDrr;
117 }
118
119 // The SPARC ABI is a bit odd in that it requires a reserved 92-byte
120 // (128 in v9) area in the user's stack, starting at %sp. Thus, the
121 // first part of the stack that can actually be used is located at
122 // %sp + 92.
123 //
124 // We therefore need to add that offset to the total stack size
125 // after all the stack objects are placed by
126 // PrologEpilogInserter calculateFrameObjectOffsets. However, since the stack needs to be
127 // aligned *after* the extra size is added, we need to disable
128 // calculateFrameObjectOffsets's built-in stack alignment, by having
129 // targetHandlesStackFrameRounding return true.
130
131
132 // Add the extra call frame stack size, if needed. (This is the same
133 // code as in PrologEpilogInserter, but also gets disabled by
134 // targetHandlesStackFrameRounding)
135 if (MFI.adjustsStack() && hasReservedCallFrame(MF))
136 NumBytes += MFI.getMaxCallFrameSize();
137
138 // Adds the SPARC subtarget-specific spill area to the stack
139 // size. Also ensures target-required alignment.
140 NumBytes = Subtarget.getAdjustedFrameSize(NumBytes);
141
142 // Finally, ensure that the size is sufficiently aligned for the
143 // data on the stack.
144 NumBytes = alignTo(NumBytes, MFI.getMaxAlign());
145
146 // Update stack size with corrected value.
147 MFI.setStackSize(NumBytes);
148
149 emitSPAdjustment(MF, MBB, MBBI, -NumBytes, SAVErr, SAVEri);
150
151 unsigned regFP = RegInfo.getDwarfRegNum(SP::I6, true);
152
153 // Emit ".cfi_def_cfa_register 30".
154 unsigned CFIIndex =
156 BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
157 .addCFIIndex(CFIIndex);
158
159 // Emit ".cfi_window_save".
160 CFIIndex = MF.addFrameInst(MCCFIInstruction::createWindowSave(nullptr));
161 BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
162 .addCFIIndex(CFIIndex);
163
164 unsigned regInRA = RegInfo.getDwarfRegNum(SP::I7, true);
165 unsigned regOutRA = RegInfo.getDwarfRegNum(SP::O7, true);
166 // Emit ".cfi_register 15, 31".
167 CFIIndex = MF.addFrameInst(
168 MCCFIInstruction::createRegister(nullptr, regOutRA, regInRA));
169 BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
170 .addCFIIndex(CFIIndex);
171
172 if (NeedsStackRealignment) {
173 int64_t Bias = Subtarget.getStackPointerBias();
174 unsigned regUnbiased;
175 if (Bias) {
176 // This clobbers G1 which we always know is available here.
177 regUnbiased = SP::G1;
178 // add %o6, BIAS, %g1
179 BuildMI(MBB, MBBI, dl, TII.get(SP::ADDri), regUnbiased)
180 .addReg(SP::O6).addImm(Bias);
181 } else
182 regUnbiased = SP::O6;
183
184 // andn %regUnbiased, MaxAlign-1, %regUnbiased
185 Align MaxAlign = MFI.getMaxAlign();
186 BuildMI(MBB, MBBI, dl, TII.get(SP::ANDNri), regUnbiased)
187 .addReg(regUnbiased)
188 .addImm(MaxAlign.value() - 1U);
189
190 if (Bias) {
191 // add %g1, -BIAS, %o6
192 BuildMI(MBB, MBBI, dl, TII.get(SP::ADDri), SP::O6)
193 .addReg(regUnbiased).addImm(-Bias);
194 }
195 }
196}
197
201 if (!hasReservedCallFrame(MF)) {
202 MachineInstr &MI = *I;
203 int Size = MI.getOperand(0).getImm();
204 if (MI.getOpcode() == SP::ADJCALLSTACKDOWN)
205 Size = -Size;
206
207 if (Size)
208 emitSPAdjustment(MF, MBB, I, Size, SP::ADDrr, SP::ADDri);
209 }
210 return MBB.erase(I);
211}
212
213
215 MachineBasicBlock &MBB) const {
218 const SparcInstrInfo &TII =
219 *static_cast<const SparcInstrInfo *>(MF.getSubtarget().getInstrInfo());
220 DebugLoc dl = MBBI->getDebugLoc();
221 assert((MBBI->getOpcode() == SP::RETL || MBBI->getOpcode() == SP::TAIL_CALL ||
222 MBBI->getOpcode() == SP::TAIL_CALLri) &&
223 "Can only put epilog before 'retl' or 'tail_call' instruction!");
224 if (!FuncInfo->isLeafProc()) {
225 BuildMI(MBB, MBBI, dl, TII.get(SP::RESTORErr), SP::G0).addReg(SP::G0)
226 .addReg(SP::G0);
227 return;
228 }
229 MachineFrameInfo &MFI = MF.getFrameInfo();
230
231 int NumBytes = (int) MFI.getStackSize();
232 if (NumBytes != 0)
233 emitSPAdjustment(MF, MBB, MBBI, NumBytes, SP::ADDrr, SP::ADDri);
234
235 // Preserve return address in %o7
236 if (MBBI->getOpcode() == SP::TAIL_CALL) {
237 MBB.addLiveIn(SP::O7);
238 BuildMI(MBB, MBBI, dl, TII.get(SP::ORrr), SP::G1)
239 .addReg(SP::G0)
240 .addReg(SP::O7);
241 BuildMI(MBB, MBBI, dl, TII.get(SP::ORrr), SP::O7)
242 .addReg(SP::G0)
243 .addReg(SP::G1);
244 }
245}
246
248 // Reserve call frame if there are no variable sized objects on the stack.
249 return !MF.getFrameInfo().hasVarSizedObjects();
250}
251
252// hasFP - Return true if the specified function should have a dedicated frame
253// pointer register. This is true if the function has variable sized allocas or
254// if frame pointer elimination is disabled.
256 const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();
257
258 const MachineFrameInfo &MFI = MF.getFrameInfo();
259 return MF.getTarget().Options.DisableFramePointerElim(MF) ||
260 RegInfo->hasStackRealignment(MF) || MFI.hasVarSizedObjects() ||
262}
263
266 Register &FrameReg) const {
267 const SparcSubtarget &Subtarget = MF.getSubtarget<SparcSubtarget>();
268 const MachineFrameInfo &MFI = MF.getFrameInfo();
269 const SparcRegisterInfo *RegInfo = Subtarget.getRegisterInfo();
271 bool isFixed = MFI.isFixedObjectIndex(FI);
272
273 // Addressable stack objects are accessed using neg. offsets from
274 // %fp, or positive offsets from %sp.
275 bool UseFP;
276
277 // Sparc uses FP-based references in general, even when "hasFP" is
278 // false. That function is rather a misnomer, because %fp is
279 // actually always available, unless isLeafProc.
280 if (FuncInfo->isLeafProc()) {
281 // If there's a leaf proc, all offsets need to be %sp-based,
282 // because we haven't caused %fp to actually point to our frame.
283 UseFP = false;
284 } else if (isFixed) {
285 // Otherwise, argument access should always use %fp.
286 UseFP = true;
287 } else if (RegInfo->hasStackRealignment(MF)) {
288 // If there is dynamic stack realignment, all local object
289 // references need to be via %sp, to take account of the
290 // re-alignment.
291 UseFP = false;
292 } else {
293 // Finally, default to using %fp.
294 UseFP = true;
295 }
296
297 int64_t FrameOffset = MF.getFrameInfo().getObjectOffset(FI) +
298 Subtarget.getStackPointerBias();
299
300 if (UseFP) {
301 FrameReg = RegInfo->getFrameRegister(MF);
302 return StackOffset::getFixed(FrameOffset);
303 } else {
304 FrameReg = SP::O6; // %sp
305 return StackOffset::getFixed(FrameOffset + MF.getFrameInfo().getStackSize());
306 }
307}
308
310{
311
312 for (unsigned reg = SP::I0; reg <= SP::I7; ++reg)
313 if (MRI->isPhysRegUsed(reg))
314 return false;
315
316 for (unsigned reg = SP::L0; reg <= SP::L7; ++reg)
317 if (MRI->isPhysRegUsed(reg))
318 return false;
319
320 return true;
321}
322
323bool SparcFrameLowering::isLeafProc(MachineFunction &MF) const
324{
325
327 MachineFrameInfo &MFI = MF.getFrameInfo();
328
329 return !(MFI.hasCalls() // has calls
330 || MRI.isPhysRegUsed(SP::L0) // Too many registers needed
331 || MRI.isPhysRegUsed(SP::O6) // %sp is used
332 || hasFP(MF) // need %fp
333 || MF.hasInlineAsm()); // has inline assembly
334}
335
336void SparcFrameLowering::remapRegsForLeafProc(MachineFunction &MF) const {
338 // Remap %i[0-7] to %o[0-7].
339 for (unsigned reg = SP::I0; reg <= SP::I7; ++reg) {
340 if (!MRI.isPhysRegUsed(reg))
341 continue;
342
343 unsigned mapped_reg = reg - SP::I0 + SP::O0;
344
345 // Replace I register with O register.
346 MRI.replaceRegWith(reg, mapped_reg);
347
348 // Also replace register pair super-registers.
349 if ((reg - SP::I0) % 2 == 0) {
350 unsigned preg = (reg - SP::I0) / 2 + SP::I0_I1;
351 unsigned mapped_preg = preg - SP::I0_I1 + SP::O0_O1;
352 MRI.replaceRegWith(preg, mapped_preg);
353 }
354 }
355
356 // Rewrite MBB's Live-ins.
357 for (MachineBasicBlock &MBB : MF) {
358 for (unsigned reg = SP::I0_I1; reg <= SP::I6_I7; ++reg) {
359 if (!MBB.isLiveIn(reg))
360 continue;
361 MBB.removeLiveIn(reg);
362 MBB.addLiveIn(reg - SP::I0_I1 + SP::O0_O1);
363 }
364 for (unsigned reg = SP::I0; reg <= SP::I7; ++reg) {
365 if (!MBB.isLiveIn(reg))
366 continue;
367 MBB.removeLiveIn(reg);
368 MBB.addLiveIn(reg - SP::I0 + SP::O0);
369 }
370 }
371
373#ifdef EXPENSIVE_CHECKS
374 MF.verify(0, "After LeafProc Remapping");
375#endif
376}
377
379 BitVector &SavedRegs,
380 RegScavenger *RS) const {
382 if (!DisableLeafProc && isLeafProc(MF)) {
384 MFI->setLeafProc(true);
385
386 remapRegsForLeafProc(MF);
387 }
388
389}
unsigned const MachineRegisterInfo * MRI
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator MBBI
#define LLVM_ATTRIBUTE_UNUSED
Definition: Compiler.h:199
uint64_t Size
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition: MD5.cpp:58
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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)
A debug info location.
Definition: DebugLoc.h:33
static MCCFIInstruction createDefCfaRegister(MCSymbol *L, unsigned Register, SMLoc Loc={})
.cfi_def_cfa_register modifies a rule for computing CFA.
Definition: MCDwarf.h:565
static MCCFIInstruction createRegister(MCSymbol *L, unsigned Register1, unsigned Register2, SMLoc Loc={})
.cfi_register Previous value of Register1 is saved in register Register2.
Definition: MCDwarf.h:615
static MCCFIInstruction createWindowSave(MCSymbol *L, SMLoc Loc={})
.cfi_window_save SPARC register window is saved.
Definition: MCDwarf.h:621
bool isLiveIn(MCPhysReg Reg, LaneBitmask LaneMask=LaneBitmask::getAll()) const
Return true if the specified register is in the live in set.
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.
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
void removeLiveIn(MCPhysReg Reg, LaneBitmask LaneMask=LaneBitmask::getAll())
Remove the specified register from 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.
unsigned addFrameInst(const MCCFIInstruction &Inst)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
bool hasInlineAsm() const
Returns true if the function contains any inline assembly.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineBasicBlock & front() const
const MachineInstrBuilder & addCFIIndex(unsigned CFIIndex) const
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:69
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 hasFP(const MachineFunction &MF) const override
hasFP - Return true if the specified function should have a dedicated frame pointer register.
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 ...
const SparcInstrInfo * getInstrInfo() const override
StackOffset holds a fixed and a scalable offset in bytes.
Definition: TypeSize.h:33
int64_t getFixed() const
Returns the fixed component of the stack.
Definition: TypeSize.h:49
Information about stack frame layout on the target.
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
bool DisableFramePointerElim(const MachineFunction &MF) const
DisableFramePointerElim - This returns true if frame pointer elimination optimization should be disab...
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
bool hasStackRealignment(const MachineFunction &MF) const
True if stack realignment is required and still possible.
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
virtual const TargetInstrInfo * getInstrInfo() const
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:443
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:174
static unsigned HIX22(int64_t imm)
Definition: Sparc.h:182
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:167
static unsigned LOX10(int64_t imm)
Definition: Sparc.h:186
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:178
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
uint64_t value() const
This is a hole in the type system and should not be abused.
Definition: Alignment.h:85
bool canRealignStack(const MachineFunction &MF) const override
Register getFrameRegister(const MachineFunction &MF) const override