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