LLVM 23.0.0git
MachineFrameInfo.cpp
Go to the documentation of this file.
1//===-- MachineFrameInfo.cpp ---------------------------------------------===//
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/// \file Implements MachineFrameInfo that manages the stack frame.
10//
11//===----------------------------------------------------------------------===//
12
14
15#include "llvm/ADT/BitVector.h"
22#include "llvm/Config/llvm-config.h"
23#include "llvm/Support/Debug.h"
25#include <cassert>
26
27#define DEBUG_TYPE "codegen"
28
29using namespace llvm;
30
32 if (!StackRealignable)
33 assert(Alignment <= StackAlignment &&
34 "For targets without stack realignment, Alignment is out of limit!");
35 if (MaxAlignment < Alignment)
36 MaxAlignment = Alignment;
37}
38
39/// Clamp the alignment if requested and emit a warning.
40static inline Align clampStackAlignment(bool ShouldClamp, Align Alignment,
41 Align StackAlignment) {
42 if (!ShouldClamp || Alignment <= StackAlignment)
43 return Alignment;
44 LLVM_DEBUG(dbgs() << "Warning: requested alignment " << DebugStr(Alignment)
45 << " exceeds the stack alignment "
46 << DebugStr(StackAlignment)
47 << " when stack realignment is off" << '\n');
48 return StackAlignment;
49}
50
52 bool IsSpillSlot,
53 const AllocaInst *Alloca,
54 uint8_t StackID) {
55 assert(Size != 0 && "Cannot allocate zero size stack objects!");
56 Alignment = clampStackAlignment(!StackRealignable, Alignment, StackAlignment);
57 Objects.push_back(StackObject(Size, Alignment, 0, false, IsSpillSlot, Alloca,
58 !IsSpillSlot, StackID));
59 int Index = (int)Objects.size() - NumFixedObjects - 1;
60 assert(Index >= 0 && "Bad frame index!");
61 if (contributesToMaxAlignment(StackID))
62 ensureMaxAlignment(Alignment);
63 return Index;
64}
65
67 TargetStackID::Value StackID) {
68 Alignment = clampStackAlignment(!StackRealignable, Alignment, StackAlignment);
69 CreateStackObject(Size, Alignment, true, nullptr, StackID);
70 int Index = (int)Objects.size() - NumFixedObjects - 1;
71 ensureMaxAlignment(Alignment);
72 return Index;
73}
74
76 const AllocaInst *Alloca) {
77 HasVarSizedObjects = true;
78 Alignment = clampStackAlignment(!StackRealignable, Alignment, StackAlignment);
79 Objects.push_back(StackObject(0, Alignment, 0, false, false, Alloca, true));
80 ensureMaxAlignment(Alignment);
81 return (int)Objects.size()-NumFixedObjects-1;
82}
83
85 bool IsImmutable, bool IsAliased) {
86 assert(Size != 0 && "Cannot allocate zero size fixed stack objects!");
87 // The alignment of the frame index can be determined from its offset from
88 // the incoming frame position. If the frame object is at offset 32 and
89 // the stack is guaranteed to be 16-byte aligned, then we know that the
90 // object is 16-byte aligned. Note that unlike the non-fixed case, if the
91 // stack needs realignment, we can't assume that the stack will in fact be
92 // aligned.
93 Align Alignment =
94 commonAlignment(ForcedRealign ? Align(1) : StackAlignment, SPOffset);
95 Alignment = clampStackAlignment(!StackRealignable, Alignment, StackAlignment);
96 Objects.insert(Objects.begin(),
97 StackObject(Size, Alignment, SPOffset, IsImmutable,
98 /*IsSpillSlot=*/false, /*Alloca=*/nullptr,
99 IsAliased));
100 return -++NumFixedObjects;
101}
102
104 int64_t SPOffset,
105 bool IsImmutable) {
106 Align Alignment =
107 commonAlignment(ForcedRealign ? Align(1) : StackAlignment, SPOffset);
108 Alignment = clampStackAlignment(!StackRealignable, Alignment, StackAlignment);
109 Objects.insert(Objects.begin(),
110 StackObject(Size, Alignment, SPOffset, IsImmutable,
111 /*IsSpillSlot=*/true, /*Alloca=*/nullptr,
112 /*IsAliased=*/false));
113 return -++NumFixedObjects;
114}
115
118 BitVector BV(TRI->getNumRegs());
119
120 // Before CSI is calculated, no registers are considered pristine. They can be
121 // freely used and PEI will make sure they are saved.
123 return BV;
124
125 const MachineRegisterInfo &MRI = MF.getRegInfo();
126 for (const MCPhysReg *CSR = MRI.getCalleeSavedRegs(); CSR && *CSR;
127 ++CSR)
128 BV.set(*CSR);
129
130 // Saved CSRs are not pristine.
131 for (const auto &I : getCalleeSavedInfo())
132 for (MCPhysReg S : TRI->subregs_inclusive(I.getReg()))
133 BV.reset(S);
134
135 return BV;
136}
137
140 const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();
141 Align MaxAlign = getMaxAlign();
142 int64_t Offset = 0;
143
144 // This code is very, very similar to PEI::calculateFrameObjectOffsets().
145 // It really should be refactored to share code. Until then, changes
146 // should keep in mind that there's tight coupling between the two.
147
148 for (int i = getObjectIndexBegin(); i != 0; ++i) {
149 // Only estimate stack size of default stack.
151 continue;
152 int64_t FixedOff = -getObjectOffset(i);
153 if (FixedOff > Offset) Offset = FixedOff;
154 }
155 for (unsigned i = 0, e = getObjectIndexEnd(); i != e; ++i) {
156 // Only estimate stack size of live objects on default stack.
158 continue;
159 Offset += getObjectSize(i);
160 Align Alignment = getObjectAlign(i);
161 // Adjust to alignment boundary
162 Offset = alignTo(Offset, Alignment);
163
164 MaxAlign = std::max(Alignment, MaxAlign);
165 }
166
167 if (adjustsStack() && TFI->hasReservedCallFrame(MF))
169
170 // Round up the size to a multiple of the alignment. If the function has
171 // any calls or alloca's, align to the target's StackAlignment value to
172 // ensure that the callee's frame or the alloca data is suitably aligned;
173 // otherwise, for leaf functions, align to the TransientStackAlignment
174 // value.
175 Align StackAlign;
176 if (adjustsStack() || hasVarSizedObjects() ||
177 (RegInfo->hasStackRealignment(MF) && getObjectIndexEnd() != 0))
178 StackAlign = TFI->getStackAlign();
179 else
180 StackAlign = TFI->getTransientStackAlign();
181
182 // If the frame pointer is eliminated, all frame offsets will be relative to
183 // SP not FP. Align to MaxAlign so this works.
184 StackAlign = std::max(StackAlign, MaxAlign);
185 return alignTo(Offset, StackAlign);
186}
187
189 MachineFunction &MF, std::vector<MachineBasicBlock::iterator> *FrameSDOps) {
191 unsigned FrameSetupOpcode = TII.getCallFrameSetupOpcode();
192 unsigned FrameDestroyOpcode = TII.getCallFrameDestroyOpcode();
193 assert(FrameSetupOpcode != ~0u && FrameDestroyOpcode != ~0u &&
194 "Can only compute MaxCallFrameSize if Setup/Destroy opcode are known");
195
196 MaxCallFrameSize = 0;
197 for (MachineBasicBlock &MBB : MF) {
198 for (MachineInstr &MI : MBB) {
199 unsigned Opcode = MI.getOpcode();
200 if (Opcode == FrameSetupOpcode || Opcode == FrameDestroyOpcode) {
201 uint64_t Size = TII.getFrameSize(MI);
202 MaxCallFrameSize = std::max(MaxCallFrameSize, Size);
203 if (FrameSDOps != nullptr)
204 FrameSDOps->push_back(&MI);
205 }
206 }
207 }
208}
209
211 if (Objects.empty()) return;
212
214 int ValOffset = (FI ? FI->getOffsetOfLocalArea() : 0);
215
216 OS << "Frame Objects:\n";
217
218 for (unsigned i = 0, e = Objects.size(); i != e; ++i) {
219 const StackObject &SO = Objects[i];
220 OS << " fi#" << (int)(i-NumFixedObjects) << ": ";
221
222 if (SO.StackID != 0)
223 OS << "id=" << static_cast<unsigned>(SO.StackID) << ' ';
224
225 if (SO.Size == ~0ULL) {
226 OS << "dead\n";
227 continue;
228 }
229 if (SO.Size == 0)
230 OS << "variable sized";
231 else
232 OS << "size=" << SO.Size;
233 OS << ", align=" << SO.Alignment.value();
234
235 if (i < NumFixedObjects)
236 OS << ", fixed";
237 if (i < NumFixedObjects || SO.SPOffset != -1) {
238 int64_t Off = SO.SPOffset - ValOffset;
239 OS << ", at location [SP";
240 if (Off > 0)
241 OS << "+" << Off;
242 else if (Off < 0)
243 OS << Off;
244 OS << "]";
245 }
246 OS << "\n";
247 }
248 OS << "save/restore points:\n";
249
250 if (!SavePoints.empty()) {
251 OS << "save points:\n";
252
253 for (auto &item : SavePoints)
254 OS << printMBBReference(*item.first) << "\n";
255 } else
256 OS << "save points are empty\n";
257
258 if (!RestorePoints.empty()) {
259 OS << "restore points:\n";
260 for (auto &item : RestorePoints)
261 OS << printMBBReference(*item.first) << "\n";
262 } else
263 OS << "restore points are empty\n";
264}
265
266#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
268 print(MF, dbgs());
269}
270#endif
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock & MBB
This file implements the BitVector class.
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Definition Compiler.h:661
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition MD5.cpp:57
static Align clampStackAlignment(bool ShouldClamp, Align Alignment, Align StackAlignment)
Clamp the alignment if requested and emit a warning.
Register const TargetRegisterInfo * TRI
#define LLVM_DEBUG(...)
Definition Debug.h:119
an instruction to allocate memory on the stack
BitVector & reset()
Reset all bits in the bitvector.
Definition BitVector.h:409
BitVector & set()
Set all bits in the bitvector.
Definition BitVector.h:366
LLVM_ABI int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
LLVM_ABI void computeMaxCallFrameSize(MachineFunction &MF, std::vector< MachineBasicBlock::iterator > *FrameSDOps=nullptr)
Computes the maximum size of a callframe.
bool adjustsStack() const
Return true if this function adjusts the stack – e.g., when calling another function.
LLVM_ABI int CreateStackObject(uint64_t Size, Align Alignment, bool isSpillSlot, const AllocaInst *Alloca=nullptr, uint8_t ID=0)
Create a new statically sized stack object, returning a nonnegative identifier to represent it.
LLVM_ABI void ensureMaxAlignment(Align Alignment)
Make sure the function is at least Align bytes aligned.
Align getMaxAlign() const
Return the alignment in bytes that this function must be aligned to, which is greater than the defaul...
bool contributesToMaxAlignment(uint8_t StackID)
Should this stack ID be considered in MaxAlignment.
uint64_t getMaxCallFrameSize() const
Return the maximum size of a call frame that must be allocated for an outgoing function call.
LLVM_ABI uint64_t estimateStackSize(const MachineFunction &MF) const
Estimate and return the size of the stack frame.
bool isCalleeSavedInfoValid() const
Has the callee saved info been calculated yet?
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
LLVM_ABI BitVector getPristineRegs(const MachineFunction &MF) const
Return a set of physical registers that are pristine.
LLVM_ABI int CreateSpillStackObject(uint64_t Size, Align Alignment, TargetStackID::Value StackID=TargetStackID::Default)
Create a new statically sized stack object that represents a spill slot, returning a nonnegative iden...
const std::vector< CalleeSavedInfo > & getCalleeSavedInfo() const
Returns a reference to call saved info vector for the current function.
LLVM_ABI void print(const MachineFunction &MF, raw_ostream &OS) const
Used by the MachineFunction printer to print information about stack objects.
LLVM_ABI int CreateVariableSizedObject(Align Alignment, const AllocaInst *Alloca)
Notify the MachineFrameInfo object that a variable sized object has been created.
LLVM_ABI void dump(const MachineFunction &MF) const
dump - Print the function to stderr.
int getObjectIndexEnd() const
Return one past the maximum frame object index.
LLVM_ABI int CreateFixedSpillStackObject(uint64_t Size, int64_t SPOffset, bool IsImmutable=false)
Create a spill slot at a fixed location on the stack.
uint8_t getStackID(int ObjectIdx) const
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
int getObjectIndexBegin() const
Return the minimum frame object index.
bool isDeadObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a dead object.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Representation of each machine instruction.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI const MCPhysReg * getCalleeSavedRegs() const
Returns list of callee saved registers.
Information about stack frame layout on the target.
virtual bool hasReservedCallFrame(const MachineFunction &MF) const
hasReservedCallFrame - Under normal circumstances, when a frame pointer is not required,...
Align getTransientStackAlign() const
getTransientStackAlignment - This method returns the number of bytes to which the stack pointer must ...
int getOffsetOfLocalArea() const
getOffsetOfLocalArea - This method returns the offset of the local area from the stack pointer on ent...
Align getStackAlign() const
getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...
TargetInstrInfo - Interface to description of machine instruction set.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetFrameLowering * getFrameLowering() const
virtual const TargetInstrInfo * getInstrInfo() const
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:558
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition Alignment.h:144
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
Definition MCRegister.h:21
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
Definition Alignment.h:201
LLVM_ABI Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
Definition Alignment.h:77