LCOV - code coverage report
Current view: top level - lib/CodeGen - TargetFrameLoweringImpl.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 32 36 88.9 %
Date: 2018-10-20 13:21:21 Functions: 6 8 75.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- TargetFrameLoweringImpl.cpp - Implement target frame interface ------==//
       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             : // Implements the layout of a stack frame on the target machine.
      11             : //
      12             : //===----------------------------------------------------------------------===//
      13             : 
      14             : #include "llvm/ADT/BitVector.h"
      15             : #include "llvm/CodeGen/MachineFrameInfo.h"
      16             : #include "llvm/CodeGen/MachineFunction.h"
      17             : #include "llvm/CodeGen/MachineRegisterInfo.h"
      18             : #include "llvm/CodeGen/TargetFrameLowering.h"
      19             : #include "llvm/CodeGen/TargetRegisterInfo.h"
      20             : #include "llvm/CodeGen/TargetSubtargetInfo.h"
      21             : #include "llvm/IR/Attributes.h"
      22             : #include "llvm/IR/CallingConv.h"
      23             : #include "llvm/IR/Function.h"
      24             : #include "llvm/MC/MCRegisterInfo.h"
      25             : #include "llvm/Support/Compiler.h"
      26             : #include "llvm/Target/TargetMachine.h"
      27             : #include "llvm/Target/TargetOptions.h"
      28             : 
      29             : using namespace llvm;
      30             : 
      31             : TargetFrameLowering::~TargetFrameLowering() = default;
      32             : 
      33             : /// The default implementation just looks at attribute "no-frame-pointer-elim".
      34    38463488 : bool TargetFrameLowering::noFramePointerElim(const MachineFunction &MF) const {
      35    38463488 :   auto Attr = MF.getFunction().getFnAttribute("no-frame-pointer-elim");
      36    38463488 :   return Attr.getValueAsString() == "true";
      37             : }
      38             : 
      39        2786 : bool TargetFrameLowering::enableCalleeSaveSkip(const MachineFunction &MF) const {
      40             :   assert(MF.getFunction().hasFnAttribute(Attribute::NoReturn) &&
      41             :          MF.getFunction().hasFnAttribute(Attribute::NoUnwind) &&
      42             :          !MF.getFunction().hasFnAttribute(Attribute::UWTable));
      43        2786 :   return false;
      44             : }
      45             : 
      46             : /// Returns the displacement from the frame register to the stack
      47             : /// frame of the specified index, along with the frame register used
      48             : /// (in output arg FrameReg). This is the default implementation which
      49             : /// is overridden for some targets.
      50        3426 : int TargetFrameLowering::getFrameIndexReference(const MachineFunction &MF,
      51             :                                              int FI, unsigned &FrameReg) const {
      52        3426 :   const MachineFrameInfo &MFI = MF.getFrameInfo();
      53        3426 :   const TargetRegisterInfo *RI = MF.getSubtarget().getRegisterInfo();
      54             : 
      55             :   // By default, assume all frame indices are referenced via whatever
      56             :   // getFrameRegister() says. The target can override this if it's doing
      57             :   // something different.
      58        3426 :   FrameReg = RI->getFrameRegister(MF);
      59             : 
      60        6852 :   return MFI.getObjectOffset(FI) + MFI.getStackSize() -
      61        6852 :          getOffsetOfLocalArea() + MFI.getOffsetAdjustment();
      62             : }
      63             : 
      64       90541 : bool TargetFrameLowering::needsFrameIndexResolution(
      65             :     const MachineFunction &MF) const {
      66      181082 :   return MF.getFrameInfo().hasStackObjects();
      67             : }
      68             : 
      69      432294 : void TargetFrameLowering::determineCalleeSaves(MachineFunction &MF,
      70             :                                                BitVector &SavedRegs,
      71             :                                                RegScavenger *RS) const {
      72      432294 :   const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo();
      73             : 
      74             :   // Resize before the early returns. Some backends expect that
      75             :   // SavedRegs.size() == TRI.getNumRegs() after this call even if there are no
      76             :   // saved registers.
      77      432294 :   SavedRegs.resize(TRI.getNumRegs());
      78             : 
      79             :   // When interprocedural register allocation is enabled caller saved registers
      80             :   // are preferred over callee saved registers.
      81      432294 :   if (MF.getTarget().Options.EnableIPRA && isSafeForNoCSROpt(MF.getFunction()))
      82             :     return;
      83             : 
      84             :   // Get the callee saved register list...
      85      432292 :   const MCPhysReg *CSRegs = MF.getRegInfo().getCalleeSavedRegs();
      86             : 
      87             :   // Early exit if there are no callee saved registers.
      88      432292 :   if (!CSRegs || CSRegs[0] == 0)
      89             :     return;
      90             : 
      91             :   // In Naked functions we aren't going to save any registers.
      92      393354 :   if (MF.getFunction().hasFnAttribute(Attribute::Naked))
      93             :     return;
      94             : 
      95             :   // Noreturn+nounwind functions never restore CSR, so no saves are needed.
      96             :   // Purely noreturn functions may still return through throws, so those must
      97             :   // save CSR for caller exception handlers.
      98             :   //
      99             :   // If the function uses longjmp to break out of its current path of
     100             :   // execution we do not need the CSR spills either: setjmp stores all CSRs
     101             :   // it was called with into the jmp_buf, which longjmp then restores.
     102      396275 :   if (MF.getFunction().hasFnAttribute(Attribute::NoReturn) &&
     103        5828 :         MF.getFunction().hasFnAttribute(Attribute::NoUnwind) &&
     104      398895 :         !MF.getFunction().hasFnAttribute(Attribute::UWTable) &&
     105        2800 :         enableCalleeSaveSkip(MF))
     106             :     return;
     107             : 
     108             :   // Functions which call __builtin_unwind_init get all their registers saved.
     109      393257 :   bool CallsUnwindInit = MF.callsUnwindInit();
     110      393257 :   const MachineRegisterInfo &MRI = MF.getRegInfo();
     111     4744318 :   for (unsigned i = 0; CSRegs[i]; ++i) {
     112     4351061 :     unsigned Reg = CSRegs[i];
     113     4351061 :     if (CallsUnwindInit || MRI.isPhysRegModified(Reg))
     114             :       SavedRegs.set(Reg);
     115             :   }
     116             : }
     117             : 
     118      404392 : unsigned TargetFrameLowering::getStackAlignmentSkew(
     119             :     const MachineFunction &MF) const {
     120             :   // When HHVM function is called, the stack is skewed as the return address
     121             :   // is removed from the stack before we enter the function.
     122      808784 :   if (LLVM_UNLIKELY(MF.getFunction().getCallingConv() == CallingConv::HHVM))
     123          11 :     return MF.getTarget().getAllocaPointerSize();
     124             : 
     125             :   return 0;
     126             : }
     127             : 
     128           0 : int TargetFrameLowering::getInitialCFAOffset(const MachineFunction &MF) const {
     129           0 :   llvm_unreachable("getInitialCFAOffset() not implemented!");
     130             : }
     131             : 
     132           0 : unsigned TargetFrameLowering::getInitialCFARegister(const MachineFunction &MF)
     133             :     const {
     134           0 :   llvm_unreachable("getInitialCFARegister() not implemented!");
     135             : }

Generated by: LCOV version 1.13