LLVM: lib/Target/AVR/AVRFrameLowering.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
14
20
26
27namespace llvm {
28
31
34
35
36 return true;
37}
38
48
57 bool HasFP = hasFP(MF);
58
59
64 }
65
66
67
72
88 }
89 }
90
91
92 if (!HasFP) {
93 return;
94 }
95
98
99
100 while (
102 (MBBI->getOpcode() == AVR::PUSHRr || MBBI->getOpcode() == AVR::PUSHWRr)) {
104 }
105
106
110
111
113 MBBJ.addLiveIn(AVR::R29R28);
114 }
115
116 if (!FrameSize) {
117 return;
118 }
119
120
121 unsigned Opcode = (isUInt<6>(FrameSize) && STI.hasADDSUBIW()) ? AVR::SBIWRdK
122 : AVR::SUBIWRdK;
123
128
129 MI->getOperand(3).setIsDead();
130
131
135}
136
140
142
146
147
148
152 }
158 }
159}
160
164
165
166
168 return;
169 }
170
173 "Can only insert epilog into returning blocks");
174
180
181
184 return;
185 }
186
187
188 while (MBBI != MBB.begin()) {
190 int Opc = PI->getOpcode();
191
192 if (Opc != AVR::POPRd && Opc != AVR::POPWRd && !PI->isTerminator()) {
193 break;
194 }
195
197 }
198
199 if (FrameSize) {
200 unsigned Opcode;
201
202
203 if (isUInt<6>(FrameSize) && STI.hasADDSUBIW()) {
204 Opcode = AVR::ADIWRdK;
205 } else {
206 Opcode = AVR::SUBIWRdK;
207 FrameSize = -FrameSize;
208 }
209
210
214
215 MI->getOperand(3).setIsDead();
216 }
217
218
221
223}
224
225
226
227
228
229
230
231
232
233
241
245 if (CSI.empty()) {
246 return false;
247 }
248
249 unsigned CalleeFrameSize = 0;
255
258 bool IsNotLiveIn = .isLiveIn(Reg);
259
260
261
262 if (IsNotLiveIn)
263 for (const auto &LiveIn : MBB.liveins())
265 IsNotLiveIn = false;
267 break;
268 }
269
270 assert(TRI->getRegSizeInBits(*TRI->getMinimalPhysRegClass(Reg)) == 8 &&
271 "Invalid register size");
272
273
274
275
276 if (IsNotLiveIn) {
278 }
279
280
284 ++CalleeFrameSize;
285 }
286
288
289 return true;
290}
291
295 if (CSI.empty()) {
296 return false;
297 }
298
303
306
307 assert(TRI->getRegSizeInBits(*TRI->getMinimalPhysRegClass(Reg)) == 8 &&
308 "Invalid register size");
309
311 }
312
313 return true;
314}
315
316
317
321
324 if (MI.isCall())
325 break;
326
327 unsigned Opcode = MI.getOpcode();
328
329
330 if (Opcode != AVR::STDSPQRr && Opcode != AVR::STDWSPQRr)
331 continue;
332
333 assert(MI.getOperand(0).getReg() == AVR::SP &&
334 "SP is expected as base pointer");
335
336
337
338 unsigned STOpc =
339 (Opcode == AVR::STDWSPQRr) ? AVR::STDWPtrQRr : AVR::STDPtrQRr;
340
341 MI.setDesc(TII.get(STOpc));
342 MI.getOperand(0).setReg(AVR::R31R30);
343 }
344}
345
351
354 }
355
357 unsigned int Opcode = MI->getOpcode();
358 int Amount = TII.getFrameSize(*MI);
359
360 if (Amount == 0) {
362 }
363
365
366 if (Opcode == TII.getCallFrameSetupOpcode()) {
367
368
369
370
371
373
378 New->getOperand(3).setIsDead();
379
381
382
383
385 } else {
386 assert(Opcode == TII.getCallFrameDestroyOpcode());
387
388
389
390
391
392
393 unsigned AddOpcode;
394
395 if (isUInt<6>(Amount) && STI.hasADDSUBIW()) {
396 AddOpcode = AVR::ADIWRdK;
397 } else {
398 AddOpcode = AVR::SUBIWRdK;
399 Amount = -Amount;
400 }
401
402
404
408 New->getOperand(3).setIsDead();
409
412 }
413
415}
416
421
422
424 SavedRegs.set(AVR::R29);
425 SavedRegs.set(AVR::R28);
426 }
427}
428
429
430
431
435
439
440
441
443
444
445
447
450 break;
451 }
452 }
453 }
454
455
456
458 return false;
459 }
460
461
462
465 int Opcode = MI.getOpcode();
466
467 if ((Opcode != AVR::LDDRdPtrQ) && (Opcode != AVR::LDDWRdPtrQ) &&
468 (Opcode != AVR::STDPtrQRr) && (Opcode != AVR::STDWPtrQRr) &&
469 (Opcode != AVR::FRMIDX)) {
470 continue;
471 }
472
474 if (!MO.isFI()) {
475 continue;
476 }
477
480 return false;
481 }
482 }
483 }
484 }
485
486 return false;
487 }
488
490};
491
493
494
496
497}
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
const TargetInstrInfo & TII
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
Register const TargetRegisterInfo * TRI
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override
emitProlog/emitEpilog - These methods insert prolog and epilog code into the function.
Definition AVRFrameLowering.cpp:49
MachineBasicBlock::iterator eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const override
This method is called during prolog/epilog code insertion to eliminate call frame setup and destroy p...
Definition AVRFrameLowering.cpp:346
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override
Definition AVRFrameLowering.cpp:161
bool hasReservedCallFrame(const MachineFunction &MF) const override
hasReservedCallFrame - Under normal circumstances, when a frame pointer is not required,...
Definition AVRFrameLowering.cpp:39
AVRFrameLowering()
Definition AVRFrameLowering.cpp:29
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 AVRFrameLowering.cpp:292
bool canSimplifyCallFramePseudos(const MachineFunction &MF) const override
canSimplifyCallFramePseudos - When possible, it's best to simplify the call frame pseudo ops before d...
Definition AVRFrameLowering.cpp:32
bool hasFPImpl(const MachineFunction &MF) const override
Definition AVRFrameLowering.cpp:234
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const override
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
Definition AVRFrameLowering.cpp:417
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 AVRFrameLowering.cpp:242
Utilities related to the AVR instruction set.
Contains AVR-specific information for each MachineFunction.
bool isInterruptHandler() const
bool getHasSpills() const
void setCalleeSavedFrameSize(unsigned Bytes)
unsigned getCalleeSavedFrameSize() const
bool getHasStackArgs() const
bool getHasAllocas() const
void setHasStackArgs(bool B)
void setHasAllocas(bool B)
bool isInterruptOrSignalHandler() const
Checks if the function is some form of interrupt service routine.
A specific AVR target MCU.
Register getTmpRegister() const
Register getZeroRegister() const
const AVRInstrInfo * getInstrInfo() const override
const AVRRegisterInfo * getRegisterInfo() const override
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
bool empty() const
empty - Check if the array is empty.
The CalleeSavedInfo class tracks the information need to locate where a callee saved register is in t...
FunctionPass class - This class is used to implement most global optimizations.
Wrapper class representing physical registers. Should be passed by value.
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.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
unsigned getNumObjects() const
Return the number of objects.
int getObjectIndexEnd() const
Return one past the maximum frame object index.
unsigned getNumFixedObjects() const
Return the number of fixed objects.
bool isFixedObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a fixed stack object.
MachineFunctionPass(char &ID)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
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 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.
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
StringRef - Represent a constant reference to a string, i.e.
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...
TargetFrameLowering(StackDirection D, Align StackAl, int LAO, Align TransAl=Align(1), bool StackReal=true)
Align getStackAlign() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
TargetInstrInfo - Interface to description of machine instruction set.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
@ Define
Register definition.
@ Kill
The last use of a register.
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
static void fixStackStores(MachineBasicBlock &MBB, MachineBasicBlock::iterator StartMI, const TargetInstrInfo &TII)
Replace pseudo store instructions that pass arguments through the stack with real instructions.
Definition AVRFrameLowering.cpp:318
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
FunctionPass * createAVRFrameAnalyzerPass()
Creates instance of the frame analyzer pass.
Definition AVRFrameLowering.cpp:495
auto reverse(ContainerTy &&C)
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
unsigned getKillRegState(bool B)
static void restoreStatusRegister(MachineFunction &MF, MachineBasicBlock &MBB)
Definition AVRFrameLowering.cpp:137
The frame analyzer pass.
Definition AVRFrameLowering.cpp:432
static char ID
Definition AVRFrameLowering.cpp:433
AVRFrameAnalyzer()
Definition AVRFrameLowering.cpp:434
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
Definition AVRFrameLowering.cpp:436
StringRef getPassName() const override
getPassName - Return a nice clean name for a pass.
Definition AVRFrameLowering.cpp:489
This struct is a compact representation of a valid (non-zero power of two) alignment.