Go to the documentation of this file.
42 #define DEBUG_TYPE "localstackalloc"
44 STATISTIC(NumAllocations,
"Number of frame indices allocated into local block");
45 STATISTIC(NumBaseRegisters,
"Number of virtual frame base registers allocated");
46 STATISTIC(NumReplacements,
"Number of frame indices references replaced");
61 FrameRef(
MachineInstr *
I, int64_t Offset,
int Idx,
unsigned Ord) :
62 MI(
I), LocalOffset(Offset), FrameIdx(Idx), Order(Ord) {}
65 return std::tie(LocalOffset, FrameIdx, Order) <
66 std::tie(
RHS.LocalOffset,
RHS.FrameIdx,
RHS.Order);
70 int64_t getLocalOffset()
const {
return LocalOffset; }
71 int getFrameIndex()
const {
return FrameIdx; }
81 bool StackGrowsDown,
Align &MaxAlign);
85 int64_t &Offset,
Align &MaxAlign);
110 "Local Stack Slot Allocation",
false,
false)
126 calculateFrameObjectOffsets(MF);
129 bool UsedBaseRegs = insertFrameReferenceRegisters(MF);
143 int64_t &Offset,
bool StackGrowsDown,
153 MaxAlign =
std::max(MaxAlign, Alignment);
158 int64_t LocalOffset = StackGrowsDown ? -
Offset :
Offset;
159 LLVM_DEBUG(
dbgs() <<
"Allocate FI(" << FrameIdx <<
") to local offset "
160 << LocalOffset <<
"\n");
162 LocalOffsets[FrameIdx] = LocalOffset;
178 for (
int i : UnassignedObjs) {
186 void LocalStackSlotPass::calculateFrameObjectOffsets(
MachineFunction &Fn) {
190 bool StackGrowsDown =
206 "Stack protector pre-allocated in LocalStackSlotAllocation");
222 if (StackProtectorFI == (
int)
i)
258 if (ProtectedObjs.
count(
i))
274 int64_t FrameSizeAdjust,
275 int64_t LocalFrameOffset,
280 int64_t Offset = FrameSizeAdjust + LocalFrameOffset - BaseOffset;
284 bool LocalStackSlotPass::insertFrameReferenceRegisters(
MachineFunction &Fn) {
291 bool UsedBaseReg =
false;
296 bool StackGrowsDown =
311 if (
MI.isDebugInstr() ||
MI.getOpcode() == TargetOpcode::STATEPOINT ||
312 MI.getOpcode() == TargetOpcode::STACKMAP ||
313 MI.getOpcode() == TargetOpcode::PATCHPOINT)
329 int Idx = MO.getIndex();
330 int64_t LocalOffset = LocalOffsets[Idx];
333 FrameReferenceInsns.push_back(FrameRef(&
MI, LocalOffset, Idx, Order++));
347 int64_t BaseOffset = 0;
350 for (
int ref = 0,
e = FrameReferenceInsns.size(); ref <
e ; ++ref) {
351 FrameRef &FR = FrameReferenceInsns[ref];
353 int64_t LocalOffset = FR.getLocalOffset();
354 int FrameIdx = FR.getFrameIndex();
356 "Only pre-allocated locals expected!");
369 for (
unsigned f =
MI.getNumOperands(); idx !=
f; ++idx) {
370 if (!
MI.getOperand(idx).isFI())
373 if (FrameIdx ==
MI.getOperand(idx).getIndex())
377 assert(idx <
MI.getNumOperands() &&
"Cannot find FI operand");
391 LocalOffset,
MI,
TRI)) {
392 LLVM_DEBUG(
dbgs() <<
" Reusing base register " << BaseReg <<
"\n");
394 Offset = FrameSizeAdjust + LocalOffset - BaseOffset;
399 int64_t PrevBaseOffset = BaseOffset;
400 BaseOffset = FrameSizeAdjust + LocalOffset + InstrOffset;
409 BaseReg, BaseOffset, FrameSizeAdjust,
410 FrameReferenceInsns[ref + 1].getLocalOffset(),
412 BaseOffset = PrevBaseOffset;
421 LLVM_DEBUG(
dbgs() <<
" Materialized base register at frame local offset "
422 << LocalOffset + InstrOffset
433 assert(BaseReg &&
"Unable to allocate virtual base register!");
INITIALIZE_PASS(LocalStackSlotPass, DEBUG_TYPE, "Local Stack Slot Allocation", false, false) bool LocalStackSlotPass
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
This is an optimization pass for GlobalISel generic memory operations.
static bool lookupCandidateBaseReg(unsigned BaseReg, int64_t BaseOffset, int64_t FrameSizeAdjust, int64_t LocalFrameOffset, const MachineInstr &MI, const TargetRegisterInfo *TRI)
virtual void resolveFrameIndex(MachineInstr &MI, Register BaseReg, int64_t Offset) const
Resolve a frame index operand of an instruction to reference the indicated base register plus offset ...
Information about stack frame layout on the target.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
virtual bool isStackIdSafeForLocalArea(unsigned StackId) const
This method returns whether or not it is safe for an object with the given stack id to be bundled int...
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
bool isObjectPreAllocated(int ObjectIdx) const
Return true if the object was pre-allocated into the local block.
char & LocalStackSlotAllocationID
LocalStackSlotAllocation - This pass assigns local frame indices to stack slots relative to one anoth...
@ SSPLK_LargeArray
Array or nested array >= SSP-buffer-size.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
Expected< ExpressionValue > max(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
int getObjectIndexEnd() const
Return one past the maximum frame object index.
unsigned const TargetRegisterInfo * TRI
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
static MachineInstr * getMachineInstr(MachineInstr *MI)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Itanium Name Demangler i e convert the string _Z1fv into f()". You can also use the CRTP base ManglingParser to perform some simple analysis on the mangled name
void setLocalFrameMaxAlign(Align Alignment)
Required alignment of the local object blob, which is the strictest alignment of any object in it.
Represent the analysis usage information of a pass.
void initializeLocalStackSlotPassPass(PassRegistry &)
MachineOperand class - Representation of each machine instruction operand.
virtual bool requiresVirtualBaseRegisters(const MachineFunction &MF) const
Returns true if the target wants the LocalStackAllocation pass to be run and virtual base registers u...
STATISTIC(NumFunctions, "Total number of functions")
uint8_t getStackID(int ObjectIdx) const
@ SSPLK_None
Did not trigger a stack protector.
This struct is a compact representation of a valid (non-zero power of two) alignment.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
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.
static void AdjustStackOffset(MachineFrameInfo &MFI, int FrameIdx, bool StackGrowsDown, int64_t &Offset, Align &MaxAlign, unsigned Skew)
AdjustStackOffset - Helper function used to adjust the stack frame offset.
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
int64_t getLocalFrameSize() const
Get the size of the local object blob.
Representation of each machine instruction.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
bool hasStackProtectorIndex() const
bool operator<(int64_t V1, const APSInt &V2)
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
void mapLocalFrameObject(int ObjectIndex, int64_t Offset)
Map a frame index into the local object block.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
StackDirection getStackGrowthDirection() const
getStackGrowthDirection - Return the direction the stack grows
bool insert(const value_type &X)
Insert a new element into the SetVector.
virtual bool needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const
Returns true if the instruction's frame index reference would be better served by a base register oth...
void setPreservesCFG()
This function should be called by the pass, iff they do not:
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static void AssignProtectedObjSet(const StackObjSet &UnassignedObjs, SmallSet< int, 16 > &ProtectedObjs, MachineFrameInfo &MFI, bool StackGrowsDown, int64_t &Offset, Align &MaxAlign, unsigned Skew)
AssignProtectedObjSet - Helper function to assign large stack objects (i.e., those required to be clo...
std::pair< NoneType, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
Wrapper class representing virtual and physical registers.
SSPLayoutKind getObjectSSPLayout(int ObjectIdx) const
virtual const TargetFrameLowering * getFrameLowering() const
void sort(IteratorTy Start, IteratorTy End)
virtual int64_t getFrameIndexInstrOffset(const MachineInstr *MI, int Idx) const
Get the offset from the referenced frame index in the instruction, if there is one.
virtual Register materializeFrameBaseRegister(MachineBasicBlock *MBB, int FrameIdx, int64_t Offset) const
Insert defining instruction(s) for a pointer to FrameIdx before insertion point I.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
@ SSPLK_AddrOf
The address of this allocation is exposed and triggered protection.
@ SSPLK_SmallArray
Array or nested array < SSP-buffer-size.
A SetVector that performs no allocations if smaller than a certain size.
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM BB
int getStackProtectorIndex() const
Return the index for the stack protector object.
virtual bool isFrameOffsetLegal(const MachineInstr *MI, Register BaseReg, int64_t Offset) const
Determine whether a given base register plus offset immediate is encodable to resolve a frame index.
Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
void setLocalFrameSize(int64_t sz)
Set the size of the local object blob.
void setUseLocalStackAllocationBlock(bool v)
setUseLocalStackAllocationBlock - Set whether the local allocation blob should be allocated together ...