diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2015-12-30 11:46:15 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2015-12-30 11:46:15 +0000 |
commit | dd58ef019b700900793a1eb48b52123db01b654e (patch) | |
tree | fcfbb4df56a744f4ddc6122c50521dd3f1c5e196 /include/llvm/CodeGen/MachineFrameInfo.h | |
parent | 2fe5752e3a7c345cdb59e869278d36af33c13fa4 (diff) |
Notes
Diffstat (limited to 'include/llvm/CodeGen/MachineFrameInfo.h')
-rw-r--r-- | include/llvm/CodeGen/MachineFrameInfo.h | 46 |
1 files changed, 40 insertions, 6 deletions
diff --git a/include/llvm/CodeGen/MachineFrameInfo.h b/include/llvm/CodeGen/MachineFrameInfo.h index cbc4e66ccc46..48e8ca75052e 100644 --- a/include/llvm/CodeGen/MachineFrameInfo.h +++ b/include/llvm/CodeGen/MachineFrameInfo.h @@ -101,6 +101,13 @@ class MachineFrameInfo { // cannot alias any other memory objects. bool isSpillSlot; + /// If true, this stack slot is used to spill a value (could be deopt + /// and/or GC related) over a statepoint. We know that the address of the + /// slot can't alias any LLVM IR value. This is very similiar to a Spill + /// Slot, but is created by statepoint lowering is SelectionDAG, not the + /// register allocator. + bool isStatepointSpillSlot; + /// If this stack object is originated from an Alloca instruction /// this value saves the original IR allocation. Can be NULL. const AllocaInst *Alloca; @@ -118,13 +125,24 @@ class MachineFrameInfo { StackObject(uint64_t Sz, unsigned Al, int64_t SP, bool IM, bool isSS, const AllocaInst *Val, bool A) : SPOffset(SP), Size(Sz), Alignment(Al), isImmutable(IM), - isSpillSlot(isSS), Alloca(Val), PreAllocated(false), isAliased(A) {} + isSpillSlot(isSS), isStatepointSpillSlot(false), Alloca(Val), + PreAllocated(false), isAliased(A) {} }; /// The alignment of the stack. unsigned StackAlignment; /// Can the stack be realigned. + /// Targets that set this to false don't have the ability to overalign + /// their stack frame, and thus, overaligned allocas are all treated + /// as dynamic allocations and the target must handle them as part + /// of DYNAMIC_STACKALLOC lowering. + /// FIXME: There is room for improvement in this case, in terms of + /// grouping overaligned allocas into a "secondary stack frame" and + /// then only use a single alloca to allocate this frame and only a + /// single virtual register to access it. Currently, without such an + /// optimization, each such alloca gets it's own dynamic + /// realignment. bool StackRealignable; /// The list of stack objects allocated. @@ -168,7 +186,7 @@ class MachineFrameInfo { /// SP then OffsetAdjustment is zero; if FP is used, OffsetAdjustment is set /// to the distance between the initial SP and the value in FP. For many /// targets, this value is only used when generating debug info (via - /// TargetRegisterInfo::getFrameIndexOffset); when generating code, the + /// TargetRegisterInfo::getFrameIndexReference); when generating code, the /// corresponding adjustments are performed directly. int OffsetAdjustment; @@ -198,7 +216,7 @@ class MachineFrameInfo { /// This contains the size of the largest call frame if the target uses frame /// setup/destroy pseudo instructions (as defined in the TargetFrameInfo /// class). This information is important for frame pointer elimination. - /// If is only valid during and after prolog/epilog code insertion. + /// It is only valid during and after prolog/epilog code insertion. unsigned MaxCallFrameSize; /// The prolog/epilog code inserter fills in this vector with each @@ -288,6 +306,7 @@ public: /// Return the index for the stack protector object. int getStackProtectorIndex() const { return StackProtectorIdx; } void setStackProtectorIndex(int I) { StackProtectorIdx = I; } + bool hasStackProtectorIndex() const { return StackProtectorIdx != -1; } /// Return the index for the function context object. /// This object is used for SjLj exceptions. @@ -337,14 +356,14 @@ public: } /// Get the local offset mapping for a for an object. - std::pair<int, int64_t> getLocalFrameObjectMap(int i) { + std::pair<int, int64_t> getLocalFrameObjectMap(int i) const { assert (i >= 0 && (unsigned)i < LocalFrameObjects.size() && "Invalid local object reference!"); return LocalFrameObjects[i]; } /// Return the number of objects allocated into the local object block. - int64_t getLocalFrameObjectCount() { return LocalFrameObjects.size(); } + int64_t getLocalFrameObjectCount() const { return LocalFrameObjects.size(); } /// Set the size of the local object blob. void setLocalFrameSize(int64_t sz) { LocalFrameSize = sz; } @@ -361,7 +380,9 @@ public: /// Get whether the local allocation blob should be allocated together or /// let PEI allocate the locals in it directly. - bool getUseLocalStackAllocationBlock() {return UseLocalStackAllocationBlock;} + bool getUseLocalStackAllocationBlock() const { + return UseLocalStackAllocationBlock; + } /// setUseLocalStackAllocationBlock - Set whether the local allocation blob /// should be allocated together or let PEI allocate the locals in it @@ -534,6 +555,12 @@ public: return Objects[ObjectIdx+NumFixedObjects].isSpillSlot; } + bool isStatepointSpillSlotObjectIndex(int ObjectIdx) const { + assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() && + "Invalid Object Idx!"); + return Objects[ObjectIdx+NumFixedObjects].isStatepointSpillSlot; + } + /// Returns true if the specified index corresponds to a dead object. bool isDeadObjectIndex(int ObjectIdx) const { assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() && @@ -549,6 +576,13 @@ public: return Objects[ObjectIdx + NumFixedObjects].Size == 0; } + void markAsStatepointSpillSlotObjectIndex(int ObjectIdx) { + assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() && + "Invalid Object Idx!"); + Objects[ObjectIdx+NumFixedObjects].isStatepointSpillSlot = true; + assert(isStatepointSpillSlotObjectIndex(ObjectIdx) && "inconsistent"); + } + /// Create a new statically sized stack object, returning /// a nonnegative identifier to represent it. int CreateStackObject(uint64_t Size, unsigned Alignment, bool isSS, |