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 && isSafeForNoCSROpt(MF.getFunction())) 75 return; 76 77 // Get the callee saved register list... 78 const MCPhysReg *CSRegs = MF.getRegInfo().getCalleeSavedRegs(); 79 80 // Early exit if there are no callee saved registers. 81 if (!CSRegs || CSRegs[0] == 0) 82 return; 83 84 // In Naked functions we aren't going to save any registers. 85 if (MF.getFunction().hasFnAttribute(Attribute::Naked)) 86 return; 87 88 // Noreturn+nounwind functions never restore CSR, so no saves are needed. 89 // Purely noreturn functions may still return through throws, so those must 90 // save CSR for caller exception handlers. 91 // 92 // If the function uses longjmp to break out of its current path of 93 // execution we do not need the CSR spills either: setjmp stores all CSRs 94 // it was called with into the jmp_buf, which longjmp then restores. 95 if (MF.getFunction().hasFnAttribute(Attribute::NoReturn) && 96 MF.getFunction().hasFnAttribute(Attribute::NoUnwind) && 97 !MF.getFunction().hasFnAttribute(Attribute::UWTable) && 98 enableCalleeSaveSkip(MF)) 99 return; 100 101 // Functions which call __builtin_unwind_init get all their registers saved. 102 bool CallsUnwindInit = MF.callsUnwindInit(); 103 const MachineRegisterInfo &MRI = MF.getRegInfo(); 104 for (unsigned i = 0; CSRegs[i]; ++i) { 105 unsigned Reg = CSRegs[i]; 106 if (CallsUnwindInit || MRI.isPhysRegModified(Reg)) 107 SavedRegs.set(Reg); 108 } 109 } 110 111 unsigned TargetFrameLowering::getStackAlignmentSkew( 112 const MachineFunction &MF) const { 113 // When HHVM function is called, the stack is skewed as the return address 114 // is removed from the stack before we enter the function. 115 if (LLVM_UNLIKELY(MF.getFunction().getCallingConv() == CallingConv::HHVM)) 116 return MF.getTarget().getAllocaPointerSize(); 117 118 return 0; 119 } 120 121 int TargetFrameLowering::getInitialCFAOffset(const MachineFunction &MF) const { 122 llvm_unreachable("getInitialCFAOffset() not implemented!"); 123 } 124 125 unsigned TargetFrameLowering::getInitialCFARegister(const MachineFunction &MF) 126 const { 127 llvm_unreachable("getInitialCFARegister() not implemented!"); 128 }