17 #define DEBUG_TYPE "localstackalloc"
41 STATISTIC(NumAllocations,
"Number of frame indices allocated into local block");
42 STATISTIC(NumBaseRegisters,
"Number of virtual frame base registers allocated");
43 STATISTIC(NumReplacements,
"Number of frame indices references replaced");
52 MI(I), LocalOffset(Offset), FrameIdx(Idx) {}
53 bool operator<(
const FrameRef &RHS)
const {
54 return LocalOffset < RHS.LocalOffset;
57 int64_t getLocalOffset()
const {
return LocalOffset; }
58 int getFrameIndex()
const {
return FrameIdx; }
65 bool StackGrowsDown,
unsigned &MaxAlign);
85 "Local Stack Slot Allocation",
false,
false)
101 calculateFrameObjectOffsets(MF);
104 bool UsedBaseRegs = insertFrameReferenceRegisters(MF);
118 int FrameIdx, int64_t &Offset,
120 unsigned &MaxAlign) {
129 MaxAlign = std::max(MaxAlign, Align);
132 Offset = (Offset + Align - 1) / Align * Align;
134 int64_t LocalOffset = StackGrowsDown ? -Offset : Offset;
135 DEBUG(
dbgs() <<
"Allocate FI(" << FrameIdx <<
") to local offset "
136 << LocalOffset <<
"\n");
138 LocalOffsets[FrameIdx] = LocalOffset;
151 void LocalStackSlotPass::calculateFrameObjectOffsets(
MachineFunction &Fn) {
155 bool StackGrowsDown =
158 unsigned MaxAlign = 0;
165 StackGrowsDown, MaxAlign);
188 if (LargeStackObjs.
count(i))
201 int64_t FrameSizeAdjust,
202 int64_t LocalFrameOffset,
207 int64_t Offset = FrameSizeAdjust + LocalFrameOffset - BaseOffset;
211 bool LocalStackSlotPass::insertFrameReferenceRegisters(
MachineFunction &Fn) {
218 bool UsedBaseReg =
false;
223 bool StackGrowsDown =
255 int64_t LocalOffset = LocalOffsets[Idx];
259 push_back(FrameRef(MI, LocalOffset, Idx));
271 unsigned BaseReg = 0;
272 int64_t BaseOffset = 0;
275 for (
int ref = 0, e = FrameReferenceInsns.
size(); ref < e ; ++ref) {
276 FrameRef &FR = FrameReferenceInsns[ref];
279 int64_t LocalOffset = FR.getLocalOffset();
280 int FrameIdx = FR.getFrameIndex();
282 "Only pre-allocated locals expected!");
291 if (FrameIdx == I->getOperand(idx).getIndex())
295 assert(idx < MI->getNumOperands() &&
"Cannot find FI operand");
300 DEBUG(
dbgs() <<
" Replacing FI in: " << *MI);
308 LocalOffset, MI, TRI)) {
309 DEBUG(
dbgs() <<
" Reusing base register " << BaseReg <<
"\n");
311 Offset = FrameSizeAdjust + LocalOffset - BaseOffset;
317 int64_t PrevBaseOffset = BaseOffset;
318 BaseOffset = FrameSizeAdjust + LocalOffset + InstrOffset;
325 bool CanReuse =
false;
326 for (
int refn = ref + 1; refn < e; ++refn) {
327 FrameRef &FRN = FrameReferenceInsns[refn];
332 FRN.getLocalOffset(), MIN, TRI);
337 BaseOffset = PrevBaseOffset;
345 DEBUG(
dbgs() <<
" Materializing base register " << BaseReg <<
346 " at frame local offset " << LocalOffset + InstrOffset <<
"\n");
357 Offset = -InstrOffset;
362 assert(BaseReg != 0 &&
"Unable to allocate virtual base register!");
const MachineFunction * getParent() const
void mapLocalFrameObject(int ObjectIndex, int64_t Offset)
mapLocalFrameObject - Map a frame index into the local object block
unsigned createVirtualRegister(const TargetRegisterClass *RegClass)
void operator<(const Optional< T > &X, const Optional< U > &Y)
Poison comparison between two Optional objects. Clients needs to explicitly compare the underlying va...
static bool lookupCandidateBaseReg(int64_t BaseOffset, int64_t FrameSizeAdjust, int64_t LocalFrameOffset, const MachineInstr *MI, const TargetRegisterInfo *TRI)
bool isObjectPreAllocated(int ObjectIdx) const
int64_t getLocalFrameSize() const
getLocalFrameSize - Get the size of the local object blob.
virtual int64_t getFrameIndexInstrOffset(const MachineInstr *MI, int Idx) const
void setLocalFrameSize(int64_t sz)
setLocalFrameSize - Set the size of the local object blob.
void setUseLocalStackAllocationBlock(bool v)
Abstract Stack Frame Information.
ID
LLVM Calling Convention Representation.
STATISTIC(NumAllocations,"Number of frame indices allocated into local block")
unsigned getNumOperands() const
INITIALIZE_PASS(LocalStackSlotPass,"localstackalloc","Local Stack Slot Allocation", false, false) bool LocalStackSlotPass
bool isFI() const
isFI - Tests if this is a MO_FrameIndex operand.
void setLocalFrameMaxAlign(unsigned Align)
virtual bool requiresVirtualBaseRegisters(const MachineFunction &MF) const
virtual void materializeFrameBaseRegister(MachineBasicBlock *MBB, unsigned BaseReg, int FrameIdx, int64_t Offset) const
virtual void resolveFrameIndex(MachineBasicBlock::iterator I, unsigned BaseReg, int64_t Offset) const
const MachineBasicBlock * getParent() const
bool isDebugValue() const
bundle_iterator< MachineInstr, instr_iterator > iterator
void array_pod_sort(IteratorTy Start, IteratorTy End)
const MachineOperand & getOperand(unsigned i) const
virtual const TargetFrameLowering * getFrameLowering() const
bool isDeadObjectIndex(int ObjectIdx) const
unsigned getObjectAlignment(int ObjectIdx) const
getObjectAlignment - Return the alignment of the specified stack object.
MachineFrameInfo * getFrameInfo()
raw_ostream & dbgs()
dbgs - Return a circular-buffered debug stream.
static void AdjustStackOffset(MachineFrameInfo *MFI, int FrameIdx, bool StackGrowsDown, int64_t &Offset, unsigned &MaxAlign)
AdjustStackOffset - Helper function used to adjust the stack frame offset.
static cl::opt< AlignMode > Align(cl::desc("Load/store alignment support"), cl::Hidden, cl::init(DefaultAlign), cl::values(clEnumValN(DefaultAlign,"arm-default-align","Generate unaligned accesses only on hardware/OS ""combinations that are known to support them"), clEnumValN(StrictAlign,"arm-strict-align","Disallow all unaligned memory accesses"), clEnumValN(NoStrictAlign,"arm-no-strict-align","Allow unaligned memory accesses"), clEnumValEnd))
int getStackProtectorIndex() const
bool count(const T &V) const
count - Return true if the element is in the set.
StackDirection getStackGrowthDirection() const
virtual bool needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const
virtual bool isFrameOffsetLegal(const MachineInstr *MI, int64_t Offset) const
MachineRegisterInfo & getRegInfo()
virtual void getAnalysisUsage(AnalysisUsage &AU) const
const TargetMachine & getTarget() const
virtual const TargetRegisterInfo * getRegisterInfo() const
BasicBlockListType::iterator iterator
int getObjectIndexEnd() const
char & LocalStackSlotAllocationID
virtual const TargetRegisterClass * getPointerRegClass(const MachineFunction &MF, unsigned Kind=0) const
int64_t getObjectSize(int ObjectIdx) const
bool MayNeedStackProtector(int ObjectIdx) const