Home | History | Annotate | Download | only in Lanai
      1 //===-- LanaiFrameLowering.cpp - Lanai 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 Lanai implementation of TargetFrameLowering class.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #include "LanaiFrameLowering.h"
     15 
     16 #include "LanaiInstrInfo.h"
     17 #include "LanaiMachineFunctionInfo.h"
     18 #include "LanaiSubtarget.h"
     19 #include "llvm/CodeGen/MachineFrameInfo.h"
     20 #include "llvm/CodeGen/MachineFunction.h"
     21 #include "llvm/CodeGen/MachineInstrBuilder.h"
     22 #include "llvm/CodeGen/MachineRegisterInfo.h"
     23 #include "llvm/IR/Function.h"
     24 
     25 using namespace llvm;
     26 
     27 // Determines the size of the frame and maximum call frame size.
     28 void LanaiFrameLowering::determineFrameLayout(MachineFunction &MF) const {
     29   MachineFrameInfo *MFI = MF.getFrameInfo();
     30   const LanaiRegisterInfo *LRI = STI.getRegisterInfo();
     31 
     32   // Get the number of bytes to allocate from the FrameInfo.
     33   unsigned FrameSize = MFI->getStackSize();
     34 
     35   // Get the alignment.
     36   unsigned StackAlign = LRI->needsStackRealignment(MF) ? MFI->getMaxAlignment()
     37                                                        : getStackAlignment();
     38 
     39   // Get the maximum call frame size of all the calls.
     40   unsigned MaxCallFrameSize = MFI->getMaxCallFrameSize();
     41 
     42   // If we have dynamic alloca then MaxCallFrameSize needs to be aligned so
     43   // that allocations will be aligned.
     44   if (MFI->hasVarSizedObjects())
     45     MaxCallFrameSize = alignTo(MaxCallFrameSize, StackAlign);
     46 
     47   // Update maximum call frame size.
     48   MFI->setMaxCallFrameSize(MaxCallFrameSize);
     49 
     50   // Include call frame size in total.
     51   if (!(hasReservedCallFrame(MF) && MFI->adjustsStack()))
     52     FrameSize += MaxCallFrameSize;
     53 
     54   // Make sure the frame is aligned.
     55   FrameSize = alignTo(FrameSize, StackAlign);
     56 
     57   // Update frame info.
     58   MFI->setStackSize(FrameSize);
     59 }
     60 
     61 // Iterates through each basic block in a machine function and replaces
     62 // ADJDYNALLOC pseudo instructions with a Lanai:ADDI with the
     63 // maximum call frame size as the immediate.
     64 void LanaiFrameLowering::replaceAdjDynAllocPseudo(MachineFunction &MF) const {
     65   const LanaiInstrInfo &LII =
     66       *static_cast<const LanaiInstrInfo *>(STI.getInstrInfo());
     67   unsigned MaxCallFrameSize = MF.getFrameInfo()->getMaxCallFrameSize();
     68 
     69   for (MachineFunction::iterator MBB = MF.begin(), E = MF.end(); MBB != E;
     70        ++MBB) {
     71     MachineBasicBlock::iterator MBBI = MBB->begin();
     72     while (MBBI != MBB->end()) {
     73       MachineInstr &MI = *MBBI++;
     74       if (MI.getOpcode() == Lanai::ADJDYNALLOC) {
     75         DebugLoc DL = MI.getDebugLoc();
     76         unsigned Dst = MI.getOperand(0).getReg();
     77         unsigned Src = MI.getOperand(1).getReg();
     78 
     79         BuildMI(*MBB, MI, DL, LII.get(Lanai::ADD_I_LO), Dst)
     80             .addReg(Src)
     81             .addImm(MaxCallFrameSize);
     82         MI.eraseFromParent();
     83       }
     84     }
     85   }
     86 }
     87 
     88 // Generates the following sequence for function entry:
     89 //   st %fp,-4[*%sp]        !push old FP
     90 //   add %sp,8,%fp          !generate new FP
     91 //   sub %sp,0x4,%sp        !allocate stack space (as needed)
     92 void LanaiFrameLowering::emitPrologue(MachineFunction &MF,
     93                                       MachineBasicBlock &MBB) const {
     94   assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported");
     95 
     96   MachineFrameInfo *MFI = MF.getFrameInfo();
     97   const LanaiInstrInfo &LII =
     98       *static_cast<const LanaiInstrInfo *>(STI.getInstrInfo());
     99   MachineBasicBlock::iterator MBBI = MBB.begin();
    100 
    101   // Debug location must be unknown since the first debug location is used
    102   // to determine the end of the prologue.
    103   DebugLoc DL;
    104 
    105   // Determine the correct frame layout
    106   determineFrameLayout(MF);
    107 
    108   // FIXME: This appears to be overallocating.  Needs investigation.
    109   // Get the number of bytes to allocate from the FrameInfo.
    110   unsigned StackSize = MFI->getStackSize();
    111 
    112   // Push old FP
    113   // st %fp,-4[*%sp]
    114   BuildMI(MBB, MBBI, DL, LII.get(Lanai::SW_RI))
    115       .addReg(Lanai::FP)
    116       .addReg(Lanai::SP)
    117       .addImm(-4)
    118       .addImm(LPAC::makePreOp(LPAC::ADD))
    119       .setMIFlag(MachineInstr::FrameSetup);
    120 
    121   // Generate new FP
    122   // add %sp,8,%fp
    123   BuildMI(MBB, MBBI, DL, LII.get(Lanai::ADD_I_LO), Lanai::FP)
    124       .addReg(Lanai::SP)
    125       .addImm(8)
    126       .setMIFlag(MachineInstr::FrameSetup);
    127 
    128   // Allocate space on the stack if needed
    129   // sub %sp,StackSize,%sp
    130   if (StackSize != 0) {
    131     BuildMI(MBB, MBBI, DL, LII.get(Lanai::SUB_I_LO), Lanai::SP)
    132         .addReg(Lanai::SP)
    133         .addImm(StackSize)
    134         .setMIFlag(MachineInstr::FrameSetup);
    135   }
    136 
    137   // Replace ADJDYNANALLOC
    138   if (MFI->hasVarSizedObjects())
    139     replaceAdjDynAllocPseudo(MF);
    140 }
    141 
    142 MachineBasicBlock::iterator LanaiFrameLowering::eliminateCallFramePseudoInstr(
    143     MachineFunction &MF, MachineBasicBlock &MBB,
    144     MachineBasicBlock::iterator I) const {
    145   // Discard ADJCALLSTACKDOWN, ADJCALLSTACKUP instructions.
    146   return MBB.erase(I);
    147 }
    148 
    149 // The function epilogue should not depend on the current stack pointer!
    150 // It should use the frame pointer only.  This is mandatory because
    151 // of alloca; we also take advantage of it to omit stack adjustments
    152 // before returning.
    153 //
    154 // Note that when we go to restore the preserved register values we must
    155 // not try to address their slots by using offsets from the stack pointer.
    156 // That's because the stack pointer may have been moved during the function
    157 // execution due to a call to alloca().  Rather, we must restore all
    158 // preserved registers via offsets from the frame pointer value.
    159 //
    160 // Note also that when the current frame is being "popped" (by adjusting
    161 // the value of the stack pointer) on function exit, we must (for the
    162 // sake of alloca) set the new value of the stack pointer based upon
    163 // the current value of the frame pointer.  We can't just add what we
    164 // believe to be the (static) frame size to the stack pointer because
    165 // if we did that, and alloca() had been called during this function,
    166 // we would end up returning *without* having fully deallocated all of
    167 // the space grabbed by alloca.  If that happened, and a function
    168 // containing one or more alloca() calls was called over and over again,
    169 // then the stack would grow without limit!
    170 //
    171 // RET is lowered to
    172 //      ld -4[%fp],%pc  # modify %pc (two delay slots)
    173 // as the return address is in the stack frame and mov to pc is allowed.
    174 // emitEpilogue emits
    175 //      mov %fp,%sp     # restore the stack pointer
    176 //      ld -8[%fp],%fp  # restore the caller's frame pointer
    177 // before RET and the delay slot filler will move RET such that these
    178 // instructions execute in the delay slots of the load to PC.
    179 void LanaiFrameLowering::emitEpilogue(MachineFunction &MF,
    180                                       MachineBasicBlock &MBB) const {
    181   MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
    182   const LanaiInstrInfo &LII =
    183       *static_cast<const LanaiInstrInfo *>(STI.getInstrInfo());
    184   DebugLoc DL = MBBI->getDebugLoc();
    185 
    186   // Restore the stack pointer using the callee's frame pointer value.
    187   BuildMI(MBB, MBBI, DL, LII.get(Lanai::ADD_I_LO), Lanai::SP)
    188       .addReg(Lanai::FP)
    189       .addImm(0);
    190 
    191   // Restore the frame pointer from the stack.
    192   BuildMI(MBB, MBBI, DL, LII.get(Lanai::LDW_RI), Lanai::FP)
    193       .addReg(Lanai::FP)
    194       .addImm(-8)
    195       .addImm(LPAC::ADD);
    196 }
    197 
    198 void LanaiFrameLowering::determineCalleeSaves(MachineFunction &MF,
    199                                               BitVector &SavedRegs,
    200                                               RegScavenger *RS) const {
    201   TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);
    202 
    203   MachineFrameInfo *MFI = MF.getFrameInfo();
    204   const LanaiRegisterInfo *LRI =
    205       static_cast<const LanaiRegisterInfo *>(STI.getRegisterInfo());
    206   int Offset = -4;
    207 
    208   // Reserve 4 bytes for the saved RCA
    209   MFI->CreateFixedObject(4, Offset, true);
    210   Offset -= 4;
    211 
    212   // Reserve 4 bytes for the saved FP
    213   MFI->CreateFixedObject(4, Offset, true);
    214   Offset -= 4;
    215 
    216   if (LRI->hasBasePointer(MF)) {
    217     MFI->CreateFixedObject(4, Offset, true);
    218     SavedRegs.reset(LRI->getBaseRegister());
    219   }
    220 }
    221