Home | History | Annotate | Download | only in NVPTX
      1 //===-- NVPTXPrologEpilogPass.cpp - NVPTX prolog/epilog inserter ----------===//
      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 is a copy of the generic LLVM PrologEpilogInserter pass, modified
     11 // to remove unneeded functionality and to handle virtual registers. Most code
     12 // here is a copy of PrologEpilogInserter.cpp.
     13 //
     14 //===----------------------------------------------------------------------===//
     15 
     16 #include "NVPTX.h"
     17 #include "llvm/Pass.h"
     18 #include "llvm/CodeGen/MachineFrameInfo.h"
     19 #include "llvm/CodeGen/MachineFunction.h"
     20 #include "llvm/CodeGen/MachineFunctionPass.h"
     21 #include "llvm/Target/TargetFrameLowering.h"
     22 #include "llvm/Target/TargetRegisterInfo.h"
     23 #include "llvm/Support/Debug.h"
     24 #include "llvm/Support/raw_ostream.h"
     25 
     26 using namespace llvm;
     27 
     28 namespace {
     29 class NVPTXPrologEpilogPass : public MachineFunctionPass {
     30 public:
     31   static char ID;
     32   NVPTXPrologEpilogPass() : MachineFunctionPass(ID) {}
     33 
     34   virtual bool runOnMachineFunction(MachineFunction &MF);
     35 
     36 private:
     37   void calculateFrameObjectOffsets(MachineFunction &Fn);
     38 };
     39 }
     40 
     41 MachineFunctionPass *llvm::createNVPTXPrologEpilogPass() {
     42   return new NVPTXPrologEpilogPass();
     43 }
     44 
     45 char NVPTXPrologEpilogPass::ID = 0;
     46 
     47 bool NVPTXPrologEpilogPass::runOnMachineFunction(MachineFunction &MF) {
     48   const TargetMachine &TM = MF.getTarget();
     49   const TargetFrameLowering &TFI = *TM.getFrameLowering();
     50   const TargetRegisterInfo &TRI = *TM.getRegisterInfo();
     51   bool Modified = false;
     52 
     53   calculateFrameObjectOffsets(MF);
     54 
     55   for (MachineFunction::iterator BB = MF.begin(), E = MF.end(); BB != E; ++BB) {
     56     for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ++I) {
     57       MachineInstr *MI = I;
     58       for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
     59         if (!MI->getOperand(i).isFI())
     60           continue;
     61         TRI.eliminateFrameIndex(MI, 0, i, NULL);
     62         Modified = true;
     63       }
     64     }
     65   }
     66 
     67   // Add function prolog/epilog
     68   TFI.emitPrologue(MF);
     69 
     70   for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) {
     71     // If last instruction is a return instruction, add an epilogue
     72     if (!I->empty() && I->back().isReturn())
     73       TFI.emitEpilogue(MF, *I);
     74   }
     75 
     76   return Modified;
     77 }
     78 
     79 /// AdjustStackOffset - Helper function used to adjust the stack frame offset.
     80 static inline void
     81 AdjustStackOffset(MachineFrameInfo *MFI, int FrameIdx,
     82                   bool StackGrowsDown, int64_t &Offset,
     83                   unsigned &MaxAlign) {
     84   // If the stack grows down, add the object size to find the lowest address.
     85   if (StackGrowsDown)
     86     Offset += MFI->getObjectSize(FrameIdx);
     87 
     88   unsigned Align = MFI->getObjectAlignment(FrameIdx);
     89 
     90   // If the alignment of this object is greater than that of the stack, then
     91   // increase the stack alignment to match.
     92   MaxAlign = std::max(MaxAlign, Align);
     93 
     94   // Adjust to alignment boundary.
     95   Offset = (Offset + Align - 1) / Align * Align;
     96 
     97   if (StackGrowsDown) {
     98     DEBUG(dbgs() << "alloc FI(" << FrameIdx << ") at SP[" << -Offset << "]\n");
     99     MFI->setObjectOffset(FrameIdx, -Offset); // Set the computed offset
    100   } else {
    101     DEBUG(dbgs() << "alloc FI(" << FrameIdx << ") at SP[" << Offset << "]\n");
    102     MFI->setObjectOffset(FrameIdx, Offset);
    103     Offset += MFI->getObjectSize(FrameIdx);
    104   }
    105 }
    106 
    107 void
    108 NVPTXPrologEpilogPass::calculateFrameObjectOffsets(MachineFunction &Fn) {
    109   const TargetFrameLowering &TFI = *Fn.getTarget().getFrameLowering();
    110   const TargetRegisterInfo *RegInfo = Fn.getTarget().getRegisterInfo();
    111 
    112   bool StackGrowsDown =
    113     TFI.getStackGrowthDirection() == TargetFrameLowering::StackGrowsDown;
    114 
    115   // Loop over all of the stack objects, assigning sequential addresses...
    116   MachineFrameInfo *MFI = Fn.getFrameInfo();
    117 
    118   // Start at the beginning of the local area.
    119   // The Offset is the distance from the stack top in the direction
    120   // of stack growth -- so it's always nonnegative.
    121   int LocalAreaOffset = TFI.getOffsetOfLocalArea();
    122   if (StackGrowsDown)
    123     LocalAreaOffset = -LocalAreaOffset;
    124   assert(LocalAreaOffset >= 0
    125          && "Local area offset should be in direction of stack growth");
    126   int64_t Offset = LocalAreaOffset;
    127 
    128   // If there are fixed sized objects that are preallocated in the local area,
    129   // non-fixed objects can't be allocated right at the start of local area.
    130   // We currently don't support filling in holes in between fixed sized
    131   // objects, so we adjust 'Offset' to point to the end of last fixed sized
    132   // preallocated object.
    133   for (int i = MFI->getObjectIndexBegin(); i != 0; ++i) {
    134     int64_t FixedOff;
    135     if (StackGrowsDown) {
    136       // The maximum distance from the stack pointer is at lower address of
    137       // the object -- which is given by offset. For down growing stack
    138       // the offset is negative, so we negate the offset to get the distance.
    139       FixedOff = -MFI->getObjectOffset(i);
    140     } else {
    141       // The maximum distance from the start pointer is at the upper
    142       // address of the object.
    143       FixedOff = MFI->getObjectOffset(i) + MFI->getObjectSize(i);
    144     }
    145     if (FixedOff > Offset) Offset = FixedOff;
    146   }
    147 
    148   // NOTE: We do not have a call stack
    149 
    150   unsigned MaxAlign = MFI->getMaxAlignment();
    151 
    152   // No scavenger
    153 
    154   // FIXME: Once this is working, then enable flag will change to a target
    155   // check for whether the frame is large enough to want to use virtual
    156   // frame index registers. Functions which don't want/need this optimization
    157   // will continue to use the existing code path.
    158   if (MFI->getUseLocalStackAllocationBlock()) {
    159     unsigned Align = MFI->getLocalFrameMaxAlign();
    160 
    161     // Adjust to alignment boundary.
    162     Offset = (Offset + Align - 1) / Align * Align;
    163 
    164     DEBUG(dbgs() << "Local frame base offset: " << Offset << "\n");
    165 
    166     // Resolve offsets for objects in the local block.
    167     for (unsigned i = 0, e = MFI->getLocalFrameObjectCount(); i != e; ++i) {
    168       std::pair<int, int64_t> Entry = MFI->getLocalFrameObjectMap(i);
    169       int64_t FIOffset = (StackGrowsDown ? -Offset : Offset) + Entry.second;
    170       DEBUG(dbgs() << "alloc FI(" << Entry.first << ") at SP[" <<
    171             FIOffset << "]\n");
    172       MFI->setObjectOffset(Entry.first, FIOffset);
    173     }
    174     // Allocate the local block
    175     Offset += MFI->getLocalFrameSize();
    176 
    177     MaxAlign = std::max(Align, MaxAlign);
    178   }
    179 
    180   // No stack protector
    181 
    182   // Then assign frame offsets to stack objects that are not used to spill
    183   // callee saved registers.
    184   for (unsigned i = 0, e = MFI->getObjectIndexEnd(); i != e; ++i) {
    185     if (MFI->isObjectPreAllocated(i) &&
    186         MFI->getUseLocalStackAllocationBlock())
    187       continue;
    188     if (MFI->isDeadObjectIndex(i))
    189       continue;
    190 
    191     AdjustStackOffset(MFI, i, StackGrowsDown, Offset, MaxAlign);
    192   }
    193 
    194   // No scavenger
    195 
    196   if (!TFI.targetHandlesStackFrameRounding()) {
    197     // If we have reserved argument space for call sites in the function
    198     // immediately on entry to the current function, count it as part of the
    199     // overall stack size.
    200     if (MFI->adjustsStack() && TFI.hasReservedCallFrame(Fn))
    201       Offset += MFI->getMaxCallFrameSize();
    202 
    203     // Round up the size to a multiple of the alignment.  If the function has
    204     // any calls or alloca's, align to the target's StackAlignment value to
    205     // ensure that the callee's frame or the alloca data is suitably aligned;
    206     // otherwise, for leaf functions, align to the TransientStackAlignment
    207     // value.
    208     unsigned StackAlign;
    209     if (MFI->adjustsStack() || MFI->hasVarSizedObjects() ||
    210         (RegInfo->needsStackRealignment(Fn) && MFI->getObjectIndexEnd() != 0))
    211       StackAlign = TFI.getStackAlignment();
    212     else
    213       StackAlign = TFI.getTransientStackAlignment();
    214 
    215     // If the frame pointer is eliminated, all frame offsets will be relative to
    216     // SP not FP. Align to MaxAlign so this works.
    217     StackAlign = std::max(StackAlign, MaxAlign);
    218     unsigned AlignMask = StackAlign - 1;
    219     Offset = (Offset + AlignMask) & ~uint64_t(AlignMask);
    220   }
    221 
    222   // Update frame info to pretend that this is part of the stack...
    223   int64_t StackSize = Offset - LocalAreaOffset;
    224   MFI->setStackSize(StackSize);
    225 }
    226