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");
63 MI(I), LocalOffset(Offset), FrameIdx(Idx), Order(Ord) {}
65 bool operator<(
const FrameRef &RHS)
const {
66 return std::tie(LocalOffset, FrameIdx, Order) <
67 std::tie(RHS.LocalOffset, RHS.FrameIdx, RHS.Order);
71 int64_t getLocalOffset()
const {
return LocalOffset; }
72 int getFrameIndex()
const {
return FrameIdx; }
82 bool StackGrowsDown,
unsigned &MaxAlign);
86 int64_t &
Offset,
unsigned &MaxAlign);
111 "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 LLVM_DEBUG(
dbgs() <<
"Allocate FI(" << FrameIdx <<
") to local offset " 162 << LocalOffset <<
"\n");
164 LocalOffsets[FrameIdx] = LocalOffset;
179 bool StackGrowsDown, int64_t &Offset,
180 unsigned &MaxAlign) {
182 E = UnassignedObjs.
end();
I !=
E; ++
I) {
191 void LocalStackSlotPass::calculateFrameObjectOffsets(
MachineFunction &Fn) {
195 bool StackGrowsDown =
198 unsigned MaxAlign = 0;
209 StackGrowsDown, MaxAlign);
249 if (ProtectedObjs.
count(i))
263 int64_t FrameSizeAdjust,
264 int64_t LocalFrameOffset,
269 int64_t Offset = FrameSizeAdjust + LocalFrameOffset - BaseOffset;
273 bool LocalStackSlotPass::insertFrameReferenceRegisters(
MachineFunction &Fn) {
280 bool UsedBaseReg =
false;
285 bool StackGrowsDown =
300 if (
MI.isDebugInstr() ||
MI.getOpcode() == TargetOpcode::STATEPOINT ||
301 MI.getOpcode() == TargetOpcode::STACKMAP ||
302 MI.getOpcode() == TargetOpcode::PATCHPOINT)
311 for (
unsigned i = 0, e =
MI.getNumOperands(); i != e; ++i) {
314 if (
MI.getOperand(i).isFI()) {
318 int Idx =
MI.getOperand(i).getIndex();
319 int64_t LocalOffset = LocalOffsets[Idx];
322 FrameReferenceInsns.
push_back(FrameRef(&
MI, LocalOffset, Idx, Order++));
335 unsigned BaseReg = 0;
336 int64_t BaseOffset = 0;
339 for (
int ref = 0, e = FrameReferenceInsns.
size(); ref < e ; ++ref) {
340 FrameRef &FR = FrameReferenceInsns[ref];
342 int64_t LocalOffset = FR.getLocalOffset();
343 int FrameIdx = FR.getFrameIndex();
345 "Only pre-allocated locals expected!");
372 LocalOffset, MI, TRI)) {
373 LLVM_DEBUG(
dbgs() <<
" Reusing base register " << BaseReg <<
"\n");
375 Offset = FrameSizeAdjust + LocalOffset - BaseOffset;
380 int64_t PrevBaseOffset = BaseOffset;
381 BaseOffset = FrameSizeAdjust + LocalOffset + InstrOffset;
390 BaseReg, BaseOffset, FrameSizeAdjust,
391 FrameReferenceInsns[ref + 1].getLocalOffset(),
393 BaseOffset = PrevBaseOffset;
399 BaseReg = Fn.getRegInfo().createVirtualRegister(RC);
402 <<
" at frame local offset " 403 << LocalOffset + InstrOffset <<
"\n");
414 Offset = -InstrOffset;
419 assert(BaseReg != 0 &&
"Unable to allocate virtual base register!");
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
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...
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
void mapLocalFrameObject(int ObjectIndex, int64_t Offset)
Map a frame index into the local object block.
const MachineFunction * getMF() const
Return the function that contains the basic block that this instruction belongs to.
This class represents lattice values for constants.
Did not trigger a stack protector.
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
bool isDeadObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a dead object.
void push_back(const T &Elt)
int64_t getLocalFrameSize() const
Get the size of the local object blob.
STATISTIC(NumFunctions, "Total number of functions")
unsigned const TargetRegisterInfo * TRI
iterator end()
Get an iterator to the end of the SetVector.
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...
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 ...
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
unsigned getNumOperands() const
Retuns the total number of operands.
The address of this allocation is exposed and triggered protection.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted...
bool insert(const value_type &X)
Insert a new element into the SetVector.
iterator begin()
Get an iterator to the beginning of the SetVector.
bool isObjectPreAllocated(int ObjectIdx) const
Return true if the object was pre-allocated into the local block.
void setLocalFrameMaxAlign(unsigned Align)
Required alignment of the local object blob, which is the strictest alignment of any object in it...
int getObjectIndexEnd() const
Return one past the maximum frame object index.
SSPLayoutKind getObjectSSPLayout(int ObjectIdx) const
static MachineInstr * getMachineInstr(MachineInstr *MI)
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
Array or nested array >= SSP-buffer-size.
unsigned getObjectAlignment(int ObjectIdx) const
Return the alignment of the specified stack object.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
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.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
StackDirection getStackGrowthDirection() const
getStackGrowthDirection - Return the direction the stack grows
int getStackProtectorIndex() const
Return the index for the stack protector object.
Represent the analysis usage information of a pass.
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.
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...
typename vector_type::const_iterator const_iterator
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void sort(IteratorTy Start, IteratorTy End)
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...
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 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...
virtual bool requiresVirtualBaseRegisters(const MachineFunction &MF) const
Returns true if the target wants the LocalStackAllocation pass to be run and virtual base registers u...
Representation of each machine instruction.
void initializeLocalStackSlotPassPass(PassRegistry &)
virtual const TargetFrameLowering * getFrameLowering() const
bool isFI() const
isFI - Tests if this is a MO_FrameIndex operand.
INITIALIZE_PASS(LocalStackSlotPass, DEBUG_TYPE, "Local Stack Slot Allocation", false, false) bool LocalStackSlotPass
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool operator<(int64_t V1, const APSInt &V2)
Array or nested array < SSP-buffer-size.
char & LocalStackSlotAllocationID
LocalStackSlotAllocation - This pass assigns local frame indices to stack slots relative to one anoth...
const MachineOperand & getOperand(unsigned i) const
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 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...
virtual const TargetRegisterClass * getPointerRegClass(const MachineFunction &MF, unsigned Kind=0) const
Returns a TargetRegisterClass used for pointer values.
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
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 ...