1 //===-- AVRFrameLowering.cpp - AVR 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 AVR implementation of TargetFrameLowering class.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "AVRFrameLowering.h"
14 
15 #include "AVR.h"
16 #include "AVRInstrInfo.h"
17 #include "AVRMachineFunctionInfo.h"
18 #include "AVRTargetMachine.h"
19 #include "MCTargetDesc/AVRMCTargetDesc.h"
20 
21 #include "llvm/CodeGen/MachineFrameInfo.h"
22 #include "llvm/CodeGen/MachineFunction.h"
23 #include "llvm/CodeGen/MachineFunctionPass.h"
24 #include "llvm/CodeGen/MachineInstrBuilder.h"
25 #include "llvm/CodeGen/MachineRegisterInfo.h"
26 #include "llvm/IR/Function.h"
27 
28 #include <vector>
29 
30 namespace llvm {
31 
AVRFrameLowering()32 AVRFrameLowering::AVRFrameLowering()
33     : TargetFrameLowering(TargetFrameLowering::StackGrowsDown, Align(1), -2) {}
34 
canSimplifyCallFramePseudos(const MachineFunction & MF) const35 bool AVRFrameLowering::canSimplifyCallFramePseudos(
36     const MachineFunction &MF) const {
37   // Always simplify call frame pseudo instructions, even when
38   // hasReservedCallFrame is false.
39   return true;
40 }
41 
hasReservedCallFrame(const MachineFunction & MF) const42 bool AVRFrameLowering::hasReservedCallFrame(const MachineFunction &MF) const {
43   // Reserve call frame memory in function prologue under the following
44   // conditions:
45   // - Y pointer is reserved to be the frame pointer.
46   // - The function does not contain variable sized objects.
47 
48   const MachineFrameInfo &MFI = MF.getFrameInfo();
49   return hasFP(MF) && !MFI.hasVarSizedObjects();
50 }
51 
emitPrologue(MachineFunction & MF,MachineBasicBlock & MBB) const52 void AVRFrameLowering::emitPrologue(MachineFunction &MF,
53                                     MachineBasicBlock &MBB) const {
54   MachineBasicBlock::iterator MBBI = MBB.begin();
55   DebugLoc DL = (MBBI != MBB.end()) ? MBBI->getDebugLoc() : DebugLoc();
56   const AVRSubtarget &STI = MF.getSubtarget<AVRSubtarget>();
57   const AVRInstrInfo &TII = *STI.getInstrInfo();
58   const AVRMachineFunctionInfo *AFI = MF.getInfo<AVRMachineFunctionInfo>();
59   const MachineRegisterInfo &MRI = MF.getRegInfo();
60   bool HasFP = hasFP(MF);
61 
62   // Interrupt handlers re-enable interrupts in function entry.
63   if (AFI->isInterruptHandler()) {
64     BuildMI(MBB, MBBI, DL, TII.get(AVR::BSETs))
65         .addImm(0x07)
66         .setMIFlag(MachineInstr::FrameSetup);
67   }
68 
69   // Emit special prologue code to save R1, R0 and SREG in interrupt/signal
70   // handlers before saving any other registers.
71   if (AFI->isInterruptOrSignalHandler()) {
72     BuildMI(MBB, MBBI, DL, TII.get(AVR::PUSHRr))
73         .addReg(STI.getTmpRegister(), RegState::Kill)
74         .setMIFlag(MachineInstr::FrameSetup);
75 
76     BuildMI(MBB, MBBI, DL, TII.get(AVR::INRdA), STI.getTmpRegister())
77         .addImm(STI.getIORegSREG())
78         .setMIFlag(MachineInstr::FrameSetup);
79     BuildMI(MBB, MBBI, DL, TII.get(AVR::PUSHRr))
80         .addReg(STI.getTmpRegister(), RegState::Kill)
81         .setMIFlag(MachineInstr::FrameSetup);
82     if (!MRI.reg_empty(STI.getZeroRegister())) {
83       BuildMI(MBB, MBBI, DL, TII.get(AVR::PUSHRr))
84           .addReg(STI.getZeroRegister(), RegState::Kill)
85           .setMIFlag(MachineInstr::FrameSetup);
86       BuildMI(MBB, MBBI, DL, TII.get(AVR::EORRdRr))
87           .addReg(STI.getZeroRegister(), RegState::Define)
88           .addReg(STI.getZeroRegister(), RegState::Kill)
89           .addReg(STI.getZeroRegister(), RegState::Kill)
90           .setMIFlag(MachineInstr::FrameSetup);
91     }
92   }
93 
94   // Early exit if the frame pointer is not needed in this function.
95   if (!HasFP) {
96     return;
97   }
98 
99   const MachineFrameInfo &MFI = MF.getFrameInfo();
100   unsigned FrameSize = MFI.getStackSize() - AFI->getCalleeSavedFrameSize();
101 
102   // Skip the callee-saved push instructions.
103   while (
104       (MBBI != MBB.end()) && MBBI->getFlag(MachineInstr::FrameSetup) &&
105       (MBBI->getOpcode() == AVR::PUSHRr || MBBI->getOpcode() == AVR::PUSHWRr)) {
106     ++MBBI;
107   }
108 
109   // Update Y with the new base value.
110   BuildMI(MBB, MBBI, DL, TII.get(AVR::SPREAD), AVR::R29R28)
111       .addReg(AVR::SP)
112       .setMIFlag(MachineInstr::FrameSetup);
113 
114   // Mark the FramePtr as live-in in every block except the entry.
115   for (MachineBasicBlock &MBBJ : llvm::drop_begin(MF)) {
116     MBBJ.addLiveIn(AVR::R29R28);
117   }
118 
119   if (!FrameSize) {
120     return;
121   }
122 
123   // Reserve the necessary frame memory by doing FP -= <size>.
124   unsigned Opcode = (isUInt<6>(FrameSize) && STI.hasADDSUBIW()) ? AVR::SBIWRdK
125                                                                 : AVR::SUBIWRdK;
126 
127   MachineInstr *MI = BuildMI(MBB, MBBI, DL, TII.get(Opcode), AVR::R29R28)
128                          .addReg(AVR::R29R28, RegState::Kill)
129                          .addImm(FrameSize)
130                          .setMIFlag(MachineInstr::FrameSetup);
131   // The SREG implicit def is dead.
132   MI->getOperand(3).setIsDead();
133 
134   // Write back R29R28 to SP and temporarily disable interrupts.
135   BuildMI(MBB, MBBI, DL, TII.get(AVR::SPWRITE), AVR::SP)
136       .addReg(AVR::R29R28)
137       .setMIFlag(MachineInstr::FrameSetup);
138 }
139 
restoreStatusRegister(MachineFunction & MF,MachineBasicBlock & MBB)140 static void restoreStatusRegister(MachineFunction &MF, MachineBasicBlock &MBB) {
141   const AVRMachineFunctionInfo *AFI = MF.getInfo<AVRMachineFunctionInfo>();
142   const MachineRegisterInfo &MRI = MF.getRegInfo();
143 
144   MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
145 
146   DebugLoc DL = MBBI->getDebugLoc();
147   const AVRSubtarget &STI = MF.getSubtarget<AVRSubtarget>();
148   const AVRInstrInfo &TII = *STI.getInstrInfo();
149 
150   // Emit special epilogue code to restore R1, R0 and SREG in interrupt/signal
151   // handlers at the very end of the function, just before reti.
152   if (AFI->isInterruptOrSignalHandler()) {
153     if (!MRI.reg_empty(STI.getZeroRegister())) {
154       BuildMI(MBB, MBBI, DL, TII.get(AVR::POPRd), STI.getZeroRegister());
155     }
156     BuildMI(MBB, MBBI, DL, TII.get(AVR::POPRd), STI.getTmpRegister());
157     BuildMI(MBB, MBBI, DL, TII.get(AVR::OUTARr))
158         .addImm(STI.getIORegSREG())
159         .addReg(STI.getTmpRegister(), RegState::Kill);
160     BuildMI(MBB, MBBI, DL, TII.get(AVR::POPRd), STI.getTmpRegister());
161   }
162 }
163 
emitEpilogue(MachineFunction & MF,MachineBasicBlock & MBB) const164 void AVRFrameLowering::emitEpilogue(MachineFunction &MF,
165                                     MachineBasicBlock &MBB) const {
166   const AVRMachineFunctionInfo *AFI = MF.getInfo<AVRMachineFunctionInfo>();
167 
168   // Early exit if the frame pointer is not needed in this function except for
169   // signal/interrupt handlers where special code generation is required.
170   if (!hasFP(MF) && !AFI->isInterruptOrSignalHandler()) {
171     return;
172   }
173 
174   MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
175   assert(MBBI->getDesc().isReturn() &&
176          "Can only insert epilog into returning blocks");
177 
178   DebugLoc DL = MBBI->getDebugLoc();
179   const MachineFrameInfo &MFI = MF.getFrameInfo();
180   unsigned FrameSize = MFI.getStackSize() - AFI->getCalleeSavedFrameSize();
181   const AVRSubtarget &STI = MF.getSubtarget<AVRSubtarget>();
182   const AVRInstrInfo &TII = *STI.getInstrInfo();
183 
184   // Early exit if there is no need to restore the frame pointer.
185   if (!FrameSize && !MF.getFrameInfo().hasVarSizedObjects()) {
186     restoreStatusRegister(MF, MBB);
187     return;
188   }
189 
190   // Skip the callee-saved pop instructions.
191   while (MBBI != MBB.begin()) {
192     MachineBasicBlock::iterator PI = std::prev(MBBI);
193     int Opc = PI->getOpcode();
194 
195     if (Opc != AVR::POPRd && Opc != AVR::POPWRd && !PI->isTerminator()) {
196       break;
197     }
198 
199     --MBBI;
200   }
201 
202   if (FrameSize) {
203     unsigned Opcode;
204 
205     // Select the optimal opcode depending on how big it is.
206     if (isUInt<6>(FrameSize) && STI.hasADDSUBIW()) {
207       Opcode = AVR::ADIWRdK;
208     } else {
209       Opcode = AVR::SUBIWRdK;
210       FrameSize = -FrameSize;
211     }
212 
213     // Restore the frame pointer by doing FP += <size>.
214     MachineInstr *MI = BuildMI(MBB, MBBI, DL, TII.get(Opcode), AVR::R29R28)
215                            .addReg(AVR::R29R28, RegState::Kill)
216                            .addImm(FrameSize);
217     // The SREG implicit def is dead.
218     MI->getOperand(3).setIsDead();
219   }
220 
221   // Write back R29R28 to SP and temporarily disable interrupts.
222   BuildMI(MBB, MBBI, DL, TII.get(AVR::SPWRITE), AVR::SP)
223       .addReg(AVR::R29R28, RegState::Kill);
224 
225   restoreStatusRegister(MF, MBB);
226 }
227 
228 // Return true if the specified function should have a dedicated frame
229 // pointer register. This is true if the function meets any of the following
230 // conditions:
231 //  - a register has been spilled
232 //  - has allocas
233 //  - input arguments are passed using the stack
234 //
235 // Notice that strictly this is not a frame pointer because it contains SP after
236 // frame allocation instead of having the original SP in function entry.
hasFP(const MachineFunction & MF) const237 bool AVRFrameLowering::hasFP(const MachineFunction &MF) const {
238   const AVRMachineFunctionInfo *FuncInfo = MF.getInfo<AVRMachineFunctionInfo>();
239 
240   return (FuncInfo->getHasSpills() || FuncInfo->getHasAllocas() ||
241           FuncInfo->getHasStackArgs() ||
242           MF.getFrameInfo().hasVarSizedObjects());
243 }
244 
spillCalleeSavedRegisters(MachineBasicBlock & MBB,MachineBasicBlock::iterator MI,ArrayRef<CalleeSavedInfo> CSI,const TargetRegisterInfo * TRI) const245 bool AVRFrameLowering::spillCalleeSavedRegisters(
246     MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
247     ArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const {
248   if (CSI.empty()) {
249     return false;
250   }
251 
252   unsigned CalleeFrameSize = 0;
253   DebugLoc DL = MBB.findDebugLoc(MI);
254   MachineFunction &MF = *MBB.getParent();
255   const AVRSubtarget &STI = MF.getSubtarget<AVRSubtarget>();
256   const TargetInstrInfo &TII = *STI.getInstrInfo();
257   AVRMachineFunctionInfo *AVRFI = MF.getInfo<AVRMachineFunctionInfo>();
258 
259   for (const CalleeSavedInfo &I : llvm::reverse(CSI)) {
260     Register Reg = I.getReg();
261     bool IsNotLiveIn = !MBB.isLiveIn(Reg);
262 
263     assert(TRI->getRegSizeInBits(*TRI->getMinimalPhysRegClass(Reg)) == 8 &&
264            "Invalid register size");
265 
266     // Add the callee-saved register as live-in only if it is not already a
267     // live-in register, this usually happens with arguments that are passed
268     // through callee-saved registers.
269     if (IsNotLiveIn) {
270       MBB.addLiveIn(Reg);
271     }
272 
273     // Do not kill the register when it is an input argument.
274     BuildMI(MBB, MI, DL, TII.get(AVR::PUSHRr))
275         .addReg(Reg, getKillRegState(IsNotLiveIn))
276         .setMIFlag(MachineInstr::FrameSetup);
277     ++CalleeFrameSize;
278   }
279 
280   AVRFI->setCalleeSavedFrameSize(CalleeFrameSize);
281 
282   return true;
283 }
284 
restoreCalleeSavedRegisters(MachineBasicBlock & MBB,MachineBasicBlock::iterator MI,MutableArrayRef<CalleeSavedInfo> CSI,const TargetRegisterInfo * TRI) const285 bool AVRFrameLowering::restoreCalleeSavedRegisters(
286     MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
287     MutableArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const {
288   if (CSI.empty()) {
289     return false;
290   }
291 
292   DebugLoc DL = MBB.findDebugLoc(MI);
293   const MachineFunction &MF = *MBB.getParent();
294   const AVRSubtarget &STI = MF.getSubtarget<AVRSubtarget>();
295   const TargetInstrInfo &TII = *STI.getInstrInfo();
296 
297   for (const CalleeSavedInfo &CCSI : CSI) {
298     Register Reg = CCSI.getReg();
299 
300     assert(TRI->getRegSizeInBits(*TRI->getMinimalPhysRegClass(Reg)) == 8 &&
301            "Invalid register size");
302 
303     BuildMI(MBB, MI, DL, TII.get(AVR::POPRd), Reg);
304   }
305 
306   return true;
307 }
308 
309 /// Replace pseudo store instructions that pass arguments through the stack with
310 /// real instructions.
fixStackStores(MachineBasicBlock & MBB,MachineBasicBlock::iterator StartMI,const TargetInstrInfo & TII)311 static void fixStackStores(MachineBasicBlock &MBB,
312                            MachineBasicBlock::iterator StartMI,
313                            const TargetInstrInfo &TII) {
314   // Iterate through the BB until we hit a call instruction or we reach the end.
315   for (MachineInstr &MI :
316        llvm::make_early_inc_range(llvm::make_range(StartMI, MBB.end()))) {
317     if (MI.isCall())
318       break;
319 
320     unsigned Opcode = MI.getOpcode();
321 
322     // Only care of pseudo store instructions where SP is the base pointer.
323     if (Opcode != AVR::STDSPQRr && Opcode != AVR::STDWSPQRr)
324       continue;
325 
326     assert(MI.getOperand(0).getReg() == AVR::SP &&
327            "SP is expected as base pointer");
328 
329     // Replace this instruction with a regular store. Use Y as the base
330     // pointer since it is guaranteed to contain a copy of SP.
331     unsigned STOpc =
332         (Opcode == AVR::STDWSPQRr) ? AVR::STDWPtrQRr : AVR::STDPtrQRr;
333 
334     MI.setDesc(TII.get(STOpc));
335     MI.getOperand(0).setReg(AVR::R31R30);
336   }
337 }
338 
eliminateCallFramePseudoInstr(MachineFunction & MF,MachineBasicBlock & MBB,MachineBasicBlock::iterator MI) const339 MachineBasicBlock::iterator AVRFrameLowering::eliminateCallFramePseudoInstr(
340     MachineFunction &MF, MachineBasicBlock &MBB,
341     MachineBasicBlock::iterator MI) const {
342   const AVRSubtarget &STI = MF.getSubtarget<AVRSubtarget>();
343   const AVRInstrInfo &TII = *STI.getInstrInfo();
344 
345   if (hasReservedCallFrame(MF)) {
346     return MBB.erase(MI);
347   }
348 
349   DebugLoc DL = MI->getDebugLoc();
350   unsigned int Opcode = MI->getOpcode();
351   int Amount = TII.getFrameSize(*MI);
352 
353   if (Amount == 0) {
354     return MBB.erase(MI);
355   }
356 
357   assert(getStackAlign() == Align(1) && "Unsupported stack alignment");
358 
359   if (Opcode == TII.getCallFrameSetupOpcode()) {
360     // Update the stack pointer.
361     // In many cases this can be done far more efficiently by pushing the
362     // relevant values directly to the stack. However, doing that correctly
363     // (in the right order, possibly skipping some empty space for undef
364     // values, etc) is tricky and thus left to be optimized in the future.
365     BuildMI(MBB, MI, DL, TII.get(AVR::SPREAD), AVR::R31R30).addReg(AVR::SP);
366 
367     MachineInstr *New =
368         BuildMI(MBB, MI, DL, TII.get(AVR::SUBIWRdK), AVR::R31R30)
369             .addReg(AVR::R31R30, RegState::Kill)
370             .addImm(Amount);
371     New->getOperand(3).setIsDead();
372 
373     BuildMI(MBB, MI, DL, TII.get(AVR::SPWRITE), AVR::SP).addReg(AVR::R31R30);
374 
375     // Make sure the remaining stack stores are converted to real store
376     // instructions.
377     fixStackStores(MBB, MI, TII);
378   } else {
379     assert(Opcode == TII.getCallFrameDestroyOpcode());
380 
381     // Note that small stack changes could be implemented more efficiently
382     // with a few pop instructions instead of the 8-9 instructions now
383     // required.
384 
385     // Select the best opcode to adjust SP based on the offset size.
386     unsigned AddOpcode;
387 
388     if (isUInt<6>(Amount) && STI.hasADDSUBIW()) {
389       AddOpcode = AVR::ADIWRdK;
390     } else {
391       AddOpcode = AVR::SUBIWRdK;
392       Amount = -Amount;
393     }
394 
395     // Build the instruction sequence.
396     BuildMI(MBB, MI, DL, TII.get(AVR::SPREAD), AVR::R31R30).addReg(AVR::SP);
397 
398     MachineInstr *New = BuildMI(MBB, MI, DL, TII.get(AddOpcode), AVR::R31R30)
399                             .addReg(AVR::R31R30, RegState::Kill)
400                             .addImm(Amount);
401     New->getOperand(3).setIsDead();
402 
403     BuildMI(MBB, MI, DL, TII.get(AVR::SPWRITE), AVR::SP)
404         .addReg(AVR::R31R30, RegState::Kill);
405   }
406 
407   return MBB.erase(MI);
408 }
409 
determineCalleeSaves(MachineFunction & MF,BitVector & SavedRegs,RegScavenger * RS) const410 void AVRFrameLowering::determineCalleeSaves(MachineFunction &MF,
411                                             BitVector &SavedRegs,
412                                             RegScavenger *RS) const {
413   TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);
414 
415   // If we have a frame pointer, the Y register needs to be saved as well.
416   if (hasFP(MF)) {
417     SavedRegs.set(AVR::R29);
418     SavedRegs.set(AVR::R28);
419   }
420 }
421 /// The frame analyzer pass.
422 ///
423 /// Scans the function for allocas and used arguments
424 /// that are passed through the stack.
425 struct AVRFrameAnalyzer : public MachineFunctionPass {
426   static char ID;
AVRFrameAnalyzerllvm::AVRFrameAnalyzer427   AVRFrameAnalyzer() : MachineFunctionPass(ID) {}
428 
runOnMachineFunctionllvm::AVRFrameAnalyzer429   bool runOnMachineFunction(MachineFunction &MF) override {
430     const MachineFrameInfo &MFI = MF.getFrameInfo();
431     AVRMachineFunctionInfo *AFI = MF.getInfo<AVRMachineFunctionInfo>();
432 
433     // If there are no fixed frame indexes during this stage it means there
434     // are allocas present in the function.
435     if (MFI.getNumObjects() != MFI.getNumFixedObjects()) {
436       // Check for the type of allocas present in the function. We only care
437       // about fixed size allocas so do not give false positives if only
438       // variable sized allocas are present.
439       for (unsigned i = 0, e = MFI.getObjectIndexEnd(); i != e; ++i) {
440         // Variable sized objects have size 0.
441         if (MFI.getObjectSize(i)) {
442           AFI->setHasAllocas(true);
443           break;
444         }
445       }
446     }
447 
448     // If there are fixed frame indexes present, scan the function to see if
449     // they are really being used.
450     if (MFI.getNumFixedObjects() == 0) {
451       return false;
452     }
453 
454     // Ok fixed frame indexes present, now scan the function to see if they
455     // are really being used, otherwise we can ignore them.
456     for (const MachineBasicBlock &BB : MF) {
457       for (const MachineInstr &MI : BB) {
458         int Opcode = MI.getOpcode();
459 
460         if ((Opcode != AVR::LDDRdPtrQ) && (Opcode != AVR::LDDWRdPtrQ) &&
461             (Opcode != AVR::STDPtrQRr) && (Opcode != AVR::STDWPtrQRr) &&
462             (Opcode != AVR::FRMIDX)) {
463           continue;
464         }
465 
466         for (const MachineOperand &MO : MI.operands()) {
467           if (!MO.isFI()) {
468             continue;
469           }
470 
471           if (MFI.isFixedObjectIndex(MO.getIndex())) {
472             AFI->setHasStackArgs(true);
473             return false;
474           }
475         }
476       }
477     }
478 
479     return false;
480   }
481 
getPassNamellvm::AVRFrameAnalyzer482   StringRef getPassName() const override { return "AVR Frame Analyzer"; }
483 };
484 
485 char AVRFrameAnalyzer::ID = 0;
486 
487 /// Creates instance of the frame analyzer pass.
createAVRFrameAnalyzerPass()488 FunctionPass *createAVRFrameAnalyzerPass() { return new AVRFrameAnalyzer(); }
489 
490 } // end of namespace llvm
491