43 #define DEBUG_TYPE "localstackalloc"
45 STATISTIC(NumAllocations,
"Number of frame indices allocated into local block");
46 STATISTIC(NumBaseRegisters,
"Number of virtual frame base registers allocated");
47 STATISTIC(NumReplacements,
"Number of frame indices references replaced");
62 MI(I), LocalOffset(Offset), FrameIdx(Idx), Order(Ord) {}
64 bool operator<(
const FrameRef &RHS)
const {
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; }
80 bool StackGrowsDown,
unsigned &MaxAlign);
84 int64_t &
Offset,
unsigned &MaxAlign);
107 "Local Stack Slot Allocation",
false,
false)
127 calculateFrameObjectOffsets(MF);
130 bool UsedBaseRegs = insertFrameReferenceRegisters(MF);
144 int FrameIdx, int64_t &
Offset,
146 unsigned &MaxAlign) {
155 MaxAlign = std::max(MaxAlign, Align);
158 Offset = (Offset + Align - 1) / Align * Align;
160 int64_t LocalOffset = StackGrowsDown ? -Offset :
Offset;
161 DEBUG(
dbgs() <<
"Allocate FI(" << FrameIdx <<
") to local offset "
162 << LocalOffset <<
"\n");
164 LocalOffsets[FrameIdx] = LocalOffset;
179 bool StackGrowsDown, int64_t &Offset,
180 unsigned &MaxAlign) {
183 E = UnassignedObjs.
end();
I !=
E; ++
I) {
193 void LocalStackSlotPass::calculateFrameObjectOffsets(
MachineFunction &Fn) {
197 bool StackGrowsDown =
200 unsigned MaxAlign = 0;
212 StackGrowsDown, MaxAlign);
252 if (ProtectedObjs.count(
i))
266 int64_t FrameSizeAdjust,
267 int64_t LocalFrameOffset,
272 int64_t Offset = FrameSizeAdjust + LocalFrameOffset - BaseOffset;
276 bool LocalStackSlotPass::insertFrameReferenceRegisters(
MachineFunction &Fn) {
283 bool UsedBaseReg =
false;
288 bool StackGrowsDown =
303 if (
MI.isDebugValue() ||
MI.getOpcode() == TargetOpcode::STATEPOINT ||
304 MI.getOpcode() == TargetOpcode::STACKMAP ||
305 MI.getOpcode() == TargetOpcode::PATCHPOINT)
314 for (
unsigned i = 0, e =
MI.getNumOperands();
i != e; ++
i) {
317 if (
MI.getOperand(
i).isFI()) {
321 int Idx =
MI.getOperand(
i).getIndex();
322 int64_t LocalOffset = LocalOffsets[Idx];
325 FrameReferenceInsns.
push_back(FrameRef(&
MI, LocalOffset, Idx, Order++));
334 std::sort(FrameReferenceInsns.
begin(), FrameReferenceInsns.
end());
338 unsigned BaseReg = 0;
339 int64_t BaseOffset = 0;
342 for (
int ref = 0, e = FrameReferenceInsns.
size(); ref < e ; ++ref) {
343 FrameRef &FR = FrameReferenceInsns[ref];
345 int64_t LocalOffset = FR.getLocalOffset();
346 int FrameIdx = FR.getFrameIndex();
348 "Only pre-allocated locals expected!");
366 DEBUG(
dbgs() <<
" Replacing FI in: " << MI);
375 LocalOffset, MI, TRI)) {
376 DEBUG(
dbgs() <<
" Reusing base register " << BaseReg <<
"\n");
378 Offset = FrameSizeAdjust + LocalOffset - BaseOffset;
383 int64_t PrevBaseOffset = BaseOffset;
384 BaseOffset = FrameSizeAdjust + LocalOffset + InstrOffset;
393 BaseReg, BaseOffset, FrameSizeAdjust,
394 FrameReferenceInsns[ref + 1].getLocalOffset(),
395 *FrameReferenceInsns[ref + 1].getMachineInstr(), TRI)) {
396 BaseOffset = PrevBaseOffset;
402 BaseReg = Fn.getRegInfo().createVirtualRegister(RC);
404 DEBUG(
dbgs() <<
" Materializing base register " << BaseReg <<
405 " at frame local offset " << LocalOffset + InstrOffset <<
"\n");
416 Offset = -InstrOffset;
421 assert(BaseReg != 0 &&
"Unable to allocate virtual base register!");
void push_back(const T &Elt)
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
static bool lookupCandidateBaseReg(unsigned BaseReg, int64_t BaseOffset, int64_t FrameSizeAdjust, int64_t LocalFrameOffset, const MachineInstr &MI, const TargetRegisterInfo *TRI)
static void AdjustStackOffset(MachineFrameInfo &MFI, int FrameIdx, bool StackGrowsDown, int64_t &Offset, unsigned &MaxAlign, unsigned Skew)
AdjustStackOffset - Helper function used to adjust the stack frame offset.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
void mapLocalFrameObject(int ObjectIndex, int64_t Offset)
Map a frame index into the local object block.
STATISTIC(NumFunctions,"Total number of functions")
INITIALIZE_PASS_BEGIN(LocalStackSlotPass,"localstackalloc","Local Stack Slot Allocation", false, false) INITIALIZE_PASS_END(LocalStackSlotPass
vector_type::const_iterator const_iterator
iterator end()
Get an iterator to the end of the SetVector.
bool isObjectPreAllocated(int ObjectIdx) const
Return true if the object was pre-allocated into the local block.
int64_t getLocalFrameSize() const
Get the size of the local object blob.
AnalysisUsage & addRequired()
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.
#define INITIALIZE_PASS_DEPENDENCY(depName)
Did not trigger a stack protector.
void setLocalFrameSize(int64_t sz)
Set the size of the local object blob.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
void setUseLocalStackAllocationBlock(bool v)
setUseLocalStackAllocationBlock - Set whether the local allocation blob should be allocated together ...
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted...
The address of this allocation is exposed and triggered protection.
unsigned getNumOperands() const
Access to explicit operands of the instruction.
bool insert(const value_type &X)
Insert a new element into the SetVector.
bool isFI() const
isFI - Tests if this is a MO_FrameIndex operand.
iterator begin()
Get an iterator to the beginning of the SetVector.
void setLocalFrameMaxAlign(unsigned Align)
Required alignment of the local object blob, which is the strictest alignment of any object in it...
virtual bool requiresVirtualBaseRegisters(const MachineFunction &MF) const
Returns true if the target wants the LocalStackAllocation pass to be run and virtual base registers u...
virtual void materializeFrameBaseRegister(MachineBasicBlock *MBB, unsigned BaseReg, int FrameIdx, int64_t Offset) const
Insert defining instruction(s) for BaseReg to be a pointer to FrameIdx before insertion point I...
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
const MachineBasicBlock * getParent() const
Local Stack Slot Allocation
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
This file contains the declarations for the subclasses of Constant, which represent the different fla...
const MachineOperand & getOperand(unsigned i) const
SmallSetVector< int, 8 > StackObjSet
StackObjSet - A set of stack object indexes.
Represent the analysis usage information of a pass.
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE,"Assign register bank of generic virtual registers", false, false) RegBankSelect
SSPLayoutKind getSSPLayout(const AllocaInst *AI) const
std::pair< NoneType, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool isDeadObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a dead object.
virtual const TargetFrameLowering * getFrameLowering() const
A SetVector that performs no allocations if smaller than a certain size.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
unsigned getObjectAlignment(int ObjectIdx) const
Return the alignment of the specified stack object.
Module.h This file contains the declarations for the Module class.
Information about stack frame layout on the target.
void setPreservesCFG()
This function should be called by the pass, iff they do not:
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
virtual bool isFrameOffsetLegal(const MachineInstr *MI, unsigned BaseReg, int64_t Offset) const
Determine whether a given base register plus offset immediate is encodable to resolve a frame index...
int getStackProtectorIndex() const
Return the index for the stack protector object.
Representation of each machine instruction.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
StackDirection getStackGrowthDirection() const
getStackGrowthDirection - Return the direction the stack grows
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 initializeLocalStackSlotPassPass(PassRegistry &)
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
virtual void resolveFrameIndex(MachineInstr &MI, unsigned BaseReg, int64_t Offset) const
Resolve a frame index operand of an instruction to reference the indicated base register plus offset ...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool operator<(int64_t V1, const APSInt &V2)
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
int getObjectIndexEnd() const
Return one past the maximum frame object index.
char & LocalStackSlotAllocationID
LocalStackSlotAllocation - This pass assigns local frame indices to stack slots relative to one anoth...
const AllocaInst * getObjectAllocation(int ObjectIdx) const
Return the underlying Alloca of the specified stack object if it exists.
virtual const TargetRegisterClass * getPointerRegClass(const MachineFunction &MF, unsigned Kind=0) const
Returns a TargetRegisterClass used for pointer values.
static void AssignProtectedObjSet(const StackObjSet &UnassignedObjs, SmallSet< int, 16 > &ProtectedObjs, MachineFrameInfo &MFI, bool StackGrowsDown, int64_t &Offset, unsigned &MaxAlign, unsigned Skew)
AssignProtectedObjSet - Helper function to assign large stack objects (i.e., those required to be clo...
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
Array or nested array >= SSP-buffer-size.
Array or nested array < SSP-buffer-size.