blob: cf78fb5a1f127827e3ee04dab6c0d4f6687998db [file] [log] [blame]
Eugene Zelenkoe74c4362017-06-06 22:22:41 +00001//===- TargetFrameLoweringImpl.cpp - Implement target frame interface ------==//
Misha Brukmanf976c852005-04-21 22:55:34 +00002//
Misha Brukmanb8bda132004-03-11 23:52:43 +00003// The LLVM Compiler Infrastructure
4//
Chris Lattner4ee451d2007-12-29 20:36:04 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Misha Brukmanf976c852005-04-21 22:55:34 +00007//
Misha Brukmanb8bda132004-03-11 23:52:43 +00008//===----------------------------------------------------------------------===//
9//
10// Implements the layout of a stack frame on the target machine.
11//
12//===----------------------------------------------------------------------===//
13
Matthias Brauna3626822015-07-14 17:17:13 +000014#include "llvm/ADT/BitVector.h"
Anton Korobeynikov0dbe54e2010-11-20 16:14:57 +000015#include "llvm/CodeGen/MachineFrameInfo.h"
16#include "llvm/CodeGen/MachineFunction.h"
Matthias Brauna3626822015-07-14 17:17:13 +000017#include "llvm/CodeGen/MachineRegisterInfo.h"
David Blaikiee3a9b4c2017-11-17 01:07:10 +000018#include "llvm/CodeGen/TargetFrameLowering.h"
19#include "llvm/CodeGen/TargetRegisterInfo.h"
20#include "llvm/CodeGen/TargetSubtargetInfo.h"
Eugene Zelenkoe74c4362017-06-06 22:22:41 +000021#include "llvm/IR/Attributes.h"
Maksim Panchenko3b3752c2015-09-29 22:09:16 +000022#include "llvm/IR/CallingConv.h"
Akira Hatanaka01461202015-05-23 01:14:08 +000023#include "llvm/IR/Function.h"
Eugene Zelenkoe74c4362017-06-06 22:22:41 +000024#include "llvm/MC/MCRegisterInfo.h"
25#include "llvm/Support/Compiler.h"
Eugene Zelenkoe74c4362017-06-06 22:22:41 +000026#include "llvm/Target/TargetMachine.h"
27#include "llvm/Target/TargetOptions.h"
Eugene Zelenkoe74c4362017-06-06 22:22:41 +000028
Misha Brukmanb8bda132004-03-11 23:52:43 +000029using namespace llvm;
30
Eugene Zelenkoe74c4362017-06-06 22:22:41 +000031TargetFrameLowering::~TargetFrameLowering() = default;
Anton Korobeynikovd9e33852010-11-18 23:25:52 +000032
Tim Northoverf6621a42018-04-07 10:57:03 +000033bool TargetFrameLowering::enableCalleeSaveSkip(const MachineFunction &MF) const {
34 assert(MF.getFunction().hasFnAttribute(Attribute::NoReturn) &&
35 MF.getFunction().hasFnAttribute(Attribute::NoUnwind) &&
36 !MF.getFunction().hasFnAttribute(Attribute::UWTable));
37 return false;
38}
39
James Y Knight276ea222015-08-15 02:32:35 +000040/// Returns the displacement from the frame register to the stack
41/// frame of the specified index, along with the frame register used
42/// (in output arg FrameReg). This is the default implementation which
43/// is overridden for some targets.
Anton Korobeynikov16c29b52011-01-10 12:39:04 +000044int TargetFrameLowering::getFrameIndexReference(const MachineFunction &MF,
45 int FI, unsigned &FrameReg) const {
Matthias Braunf79c57a2016-07-28 18:40:00 +000046 const MachineFrameInfo &MFI = MF.getFrameInfo();
Eric Christopher60355182014-08-05 02:39:49 +000047 const TargetRegisterInfo *RI = MF.getSubtarget().getRegisterInfo();
Anton Korobeynikov82f58742010-11-20 15:59:32 +000048
49 // By default, assume all frame indices are referenced via whatever
50 // getFrameRegister() says. The target can override this if it's doing
51 // something different.
52 FrameReg = RI->getFrameRegister(MF);
James Y Knight276ea222015-08-15 02:32:35 +000053
Matthias Braunf79c57a2016-07-28 18:40:00 +000054 return MFI.getObjectOffset(FI) + MFI.getStackSize() -
55 getOffsetOfLocalArea() + MFI.getOffsetAdjustment();
Anton Korobeynikov82f58742010-11-20 15:59:32 +000056}
Michael Kupersteinacd5f132015-02-01 16:56:04 +000057
58bool TargetFrameLowering::needsFrameIndexResolution(
59 const MachineFunction &MF) const {
Matthias Braunf79c57a2016-07-28 18:40:00 +000060 return MF.getFrameInfo().hasStackObjects();
Michael Kupersteinacd5f132015-02-01 16:56:04 +000061}
Matthias Brauna3626822015-07-14 17:17:13 +000062
63void TargetFrameLowering::determineCalleeSaves(MachineFunction &MF,
64 BitVector &SavedRegs,
65 RegScavenger *RS) const {
Matthias Brauna3626822015-07-14 17:17:13 +000066 const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo();
Matthias Brauna3626822015-07-14 17:17:13 +000067
Chuang-Yu Chengeb92f5a2016-04-08 12:04:32 +000068 // Resize before the early returns. Some backends expect that
69 // SavedRegs.size() == TRI.getNumRegs() after this call even if there are no
70 // saved registers.
71 SavedRegs.resize(TRI.getNumRegs());
72
Mehdi Aminibf8318cc2016-07-13 23:39:34 +000073 // When interprocedural register allocation is enabled caller saved registers
74 // are preferred over callee saved registers.
Mehdi Aminif167a262016-07-13 23:39:46 +000075 if (MF.getTarget().Options.EnableIPRA && isSafeForNoCSROpt(MF.getFunction()))
Mehdi Aminibf8318cc2016-07-13 23:39:34 +000076 return;
77
78 // Get the callee saved register list...
Oren Ben Simhon6095a792017-03-14 09:09:26 +000079 const MCPhysReg *CSRegs = MF.getRegInfo().getCalleeSavedRegs();
Mehdi Aminibf8318cc2016-07-13 23:39:34 +000080
Matthias Brauna3626822015-07-14 17:17:13 +000081 // Early exit if there are no callee saved registers.
82 if (!CSRegs || CSRegs[0] == 0)
83 return;
84
Matthias Brauna3626822015-07-14 17:17:13 +000085 // In Naked functions we aren't going to save any registers.
Matthias Braund3181392017-12-15 22:22:58 +000086 if (MF.getFunction().hasFnAttribute(Attribute::Naked))
Matthias Brauna3626822015-07-14 17:17:13 +000087 return;
88
Tim Northoverf6621a42018-04-07 10:57:03 +000089 // Noreturn+nounwind functions never restore CSR, so no saves are needed.
90 // Purely noreturn functions may still return through throws, so those must
91 // save CSR for caller exception handlers.
92 //
93 // If the function uses longjmp to break out of its current path of
94 // execution we do not need the CSR spills either: setjmp stores all CSRs
95 // it was called with into the jmp_buf, which longjmp then restores.
96 if (MF.getFunction().hasFnAttribute(Attribute::NoReturn) &&
97 MF.getFunction().hasFnAttribute(Attribute::NoUnwind) &&
98 !MF.getFunction().hasFnAttribute(Attribute::UWTable) &&
99 enableCalleeSaveSkip(MF))
100 return;
101
Matthias Brauna3626822015-07-14 17:17:13 +0000102 // Functions which call __builtin_unwind_init get all their registers saved.
Matthias Braun347847b2016-12-01 19:32:15 +0000103 bool CallsUnwindInit = MF.callsUnwindInit();
Matthias Brauna3626822015-07-14 17:17:13 +0000104 const MachineRegisterInfo &MRI = MF.getRegInfo();
105 for (unsigned i = 0; CSRegs[i]; ++i) {
106 unsigned Reg = CSRegs[i];
107 if (CallsUnwindInit || MRI.isPhysRegModified(Reg))
108 SavedRegs.set(Reg);
109 }
110}
Maksim Panchenko3b3752c2015-09-29 22:09:16 +0000111
112unsigned TargetFrameLowering::getStackAlignmentSkew(
113 const MachineFunction &MF) const {
114 // When HHVM function is called, the stack is skewed as the return address
115 // is removed from the stack before we enter the function.
Matthias Braund3181392017-12-15 22:22:58 +0000116 if (LLVM_UNLIKELY(MF.getFunction().getCallingConv() == CallingConv::HHVM))
Matt Arsenault6f1d6422018-03-14 00:36:23 +0000117 return MF.getTarget().getAllocaPointerSize();
Maksim Panchenko3b3752c2015-09-29 22:09:16 +0000118
119 return 0;
120}
Petar Jovanovicb6bee652018-04-24 10:32:08 +0000121
122int TargetFrameLowering::getInitialCFAOffset(const MachineFunction &MF) const {
123 llvm_unreachable("getInitialCFAOffset() not implemented!");
124}
125
126unsigned TargetFrameLowering::getInitialCFARegister(const MachineFunction &MF)
127 const {
128 llvm_unreachable("getInitialCFARegister() not implemented!");
129}