Go to the documentation of this file.
13 #ifndef LLVM_CODEGEN_MACHINEFRAMEINFO_H
14 #define LLVM_CODEGEN_MACHINEFRAMEINFO_H
25 class MachineFunction;
26 class MachineBasicBlock;
150 bool isStatepointSpillSlot =
false;
169 bool PreAllocated =
false;
185 StackObject(uint64_t
Size,
Align Alignment, int64_t SPOffset,
186 bool IsImmutable,
bool IsSpillSlot,
const AllocaInst *Alloca,
187 bool IsAliased, uint8_t StackID = 0)
188 : SPOffset(SPOffset),
Size(
Size), Alignment(Alignment),
189 isImmutable(IsImmutable), isSpillSlot(IsSpillSlot), StackID(StackID),
190 Alloca(Alloca), isAliased(IsAliased), SSPLayout(
SSPLK_None) {}
194 Align StackAlignment;
207 bool StackRealignable;
213 std::vector<StackObject> Objects;
218 unsigned NumFixedObjects = 0;
222 bool HasVarSizedObjects =
false;
226 bool FrameAddressTaken =
false;
230 bool ReturnAddressTaken =
false;
234 bool HasStackMap =
false;
238 bool HasPatchPoint =
false;
244 uint64_t StackSize = 0;
255 int OffsetAdjustment = 0;
269 bool AdjustsStack =
false;
272 bool HasCalls =
false;
275 int StackProtectorIdx = -1;
278 int FunctionContextIdx = -1;
284 unsigned MaxCallFrameSize = ~0u;
288 unsigned CVBytesOfCalleeSavedRegisters = 0;
294 std::vector<CalleeSavedInfo> CSInfo;
297 bool CSIValid =
false;
301 SmallVector<std::pair<int, int64_t>, 32> LocalFrameObjects;
304 int64_t LocalFrameSize = 0;
308 Align LocalFrameMaxAlign;
313 bool UseLocalStackAllocationBlock =
false;
317 bool HasOpaqueSPAdjustment =
false;
321 bool HasCopyImplyingStackAdjustment =
false;
324 bool HasVAStart =
false;
327 bool HasMustTailInVarArgFunc =
false;
332 bool HasTailCall =
false;
335 MachineBasicBlock *Save =
nullptr;
337 MachineBasicBlock *Restore =
nullptr;
343 StackRealignable(StackRealignable), ForcedRealign(ForcedRealign) {}
401 LocalFrameObjects.push_back(std::pair<int, int64_t>(ObjectIndex,
Offset));
402 Objects[ObjectIndex + NumFixedObjects].PreAllocated =
true;
407 assert (
i >= 0 && (
unsigned)
i < LocalFrameObjects.size() &&
408 "Invalid local object reference!");
409 return LocalFrameObjects[
i];
424 LocalFrameMaxAlign = Alignment;
433 return UseLocalStackAllocationBlock;
440 UseLocalStackAllocationBlock = v;
445 assert(
unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
446 "Invalid Object Idx!");
447 return Objects[ObjectIdx+NumFixedObjects].PreAllocated;
452 assert(
unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
453 "Invalid Object Idx!");
454 return Objects[ObjectIdx+NumFixedObjects].Size;
459 assert(
unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
460 "Invalid Object Idx!");
461 Objects[ObjectIdx+NumFixedObjects].Size =
Size;
466 "Use getObjectAlign instead") {
472 assert(
unsigned(ObjectIdx + NumFixedObjects) < Objects.size() &&
473 "Invalid Object Idx!");
474 return Objects[ObjectIdx + NumFixedObjects].Alignment;
479 assert(
unsigned(ObjectIdx + NumFixedObjects) < Objects.size() &&
480 "Invalid Object Idx!");
481 Objects[ObjectIdx + NumFixedObjects].Alignment = Alignment;
490 "Use the version that takes Align instead") {
497 assert(
unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
498 "Invalid Object Idx!");
499 return Objects[ObjectIdx+NumFixedObjects].Alloca;
505 assert(
unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
506 "Invalid Object Idx!");
508 "Getting frame offset for a dead object?");
509 return Objects[ObjectIdx+NumFixedObjects].SPOffset;
513 assert(
unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
514 "Invalid Object Idx!");
515 return Objects[ObjectIdx+NumFixedObjects].isZExt;
519 assert(
unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
520 "Invalid Object Idx!");
521 Objects[ObjectIdx+NumFixedObjects].isZExt = IsZExt;
525 assert(
unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
526 "Invalid Object Idx!");
527 return Objects[ObjectIdx+NumFixedObjects].isSExt;
531 assert(
unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
532 "Invalid Object Idx!");
533 Objects[ObjectIdx+NumFixedObjects].isSExt = IsSExt;
539 assert(
unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
540 "Invalid Object Idx!");
542 "Setting frame offset for a dead object?");
543 Objects[ObjectIdx+NumFixedObjects].SPOffset = SPOffset;
547 assert(
unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
548 "Invalid Object Idx!");
549 return (
SSPLayoutKind)Objects[ObjectIdx+NumFixedObjects].SSPLayout;
553 assert(
unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
554 "Invalid Object Idx!");
556 "Setting SSP layout for a dead object?");
557 Objects[ObjectIdx+NumFixedObjects].SSPLayout =
Kind;
580 "Use getMaxAlign instead") {
581 return MaxAlignment.value();
591 "Use the version that uses Align instead") {
612 return HasCopyImplyingStackAdjustment;
615 HasCopyImplyingStackAdjustment =
B;
648 return MaxCallFrameSize;
651 return MaxCallFrameSize != ~0u;
658 return CVBytesOfCalleeSavedRegisters;
661 CVBytesOfCalleeSavedRegisters =
S;
669 bool isAliased =
false);
674 bool IsImmutable =
false);
678 return ObjectIdx < 0 && (ObjectIdx >= -(
int)NumFixedObjects);
684 assert(
unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
685 "Invalid Object Idx!");
686 return Objects[ObjectIdx+NumFixedObjects].isAliased;
694 assert(
unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
695 "Invalid Object Idx!");
696 return Objects[ObjectIdx+NumFixedObjects].isImmutable;
701 assert(
unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
702 "Invalid Object Idx!");
703 Objects[ObjectIdx+NumFixedObjects].isImmutable = IsImmutable;
708 assert(
unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
709 "Invalid Object Idx!");
710 return Objects[ObjectIdx+NumFixedObjects].isSpillSlot;
714 assert(
unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
715 "Invalid Object Idx!");
716 return Objects[ObjectIdx+NumFixedObjects].isStatepointSpillSlot;
721 return Objects[ObjectIdx+NumFixedObjects].StackID;
726 assert(
unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
727 "Invalid Object Idx!");
728 Objects[ObjectIdx+NumFixedObjects].StackID =
ID;
735 assert(
unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
736 "Invalid Object Idx!");
737 return Objects[ObjectIdx+NumFixedObjects].Size == ~0ULL;
743 assert(
unsigned(ObjectIdx + NumFixedObjects) < Objects.size() &&
744 "Invalid Object Idx!");
745 return Objects[ObjectIdx + NumFixedObjects].Size == 0;
749 assert(
unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
750 "Invalid Object Idx!");
751 Objects[ObjectIdx+NumFixedObjects].isStatepointSpillSlot =
true;
764 "Use CreateStackObject that takes an Align instead") {
774 "Use CreateSpillStackObject that takes an Align instead") {
781 Objects[ObjectIdx+NumFixedObjects].Size = ~0ULL;
790 unsigned Alignment,
const AllocaInst *Alloca),
791 "Use the version that takes an Align instead") {
LLVM_ATTRIBUTE_DEPRECATED(inline int CreateSpillStackObject(uint64_t Size, unsigned Alignment), "Use CreateSpillStackObject that takes an Align instead")
bool isObjectZExt(int ObjectIdx) const
bool isMaxCallFrameSizeComputed() const
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
uint64_t estimateStackSize(const MachineFunction &MF) const
Estimate and return the size of the stack frame.
bool hasVAStart() const
Returns true if the function calls the llvm.va_start intrinsic.
unsigned getNumFixedObjects() const
Return the number of fixed objects.
void setReturnAddressIsTaken(bool s)
bool hasCopyImplyingStackAdjustment() const
Returns true if the function contains operations which will lower down to instructions which manipula...
LLVM_ATTRIBUTE_DEPRECATED(int CreateVariableSizedObject(unsigned Alignment, const AllocaInst *Alloca), "Use the version that takes an Align instead")
FIXME: Remove this function when transition to Align is over.
void setCVBytesOfCalleeSavedRegisters(unsigned S)
unsigned getCVBytesOfCalleeSavedRegisters() const
Returns how many bytes of callee-saved registers the target pushed in the prologue.
bool getUseLocalStackAllocationBlock() const
Get whether the local allocation blob should be allocated together or let PEI allocate the locals in ...
int getOffsetAdjustment() const
Return the correction for frame offsets.
LLVM_ATTRIBUTE_DEPRECATED(inline int CreateStackObject(uint64_t Size, unsigned Alignment, bool isSpillSlot, const AllocaInst *Alloca=nullptr, uint8_t ID=0), "Use CreateStackObject that takes an Align instead")
void setStackSize(uint64_t Size)
Set the size of the stack.
bool isObjectPreAllocated(int ObjectIdx) const
Return true if the object was pre-allocated into the local block.
@ SSPLK_LargeArray
Array or nested array >= SSP-buffer-size.
void setMaxCallFrameSize(unsigned S)
void setAdjustsStack(bool V)
void setObjectSize(int ObjectIdx, int64_t Size)
Change the size of the specified stack object.
void RemoveStackObject(int ObjectIdx)
Remove or mark dead a statically sized stack object.
int getObjectIndexEnd() const
Return one past the maximum frame object index.
int CreateVariableSizedObject(Align Alignment, const AllocaInst *Alloca)
Notify the MachineFrameInfo object that a variable sized object has been created.
LLVM_ATTRIBUTE_DEPRECATED(unsigned getMaxAlignment() const, "Use getMaxAlign instead")
Return the alignment in bytes that this function must be aligned to, which is greater than the defaul...
unsigned getMaxCallFrameSize() const
Return the maximum size of a call frame that must be allocated for an outgoing function call.
void setObjectAlignment(int ObjectIdx, Align Alignment)
setObjectAlignment - Change the alignment of the specified stack object.
void setDstReg(Register SpillReg)
bool hasStackObjects() const
Return true if there are any stack objects in this function.
void setHasStackMap(bool s=true)
void ensureMaxAlignment(Align Alignment)
Make sure the function is at least Align bytes aligned.
bool isReturnAddressTaken() const
This method may be called any time after instruction selection is complete to determine if there is a...
void setObjectSSPLayout(int ObjectIdx, SSPLayoutKind Kind)
void setCalleeSavedInfoValid(bool v)
void setLocalFrameMaxAlign(Align Alignment)
Required alignment of the local object blob, which is the strictest alignment of any object in it.
Clang compiles this i1 i64 store i64 i64 store i64 i64 store i64 i64 store i64 align Which gets codegen d xmm0 movaps rbp movaps rbp movaps rbp movaps rbp rbp rbp rbp rbp It would be better to have movq s of instead of the movaps s LLVM produces ret int
void print(const MachineFunction &MF, raw_ostream &OS) const
Used by the MachineFunction printer to print information about stack objects.
LLVM_ATTRIBUTE_DEPRECATED(inline void ensureMaxAlignment(unsigned Align), "Use the version that uses Align instead")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
void setHasOpaqueSPAdjustment(bool B)
MachineBasicBlock * getRestorePoint() const
uint8_t getStackID(int ObjectIdx) const
This class implements an extremely fast bulk output stream that can only output to a stream.
bool isAliasedObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to an object that might be pointed to by an LLVM IR v...
@ SSPLK_None
Did not trigger a stack protector.
LLVM_ATTRIBUTE_DEPRECATED(inline void setObjectAlignment(int ObjectIdx, unsigned Align), "Use the version that takes Align instead")
Align getLocalFrameMaxAlign() const
Return the required alignment of the local object blob.
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects.
bool hasMustTailInVarArgFunc() const
Returns true if the function is variadic and contains a musttail call.
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
bool isFixedObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a fixed stack object.
This struct is a compact representation of a valid (non-zero power of two) alignment.
int getObjectIndexBegin() const
Return the minimum frame object index.
bool isCalleeSavedInfoValid() const
Has the callee saved info been calculated yet?
bool isDeadObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a dead object.
int CreateSpillStackObject(uint64_t Size, Align Alignment)
Create a new statically sized stack object that represents a spill slot, returning a nonnegative iden...
std::pair< int, int64_t > getLocalFrameObjectMap(int i) const
Get the local offset mapping for a for an object.
MachineFrameInfo(unsigned StackAlignment, bool StackRealignable, bool ForcedRealign)
void setCalleeSavedInfo(std::vector< CalleeSavedInfo > CSI)
Used by prolog/epilog inserter to set the function's callee saved information.
bool isSpilledToReg() const
void setHasMustTailInVarArgFunc(bool B)
int CreateFixedSpillStackObject(uint64_t Size, int64_t SPOffset, bool IsImmutable=false)
Create a spill slot at a fixed location on the stack.
int64_t getLocalFrameSize() const
Get the size of the local object blob.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
bool hasStackProtectorIndex() const
multiplies can be turned into SHL s
void setHasCopyImplyingStackAdjustment(bool B)
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Align assumeAligned(uint64_t Value)
Treats the value 0 as a 1, so Align is always at least 1.
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
void computeMaxCallFrameSize(const MachineFunction &MF)
Computes the maximum size of a callframe and the AdjustsStack property.
void setObjectOffset(int ObjectIdx, int64_t SPOffset)
Set the stack frame offset of the specified object.
void setRestorePoint(MachineBasicBlock *NewRestore)
void setFunctionContextIndex(int I)
void mapLocalFrameObject(int ObjectIndex, int64_t Offset)
Map a frame index into the local object block.
void setHasTailCall(bool V=true)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
void setSavePoint(MachineBasicBlock *NewSave)
const std::vector< CalleeSavedInfo > & getCalleeSavedInfo() const
Returns a reference to call saved info vector for the current function.
void setStackID(int ObjectIdx, uint8_t ID)
bool hasPatchPoint() const
This method may be called any time after instruction selection is complete to determine if there is a...
bool isStatepointSpillSlotObjectIndex(int ObjectIdx) const
int CreateStackObject(uint64_t Size, Align Alignment, bool isSpillSlot, const AllocaInst *Alloca=nullptr, uint8_t ID=0)
Create a new statically sized stack object, returning a nonnegative identifier to represent it.
BitVector getPristineRegs(const MachineFunction &MF) const
Return a set of physical registers that are pristine.
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
bool isObjectSExt(int ObjectIdx) const
int64_t getLocalFrameObjectCount() const
Return the number of objects allocated into the local object block.
Align getMaxAlign() const
Return the alignment in bytes that this function must be aligned to, which is greater than the defaul...
Wrapper class representing virtual and physical registers.
bool isFrameAddressTaken() const
This method may be called any time after instruction selection is complete to determine if there is a...
bool hasCalls() const
Return true if the current function has any function calls.
void dump(const MachineFunction &MF) const
dump - Print the function to stderr.
MachineBasicBlock * getSavePoint() const
SSPLayoutKind getObjectSSPLayout(int ObjectIdx) const
The CalleeSavedInfo class tracks the information need to locate where a callee saved register is in t...
bool isVariableSizedObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a variable sized object.
uint64_t value() const
This is a hole in the type system and should not be abused.
void setIsImmutableObjectIndex(int ObjectIdx, bool IsImmutable)
Marks the immutability of an object.
unsigned getDstReg() const
void setObjectSExt(int ObjectIdx, bool IsSExt)
bool isSpillSlotObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a spill slot.
void setStackProtectorIndex(int I)
unsigned getNumObjects() const
Return the number of objects.
bool isImmutableObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to an immutable object.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
@ SSPLK_AddrOf
The address of this allocation is exposed and triggered protection.
SSPLayoutKind
Stack Smashing Protection (SSP) rules require that vulnerable stack allocations are located close the...
@ SSPLK_SmallArray
Array or nested array < SSP-buffer-size.
void setHasPatchPoint(bool s=true)
void markAsStatepointSpillSlotObjectIndex(int ObjectIdx)
void setOffsetAdjustment(int Adj)
Set the correction for frame offsets.
bool hasOpaqueSPAdjustment() const
Returns true if the function contains opaque dynamic stack adjustments.
std::vector< CalleeSavedInfo > & getCalleeSavedInfo()
int getStackProtectorIndex() const
Return the index for the stack protector object.
bool hasStackMap() const
This method may be called any time after instruction selection is complete to determine if there is a...
bool adjustsStack() const
Return true if this function adjusts the stack – e.g., when calling another function.
void setFrameAddressIsTaken(bool T)
an instruction to allocate memory on the stack
bool hasTailCall() const
Returns true if the function contains a tail call.
void setObjectZExt(int ObjectIdx, bool IsZExt)
void setLocalFrameSize(int64_t sz)
Set the size of the local object blob.
void setHasVAStart(bool B)
CalleeSavedInfo(unsigned R, int FI=0)
void setUseLocalStackAllocationBlock(bool v)
setUseLocalStackAllocationBlock - Set whether the local allocation blob should be allocated together ...
int getFunctionContextIndex() const
Return the index for the function context object.
const AllocaInst * getObjectAllocation(int ObjectIdx) const
Return the underlying Alloca of the specified stack object if it exists.