LLVM 19.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 Alignment = clampStackAlignment(!StackRealignable, Alignment, StackAlignment);
68 CreateStackObject(Size, Alignment, true);
69 int Index = (int)Objects.size() - NumFixedObjects - 1;
70 ensureMaxAlignment(Alignment);
71 return Index;
72}
73
75 const AllocaInst *Alloca) {
76 HasVarSizedObjects = true;
77 Alignment = clampStackAlignment(!StackRealignable, Alignment, StackAlignment);
78 Objects.push_back(StackObject(0, Alignment, 0, false, false, Alloca, true));
79 ensureMaxAlignment(Alignment);
80 return (int)Objects.size()-NumFixedObjects-1;
81}
82
84 bool IsImmutable, bool IsAliased) {
85 assert(Size != 0 && "Cannot allocate zero size fixed stack objects!");
86 // The alignment of the frame index can be determined from its offset from
87 // the incoming frame position. If the frame object is at offset 32 and
88 // the stack is guaranteed to be 16-byte aligned, then we know that the
89 // object is 16-byte aligned. Note that unlike the non-fixed case, if the
90 // stack needs realignment, we can't assume that the stack will in fact be
91 // aligned.
92 Align Alignment =
93 commonAlignment(ForcedRealign ? Align(1) : StackAlignment, SPOffset);
94 Alignment = clampStackAlignment(!StackRealignable, Alignment, StackAlignment);
95 Objects.insert(Objects.begin(),
96 StackObject(Size, Alignment, SPOffset, IsImmutable,
97 /*IsSpillSlot=*/false, /*Alloca=*/nullptr,
98 IsAliased));
99 return -++NumFixedObjects;
100}
101
103 int64_t SPOffset,
104 bool IsImmutable) {
105 Align Alignment =
106 commonAlignment(ForcedRealign ? Align(1) : StackAlignment, SPOffset);
107 Alignment = clampStackAlignment(!StackRealignable, Alignment, StackAlignment);
108 Objects.insert(Objects.begin(),
109 StackObject(Size, Alignment, SPOffset, IsImmutable,
110 /*IsSpillSlot=*/true, /*Alloca=*/nullptr,
111 /*IsAliased=*/false));
112 return -++NumFixedObjects;
113}
114
117 BitVector BV(TRI->getNumRegs());
118
119 // Before CSI is calculated, no registers are considered pristine. They can be
120 // freely used and PEI will make sure they are saved.
122 return BV;
123
124 const MachineRegisterInfo &MRI = MF.getRegInfo();
125 for (const MCPhysReg *CSR = MRI.getCalleeSavedRegs(); CSR && *CSR;
126 ++CSR)
127 BV.set(*CSR);
128
129 // Saved CSRs are not pristine.
130 for (const auto &I : getCalleeSavedInfo())
131 for (MCPhysReg S : TRI->subregs_inclusive(I.getReg()))
132 BV.reset(S);
133
134 return BV;
135}
136
139 const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();
140 Align MaxAlign = getMaxAlign();
141 int64_t Offset = 0;
142
143 // This code is very, very similar to PEI::calculateFrameObjectOffsets().
144 // It really should be refactored to share code. Until then, changes
145 // should keep in mind that there's tight coupling between the two.
146
147 for (int i = getObjectIndexBegin(); i != 0; ++i) {
148 // Only estimate stack size of default stack.
150 continue;
151 int64_t FixedOff = -getObjectOffset(i);
152 if (FixedOff > Offset) Offset = FixedOff;
153 }
154 for (unsigned i = 0, e = getObjectIndexEnd(); i != e; ++i) {
155 // Only estimate stack size of live objects on default stack.
157 continue;
158 Offset += getObjectSize(i);
159 Align Alignment = getObjectAlign(i);
160 // Adjust to alignment boundary
161 Offset = alignTo(Offset, Alignment);
162
163 MaxAlign = std::max(Alignment, MaxAlign);
164 }
165
166 if (adjustsStack() && TFI->hasReservedCallFrame(MF))
168
169 // Round up the size to a multiple of the alignment. If the function has
170 // any calls or alloca's, align to the target's StackAlignment value to
171 // ensure that the callee's frame or the alloca data is suitably aligned;
172 // otherwise, for leaf functions, align to the TransientStackAlignment
173 // value.
174 Align StackAlign;
175 if (adjustsStack() || hasVarSizedObjects() ||
176 (RegInfo->hasStackRealignment(MF) && getObjectIndexEnd() != 0))
177 StackAlign = TFI->getStackAlign();
178 else
179 StackAlign = TFI->getTransientStackAlign();
180
181 // If the frame pointer is eliminated, all frame offsets will be relative to
182 // SP not FP. Align to MaxAlign so this works.
183 StackAlign = std::max(StackAlign, MaxAlign);
184 return alignTo(Offset, StackAlign);
185}
186
189 unsigned FrameSetupOpcode = TII.getCallFrameSetupOpcode();
190 unsigned FrameDestroyOpcode = TII.getCallFrameDestroyOpcode();
191 assert(FrameSetupOpcode != ~0u && FrameDestroyOpcode != ~0u &&
192 "Can only compute MaxCallFrameSize if Setup/Destroy opcode are known");
193
194 MaxCallFrameSize = 0;
195 for (const MachineBasicBlock &MBB : MF) {
196 for (const MachineInstr &MI : MBB) {
197 unsigned Opcode = MI.getOpcode();
198 if (Opcode == FrameSetupOpcode || Opcode == FrameDestroyOpcode) {
199 unsigned Size = TII.getFrameSize(MI);
200 MaxCallFrameSize = std::max(MaxCallFrameSize, Size);
201 AdjustsStack = true;
202 } else if (MI.isInlineAsm()) {
203 // Some inline asm's need a stack frame, as indicated by operand 1.
204 unsigned ExtraInfo = MI.getOperand(InlineAsm::MIOp_ExtraInfo).getImm();
205 if (ExtraInfo & InlineAsm::Extra_IsAlignStack)
206 AdjustsStack = true;
207 }
208 }
209 }
210}
211
213 if (Objects.empty()) return;
214
216 int ValOffset = (FI ? FI->getOffsetOfLocalArea() : 0);
217
218 OS << "Frame Objects:\n";
219
220 for (unsigned i = 0, e = Objects.size(); i != e; ++i) {
221 const StackObject &SO = Objects[i];
222 OS << " fi#" << (int)(i-NumFixedObjects) << ": ";
223
224 if (SO.StackID != 0)
225 OS << "id=" << static_cast<unsigned>(SO.StackID) << ' ';
226
227 if (SO.Size == ~0ULL) {
228 OS << "dead\n";
229 continue;
230 }
231 if (SO.Size == 0)
232 OS << "variable sized";
233 else
234 OS << "size=" << SO.Size;
235 OS << ", align=" << SO.Alignment.value();
236
237 if (i < NumFixedObjects)
238 OS << ", fixed";
239 if (i < NumFixedObjects || SO.SPOffset != -1) {
240 int64_t Off = SO.SPOffset - ValOffset;
241 OS << ", at location [SP";
242 if (Off > 0)
243 OS << "+" << Off;
244 else if (Off < 0)
245 OS << Off;
246 OS << "]";
247 }
248 OS << "\n";
249 }
250}
251
252#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
254 print(MF, dbgs());
255}
256#endif
unsigned const MachineRegisterInfo * MRI
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:529
#define LLVM_DEBUG(X)
Definition: Debug.h:101
uint64_t Size
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition: MD5.cpp:58
static Align clampStackAlignment(bool ShouldClamp, Align Alignment, Align StackAlignment)
Clamp the alignment if requested and emit a warning.
unsigned const TargetRegisterInfo * TRI
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
an instruction to allocate memory on the stack
Definition: Instructions.h:59
BitVector & reset()
Definition: BitVector.h:392
BitVector & set()
Definition: BitVector.h:351
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 ...
bool adjustsStack() const
Return true if this function adjusts the stack – e.g., when calling another function.
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.
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.
int CreateSpillStackObject(uint64_t Size, Align Alignment)
Create a new statically sized stack object that represents a spill slot, returning a nonnegative iden...
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?
void computeMaxCallFrameSize(const MachineFunction &MF)
Computes the maximum size of a callframe and the AdjustsStack property.
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.
BitVector getPristineRegs(const MachineFunction &MF) const
Return a set of physical registers that are pristine.
const std::vector< CalleeSavedInfo > & getCalleeSavedInfo() const
Returns a reference to call saved info vector for the current function.
void print(const MachineFunction &MF, raw_ostream &OS) const
Used by the MachineFunction printer to print information about stack objects.
int CreateVariableSizedObject(Align Alignment, const AllocaInst *Alloca)
Notify the MachineFrameInfo object that a variable sized object has been created.
void dump(const MachineFunction &MF) const
dump - Print the function to stderr.
unsigned getMaxCallFrameSize() const
Return the maximum size of a call frame that must be allocated for an outgoing function call.
int getObjectIndexEnd() const
Return one past the maximum frame object index.
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.
Definition: MachineInstr.h:69
MachineRegisterInfo - Keep track of information for virtual and physical 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...
bool hasStackRealignment(const MachineFunction &MF) const
True if stack realignment is required and still possible.
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
virtual const TargetFrameLowering * getFrameLowering() const
virtual const TargetInstrInfo * getInstrInfo() const
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:456
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition: Alignment.h:155
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
Definition: Alignment.h:212
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39