LLVM  12.0.0git
VEFrameLowering.cpp
Go to the documentation of this file.
1 //===-- VEFrameLowering.cpp - VE 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 VE implementation of TargetFrameLowering class.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "VEFrameLowering.h"
14 #include "VEInstrInfo.h"
15 #include "VEMachineFunctionInfo.h"
16 #include "VESubtarget.h"
23 #include "llvm/IR/DataLayout.h"
24 #include "llvm/IR/Function.h"
28 
29 using namespace llvm;
30 
32  : TargetFrameLowering(TargetFrameLowering::StackGrowsDown, Align(16), 0,
33  Align(16)),
34  STI(ST) {}
35 
39  uint64_t NumBytes,
40  bool RequireFPUpdate) const {
41 
42  DebugLoc dl;
43  const VEInstrInfo &TII =
44  *static_cast<const VEInstrInfo *>(MF.getSubtarget().getInstrInfo());
45  // Insert following codes here as prologue
46  //
47  // st %fp, 0(,%sp)
48  // st %lr, 8(,%sp)
49  // st %got, 24(,%sp)
50  // st %plt, 32(,%sp)
51  // st %s17, 40(,%sp) iff this function is using s17 as BP
52  // or %fp, 0, %sp
53 
54  BuildMI(MBB, MBBI, dl, TII.get(VE::STrii))
55  .addReg(VE::SX11)
56  .addImm(0)
57  .addImm(0)
58  .addReg(VE::SX9);
59  BuildMI(MBB, MBBI, dl, TII.get(VE::STrii))
60  .addReg(VE::SX11)
61  .addImm(0)
62  .addImm(8)
63  .addReg(VE::SX10);
64  BuildMI(MBB, MBBI, dl, TII.get(VE::STrii))
65  .addReg(VE::SX11)
66  .addImm(0)
67  .addImm(24)
68  .addReg(VE::SX15);
69  BuildMI(MBB, MBBI, dl, TII.get(VE::STrii))
70  .addReg(VE::SX11)
71  .addImm(0)
72  .addImm(32)
73  .addReg(VE::SX16);
74  if (hasBP(MF))
75  BuildMI(MBB, MBBI, dl, TII.get(VE::STrii))
76  .addReg(VE::SX11)
77  .addImm(0)
78  .addImm(40)
79  .addReg(VE::SX17);
80  BuildMI(MBB, MBBI, dl, TII.get(VE::ORri), VE::SX9)
81  .addReg(VE::SX11)
82  .addImm(0);
83 }
84 
88  uint64_t NumBytes,
89  bool RequireFPUpdate) const {
90 
91  DebugLoc dl;
92  const VEInstrInfo &TII =
93  *static_cast<const VEInstrInfo *>(MF.getSubtarget().getInstrInfo());
94  // Insert following codes here as epilogue
95  //
96  // or %sp, 0, %fp
97  // ld %s17, 40(,%sp) iff this function is using s17 as BP
98  // ld %got, 32(,%sp)
99  // ld %plt, 24(,%sp)
100  // ld %lr, 8(,%sp)
101  // ld %fp, 0(,%sp)
102 
103  BuildMI(MBB, MBBI, dl, TII.get(VE::ORri), VE::SX11)
104  .addReg(VE::SX9)
105  .addImm(0);
106  if (hasBP(MF))
107  BuildMI(MBB, MBBI, dl, TII.get(VE::LDrii), VE::SX17)
108  .addReg(VE::SX11)
109  .addImm(0)
110  .addImm(40);
111  BuildMI(MBB, MBBI, dl, TII.get(VE::LDrii), VE::SX16)
112  .addReg(VE::SX11)
113  .addImm(0)
114  .addImm(32);
115  BuildMI(MBB, MBBI, dl, TII.get(VE::LDrii), VE::SX15)
116  .addReg(VE::SX11)
117  .addImm(0)
118  .addImm(24);
119  BuildMI(MBB, MBBI, dl, TII.get(VE::LDrii), VE::SX10)
120  .addReg(VE::SX11)
121  .addImm(0)
122  .addImm(8);
123  BuildMI(MBB, MBBI, dl, TII.get(VE::LDrii), VE::SX9)
124  .addReg(VE::SX11)
125  .addImm(0)
126  .addImm(0);
127 }
128 
129 void VEFrameLowering::emitSPAdjustment(MachineFunction &MF,
132  int64_t NumBytes,
133  MaybeAlign MaybeAlign) const {
134  DebugLoc dl;
135  const VEInstrInfo &TII =
136  *static_cast<const VEInstrInfo *>(MF.getSubtarget().getInstrInfo());
137 
138  if (NumBytes >= -64 && NumBytes < 63) {
139  BuildMI(MBB, MBBI, dl, TII.get(VE::ADDSLri), VE::SX11)
140  .addReg(VE::SX11)
141  .addImm(NumBytes);
142  return;
143  }
144 
145  // Emit following codes. This clobbers SX13 which we always know is
146  // available here.
147  // lea %s13,%lo(NumBytes)
148  // and %s13,%s13,(32)0
149  // lea.sl %sp,%hi(NumBytes)(%sp, %s13)
150  BuildMI(MBB, MBBI, dl, TII.get(VE::LEAzii), VE::SX13)
151  .addImm(0)
152  .addImm(0)
153  .addImm(Lo_32(NumBytes));
154  BuildMI(MBB, MBBI, dl, TII.get(VE::ANDrm), VE::SX13)
155  .addReg(VE::SX13)
156  .addImm(M0(32));
157  BuildMI(MBB, MBBI, dl, TII.get(VE::LEASLrri), VE::SX11)
158  .addReg(VE::SX11)
159  .addReg(VE::SX13)
160  .addImm(Hi_32(NumBytes));
161 
162  if (MaybeAlign) {
163  // and %sp, %sp, Align-1
164  BuildMI(MBB, MBBI, dl, TII.get(VE::ANDrm), VE::SX11)
165  .addReg(VE::SX11)
166  .addImm(M1(64 - Log2_64(MaybeAlign.valueOrOne().value())));
167  }
168 }
169 
170 void VEFrameLowering::emitSPExtend(MachineFunction &MF, MachineBasicBlock &MBB,
171  MachineBasicBlock::iterator MBBI) const {
172  DebugLoc dl;
173  const VEInstrInfo &TII =
174  *static_cast<const VEInstrInfo *>(MF.getSubtarget().getInstrInfo());
175 
176  // Emit following codes. It is not possible to insert multiple
177  // BasicBlocks in PEI pass, so we emit two pseudo instructions here.
178  //
179  // EXTEND_STACK // pseudo instrcution
180  // EXTEND_STACK_GUARD // pseudo instrcution
181  //
182  // EXTEND_STACK pseudo will be converted by ExpandPostRA pass into
183  // following instructions with multiple basic blocks later.
184  //
185  // thisBB:
186  // brge.l.t %sp, %sl, sinkBB
187  // syscallBB:
188  // ld %s61, 0x18(, %tp) // load param area
189  // or %s62, 0, %s0 // spill the value of %s0
190  // lea %s63, 0x13b // syscall # of grow
191  // shm.l %s63, 0x0(%s61) // store syscall # at addr:0
192  // shm.l %sl, 0x8(%s61) // store old limit at addr:8
193  // shm.l %sp, 0x10(%s61) // store new limit at addr:16
194  // monc // call monitor
195  // or %s0, 0, %s62 // restore the value of %s0
196  // sinkBB:
197  //
198  // EXTEND_STACK_GUARD pseudo will be simply eliminated by ExpandPostRA
199  // pass. This pseudo is required to be at the next of EXTEND_STACK
200  // pseudo in order to protect iteration loop in ExpandPostRA.
201 
202  BuildMI(MBB, MBBI, dl, TII.get(VE::EXTEND_STACK));
203  BuildMI(MBB, MBBI, dl, TII.get(VE::EXTEND_STACK_GUARD));
204 }
205 
207  MachineBasicBlock &MBB) const {
208  assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported");
209  MachineFrameInfo &MFI = MF.getFrameInfo();
210  const VEInstrInfo &TII = *STI.getInstrInfo();
211  const VERegisterInfo &RegInfo = *STI.getRegisterInfo();
212  MachineBasicBlock::iterator MBBI = MBB.begin();
213  // Debug location must be unknown since the first debug location is used
214  // to determine the end of the prologue.
215  DebugLoc dl;
216  bool NeedsStackRealignment = RegInfo.needsStackRealignment(MF);
217 
218  // FIXME: unfortunately, returning false from canRealignStack
219  // actually just causes needsStackRealignment to return false,
220  // rather than reporting an error, as would be sensible. This is
221  // poor, but fixing that bogosity is going to be a large project.
222  // For now, just see if it's lied, and report an error here.
223  if (!NeedsStackRealignment && MFI.getMaxAlign() > getStackAlign())
224  report_fatal_error("Function \"" + Twine(MF.getName()) +
225  "\" required "
226  "stack re-alignment, but LLVM couldn't handle it "
227  "(probably because it has a dynamic alloca).");
228 
229  // Get the number of bytes to allocate from the FrameInfo
230  uint64_t NumBytes = MFI.getStackSize();
231 
232  // The VE ABI requires a reserved 176 bytes area at the top
233  // of stack as described in VESubtarget.cpp. So, we adjust it here.
234  NumBytes = STI.getAdjustedFrameSize(NumBytes);
235 
236  // Finally, ensure that the size is sufficiently aligned for the
237  // data on the stack.
238  NumBytes = alignTo(NumBytes, MFI.getMaxAlign());
239 
240  // Update stack size with corrected value.
241  MFI.setStackSize(NumBytes);
242 
243  // Emit Prologue instructions to save %lr
244  emitPrologueInsns(MF, MBB, MBBI, NumBytes, true);
245 
246  // Emit stack adjust instructions
247  MaybeAlign RuntimeAlign =
248  NeedsStackRealignment ? MaybeAlign(MFI.getMaxAlign()) : None;
249  emitSPAdjustment(MF, MBB, MBBI, -(int64_t)NumBytes, RuntimeAlign);
250 
251  if (hasBP(MF)) {
252  // Copy SP to BP.
253  BuildMI(MBB, MBBI, dl, TII.get(VE::ORri), VE::SX17)
254  .addReg(VE::SX11)
255  .addImm(0);
256  }
257 
258  // Emit stack extend instructions
259  emitSPExtend(MF, MBB, MBBI);
260 
261  Register RegFP = RegInfo.getDwarfRegNum(VE::SX9, true);
262 
263  // Emit ".cfi_def_cfa_register 30".
264  unsigned CFIIndex =
266  BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
267  .addCFIIndex(CFIIndex);
268 
269  // Emit ".cfi_window_save".
270  CFIIndex = MF.addFrameInst(MCCFIInstruction::createWindowSave(nullptr));
271  BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION))
272  .addCFIIndex(CFIIndex);
273 }
274 
278  if (!hasReservedCallFrame(MF)) {
279  MachineInstr &MI = *I;
280  int64_t Size = MI.getOperand(0).getImm();
281  if (MI.getOpcode() == VE::ADJCALLSTACKDOWN)
282  Size = -Size;
283 
284  if (Size)
285  emitSPAdjustment(MF, MBB, I, Size);
286  }
287  return MBB.erase(I);
288 }
289 
291  MachineBasicBlock &MBB) const {
293  DebugLoc dl = MBBI->getDebugLoc();
294  MachineFrameInfo &MFI = MF.getFrameInfo();
295 
296  uint64_t NumBytes = MFI.getStackSize();
297 
298  // Emit Epilogue instructions to restore %lr
299  emitEpilogueInsns(MF, MBB, MBBI, NumBytes, true);
300 }
301 
302 // hasFP - Return true if the specified function should have a dedicated frame
303 // pointer register. This is true if the function has variable sized allocas
304 // or if frame pointer elimination is disabled. For the case of VE, we don't
305 // implement FP eliminator yet, but we returns false from this function to
306 // not refer fp from generated code.
308  const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();
309 
310  const MachineFrameInfo &MFI = MF.getFrameInfo();
311  return MF.getTarget().Options.DisableFramePointerElim(MF) ||
312  RegInfo->needsStackRealignment(MF) || MFI.hasVarSizedObjects() ||
313  MFI.isFrameAddressTaken();
314 }
315 
317  const MachineFrameInfo &MFI = MF.getFrameInfo();
319 
320  return MFI.hasVarSizedObjects() && TRI->needsStackRealignment(MF);
321 }
322 
324  Register &FrameReg) const {
325  const MachineFrameInfo &MFI = MF.getFrameInfo();
326  const VERegisterInfo *RegInfo = STI.getRegisterInfo();
327  const VEMachineFunctionInfo *FuncInfo = MF.getInfo<VEMachineFunctionInfo>();
328  bool isFixed = MFI.isFixedObjectIndex(FI);
329 
330  int64_t FrameOffset = MF.getFrameInfo().getObjectOffset(FI);
331 
332  if (FuncInfo->isLeafProc()) {
333  // If there's a leaf proc, all offsets need to be %sp-based,
334  // because we haven't caused %fp to actually point to our frame.
335  FrameReg = VE::SX11; // %sp
336  return FrameOffset + MF.getFrameInfo().getStackSize();
337  }
338  if (RegInfo->needsStackRealignment(MF) && !isFixed) {
339  // If there is dynamic stack realignment, all local object
340  // references need to be via %sp or %s17 (bp), to take account
341  // of the re-alignment.
342  if (hasBP(MF))
343  FrameReg = VE::SX17; // %bp
344  else
345  FrameReg = VE::SX11; // %sp
346  return FrameOffset + MF.getFrameInfo().getStackSize();
347  }
348  // Finally, default to using %fp.
349  FrameReg = RegInfo->getFrameRegister(MF);
350  return FrameOffset;
351 }
352 
353 bool VEFrameLowering::isLeafProc(MachineFunction &MF) const {
354 
356  MachineFrameInfo &MFI = MF.getFrameInfo();
357 
358  return !MFI.hasCalls() // No calls
359  && !MRI.isPhysRegUsed(VE::SX18) // Registers within limits
360  // (s18 is first CSR)
361  && !MRI.isPhysRegUsed(VE::SX11) // %sp un-used
362  && !hasFP(MF); // Don't need %fp
363 }
364 
366  BitVector &SavedRegs,
367  RegScavenger *RS) const {
369 
370  if (isLeafProc(MF)) {
372  MFI->setLeafProc(true);
373  }
374 }
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override
Align valueOrOne() const
For convenience, returns a valid alignment or 1 if undefined.
Definition: Alignment.h:144
void emitPrologueInsns(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, uint64_t NumBytes, bool RequireFPUpdate) const
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:140
This class represents lattice values for constants.
Definition: AllocatorList.h:23
unsigned M1(unsigned Val)
Definition: VE.h:353
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
Definition: MathExtras.h:354
VEFrameLowering(const VESubtarget &ST)
LLVM_NODISCARD unsigned addFrameInst(const MCCFIInstruction &Inst)
void emitEpilogueInsns(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, uint64_t NumBytes, bool RequireFPUpdate) const
unsigned const TargetRegisterInfo * TRI
A debug info location.
Definition: DebugLoc.h:33
const VERegisterInfo * getRegisterInfo() const override
Definition: VESubtarget.h:48
virtual void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
MachineBasicBlock & MBB
bool isFrameAddressTaken() const
This method may be called any time after instruction selection is complete to determine if there is a...
unsigned M0(unsigned Val)
Definition: VE.h:352
Register getFrameRegister(const MachineFunction &MF) const override
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:80
const HexagonInstrInfo * TII
const VEInstrInfo * getInstrInfo() const override
Definition: VESubtarget.h:44
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
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 ...
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:456
int 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...
bool DisableFramePointerElim(const MachineFunction &MF) const
DisableFramePointerElim - This returns true if frame pointer elimination optimization should be disab...
bool hasFP(const MachineFunction &MF) const override
hasFP - Return true if the specified function should have a dedicated frame pointer register...
iterator getLastNonDebugInstr()
Returns an iterator to the last non-debug instruction in the basic block, or end().
virtual const TargetInstrInfo * getInstrInfo() const
uint64_t value() const
This is a hole in the type system and should not be abused.
Definition: Alignment.h:85
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
This file declares the machine register scavenger class.
unsigned const MachineRegisterInfo * MRI
Align getStackAlign() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
static MCCFIInstruction createDefCfaRegister(MCSymbol *L, unsigned Register)
.cfi_def_cfa_register modifies a rule for computing CFA.
Definition: MCDwarf.h:492
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const override
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
static MCCFIInstruction createWindowSave(MCSymbol *L)
.cfi_window_save SPARC register window is saved.
Definition: MCDwarf.h:533
bool isFixedObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a fixed stack object.
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...
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
bool isPhysRegUsed(MCRegister PhysReg) const
Return true if the specified register is modified or read in this function.
bool hasReservedCallFrame(const MachineFunction &MF) const override
hasReservedCallFrame - Under normal circumstances, when a frame pointer is not required, we reserve argument space for call sites in the function immediately on entry to the current function.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
const MachineBasicBlock & front() const
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override
emitProlog/emitEpilog - These methods insert prolog and epilog code into the function.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment...
Definition: Alignment.h:119
Information about stack frame layout on the target.
int64_t getImm() const
int getAdjustedFrameSize(int stackSize) const
Given a actual stack size as determined by FrameInfo, this function returns adjusted framesize which ...
Definition: VESubtarget.cpp:47
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
Representation of each machine instruction.
Definition: MachineInstr.h:62
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition: Alignment.h:158
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
TargetOptions Options
#define I(x, y, z)
Definition: MD5.cpp:59
uint32_t Size
Definition: Profile.cpp:46
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
Definition: MathExtras.h:349
bool needsStackRealignment(const MachineFunction &MF) const
True if storage within the function requires the stack pointer to be aligned more than the normal cal...
bool hasBP(const MachineFunction &MF) const
IRTranslator LLVM IR MI
const VESubtarget & STI
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:466
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects...
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
unsigned Log2_64(uint64_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition: MathExtras.h:603
MachineBasicBlock MachineBasicBlock::iterator MBBI
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
bool hasCalls() const
Return true if the current function has any function calls.