LLVM: lib/Target/Xtensa/XtensaFrameLowering.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
23
24using namespace llvm;
25
26
27
28
29#define UNITS_PER_WORD 4
30#define MIN_FRAME_SIZE (8 * UNITS_PER_WORD)
31
35 STI(STI), TII(*STI.getInstrInfo()), TRI(STI.getRegisterInfo()) {}
36
42
45 assert(&MBB == &MF.front() && "Shrink-wrapping not yet implemented");
53
54
56 uint64_t PrevStackSize = StackSize;
57
58
59 StackSize += (16 - StackSize) & 0xf;
60
61 if (STI.isWindowedABI()) {
62 StackSize += 32;
64 if (MaxAlignment > 32)
65 StackSize += MaxAlignment;
66
67 if (StackSize <= 32760) {
71 } else {
72
74
83 }
84
85
86
87
88
89
90
92 if (MaxAlignment > 32) {
93 TII.loadImmediate(MBB, MBBI, &RegMisAlign, MaxAlignment - 1);
94 TII.loadImmediate(MBB, MBBI, &Reg, MaxAlignment);
101 .addReg(RegMisAlign);
105 }
106
107
108
113 }
114
115
117
122
124 nullptr, MRI->getDwarfRegNum(FP, true), StackSize);
126 BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))
128 } else {
129
132 BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))
134 }
135 } else {
136
138 return;
139
140
141 TII.adjustStackPtr(SP, -StackSize, MBB, MBBI);
142
143
144 unsigned CFIIndex =
146 BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))
148
150
151 if (!CSI.empty()) {
152
153
154
155
156
157 for (unsigned i = 0, e = CSI.size(); i < e; ++i) {
158#ifndef NDEBUG
160 int FI = Info.getFrameIdx();
161 int StoreFI = 0;
162
163
164 bool IsStoreInst = false;
165 if (MBBI->getOpcode() == TargetOpcode::COPY && Info.isSpilledToReg()) {
166 Register DstReg = MBBI->getOperand(0).getReg();
168 IsStoreInst = Info.getDstReg() == DstReg.asMCReg() &&
169 Info.getReg() == Reg.asMCReg();
170 } else {
171 Register Reg = TII.isStoreToStackSlot(*MBBI, StoreFI);
172 IsStoreInst = Reg.asMCReg() == Info.getReg() && StoreFI == FI;
173 }
174 assert(IsStoreInst &&
175 "Unexpected callee-saved register store instruction");
176#endif
178 }
179
180
181
182 for (const auto &I : CSI) {
185
187 nullptr, MRI->getDwarfRegNum(Reg, 1), Offset));
188 BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))
190 }
191 }
192
193
195
200
201
202 unsigned CFIIndex =
204 nullptr, MRI->getDwarfRegNum(FP, true)));
205 BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))
207 }
208 }
209
210 if (StackSize != PrevStackSize) {
212
216
217 if (SPOffset < 0)
218 MFI.setObjectOffset(i, SPOffset - StackSize + PrevStackSize);
219 }
220 }
221 }
222}
223
231
232
234
235
236
237
239
241
242
243
244 for (unsigned i = 0, e = CSI.size(); i < e; ++i) {
245 --I;
246#ifndef NDEBUG
248 int FI = Info.getFrameIdx();
249 int LoadFI = 0;
250
251
252 bool IsRestoreInst = false;
253 if (I->getOpcode() == TargetOpcode::COPY && Info.isSpilledToReg()) {
254 Register Reg = I->getOperand(0).getReg();
255 Register DstReg = I->getOperand(1).getReg();
256 IsRestoreInst = Info.getDstReg() == DstReg.asMCReg() &&
257 Info.getReg() == Reg.asMCReg();
258 } else {
259 Register Reg = TII.isLoadFromStackSlot(*I, LoadFI);
260 IsRestoreInst = Info.getReg() == Reg.asMCReg() && LoadFI == FI;
261 }
262 assert(IsRestoreInst &&
263 "Unexpected callee-saved register restore instruction");
264#endif
265 }
266 if (STI.isWindowedABI()) {
267
268
269
270
271
272
273
274 } else {
276 }
277 }
278
279 if (STI.isWindowedABI())
280 return;
281
282
284
285 if (!StackSize)
286 return;
287
288
289 TII.adjustStackPtr(SP, StackSize, MBB, MBBI);
290}
291
297
298 if (STI.isWindowedABI())
299 return true;
300
301 for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
302
303
304
305
306
308 bool IsA0AndRetAddrIsTaken =
310 if (!IsA0AndRetAddrIsTaken)
312
313
314 bool IsKill = !IsA0AndRetAddrIsTaken;
316 TII.storeRegToStackSlot(EntryBlock, MI, Reg, IsKill, CSI[i].getFrameIdx(),
318 }
319
320 return true;
321}
322
326 if (STI.isWindowedABI())
327 return true;
329}
330
331
336 int64_t Amount = I->getOperand(0).getImm();
337
338 if (I->getOpcode() == Xtensa::ADJCALLSTACKDOWN)
339 Amount = -Amount;
340
341 TII.adjustStackPtr(Xtensa::SP, Amount, MBB, I);
342 }
343
345}
346
351
352 if (STI.isWindowedABI()) {
353 return;
354 }
355
357
358
361}
362
365
369 unsigned ScavSlotsNum = 0;
370
372 ScavSlotsNum = 1;
373
374
376 if (IsLargeFunction)
377 ScavSlotsNum = std::max(ScavSlotsNum, 1u);
378
380 unsigned Size = TRI->getSpillSize(RC);
381 Align Alignment = TRI->getSpillAlign(RC);
382 for (unsigned I = 0; I < ScavSlotsNum; I++) {
384 RS->addScavengingFrameIndex(FI);
385
386 if (IsLargeFunction &&
387 XtensaFI->getBranchRelaxationScratchFrameIndex() == -1)
388 XtensaFI->setBranchRelaxationScratchFrameIndex(FI);
389 }
390}
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
Promote Memory to Register
This file declares the machine register scavenger class.
#define MIN_FRAME_SIZE
Definition XtensaFrameLowering.cpp:30
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
The CalleeSavedInfo class tracks the information need to locate where a callee saved register is in t...
static MCCFIInstruction createDefCfaRegister(MCSymbol *L, unsigned Register, SMLoc Loc={})
.cfi_def_cfa_register modifies a rule for computing CFA.
static MCCFIInstruction cfiDefCfa(MCSymbol *L, unsigned Register, int64_t Offset, SMLoc Loc={})
.cfi_def_cfa defines a rule for computing CFA as: take address from Register and add Offset to it.
static MCCFIInstruction createOffset(MCSymbol *L, unsigned Register, int64_t Offset, SMLoc Loc={})
.cfi_offset Previous value of Register is saved at offset Offset from CFA.
static MCCFIInstruction cfiDefCfaOffset(MCSymbol *L, int64_t Offset, SMLoc Loc={})
.cfi_def_cfa_offset modifies a rule for computing CFA.
const MCRegisterInfo * getRegisterInfo() const
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
Wrapper class representing physical registers. Should be passed by value.
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
MachineInstrBundleIterator< MachineInstr > iterator
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 isReturnAddressTaken() 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...
void setObjectOffset(int ObjectIdx, int64_t SPOffset)
Set the stack frame offset of the specified object.
LLVM_ABI int CreateSpillStackObject(uint64_t Size, Align Alignment)
Create a new statically sized stack object that represents a spill slot, returning a nonnegative iden...
LLVM_ABI uint64_t estimateStackSize(const MachineFunction &MF) const
Estimate and return the size of the stack frame.
const std::vector< CalleeSavedInfo > & getCalleeSavedInfo() const
Returns a reference to call saved info vector for the current function.
int getObjectIndexEnd() const
Return one past the maximum frame object index.
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.
int getObjectIndexBegin() const
Return the minimum frame object index.
bool isDeadObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a dead object.
unsigned addFrameInst(const MCCFIInstruction &Inst)
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MCContext & getContext() const
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineBasicBlock & front() const
int64_t estimateFunctionSizeInBytes()
Return an estimate of the function's code size, taking into account block and function alignment.
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
const MachineInstrBuilder & addCFIIndex(unsigned CFIIndex) const
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) 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.
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
Wrapper class representing virtual and physical registers.
MCRegister asMCReg() const
Utility to check-convert this value to a MCRegister.
bool hasFP(const MachineFunction &MF) const
hasFP - Return true if the specified function should have a dedicated frame pointer register.
virtual bool hasReservedCallFrame(const MachineFunction &MF) const
hasReservedCallFrame - Under normal circumstances, when a frame pointer is not required,...
virtual void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
TargetFrameLowering(StackDirection D, Align StackAl, int LAO, Align TransAl=Align(1), bool StackReal=true)
virtual bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, MutableArrayRef< CalleeSavedInfo > CSI, const TargetRegisterInfo *TRI) const
restoreCalleeSavedRegisters - Issues instruction(s) to restore all callee saved registers and returns...
LLVM_ABI 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...
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override
Definition XtensaFrameLowering.cpp:224
void processFunctionBeforeFrameFinalized(MachineFunction &MF, RegScavenger *RS) const override
processFunctionBeforeFrameFinalized - This method is called immediately before the specified function...
Definition XtensaFrameLowering.cpp:363
bool hasFPImpl(const MachineFunction &MF) const override
Definition XtensaFrameLowering.cpp:37
bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, MutableArrayRef< CalleeSavedInfo > CSI, const TargetRegisterInfo *TRI) const override
restoreCalleeSavedRegisters - Issues instruction(s) to restore all callee saved registers and returns...
Definition XtensaFrameLowering.cpp:323
void emitPrologue(MachineFunction &, MachineBasicBlock &) const override
emitProlog/emitEpilog - These methods insert prolog and epilog code into the function.
Definition XtensaFrameLowering.cpp:43
XtensaFrameLowering(const XtensaSubtarget &STI)
Definition XtensaFrameLowering.cpp:32
bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, ArrayRef< CalleeSavedInfo > CSI, const TargetRegisterInfo *TRI) const override
spillCalleeSavedRegisters - Issues instruction(s) to spill all callee saved registers and returns tru...
Definition XtensaFrameLowering.cpp:292
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...
Definition XtensaFrameLowering.cpp:332
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS) const override
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
Definition XtensaFrameLowering.cpp:347
bool isSaveFrameRegister() const
@ Define
Register definition.
@ Kill
The last use of a register.
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
This struct is a compact representation of a valid (non-zero power of two) alignment.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.