1321369Sdim//===- TargetFrameLoweringImpl.cpp - Implement target frame interface ------==// 2234285Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6234285Sdim// 7234285Sdim//===----------------------------------------------------------------------===// 8234285Sdim// 9234285Sdim// Implements the layout of a stack frame on the target machine. 10234285Sdim// 11234285Sdim//===----------------------------------------------------------------------===// 12234285Sdim 13288943Sdim#include "llvm/ADT/BitVector.h" 14234285Sdim#include "llvm/CodeGen/MachineFrameInfo.h" 15234285Sdim#include "llvm/CodeGen/MachineFunction.h" 16288943Sdim#include "llvm/CodeGen/MachineRegisterInfo.h" 17327952Sdim#include "llvm/CodeGen/TargetFrameLowering.h" 18327952Sdim#include "llvm/CodeGen/TargetRegisterInfo.h" 19327952Sdim#include "llvm/CodeGen/TargetSubtargetInfo.h" 20321369Sdim#include "llvm/IR/Attributes.h" 21360784Sdim#include "llvm/IR/CallSite.h" 22296417Sdim#include "llvm/IR/CallingConv.h" 23288943Sdim#include "llvm/IR/Function.h" 24321369Sdim#include "llvm/MC/MCRegisterInfo.h" 25321369Sdim#include "llvm/Support/Compiler.h" 26321369Sdim#include "llvm/Target/TargetMachine.h" 27321369Sdim#include "llvm/Target/TargetOptions.h" 28321369Sdim 29234285Sdimusing namespace llvm; 30234285Sdim 31321369SdimTargetFrameLowering::~TargetFrameLowering() = default; 32234285Sdim 33341825Sdimbool TargetFrameLowering::enableCalleeSaveSkip(const MachineFunction &MF) const { 34341825Sdim assert(MF.getFunction().hasFnAttribute(Attribute::NoReturn) && 35341825Sdim MF.getFunction().hasFnAttribute(Attribute::NoUnwind) && 36341825Sdim !MF.getFunction().hasFnAttribute(Attribute::UWTable)); 37341825Sdim return false; 38341825Sdim} 39341825Sdim 40296417Sdim/// Returns the displacement from the frame register to the stack 41296417Sdim/// frame of the specified index, along with the frame register used 42296417Sdim/// (in output arg FrameReg). This is the default implementation which 43296417Sdim/// is overridden for some targets. 44234285Sdimint TargetFrameLowering::getFrameIndexReference(const MachineFunction &MF, 45234285Sdim int FI, unsigned &FrameReg) const { 46314564Sdim const MachineFrameInfo &MFI = MF.getFrameInfo(); 47280031Sdim const TargetRegisterInfo *RI = MF.getSubtarget().getRegisterInfo(); 48234285Sdim 49234285Sdim // By default, assume all frame indices are referenced via whatever 50234285Sdim // getFrameRegister() says. The target can override this if it's doing 51234285Sdim // something different. 52234285Sdim FrameReg = RI->getFrameRegister(MF); 53296417Sdim 54314564Sdim return MFI.getObjectOffset(FI) + MFI.getStackSize() - 55314564Sdim getOffsetOfLocalArea() + MFI.getOffsetAdjustment(); 56234285Sdim} 57280031Sdim 58280031Sdimbool TargetFrameLowering::needsFrameIndexResolution( 59280031Sdim const MachineFunction &MF) const { 60314564Sdim return MF.getFrameInfo().hasStackObjects(); 61280031Sdim} 62288943Sdim 63360784Sdimvoid TargetFrameLowering::getCalleeSaves(const MachineFunction &MF, 64360784Sdim BitVector &CalleeSaves) const { 65360784Sdim const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo(); 66360784Sdim CalleeSaves.resize(TRI.getNumRegs()); 67360784Sdim 68360784Sdim const MachineFrameInfo &MFI = MF.getFrameInfo(); 69360784Sdim if (!MFI.isCalleeSavedInfoValid()) 70360784Sdim return; 71360784Sdim 72360784Sdim for (const CalleeSavedInfo &Info : MFI.getCalleeSavedInfo()) 73360784Sdim CalleeSaves.set(Info.getReg()); 74360784Sdim} 75360784Sdim 76288943Sdimvoid TargetFrameLowering::determineCalleeSaves(MachineFunction &MF, 77288943Sdim BitVector &SavedRegs, 78288943Sdim RegScavenger *RS) const { 79309124Sdim const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo(); 80309124Sdim 81309124Sdim // Resize before the early returns. Some backends expect that 82309124Sdim // SavedRegs.size() == TRI.getNumRegs() after this call even if there are no 83309124Sdim // saved registers. 84309124Sdim SavedRegs.resize(TRI.getNumRegs()); 85309124Sdim 86309124Sdim // When interprocedural register allocation is enabled caller saved registers 87309124Sdim // are preferred over callee saved registers. 88360784Sdim if (MF.getTarget().Options.EnableIPRA && 89360784Sdim isSafeForNoCSROpt(MF.getFunction()) && 90360784Sdim isProfitableForNoCSROpt(MF.getFunction())) 91309124Sdim return; 92309124Sdim 93288943Sdim // Get the callee saved register list... 94321369Sdim const MCPhysReg *CSRegs = MF.getRegInfo().getCalleeSavedRegs(); 95288943Sdim 96288943Sdim // Early exit if there are no callee saved registers. 97288943Sdim if (!CSRegs || CSRegs[0] == 0) 98288943Sdim return; 99288943Sdim 100288943Sdim // In Naked functions we aren't going to save any registers. 101327952Sdim if (MF.getFunction().hasFnAttribute(Attribute::Naked)) 102288943Sdim return; 103288943Sdim 104341825Sdim // Noreturn+nounwind functions never restore CSR, so no saves are needed. 105341825Sdim // Purely noreturn functions may still return through throws, so those must 106341825Sdim // save CSR for caller exception handlers. 107341825Sdim // 108341825Sdim // If the function uses longjmp to break out of its current path of 109341825Sdim // execution we do not need the CSR spills either: setjmp stores all CSRs 110341825Sdim // it was called with into the jmp_buf, which longjmp then restores. 111341825Sdim if (MF.getFunction().hasFnAttribute(Attribute::NoReturn) && 112341825Sdim MF.getFunction().hasFnAttribute(Attribute::NoUnwind) && 113341825Sdim !MF.getFunction().hasFnAttribute(Attribute::UWTable) && 114341825Sdim enableCalleeSaveSkip(MF)) 115341825Sdim return; 116341825Sdim 117288943Sdim // Functions which call __builtin_unwind_init get all their registers saved. 118314564Sdim bool CallsUnwindInit = MF.callsUnwindInit(); 119288943Sdim const MachineRegisterInfo &MRI = MF.getRegInfo(); 120288943Sdim for (unsigned i = 0; CSRegs[i]; ++i) { 121288943Sdim unsigned Reg = CSRegs[i]; 122288943Sdim if (CallsUnwindInit || MRI.isPhysRegModified(Reg)) 123288943Sdim SavedRegs.set(Reg); 124288943Sdim } 125288943Sdim} 126296417Sdim 127296417Sdimunsigned TargetFrameLowering::getStackAlignmentSkew( 128296417Sdim const MachineFunction &MF) const { 129296417Sdim // When HHVM function is called, the stack is skewed as the return address 130296417Sdim // is removed from the stack before we enter the function. 131327952Sdim if (LLVM_UNLIKELY(MF.getFunction().getCallingConv() == CallingConv::HHVM)) 132341825Sdim return MF.getTarget().getAllocaPointerSize(); 133296417Sdim 134296417Sdim return 0; 135296417Sdim} 136341825Sdim 137360784Sdimbool TargetFrameLowering::isSafeForNoCSROpt(const Function &F) { 138360784Sdim if (!F.hasLocalLinkage() || F.hasAddressTaken() || 139360784Sdim !F.hasFnAttribute(Attribute::NoRecurse)) 140360784Sdim return false; 141360784Sdim // Function should not be optimized as tail call. 142360784Sdim for (const User *U : F.users()) 143360784Sdim if (auto CS = ImmutableCallSite(U)) 144360784Sdim if (CS.isTailCall()) 145360784Sdim return false; 146360784Sdim return true; 147360784Sdim} 148360784Sdim 149341825Sdimint TargetFrameLowering::getInitialCFAOffset(const MachineFunction &MF) const { 150341825Sdim llvm_unreachable("getInitialCFAOffset() not implemented!"); 151341825Sdim} 152341825Sdim 153341825Sdimunsigned TargetFrameLowering::getInitialCFARegister(const MachineFunction &MF) 154341825Sdim const { 155341825Sdim llvm_unreachable("getInitialCFARegister() not implemented!"); 156360784Sdim} 157