LCOV - code coverage report
Current view: top level - lib/Target/AVR - AVRFrameLowering.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 173 177 97.7 %
Date: 2018-10-20 13:21:21 Functions: 16 17 94.1 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===-- AVRFrameLowering.cpp - AVR Frame Information ----------------------===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : //
      10             : // This file contains the AVR implementation of TargetFrameLowering class.
      11             : //
      12             : //===----------------------------------------------------------------------===//
      13             : 
      14             : #include "AVRFrameLowering.h"
      15             : 
      16             : #include "AVR.h"
      17             : #include "AVRInstrInfo.h"
      18             : #include "AVRMachineFunctionInfo.h"
      19             : #include "AVRTargetMachine.h"
      20             : #include "MCTargetDesc/AVRMCTargetDesc.h"
      21             : 
      22             : #include "llvm/CodeGen/MachineFrameInfo.h"
      23             : #include "llvm/CodeGen/MachineFunction.h"
      24             : #include "llvm/CodeGen/MachineFunctionPass.h"
      25             : #include "llvm/CodeGen/MachineInstrBuilder.h"
      26             : #include "llvm/CodeGen/MachineRegisterInfo.h"
      27             : #include "llvm/IR/Function.h"
      28             : 
      29             : #include <vector>
      30             : 
      31             : namespace llvm {
      32             : 
      33         119 : AVRFrameLowering::AVRFrameLowering()
      34         119 :     : TargetFrameLowering(TargetFrameLowering::StackGrowsDown, 1, -2) {}
      35             : 
      36         280 : bool AVRFrameLowering::canSimplifyCallFramePseudos(
      37             :     const MachineFunction &MF) const {
      38             :   // Always simplify call frame pseudo instructions, even when
      39             :   // hasReservedCallFrame is false.
      40         280 :   return true;
      41             : }
      42             : 
      43         359 : bool AVRFrameLowering::hasReservedCallFrame(const MachineFunction &MF) const {
      44             :   // Reserve call frame memory in function prologue under the following
      45             :   // conditions:
      46             :   // - Y pointer is reserved to be the frame pointer.
      47             :   // - The function does not contain variable sized objects.
      48             : 
      49         359 :   const MachineFrameInfo &MFI = MF.getFrameInfo();
      50         359 :   return hasFP(MF) && !MFI.hasVarSizedObjects();
      51             : }
      52             : 
      53         303 : void AVRFrameLowering::emitPrologue(MachineFunction &MF,
      54             :                                     MachineBasicBlock &MBB) const {
      55             :   MachineBasicBlock::iterator MBBI = MBB.begin();
      56         303 :   CallingConv::ID CallConv = MF.getFunction().getCallingConv();
      57         303 :   DebugLoc DL = (MBBI != MBB.end()) ? MBBI->getDebugLoc() : DebugLoc();
      58         303 :   const AVRSubtarget &STI = MF.getSubtarget<AVRSubtarget>();
      59         303 :   const AVRInstrInfo &TII = *STI.getInstrInfo();
      60         303 :   bool HasFP = hasFP(MF);
      61             : 
      62             :   // Interrupt handlers re-enable interrupts in function entry.
      63         303 :   if (CallConv == CallingConv::AVR_INTR) {
      64           4 :     BuildMI(MBB, MBBI, DL, TII.get(AVR::BSETs))
      65             :         .addImm(0x07)
      66             :         .setMIFlag(MachineInstr::FrameSetup);
      67             :   }
      68             : 
      69             :   // Save the frame pointer if we have one.
      70         303 :   if (HasFP) {
      71          78 :     BuildMI(MBB, MBBI, DL, TII.get(AVR::PUSHWRr))
      72          26 :         .addReg(AVR::R29R28, RegState::Kill)
      73             :         .setMIFlag(MachineInstr::FrameSetup);
      74             :   }
      75             : 
      76             :   // Emit special prologue code to save R1, R0 and SREG in interrupt/signal
      77             :   // handlers before saving any other registers.
      78         303 :   if (CallConv == CallingConv::AVR_INTR ||
      79             :       CallConv == CallingConv::AVR_SIGNAL) {
      80           8 :     BuildMI(MBB, MBBI, DL, TII.get(AVR::PUSHWRr))
      81           4 :         .addReg(AVR::R1R0, RegState::Kill)
      82             :         .setMIFlag(MachineInstr::FrameSetup);
      83             : 
      84           8 :     BuildMI(MBB, MBBI, DL, TII.get(AVR::INRdA), AVR::R0)
      85             :         .addImm(0x3f)
      86             :         .setMIFlag(MachineInstr::FrameSetup);
      87           8 :     BuildMI(MBB, MBBI, DL, TII.get(AVR::PUSHRr))
      88           4 :         .addReg(AVR::R0, RegState::Kill)
      89             :         .setMIFlag(MachineInstr::FrameSetup);
      90          12 :     BuildMI(MBB, MBBI, DL, TII.get(AVR::EORRdRr))
      91           4 :         .addReg(AVR::R0, RegState::Define)
      92           4 :         .addReg(AVR::R0, RegState::Kill)
      93           4 :         .addReg(AVR::R0, RegState::Kill)
      94             :         .setMIFlag(MachineInstr::FrameSetup);
      95             :   }
      96             : 
      97             :   // Early exit if the frame pointer is not needed in this function.
      98         303 :   if (!HasFP) {
      99             :     return;
     100             :   }
     101             : 
     102          26 :   const MachineFrameInfo &MFI = MF.getFrameInfo();
     103             :   const AVRMachineFunctionInfo *AFI = MF.getInfo<AVRMachineFunctionInfo>();
     104          26 :   unsigned FrameSize = MFI.getStackSize() - AFI->getCalleeSavedFrameSize();
     105             : 
     106             :   // Skip the callee-saved push instructions.
     107             :   while (
     108         110 :       (MBBI != MBB.end()) && MBBI->getFlag(MachineInstr::FrameSetup) &&
     109          84 :       (MBBI->getOpcode() == AVR::PUSHRr || MBBI->getOpcode() == AVR::PUSHWRr)) {
     110             :     ++MBBI;
     111             :   }
     112             : 
     113             :   // Update Y with the new base value.
     114          78 :   BuildMI(MBB, MBBI, DL, TII.get(AVR::SPREAD), AVR::R29R28)
     115          26 :       .addReg(AVR::SP)
     116             :       .setMIFlag(MachineInstr::FrameSetup);
     117             : 
     118             :   // Mark the FramePtr as live-in in every block except the entry.
     119             :   for (MachineFunction::iterator I = std::next(MF.begin()), E = MF.end();
     120         163 :        I != E; ++I) {
     121             :     I->addLiveIn(AVR::R29R28);
     122             :   }
     123             : 
     124          26 :   if (!FrameSize) {
     125             :     return;
     126             :   }
     127             : 
     128             :   // Reserve the necessary frame memory by doing FP -= <size>.
     129          23 :   unsigned Opcode = (isUInt<6>(FrameSize)) ? AVR::SBIWRdK : AVR::SUBIWRdK;
     130             : 
     131          46 :   MachineInstr *MI = BuildMI(MBB, MBBI, DL, TII.get(Opcode), AVR::R29R28)
     132          23 :                          .addReg(AVR::R29R28, RegState::Kill)
     133          23 :                          .addImm(FrameSize)
     134          23 :                          .setMIFlag(MachineInstr::FrameSetup);
     135             :   // The SREG implicit def is dead.
     136          23 :   MI->getOperand(3).setIsDead();
     137             : 
     138             :   // Write back R29R28 to SP and temporarily disable interrupts.
     139          69 :   BuildMI(MBB, MBBI, DL, TII.get(AVR::SPWRITE), AVR::SP)
     140          23 :       .addReg(AVR::R29R28)
     141             :       .setMIFlag(MachineInstr::FrameSetup);
     142             : }
     143             : 
     144         303 : void AVRFrameLowering::emitEpilogue(MachineFunction &MF,
     145             :                                     MachineBasicBlock &MBB) const {
     146         303 :   CallingConv::ID CallConv = MF.getFunction().getCallingConv();
     147         303 :   bool isHandler = (CallConv == CallingConv::AVR_INTR ||
     148             :                     CallConv == CallingConv::AVR_SIGNAL);
     149             : 
     150             :   // Early exit if the frame pointer is not needed in this function except for
     151             :   // signal/interrupt handlers where special code generation is required.
     152         303 :   if (!hasFP(MF) && !isHandler) {
     153         281 :     return;
     154             :   }
     155             : 
     156          29 :   MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
     157             :   assert(MBBI->getDesc().isReturn() &&
     158             :          "Can only insert epilog into returning blocks");
     159             : 
     160             :   DebugLoc DL = MBBI->getDebugLoc();
     161          29 :   const MachineFrameInfo &MFI = MF.getFrameInfo();
     162             :   const AVRMachineFunctionInfo *AFI = MF.getInfo<AVRMachineFunctionInfo>();
     163          29 :   unsigned FrameSize = MFI.getStackSize() - AFI->getCalleeSavedFrameSize();
     164          29 :   const AVRSubtarget &STI = MF.getSubtarget<AVRSubtarget>();
     165          29 :   const AVRInstrInfo &TII = *STI.getInstrInfo();
     166             : 
     167             :   // Emit special epilogue code to restore R1, R0 and SREG in interrupt/signal
     168             :   // handlers at the very end of the function, just before reti.
     169          29 :   if (isHandler) {
     170           8 :     BuildMI(MBB, MBBI, DL, TII.get(AVR::POPRd), AVR::R0);
     171           8 :     BuildMI(MBB, MBBI, DL, TII.get(AVR::OUTARr))
     172             :         .addImm(0x3f)
     173           4 :         .addReg(AVR::R0, RegState::Kill);
     174           8 :     BuildMI(MBB, MBBI, DL, TII.get(AVR::POPWRd), AVR::R1R0);
     175             :   }
     176             : 
     177          29 :   if (hasFP(MF))
     178          50 :     BuildMI(MBB, MBBI, DL, TII.get(AVR::POPWRd), AVR::R29R28);
     179             : 
     180             :   // Early exit if there is no need to restore the frame pointer.
     181          29 :   if (!FrameSize) {
     182             :     return;
     183             :   }
     184             : 
     185             :   // Skip the callee-saved pop instructions.
     186         126 :   while (MBBI != MBB.begin()) {
     187         125 :     MachineBasicBlock::iterator PI = std::prev(MBBI);
     188         125 :     int Opc = PI->getOpcode();
     189             : 
     190         146 :     if (Opc != AVR::POPRd && Opc != AVR::POPWRd && !PI->isTerminator()) {
     191             :       break;
     192             :     }
     193             : 
     194             :     --MBBI;
     195             :   }
     196             : 
     197             :   unsigned Opcode;
     198             : 
     199             :   // Select the optimal opcode depending on how big it is.
     200          22 :   if (isUInt<6>(FrameSize)) {
     201             :     Opcode = AVR::ADIWRdK;
     202             :   } else {
     203             :     Opcode = AVR::SUBIWRdK;
     204           6 :     FrameSize = -FrameSize;
     205             :   }
     206             : 
     207             :   // Restore the frame pointer by doing FP += <size>.
     208          44 :   MachineInstr *MI = BuildMI(MBB, MBBI, DL, TII.get(Opcode), AVR::R29R28)
     209          22 :                          .addReg(AVR::R29R28, RegState::Kill)
     210          22 :                          .addImm(FrameSize);
     211             :   // The SREG implicit def is dead.
     212          22 :   MI->getOperand(3).setIsDead();
     213             : 
     214             :   // Write back R29R28 to SP and temporarily disable interrupts.
     215          66 :   BuildMI(MBB, MBBI, DL, TII.get(AVR::SPWRITE), AVR::SP)
     216          22 :       .addReg(AVR::R29R28, RegState::Kill);
     217             : }
     218             : 
     219             : // Return true if the specified function should have a dedicated frame
     220             : // pointer register. This is true if the function meets any of the following
     221             : // conditions:
     222             : //  - a register has been spilled
     223             : //  - has allocas
     224             : //  - input arguments are passed using the stack
     225             : //
     226             : // Notice that strictly this is not a frame pointer because it contains SP after
     227             : // frame allocation instead of having the original SP in function entry.
     228        5459 : bool AVRFrameLowering::hasFP(const MachineFunction &MF) const {
     229             :   const AVRMachineFunctionInfo *FuncInfo = MF.getInfo<AVRMachineFunctionInfo>();
     230             : 
     231        5459 :   return (FuncInfo->getHasSpills() || FuncInfo->getHasAllocas() ||
     232        5227 :           FuncInfo->getHasStackArgs());
     233             : }
     234             : 
     235          24 : bool AVRFrameLowering::spillCalleeSavedRegisters(
     236             :     MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
     237             :     const std::vector<CalleeSavedInfo> &CSI,
     238             :     const TargetRegisterInfo *TRI) const {
     239          24 :   if (CSI.empty()) {
     240             :     return false;
     241             :   }
     242             : 
     243             :   unsigned CalleeFrameSize = 0;
     244             :   DebugLoc DL = MBB.findDebugLoc(MI);
     245          24 :   MachineFunction &MF = *MBB.getParent();
     246          24 :   const AVRSubtarget &STI = MF.getSubtarget<AVRSubtarget>();
     247          24 :   const TargetInstrInfo &TII = *STI.getInstrInfo();
     248             :   AVRMachineFunctionInfo *AVRFI = MF.getInfo<AVRMachineFunctionInfo>();
     249             : 
     250         209 :   for (unsigned i = CSI.size(); i != 0; --i) {
     251         161 :     unsigned Reg = CSI[i - 1].getReg();
     252         161 :     bool IsNotLiveIn = !MBB.isLiveIn(Reg);
     253             : 
     254             :     assert(TRI->getRegSizeInBits(*TRI->getMinimalPhysRegClass(Reg)) == 8 &&
     255             :            "Invalid register size");
     256             : 
     257             :     // Add the callee-saved register as live-in only if it is not already a
     258             :     // live-in register, this usually happens with arguments that are passed
     259             :     // through callee-saved registers.
     260         161 :     if (IsNotLiveIn) {
     261             :       MBB.addLiveIn(Reg);
     262             :     }
     263             : 
     264             :     // Do not kill the register when it is an input argument.
     265         322 :     BuildMI(MBB, MI, DL, TII.get(AVR::PUSHRr))
     266         161 :         .addReg(Reg, getKillRegState(IsNotLiveIn))
     267             :         .setMIFlag(MachineInstr::FrameSetup);
     268         161 :     ++CalleeFrameSize;
     269             :   }
     270             : 
     271             :   AVRFI->setCalleeSavedFrameSize(CalleeFrameSize);
     272             : 
     273             :   return true;
     274             : }
     275             : 
     276          24 : bool AVRFrameLowering::restoreCalleeSavedRegisters(
     277             :     MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
     278             :     std::vector<CalleeSavedInfo> &CSI,
     279             :     const TargetRegisterInfo *TRI) const {
     280          24 :   if (CSI.empty()) {
     281             :     return false;
     282             :   }
     283             : 
     284             :   DebugLoc DL = MBB.findDebugLoc(MI);
     285          24 :   const MachineFunction &MF = *MBB.getParent();
     286          24 :   const AVRSubtarget &STI = MF.getSubtarget<AVRSubtarget>();
     287          24 :   const TargetInstrInfo &TII = *STI.getInstrInfo();
     288             : 
     289         194 :   for (const CalleeSavedInfo &CCSI : CSI) {
     290         170 :     unsigned Reg = CCSI.getReg();
     291             : 
     292             :     assert(TRI->getRegSizeInBits(*TRI->getMinimalPhysRegClass(Reg)) == 8 &&
     293             :            "Invalid register size");
     294             : 
     295         340 :     BuildMI(MBB, MI, DL, TII.get(AVR::POPRd), Reg);
     296             :   }
     297             : 
     298             :   return true;
     299             : }
     300             : 
     301             : /// Replace pseudo store instructions that pass arguments through the stack with
     302             : /// real instructions. If insertPushes is true then all instructions are
     303             : /// replaced with push instructions, otherwise regular std instructions are
     304             : /// inserted.
     305         126 : static void fixStackStores(MachineBasicBlock &MBB,
     306             :                            MachineBasicBlock::iterator MI,
     307             :                            const TargetInstrInfo &TII, bool insertPushes) {
     308         126 :   const AVRSubtarget &STI = MBB.getParent()->getSubtarget<AVRSubtarget>();
     309         126 :   const TargetRegisterInfo &TRI = *STI.getRegisterInfo();
     310             : 
     311             :   // Iterate through the BB until we hit a call instruction or we reach the end.
     312        1632 :   for (auto I = MI, E = MBB.end(); I != E && !I->isCall();) {
     313         704 :     MachineBasicBlock::iterator NextMI = std::next(I);
     314             :     MachineInstr &MI = *I;
     315         704 :     unsigned Opcode = I->getOpcode();
     316             : 
     317             :     // Only care of pseudo store instructions where SP is the base pointer.
     318         704 :     if (Opcode != AVR::STDSPQRr && Opcode != AVR::STDWSPQRr) {
     319             :       I = NextMI;
     320             :       continue;
     321             :     }
     322             : 
     323             :     assert(MI.getOperand(0).getReg() == AVR::SP &&
     324             :            "Invalid register, should be SP!");
     325          38 :     if (insertPushes) {
     326             :       // Replace this instruction with a push.
     327          16 :       unsigned SrcReg = MI.getOperand(2).getReg();
     328             :       bool SrcIsKill = MI.getOperand(2).isKill();
     329             : 
     330             :       // We can't use PUSHWRr here because when expanded the order of the new
     331             :       // instructions are reversed from what we need. Perform the expansion now.
     332          16 :       if (Opcode == AVR::STDWSPQRr) {
     333          32 :         BuildMI(MBB, I, MI.getDebugLoc(), TII.get(AVR::PUSHRr))
     334             :             .addReg(TRI.getSubReg(SrcReg, AVR::sub_hi),
     335          16 :                     getKillRegState(SrcIsKill));
     336          48 :         BuildMI(MBB, I, MI.getDebugLoc(), TII.get(AVR::PUSHRr))
     337             :             .addReg(TRI.getSubReg(SrcReg, AVR::sub_lo),
     338          16 :                     getKillRegState(SrcIsKill));
     339             :       } else {
     340           0 :         BuildMI(MBB, I, MI.getDebugLoc(), TII.get(AVR::PUSHRr))
     341           0 :             .addReg(SrcReg, getKillRegState(SrcIsKill));
     342             :       }
     343             : 
     344          16 :       MI.eraseFromParent();
     345             :       I = NextMI;
     346          16 :       continue;
     347             :     }
     348             : 
     349             :     // Replace this instruction with a regular store. Use Y as the base
     350             :     // pointer since it is guaranteed to contain a copy of SP.
     351             :     unsigned STOpc =
     352          22 :         (Opcode == AVR::STDWSPQRr) ? AVR::STDWPtrQRr : AVR::STDPtrQRr;
     353             : 
     354          22 :     MI.setDesc(TII.get(STOpc));
     355          22 :     MI.getOperand(0).setReg(AVR::R29R28);
     356             : 
     357             :     I = NextMI;
     358             :   }
     359         126 : }
     360             : 
     361         280 : MachineBasicBlock::iterator AVRFrameLowering::eliminateCallFramePseudoInstr(
     362             :     MachineFunction &MF, MachineBasicBlock &MBB,
     363             :     MachineBasicBlock::iterator MI) const {
     364         280 :   const AVRSubtarget &STI = MF.getSubtarget<AVRSubtarget>();
     365         280 :   const TargetFrameLowering &TFI = *STI.getFrameLowering();
     366         280 :   const AVRInstrInfo &TII = *STI.getInstrInfo();
     367             : 
     368             :   // There is nothing to insert when the call frame memory is allocated during
     369             :   // function entry. Delete the call frame pseudo and replace all pseudo stores
     370             :   // with real store instructions.
     371         280 :   if (TFI.hasReservedCallFrame(MF)) {
     372         120 :     fixStackStores(MBB, MI, TII, false);
     373         120 :     return MBB.erase(MI);
     374             :   }
     375             : 
     376             :   DebugLoc DL = MI->getDebugLoc();
     377         160 :   unsigned int Opcode = MI->getOpcode();
     378         160 :   int Amount = TII.getFrameSize(*MI);
     379             : 
     380             :   // Adjcallstackup does not need to allocate stack space for the call, instead
     381             :   // we insert push instructions that will allocate the necessary stack.
     382             :   // For adjcallstackdown we convert it into an 'adiw reg, <amt>' handling
     383             :   // the read and write of SP in I/O space.
     384         160 :   if (Amount != 0) {
     385             :     assert(TFI.getStackAlignment() == 1 && "Unsupported stack alignment");
     386             : 
     387          12 :     if (Opcode == TII.getCallFrameSetupOpcode()) {
     388           6 :       fixStackStores(MBB, MI, TII, true);
     389             :     } else {
     390             :       assert(Opcode == TII.getCallFrameDestroyOpcode());
     391             : 
     392             :       // Select the best opcode to adjust SP based on the offset size.
     393             :       unsigned addOpcode;
     394           6 :       if (isUInt<6>(Amount)) {
     395             :         addOpcode = AVR::ADIWRdK;
     396             :       } else {
     397             :         addOpcode = AVR::SUBIWRdK;
     398           0 :         Amount = -Amount;
     399             :       }
     400             : 
     401             :       // Build the instruction sequence.
     402          12 :       BuildMI(MBB, MI, DL, TII.get(AVR::SPREAD), AVR::R31R30).addReg(AVR::SP);
     403             : 
     404          12 :       MachineInstr *New = BuildMI(MBB, MI, DL, TII.get(addOpcode), AVR::R31R30)
     405           6 :                               .addReg(AVR::R31R30, RegState::Kill)
     406           6 :                               .addImm(Amount);
     407           6 :       New->getOperand(3).setIsDead();
     408             : 
     409          18 :       BuildMI(MBB, MI, DL, TII.get(AVR::SPWRITE), AVR::SP)
     410           6 :           .addReg(AVR::R31R30, RegState::Kill);
     411             :     }
     412             :   }
     413             : 
     414         160 :   return MBB.erase(MI);
     415             : }
     416             : 
     417         304 : void AVRFrameLowering::determineCalleeSaves(MachineFunction &MF,
     418             :                                             BitVector &SavedRegs,
     419             :                                             RegScavenger *RS) const {
     420         304 :   TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);
     421             : 
     422             :   // If we have a frame pointer, the Y register needs to be saved as well.
     423             :   // We don't do that here however - the prologue and epilogue generation
     424             :   // code will handle it specially.
     425         304 : }
     426             : /// The frame analyzer pass.
     427             : ///
     428             : /// Scans the function for allocas and used arguments
     429             : /// that are passed through the stack.
     430             : struct AVRFrameAnalyzer : public MachineFunctionPass {
     431             :   static char ID;
     432          81 :   AVRFrameAnalyzer() : MachineFunctionPass(ID) {}
     433             : 
     434         304 :   bool runOnMachineFunction(MachineFunction &MF) {
     435         304 :     const MachineFrameInfo &MFI = MF.getFrameInfo();
     436             :     AVRMachineFunctionInfo *FuncInfo = MF.getInfo<AVRMachineFunctionInfo>();
     437             : 
     438             :     // If there are no fixed frame indexes during this stage it means there
     439             :     // are allocas present in the function.
     440         304 :     if (MFI.getNumObjects() != MFI.getNumFixedObjects()) {
     441             :       // Check for the type of allocas present in the function. We only care
     442             :       // about fixed size allocas so do not give false positives if only
     443             :       // variable sized allocas are present.
     444          20 :       for (unsigned i = 0, e = MFI.getObjectIndexEnd(); i != e; ++i) {
     445             :         // Variable sized objects have size 0.
     446          19 :         if (MFI.getObjectSize(i)) {
     447             :           FuncInfo->setHasAllocas(true);
     448             :           break;
     449             :         }
     450             :       }
     451             :     }
     452             : 
     453             :     // If there are fixed frame indexes present, scan the function to see if
     454             :     // they are really being used.
     455         304 :     if (MFI.getNumFixedObjects() == 0) {
     456             :       return false;
     457             :     }
     458             : 
     459             :     // Ok fixed frame indexes present, now scan the function to see if they
     460             :     // are really being used, otherwise we can ignore them.
     461           7 :     for (const MachineBasicBlock &BB : MF) {
     462          34 :       for (const MachineInstr &MI : BB) {
     463          34 :         int Opcode = MI.getOpcode();
     464             : 
     465          34 :         if ((Opcode != AVR::LDDRdPtrQ) && (Opcode != AVR::LDDWRdPtrQ) &&
     466          27 :             (Opcode != AVR::STDPtrQRr) && (Opcode != AVR::STDWPtrQRr)) {
     467             :           continue;
     468             :         }
     469             : 
     470          22 :         for (const MachineOperand &MO : MI.operands()) {
     471          20 :           if (!MO.isFI()) {
     472             :             continue;
     473             :           }
     474             : 
     475           9 :           if (MFI.isFixedObjectIndex(MO.getIndex())) {
     476             :             FuncInfo->setHasStackArgs(true);
     477             :             return false;
     478             :           }
     479             :         }
     480             :       }
     481             :     }
     482             : 
     483             :     return false;
     484             :   }
     485             : 
     486           0 :   StringRef getPassName() const { return "AVR Frame Analyzer"; }
     487             : };
     488             : 
     489             : char AVRFrameAnalyzer::ID = 0;
     490             : 
     491             : /// Creates instance of the frame analyzer pass.
     492          81 : FunctionPass *createAVRFrameAnalyzerPass() { return new AVRFrameAnalyzer(); }
     493             : 
     494             : /// Create the Dynalloca Stack Pointer Save/Restore pass.
     495             : /// Insert a copy of SP before allocating the dynamic stack memory and restore
     496             : /// it in function exit to restore the original SP state. This avoids the need
     497             : /// of reserving a register pair for a frame pointer.
     498             : struct AVRDynAllocaSR : public MachineFunctionPass {
     499             :   static char ID;
     500          81 :   AVRDynAllocaSR() : MachineFunctionPass(ID) {}
     501             : 
     502         304 :   bool runOnMachineFunction(MachineFunction &MF) {
     503             :     // Early exit when there are no variable sized objects in the function.
     504         304 :     if (!MF.getFrameInfo().hasVarSizedObjects()) {
     505             :       return false;
     506             :     }
     507             : 
     508           2 :     const AVRSubtarget &STI = MF.getSubtarget<AVRSubtarget>();
     509           2 :     const TargetInstrInfo &TII = *STI.getInstrInfo();
     510             :     MachineBasicBlock &EntryMBB = MF.front();
     511             :     MachineBasicBlock::iterator MBBI = EntryMBB.begin();
     512             :     DebugLoc DL = EntryMBB.findDebugLoc(MBBI);
     513             : 
     514             :     unsigned SPCopy =
     515           4 :         MF.getRegInfo().createVirtualRegister(&AVR::DREGSRegClass);
     516             : 
     517             :     // Create a copy of SP in function entry before any dynallocas are
     518             :     // inserted.
     519           4 :     BuildMI(EntryMBB, MBBI, DL, TII.get(AVR::COPY), SPCopy).addReg(AVR::SP);
     520             : 
     521             :     // Restore SP in all exit basic blocks.
     522           4 :     for (MachineBasicBlock &MBB : MF) {
     523             :       // If last instruction is a return instruction, add a restore copy.
     524           4 :       if (!MBB.empty() && MBB.back().isReturn()) {
     525           2 :         MBBI = MBB.getLastNonDebugInstr();
     526             :         DL = MBBI->getDebugLoc();
     527           6 :         BuildMI(MBB, MBBI, DL, TII.get(AVR::COPY), AVR::SP)
     528           2 :             .addReg(SPCopy, RegState::Kill);
     529             :       }
     530             :     }
     531             : 
     532             :     return true;
     533             :   }
     534             : 
     535          81 :   StringRef getPassName() const {
     536          81 :     return "AVR dynalloca stack pointer save/restore";
     537             :   }
     538             : };
     539             : 
     540             : char AVRDynAllocaSR::ID = 0;
     541             : 
     542             : /// createAVRDynAllocaSRPass - returns an instance of the dynalloca stack
     543             : /// pointer save/restore pass.
     544          81 : FunctionPass *createAVRDynAllocaSRPass() { return new AVRDynAllocaSR(); }
     545             : 
     546             : } // end of namespace llvm
     547             : 

Generated by: LCOV version 1.13