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");
56 MI(I), LocalOffset(Offset), FrameIdx(Idx) {}
57 bool operator<(
const FrameRef &RHS)
const {
58 return LocalOffset < RHS.LocalOffset;
61 int64_t getLocalOffset()
const {
return LocalOffset; }
62 int getFrameIndex()
const {
return FrameIdx; }
71 bool StackGrowsDown,
unsigned &MaxAlign);
75 int64_t &Offset,
unsigned &MaxAlign);
98 "Local Stack Slot Allocation",
false,
false)
118 calculateFrameObjectOffsets(MF);
121 bool UsedBaseRegs = insertFrameReferenceRegisters(MF);
135 int FrameIdx, int64_t &Offset,
137 unsigned &MaxAlign) {
146 MaxAlign = std::max(MaxAlign, Align);
149 Offset = (Offset + Align - 1) / Align * Align;
151 int64_t LocalOffset = StackGrowsDown ? -Offset : Offset;
152 DEBUG(
dbgs() <<
"Allocate FI(" << FrameIdx <<
") to local offset "
153 << LocalOffset <<
"\n");
155 LocalOffsets[FrameIdx] = LocalOffset;
170 bool StackGrowsDown, int64_t &Offset,
171 unsigned &MaxAlign) {
174 E = UnassignedObjs.
end();
I != E; ++
I) {
184 void LocalStackSlotPass::calculateFrameObjectOffsets(
MachineFunction &Fn) {
188 bool StackGrowsDown =
191 unsigned MaxAlign = 0;
203 StackGrowsDown, MaxAlign);
243 if (ProtectedObjs.count(i))
257 int64_t FrameSizeAdjust,
258 int64_t LocalFrameOffset,
263 int64_t Offset = FrameSizeAdjust + LocalFrameOffset - BaseOffset;
267 bool LocalStackSlotPass::insertFrameReferenceRegisters(
MachineFunction &Fn) {
274 bool UsedBaseReg =
false;
279 bool StackGrowsDown =
314 int64_t LocalOffset = LocalOffsets[Idx];
318 push_back(FrameRef(MI, LocalOffset, Idx));
330 unsigned BaseReg = 0;
331 int64_t BaseOffset = 0;
334 for (
int ref = 0, e = FrameReferenceInsns.
size(); ref < e ; ++ref) {
335 FrameRef &FR = FrameReferenceInsns[ref];
338 int64_t LocalOffset = FR.getLocalOffset();
339 int FrameIdx = FR.getFrameIndex();
341 "Only pre-allocated locals expected!");
350 if (FrameIdx == I->getOperand(idx).getIndex())
354 assert(idx < MI->getNumOperands() &&
"Cannot find FI operand");
359 DEBUG(
dbgs() <<
" Replacing FI in: " << *MI);
367 FrameSizeAdjust, LocalOffset, MI,
369 DEBUG(
dbgs() <<
" Reusing base register " << BaseReg <<
"\n");
371 Offset = FrameSizeAdjust + LocalOffset - BaseOffset;
377 int64_t PrevBaseOffset = BaseOffset;
378 BaseOffset = FrameSizeAdjust + LocalOffset + InstrOffset;
387 BaseReg, BaseOffset, FrameSizeAdjust,
388 FrameReferenceInsns[ref + 1].getLocalOffset(),
389 FrameReferenceInsns[ref + 1].getMachineInstr(), TRI)) {
390 BaseOffset = PrevBaseOffset;
398 DEBUG(
dbgs() <<
" Materializing base register " << BaseReg <<
399 " at frame local offset " << LocalOffset + InstrOffset <<
"\n");
410 Offset = -InstrOffset;
415 assert(BaseReg != 0 &&
"Unable to allocate virtual base register!");
const MachineFunction * getParent() const
getParent - Return the MachineFunction containing this basic block.
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")
unsigned createVirtualRegister(const TargetRegisterClass *RegClass)
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
INITIALIZE_PASS_BEGIN(LocalStackSlotPass,"localstackalloc","Local Stack Slot Allocation", false, false) INITIALIZE_PASS_END(LocalStackSlotPass
A Stackmap instruction captures the location of live variables at its position in the instruction str...
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
getFrameIndexInstrOffset - 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...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
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.
static bool lookupCandidateBaseReg(unsigned BaseReg, int64_t BaseOffset, int64_t FrameSizeAdjust, int64_t LocalFrameOffset, const MachineInstr *MI, const TargetRegisterInfo *TRI)
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
requiresVirtualBaseRegisters - Returns true if the target wants the LocalStackAllocation pass to be r...
virtual void materializeFrameBaseRegister(MachineBasicBlock *MBB, unsigned BaseReg, int FrameIdx, int64_t Offset) const
materializeFrameBaseRegister - Insert defining instruction(s) for BaseReg to be a pointer to FrameIdx...
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
bool isDebugValue() const
Local Stack Slot Allocation
bundle_iterator< MachineInstr, instr_iterator > iterator
void array_pod_sort(IteratorTy Start, IteratorTy End)
array_pod_sort - This sorts an array with the specified start and end extent.
Patchable call instruction - this instruction represents a call to a constant address, followed by a series of NOPs.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
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.
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...
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.
MachineFrameInfo * getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
void setPreservesCFG()
This function should be called by the pass, iff they do not:
static cl::opt< AlignMode > Align(cl::desc("Load/store alignment support"), cl::Hidden, cl::init(NoStrictAlign), cl::values(clEnumValN(StrictAlign,"aarch64-strict-align","Disallow all unaligned memory accesses"), clEnumValN(NoStrictAlign,"aarch64-no-strict-align","Allow unaligned memory accesses"), clEnumValEnd))
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
static void AdjustStackOffset(MachineFrameInfo *MFI, int FrameIdx, bool StackGrowsDown, int64_t &Offset, unsigned &MaxAlign)
AdjustStackOffset - Helper function used to adjust the stack frame offset.
virtual bool isFrameOffsetLegal(const MachineInstr *MI, unsigned BaseReg, int64_t Offset) const
isFrameOffsetLegal - Determine whether a given base register plus offset immediate is encodable to re...
int getStackProtectorIndex() const
Return the index for the stack protector object.
Representation of each machine instruction.
StackDirection getStackGrowthDirection() const
getStackGrowthDirection - Return the direction the stack grows
virtual bool needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const
needsFrameBaseReg - Returns true if the instruction's frame index reference would be better served by...
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
void initializeLocalStackSlotPassPass(PassRegistry &)
Call instruction with associated vm state for deoptimization and list of live pointers for relocation...
virtual void resolveFrameIndex(MachineInstr &MI, unsigned BaseReg, int64_t Offset) const
resolveFrameIndex - Resolve a frame index operand of an instruction to reference the indicated base r...
bool operator<(int64_t V1, const APSInt &V2)
BasicBlockListType::iterator iterator
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.
static void AssignProtectedObjSet(const StackObjSet &UnassignedObjs, SmallSet< int, 16 > &ProtectedObjs, MachineFrameInfo *MFI, bool StackGrowsDown, int64_t &Offset, unsigned &MaxAlign)
AssignProtectedObjSet - Helper function to assign large stack objects (i.e., those required to be clo...
virtual const TargetRegisterClass * getPointerRegClass(const MachineFunction &MF, unsigned Kind=0) const
getPointerRegClass - Returns a TargetRegisterClass used for pointer values.
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.