44#define DEBUG_TYPE "localstackalloc"
46STATISTIC(NumAllocations,
"Number of frame indices allocated into local block");
47STATISTIC(NumBaseRegisters,
"Number of virtual frame base registers allocated");
48STATISTIC(NumReplacements,
"Number of frame indices references replaced");
66 :
MI(
I), LocalOffset(
Offset), InstrOffset(InstrOffset), FrameIdx(Idx),
70 return std::tuple(LocalOffset + InstrOffset, FrameIdx, Order) <
71 std::tuple(
RHS.LocalOffset +
RHS.InstrOffset,
RHS.FrameIdx,
76 int64_t getLocalOffset()
const {
return LocalOffset; }
77 int64_t getInstrOffset()
const {
return InstrOffset; }
78 int getFrameIndex()
const {
return FrameIdx; }
81 class LocalStackSlotImpl {
85 using StackObjSet = SmallSetVector<int, 8>;
88 bool StackGrowsDown, Align &MaxAlign);
90 SmallSet<int, 16> &ProtectedObjs,
91 MachineFrameInfo &MFI,
bool StackGrowsDown,
92 int64_t &
Offset, Align &MaxAlign);
93 void calculateFrameObjectOffsets(MachineFunction &Fn);
94 bool insertFrameReferenceRegisters(MachineFunction &Fn);
97 bool runOnMachineFunction(MachineFunction &MF);
104 explicit LocalStackSlotPass() : MachineFunctionPass(ID) {}
106 bool runOnMachineFunction(MachineFunction &MF)
override {
107 return LocalStackSlotImpl().runOnMachineFunction(MF);
110 void getAnalysisUsage(AnalysisUsage &AU)
const override {
122 bool Changed = LocalStackSlotImpl().runOnMachineFunction(MF);
131char LocalStackSlotPass::ID = 0;
135 "Local Stack Slot Allocation",
false,
false)
144 if (LocalObjectCount == 0 || !
TRI->requiresVirtualBaseRegisters(MF))
151 calculateFrameObjectOffsets(MF);
154 bool UsedBaseRegs = insertFrameReferenceRegisters(MF);
167void LocalStackSlotImpl::AdjustStackOffset(
MachineFrameInfo &MFI,
int FrameIdx,
168 int64_t &
Offset,
bool StackGrowsDown,
178 MaxAlign = std::max(MaxAlign, Alignment);
183 int64_t LocalOffset = StackGrowsDown ? -
Offset :
Offset;
184 LLVM_DEBUG(
dbgs() <<
"Allocate FI(" << FrameIdx <<
") to local offset "
185 << LocalOffset <<
"\n");
187 LocalOffsets[FrameIdx] = LocalOffset;
199void LocalStackSlotImpl::AssignProtectedObjSet(
203 for (
int i : UnassignedObjs) {
211void LocalStackSlotImpl::calculateFrameObjectOffsets(
MachineFunction &Fn) {
215 bool StackGrowsDown =
231 "Stack protector pre-allocated in LocalStackSlotAllocation");
247 if (StackProtectorFI == (
int)i)
283 if (ProtectedObjs.
count(i))
297 int64_t FrameSizeAdjust,
298 int64_t LocalFrameOffset,
303 int64_t
Offset = FrameSizeAdjust + LocalFrameOffset - BaseOffset;
304 return TRI->isFrameOffsetLegal(&
MI, BaseReg,
Offset);
307bool LocalStackSlotImpl::insertFrameReferenceRegisters(
MachineFunction &Fn) {
318 bool StackGrowsDown =
333 if (
MI.isDebugInstr() ||
MI.getOpcode() == TargetOpcode::STATEPOINT ||
334 MI.getOpcode() == TargetOpcode::STACKMAP ||
335 MI.getOpcode() == TargetOpcode::PATCHPOINT)
344 for (
unsigned OpIdx = 0, OpEnd =
MI.getNumOperands();
OpIdx != OpEnd;
357 int64_t LocalOffset = LocalOffsets[FrameIdx];
358 if (!
TRI->needsFrameBaseReg(&
MI, LocalOffset))
361 int64_t InstrOffset =
TRI->getFrameIndexInstrOffset(&
MI,
OpIdx);
376 int64_t BaseOffset = 0;
379 for (
int ref = 0, e = FrameReferenceInsns.
size(); ref < e ; ++ref) {
380 FrameRef &FR = FrameReferenceInsns[ref];
382 int64_t LocalOffset = FR.getLocalOffset();
383 int FrameIdx = FR.getFrameIndex();
385 "Only pre-allocated locals expected!");
398 for (
unsigned f =
MI.getNumOperands(); idx != f; ++idx) {
399 if (!
MI.getOperand(idx).isFI())
402 if (FrameIdx ==
MI.getOperand(idx).getIndex())
406 assert(idx <
MI.getNumOperands() &&
"Cannot find FI operand");
420 LocalOffset,
MI,
TRI)) {
424 Offset = FrameSizeAdjust + LocalOffset - BaseOffset;
427 int64_t InstrOffset =
TRI->getFrameIndexInstrOffset(&
MI, idx);
429 int64_t CandBaseOffset = FrameSizeAdjust + LocalOffset + InstrOffset;
438 BaseReg, CandBaseOffset, FrameSizeAdjust,
439 FrameReferenceInsns[ref + 1].getLocalOffset(),
444 BaseOffset = CandBaseOffset;
449 BaseReg =
TRI->materializeFrameBaseRegister(Entry, FrameIdx, InstrOffset);
451 LLVM_DEBUG(
dbgs() <<
" Materialized base register at frame local offset "
452 << LocalOffset + InstrOffset
462 assert(BaseReg &&
"Unable to allocate virtual base register!");
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static MachineInstr * getMachineInstr(MachineInstr *MI)
static bool lookupCandidateBaseReg(Register BaseReg, int64_t BaseOffset, int64_t FrameSizeAdjust, int64_t LocalFrameOffset, const MachineInstr &MI, const TargetRegisterInfo *TRI)
Register const TargetRegisterInfo * TRI
MachineInstr unsigned OpIdx
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
static void AssignProtectedObjSet(const StackObjSet &UnassignedObjs, SmallSet< int, 16 > &ProtectedObjs, MachineFrameInfo &MFI, bool StackGrowsDown, int64_t &Offset, Align &MaxAlign)
AssignProtectedObjSet - Helper function to assign large stack objects (i.e., those required to be clo...
static void AdjustStackOffset(MachineFrameInfo &MFI, int FrameIdx, bool StackGrowsDown, int64_t &Offset, Align &MaxAlign)
AdjustStackOffset - Helper function used to adjust the stack frame offset.
SmallSetVector< int, 8 > StackObjSet
StackObjSet - A set of stack object indexes.
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
Represents analyses that only rely on functions' control flow.
LLVM_ABI PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &)
MachineInstrBundleIterator< MachineInstr > iterator
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
SSPLayoutKind getObjectSSPLayout(int ObjectIdx) const
bool isObjectPreAllocated(int ObjectIdx) const
Return true if the object was pre-allocated into the local block.
void setUseLocalStackAllocationBlock(bool v)
setUseLocalStackAllocationBlock - Set whether the local allocation blob should be allocated together ...
void setLocalFrameSize(int64_t sz)
Set the size of the local object blob.
@ SSPLK_SmallArray
Array or nested array < SSP-buffer-size.
@ SSPLK_LargeArray
Array or nested array >= SSP-buffer-size.
@ SSPLK_AddrOf
The address of this allocation is exposed and triggered protection.
@ SSPLK_None
Did not trigger a stack protector.
void setLocalFrameMaxAlign(Align Alignment)
Required alignment of the local object blob, which is the strictest alignment of any object in it.
int getStackProtectorIndex() const
Return the index for the stack protector object.
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.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
int64_t getLocalFrameSize() const
Get the size of the local object blob.
int getObjectIndexEnd() const
Return one past the maximum frame object index.
bool hasStackProtectorIndex() const
uint8_t getStackID(int ObjectIdx) const
bool isDeadObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a dead object.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
bool isFI() const
isFI - Tests if this is a MO_FrameIndex operand.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Wrapper class representing virtual and physical registers.
bool insert(const value_type &X)
Insert a new element into the SetVector.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
reference emplace_back(ArgTypes &&... Args)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Information about stack frame layout on the target.
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...
StackDirection getStackGrowthDirection() const
getStackGrowthDirection - Return the direction the stack grows
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetFrameLowering * getFrameLowering() const
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
This is an optimization pass for GlobalISel generic memory operations.
bool operator<(int64_t V1, const APSInt &V2)
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
void sort(IteratorTy Start, IteratorTy End)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
LLVM_ABI char & LocalStackSlotAllocationID
LocalStackSlotAllocation - This pass assigns local frame indices to stack slots relative to one anoth...
LLVM_ABI 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.
This struct is a compact representation of a valid (non-zero power of two) alignment.