xref: /freebsd/contrib/llvm-project/llvm/lib/Target/AVR/AVRFrameLowering.cpp (revision f126890ac5386406dadf7c4cfa9566cbb56537c5)
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 
32 AVRFrameLowering::AVRFrameLowering()
33     : TargetFrameLowering(TargetFrameLowering::StackGrowsDown, Align(1), -2) {}
34 
35 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 
42 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 
52 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 
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 
164 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.
237 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 
245 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     // Check if Reg is a sub register of a 16-bit livein register, and then
264     // add it to the livein list.
265     if (IsNotLiveIn)
266       for (const auto &LiveIn : MBB.liveins())
267         if (STI.getRegisterInfo()->isSubRegister(LiveIn.PhysReg, Reg)) {
268           IsNotLiveIn = false;
269           MBB.addLiveIn(Reg);
270           break;
271         }
272 
273     assert(TRI->getRegSizeInBits(*TRI->getMinimalPhysRegClass(Reg)) == 8 &&
274            "Invalid register size");
275 
276     // Add the callee-saved register as live-in only if it is not already a
277     // live-in register, this usually happens with arguments that are passed
278     // through callee-saved registers.
279     if (IsNotLiveIn) {
280       MBB.addLiveIn(Reg);
281     }
282 
283     // Do not kill the register when it is an input argument.
284     BuildMI(MBB, MI, DL, TII.get(AVR::PUSHRr))
285         .addReg(Reg, getKillRegState(IsNotLiveIn))
286         .setMIFlag(MachineInstr::FrameSetup);
287     ++CalleeFrameSize;
288   }
289 
290   AVRFI->setCalleeSavedFrameSize(CalleeFrameSize);
291 
292   return true;
293 }
294 
295 bool AVRFrameLowering::restoreCalleeSavedRegisters(
296     MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
297     MutableArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const {
298   if (CSI.empty()) {
299     return false;
300   }
301 
302   DebugLoc DL = MBB.findDebugLoc(MI);
303   const MachineFunction &MF = *MBB.getParent();
304   const AVRSubtarget &STI = MF.getSubtarget<AVRSubtarget>();
305   const TargetInstrInfo &TII = *STI.getInstrInfo();
306 
307   for (const CalleeSavedInfo &CCSI : CSI) {
308     Register Reg = CCSI.getReg();
309 
310     assert(TRI->getRegSizeInBits(*TRI->getMinimalPhysRegClass(Reg)) == 8 &&
311            "Invalid register size");
312 
313     BuildMI(MBB, MI, DL, TII.get(AVR::POPRd), Reg);
314   }
315 
316   return true;
317 }
318 
319 /// Replace pseudo store instructions that pass arguments through the stack with
320 /// real instructions.
321 static void fixStackStores(MachineBasicBlock &MBB,
322                            MachineBasicBlock::iterator StartMI,
323                            const TargetInstrInfo &TII) {
324   // Iterate through the BB until we hit a call instruction or we reach the end.
325   for (MachineInstr &MI :
326        llvm::make_early_inc_range(llvm::make_range(StartMI, MBB.end()))) {
327     if (MI.isCall())
328       break;
329 
330     unsigned Opcode = MI.getOpcode();
331 
332     // Only care of pseudo store instructions where SP is the base pointer.
333     if (Opcode != AVR::STDSPQRr && Opcode != AVR::STDWSPQRr)
334       continue;
335 
336     assert(MI.getOperand(0).getReg() == AVR::SP &&
337            "SP is expected as base pointer");
338 
339     // Replace this instruction with a regular store. Use Y as the base
340     // pointer since it is guaranteed to contain a copy of SP.
341     unsigned STOpc =
342         (Opcode == AVR::STDWSPQRr) ? AVR::STDWPtrQRr : AVR::STDPtrQRr;
343 
344     MI.setDesc(TII.get(STOpc));
345     MI.getOperand(0).setReg(AVR::R31R30);
346   }
347 }
348 
349 MachineBasicBlock::iterator AVRFrameLowering::eliminateCallFramePseudoInstr(
350     MachineFunction &MF, MachineBasicBlock &MBB,
351     MachineBasicBlock::iterator MI) const {
352   const AVRSubtarget &STI = MF.getSubtarget<AVRSubtarget>();
353   const AVRInstrInfo &TII = *STI.getInstrInfo();
354 
355   if (hasReservedCallFrame(MF)) {
356     return MBB.erase(MI);
357   }
358 
359   DebugLoc DL = MI->getDebugLoc();
360   unsigned int Opcode = MI->getOpcode();
361   int Amount = TII.getFrameSize(*MI);
362 
363   if (Amount == 0) {
364     return MBB.erase(MI);
365   }
366 
367   assert(getStackAlign() == Align(1) && "Unsupported stack alignment");
368 
369   if (Opcode == TII.getCallFrameSetupOpcode()) {
370     // Update the stack pointer.
371     // In many cases this can be done far more efficiently by pushing the
372     // relevant values directly to the stack. However, doing that correctly
373     // (in the right order, possibly skipping some empty space for undef
374     // values, etc) is tricky and thus left to be optimized in the future.
375     BuildMI(MBB, MI, DL, TII.get(AVR::SPREAD), AVR::R31R30).addReg(AVR::SP);
376 
377     MachineInstr *New =
378         BuildMI(MBB, MI, DL, TII.get(AVR::SUBIWRdK), AVR::R31R30)
379             .addReg(AVR::R31R30, RegState::Kill)
380             .addImm(Amount);
381     New->getOperand(3).setIsDead();
382 
383     BuildMI(MBB, MI, DL, TII.get(AVR::SPWRITE), AVR::SP).addReg(AVR::R31R30);
384 
385     // Make sure the remaining stack stores are converted to real store
386     // instructions.
387     fixStackStores(MBB, MI, TII);
388   } else {
389     assert(Opcode == TII.getCallFrameDestroyOpcode());
390 
391     // Note that small stack changes could be implemented more efficiently
392     // with a few pop instructions instead of the 8-9 instructions now
393     // required.
394 
395     // Select the best opcode to adjust SP based on the offset size.
396     unsigned AddOpcode;
397 
398     if (isUInt<6>(Amount) && STI.hasADDSUBIW()) {
399       AddOpcode = AVR::ADIWRdK;
400     } else {
401       AddOpcode = AVR::SUBIWRdK;
402       Amount = -Amount;
403     }
404 
405     // Build the instruction sequence.
406     BuildMI(MBB, MI, DL, TII.get(AVR::SPREAD), AVR::R31R30).addReg(AVR::SP);
407 
408     MachineInstr *New = BuildMI(MBB, MI, DL, TII.get(AddOpcode), AVR::R31R30)
409                             .addReg(AVR::R31R30, RegState::Kill)
410                             .addImm(Amount);
411     New->getOperand(3).setIsDead();
412 
413     BuildMI(MBB, MI, DL, TII.get(AVR::SPWRITE), AVR::SP)
414         .addReg(AVR::R31R30, RegState::Kill);
415   }
416 
417   return MBB.erase(MI);
418 }
419 
420 void AVRFrameLowering::determineCalleeSaves(MachineFunction &MF,
421                                             BitVector &SavedRegs,
422                                             RegScavenger *RS) const {
423   TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);
424 
425   // If we have a frame pointer, the Y register needs to be saved as well.
426   if (hasFP(MF)) {
427     SavedRegs.set(AVR::R29);
428     SavedRegs.set(AVR::R28);
429   }
430 }
431 /// The frame analyzer pass.
432 ///
433 /// Scans the function for allocas and used arguments
434 /// that are passed through the stack.
435 struct AVRFrameAnalyzer : public MachineFunctionPass {
436   static char ID;
437   AVRFrameAnalyzer() : MachineFunctionPass(ID) {}
438 
439   bool runOnMachineFunction(MachineFunction &MF) override {
440     const MachineFrameInfo &MFI = MF.getFrameInfo();
441     AVRMachineFunctionInfo *AFI = MF.getInfo<AVRMachineFunctionInfo>();
442 
443     // If there are no fixed frame indexes during this stage it means there
444     // are allocas present in the function.
445     if (MFI.getNumObjects() != MFI.getNumFixedObjects()) {
446       // Check for the type of allocas present in the function. We only care
447       // about fixed size allocas so do not give false positives if only
448       // variable sized allocas are present.
449       for (unsigned i = 0, e = MFI.getObjectIndexEnd(); i != e; ++i) {
450         // Variable sized objects have size 0.
451         if (MFI.getObjectSize(i)) {
452           AFI->setHasAllocas(true);
453           break;
454         }
455       }
456     }
457 
458     // If there are fixed frame indexes present, scan the function to see if
459     // they are really being used.
460     if (MFI.getNumFixedObjects() == 0) {
461       return false;
462     }
463 
464     // Ok fixed frame indexes present, now scan the function to see if they
465     // are really being used, otherwise we can ignore them.
466     for (const MachineBasicBlock &BB : MF) {
467       for (const MachineInstr &MI : BB) {
468         int Opcode = MI.getOpcode();
469 
470         if ((Opcode != AVR::LDDRdPtrQ) && (Opcode != AVR::LDDWRdPtrQ) &&
471             (Opcode != AVR::STDPtrQRr) && (Opcode != AVR::STDWPtrQRr) &&
472             (Opcode != AVR::FRMIDX)) {
473           continue;
474         }
475 
476         for (const MachineOperand &MO : MI.operands()) {
477           if (!MO.isFI()) {
478             continue;
479           }
480 
481           if (MFI.isFixedObjectIndex(MO.getIndex())) {
482             AFI->setHasStackArgs(true);
483             return false;
484           }
485         }
486       }
487     }
488 
489     return false;
490   }
491 
492   StringRef getPassName() const override { return "AVR Frame Analyzer"; }
493 };
494 
495 char AVRFrameAnalyzer::ID = 0;
496 
497 /// Creates instance of the frame analyzer pass.
498 FunctionPass *createAVRFrameAnalyzerPass() { return new AVRFrameAnalyzer(); }
499 
500 } // end of namespace llvm
501