llvm/lib/CodeGen/TargetFrameLoweringImpl.cpp

105 lines
4.0 KiB
C++
Raw Normal View History

//===----- TargetFrameLoweringImpl.cpp - Implement target frame interface --==//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Implements the layout of a stack frame on the target machine.
//
//===----------------------------------------------------------------------===//
#include "llvm/ADT/BitVector.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/IR/Function.h"
#include "llvm/Target/TargetFrameLowering.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Target/TargetSubtargetInfo.h"
#include <cstdlib>
using namespace llvm;
TargetFrameLowering::~TargetFrameLowering() {
}
/// The default implementation just looks at attribute "no-frame-pointer-elim".
bool TargetFrameLowering::noFramePointerElim(const MachineFunction &MF) const {
auto Attr = MF.getFunction()->getFnAttribute("no-frame-pointer-elim");
return Attr.getValueAsString() == "true";
}
/// Returns the displacement from the frame register to the stack
/// frame of the specified index, along with the frame register used
/// (in output arg FrameReg). This is the default implementation which
/// is overridden for some targets.
int TargetFrameLowering::getFrameIndexReference(const MachineFunction &MF,
int FI, unsigned &FrameReg) const {
const MachineFrameInfo &MFI = MF.getFrameInfo();
const TargetRegisterInfo *RI = MF.getSubtarget().getRegisterInfo();
// By default, assume all frame indices are referenced via whatever
// getFrameRegister() says. The target can override this if it's doing
// something different.
FrameReg = RI->getFrameRegister(MF);
return MFI.getObjectOffset(FI) + MFI.getStackSize() -
getOffsetOfLocalArea() + MFI.getOffsetAdjustment();
}
bool TargetFrameLowering::needsFrameIndexResolution(
const MachineFunction &MF) const {
return MF.getFrameInfo().hasStackObjects();
}
void TargetFrameLowering::determineCalleeSaves(MachineFunction &MF,
BitVector &SavedRegs,
RegScavenger *RS) const {
const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo();
CXX_FAST_TLS calling convention: performance improvement for PPC64 This is the same change on PPC64 as r255821 on AArch64. I have even borrowed his commit message. The access function has a short entry and a short exit, the initialization block is only run the first time. To improve the performance, we want to have a short frame at the entry and exit. We explicitly handle most of the CSRs via copies. Only the CSRs that are not handled via copies will be in CSR_SaveList. Frame lowering and prologue/epilogue insertion will generate a short frame in the entry and exit according to CSR_SaveList. The majority of the CSRs will be handled by register allcoator. Register allocator will try to spill and reload them in the initialization block. We add CSRsViaCopy, it will be explicitly handled during lowering. 1> we first set FunctionLoweringInfo->SplitCSR if conditions are met (the target supports it for the given machine function and the function has only return exits). We also call TLI->initializeSplitCSR to perform initialization. 2> we call TLI->insertCopiesSplitCSR to insert copies from CSRsViaCopy to virtual registers at beginning of the entry block and copies from virtual registers to CSRsViaCopy at beginning of the exit blocks. 3> we also need to make sure the explicit copies will not be eliminated. Author: Tom Jablin (tjablin) Reviewers: hfinkel kbarton cycheng http://reviews.llvm.org/D17533 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@265781 91177308-0d34-0410-b5e6-96231b3b80d8
2016-04-08 12:04:32 +00:00
// Resize before the early returns. Some backends expect that
// SavedRegs.size() == TRI.getNumRegs() after this call even if there are no
// saved registers.
SavedRegs.resize(TRI.getNumRegs());
// When interprocedural register allocation is enabled caller saved registers
// are preferred over callee saved registers.
if (MF.getTarget().Options.EnableIPRA && isSafeForNoCSROpt(MF.getFunction()))
return;
// Get the callee saved register list...
const MCPhysReg *CSRegs = MF.getRegInfo().getCalleeSavedRegs();
// Early exit if there are no callee saved registers.
if (!CSRegs || CSRegs[0] == 0)
return;
// In Naked functions we aren't going to save any registers.
if (MF.getFunction()->hasFnAttribute(Attribute::Naked))
return;
// Functions which call __builtin_unwind_init get all their registers saved.
bool CallsUnwindInit = MF.callsUnwindInit();
const MachineRegisterInfo &MRI = MF.getRegInfo();
for (unsigned i = 0; CSRegs[i]; ++i) {
unsigned Reg = CSRegs[i];
if (CallsUnwindInit || MRI.isPhysRegModified(Reg))
SavedRegs.set(Reg);
}
}
unsigned TargetFrameLowering::getStackAlignmentSkew(
const MachineFunction &MF) const {
// When HHVM function is called, the stack is skewed as the return address
// is removed from the stack before we enter the function.
if (LLVM_UNLIKELY(MF.getFunction()->getCallingConv() == CallingConv::HHVM))
return MF.getTarget().getPointerSize();
return 0;
}