109467b48Spatrick //===-- CodeGen/MachineFrameInfo.h - Abstract Stack Frame Rep. --*- C++ -*-===// 209467b48Spatrick // 309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information. 509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 609467b48Spatrick // 709467b48Spatrick //===----------------------------------------------------------------------===// 809467b48Spatrick // 909467b48Spatrick // The file defines the MachineFrameInfo class. 1009467b48Spatrick // 1109467b48Spatrick //===----------------------------------------------------------------------===// 1209467b48Spatrick 1309467b48Spatrick #ifndef LLVM_CODEGEN_MACHINEFRAMEINFO_H 1409467b48Spatrick #define LLVM_CODEGEN_MACHINEFRAMEINFO_H 1509467b48Spatrick 1609467b48Spatrick #include "llvm/ADT/SmallVector.h" 17*a0747c9fSpatrick #include "llvm/CodeGen/Register.h" 1809467b48Spatrick #include "llvm/Support/Alignment.h" 1909467b48Spatrick #include "llvm/Support/DataTypes.h" 2009467b48Spatrick #include <cassert> 2109467b48Spatrick #include <vector> 2209467b48Spatrick 2309467b48Spatrick namespace llvm { 2409467b48Spatrick class raw_ostream; 2509467b48Spatrick class MachineFunction; 2609467b48Spatrick class MachineBasicBlock; 2709467b48Spatrick class BitVector; 2809467b48Spatrick class AllocaInst; 2909467b48Spatrick 3009467b48Spatrick /// The CalleeSavedInfo class tracks the information need to locate where a 3109467b48Spatrick /// callee saved register is in the current frame. 3209467b48Spatrick /// Callee saved reg can also be saved to a different register rather than 3309467b48Spatrick /// on the stack by setting DstReg instead of FrameIdx. 3409467b48Spatrick class CalleeSavedInfo { 35*a0747c9fSpatrick Register Reg; 3609467b48Spatrick union { 3709467b48Spatrick int FrameIdx; 3809467b48Spatrick unsigned DstReg; 3909467b48Spatrick }; 4009467b48Spatrick /// Flag indicating whether the register is actually restored in the epilog. 4109467b48Spatrick /// In most cases, if a register is saved, it is also restored. There are 4209467b48Spatrick /// some situations, though, when this is not the case. For example, the 4309467b48Spatrick /// LR register on ARM is usually saved, but on exit from the function its 4409467b48Spatrick /// saved value may be loaded directly into PC. Since liveness tracking of 4509467b48Spatrick /// physical registers treats callee-saved registers are live outside of 4609467b48Spatrick /// the function, LR would be treated as live-on-exit, even though in these 4709467b48Spatrick /// scenarios it is not. This flag is added to indicate that the saved 4809467b48Spatrick /// register described by this object is not restored in the epilog. 4909467b48Spatrick /// The long-term solution is to model the liveness of callee-saved registers 5009467b48Spatrick /// by implicit uses on the return instructions, however, the required 5109467b48Spatrick /// changes in the ARM backend would be quite extensive. 5209467b48Spatrick bool Restored; 5309467b48Spatrick /// Flag indicating whether the register is spilled to stack or another 5409467b48Spatrick /// register. 5509467b48Spatrick bool SpilledToReg; 5609467b48Spatrick 5709467b48Spatrick public: 5809467b48Spatrick explicit CalleeSavedInfo(unsigned R, int FI = 0) 5909467b48Spatrick : Reg(R), FrameIdx(FI), Restored(true), SpilledToReg(false) {} 6009467b48Spatrick 6109467b48Spatrick // Accessors. 62*a0747c9fSpatrick Register getReg() const { return Reg; } 6309467b48Spatrick int getFrameIdx() const { return FrameIdx; } 6409467b48Spatrick unsigned getDstReg() const { return DstReg; } 6509467b48Spatrick void setFrameIdx(int FI) { 6609467b48Spatrick FrameIdx = FI; 6709467b48Spatrick SpilledToReg = false; 6809467b48Spatrick } 69*a0747c9fSpatrick void setDstReg(Register SpillReg) { 7009467b48Spatrick DstReg = SpillReg; 7109467b48Spatrick SpilledToReg = true; 7209467b48Spatrick } 7309467b48Spatrick bool isRestored() const { return Restored; } 7409467b48Spatrick void setRestored(bool R) { Restored = R; } 7509467b48Spatrick bool isSpilledToReg() const { return SpilledToReg; } 7609467b48Spatrick }; 7709467b48Spatrick 7809467b48Spatrick /// The MachineFrameInfo class represents an abstract stack frame until 7909467b48Spatrick /// prolog/epilog code is inserted. This class is key to allowing stack frame 8009467b48Spatrick /// representation optimizations, such as frame pointer elimination. It also 8109467b48Spatrick /// allows more mundane (but still important) optimizations, such as reordering 8209467b48Spatrick /// of abstract objects on the stack frame. 8309467b48Spatrick /// 8409467b48Spatrick /// To support this, the class assigns unique integer identifiers to stack 8509467b48Spatrick /// objects requested clients. These identifiers are negative integers for 8609467b48Spatrick /// fixed stack objects (such as arguments passed on the stack) or nonnegative 8709467b48Spatrick /// for objects that may be reordered. Instructions which refer to stack 8809467b48Spatrick /// objects use a special MO_FrameIndex operand to represent these frame 8909467b48Spatrick /// indexes. 9009467b48Spatrick /// 9109467b48Spatrick /// Because this class keeps track of all references to the stack frame, it 9209467b48Spatrick /// knows when a variable sized object is allocated on the stack. This is the 9309467b48Spatrick /// sole condition which prevents frame pointer elimination, which is an 9409467b48Spatrick /// important optimization on register-poor architectures. Because original 9509467b48Spatrick /// variable sized alloca's in the source program are the only source of 9609467b48Spatrick /// variable sized stack objects, it is safe to decide whether there will be 9709467b48Spatrick /// any variable sized objects before all stack objects are known (for 9809467b48Spatrick /// example, register allocator spill code never needs variable sized 9909467b48Spatrick /// objects). 10009467b48Spatrick /// 10109467b48Spatrick /// When prolog/epilog code emission is performed, the final stack frame is 10209467b48Spatrick /// built and the machine instructions are modified to refer to the actual 10309467b48Spatrick /// stack offsets of the object, eliminating all MO_FrameIndex operands from 10409467b48Spatrick /// the program. 10509467b48Spatrick /// 10609467b48Spatrick /// Abstract Stack Frame Information 10709467b48Spatrick class MachineFrameInfo { 10809467b48Spatrick public: 10909467b48Spatrick /// Stack Smashing Protection (SSP) rules require that vulnerable stack 11009467b48Spatrick /// allocations are located close the stack protector. 11109467b48Spatrick enum SSPLayoutKind { 11209467b48Spatrick SSPLK_None, ///< Did not trigger a stack protector. No effect on data 11309467b48Spatrick ///< layout. 11409467b48Spatrick SSPLK_LargeArray, ///< Array or nested array >= SSP-buffer-size. Closest 11509467b48Spatrick ///< to the stack protector. 11609467b48Spatrick SSPLK_SmallArray, ///< Array or nested array < SSP-buffer-size. 2nd closest 11709467b48Spatrick ///< to the stack protector. 11809467b48Spatrick SSPLK_AddrOf ///< The address of this allocation is exposed and 11909467b48Spatrick ///< triggered protection. 3rd closest to the protector. 12009467b48Spatrick }; 12109467b48Spatrick 12209467b48Spatrick private: 12309467b48Spatrick // Represent a single object allocated on the stack. 12409467b48Spatrick struct StackObject { 12509467b48Spatrick // The offset of this object from the stack pointer on entry to 12609467b48Spatrick // the function. This field has no meaning for a variable sized element. 12709467b48Spatrick int64_t SPOffset; 12809467b48Spatrick 12909467b48Spatrick // The size of this object on the stack. 0 means a variable sized object, 13009467b48Spatrick // ~0ULL means a dead object. 13109467b48Spatrick uint64_t Size; 13209467b48Spatrick 13309467b48Spatrick // The required alignment of this stack slot. 13409467b48Spatrick Align Alignment; 13509467b48Spatrick 13609467b48Spatrick // If true, the value of the stack object is set before 13709467b48Spatrick // entering the function and is not modified inside the function. By 13809467b48Spatrick // default, fixed objects are immutable unless marked otherwise. 13909467b48Spatrick bool isImmutable; 14009467b48Spatrick 14109467b48Spatrick // If true the stack object is used as spill slot. It 14209467b48Spatrick // cannot alias any other memory objects. 14309467b48Spatrick bool isSpillSlot; 14409467b48Spatrick 14509467b48Spatrick /// If true, this stack slot is used to spill a value (could be deopt 14609467b48Spatrick /// and/or GC related) over a statepoint. We know that the address of the 14709467b48Spatrick /// slot can't alias any LLVM IR value. This is very similar to a Spill 14809467b48Spatrick /// Slot, but is created by statepoint lowering is SelectionDAG, not the 14909467b48Spatrick /// register allocator. 15009467b48Spatrick bool isStatepointSpillSlot = false; 15109467b48Spatrick 15209467b48Spatrick /// Identifier for stack memory type analagous to address space. If this is 15309467b48Spatrick /// non-0, the meaning is target defined. Offsets cannot be directly 15409467b48Spatrick /// compared between objects with different stack IDs. The object may not 15509467b48Spatrick /// necessarily reside in the same contiguous memory block as other stack 15609467b48Spatrick /// objects. Objects with differing stack IDs should not be merged or 15709467b48Spatrick /// replaced substituted for each other. 15809467b48Spatrick // 15909467b48Spatrick /// It is assumed a target uses consecutive, increasing stack IDs starting 16009467b48Spatrick /// from 1. 16109467b48Spatrick uint8_t StackID; 16209467b48Spatrick 16309467b48Spatrick /// If this stack object is originated from an Alloca instruction 16409467b48Spatrick /// this value saves the original IR allocation. Can be NULL. 16509467b48Spatrick const AllocaInst *Alloca; 16609467b48Spatrick 16709467b48Spatrick // If true, the object was mapped into the local frame 16809467b48Spatrick // block and doesn't need additional handling for allocation beyond that. 16909467b48Spatrick bool PreAllocated = false; 17009467b48Spatrick 17109467b48Spatrick // If true, an LLVM IR value might point to this object. 17209467b48Spatrick // Normally, spill slots and fixed-offset objects don't alias IR-accessible 17309467b48Spatrick // objects, but there are exceptions (on PowerPC, for example, some byval 17409467b48Spatrick // arguments have ABI-prescribed offsets). 17509467b48Spatrick bool isAliased; 17609467b48Spatrick 17709467b48Spatrick /// If true, the object has been zero-extended. 17809467b48Spatrick bool isZExt = false; 17909467b48Spatrick 180*a0747c9fSpatrick /// If true, the object has been sign-extended. 18109467b48Spatrick bool isSExt = false; 18209467b48Spatrick 18309467b48Spatrick uint8_t SSPLayout; 18409467b48Spatrick 18509467b48Spatrick StackObject(uint64_t Size, Align Alignment, int64_t SPOffset, 18609467b48Spatrick bool IsImmutable, bool IsSpillSlot, const AllocaInst *Alloca, 18709467b48Spatrick bool IsAliased, uint8_t StackID = 0) 18809467b48Spatrick : SPOffset(SPOffset), Size(Size), Alignment(Alignment), 18909467b48Spatrick isImmutable(IsImmutable), isSpillSlot(IsSpillSlot), StackID(StackID), 19009467b48Spatrick Alloca(Alloca), isAliased(IsAliased), SSPLayout(SSPLK_None) {} 19109467b48Spatrick }; 19209467b48Spatrick 19309467b48Spatrick /// The alignment of the stack. 19409467b48Spatrick Align StackAlignment; 19509467b48Spatrick 19609467b48Spatrick /// Can the stack be realigned. This can be false if the target does not 19709467b48Spatrick /// support stack realignment, or if the user asks us not to realign the 19809467b48Spatrick /// stack. In this situation, overaligned allocas are all treated as dynamic 19909467b48Spatrick /// allocations and the target must handle them as part of DYNAMIC_STACKALLOC 20009467b48Spatrick /// lowering. All non-alloca stack objects have their alignment clamped to the 20109467b48Spatrick /// base ABI stack alignment. 20209467b48Spatrick /// FIXME: There is room for improvement in this case, in terms of 20309467b48Spatrick /// grouping overaligned allocas into a "secondary stack frame" and 20409467b48Spatrick /// then only use a single alloca to allocate this frame and only a 20509467b48Spatrick /// single virtual register to access it. Currently, without such an 20609467b48Spatrick /// optimization, each such alloca gets its own dynamic realignment. 20709467b48Spatrick bool StackRealignable; 20809467b48Spatrick 20909467b48Spatrick /// Whether the function has the \c alignstack attribute. 21009467b48Spatrick bool ForcedRealign; 21109467b48Spatrick 21209467b48Spatrick /// The list of stack objects allocated. 21309467b48Spatrick std::vector<StackObject> Objects; 21409467b48Spatrick 21509467b48Spatrick /// This contains the number of fixed objects contained on 21609467b48Spatrick /// the stack. Because fixed objects are stored at a negative index in the 21709467b48Spatrick /// Objects list, this is also the index to the 0th object in the list. 21809467b48Spatrick unsigned NumFixedObjects = 0; 21909467b48Spatrick 22009467b48Spatrick /// This boolean keeps track of whether any variable 22109467b48Spatrick /// sized objects have been allocated yet. 22209467b48Spatrick bool HasVarSizedObjects = false; 22309467b48Spatrick 22409467b48Spatrick /// This boolean keeps track of whether there is a call 22509467b48Spatrick /// to builtin \@llvm.frameaddress. 22609467b48Spatrick bool FrameAddressTaken = false; 22709467b48Spatrick 22809467b48Spatrick /// This boolean keeps track of whether there is a call 22909467b48Spatrick /// to builtin \@llvm.returnaddress. 23009467b48Spatrick bool ReturnAddressTaken = false; 23109467b48Spatrick 23209467b48Spatrick /// This boolean keeps track of whether there is a call 23309467b48Spatrick /// to builtin \@llvm.experimental.stackmap. 23409467b48Spatrick bool HasStackMap = false; 23509467b48Spatrick 23609467b48Spatrick /// This boolean keeps track of whether there is a call 23709467b48Spatrick /// to builtin \@llvm.experimental.patchpoint. 23809467b48Spatrick bool HasPatchPoint = false; 23909467b48Spatrick 24009467b48Spatrick /// The prolog/epilog code inserter calculates the final stack 24109467b48Spatrick /// offsets for all of the fixed size objects, updating the Objects list 24209467b48Spatrick /// above. It then updates StackSize to contain the number of bytes that need 24309467b48Spatrick /// to be allocated on entry to the function. 24409467b48Spatrick uint64_t StackSize = 0; 24509467b48Spatrick 24609467b48Spatrick /// The amount that a frame offset needs to be adjusted to 24709467b48Spatrick /// have the actual offset from the stack/frame pointer. The exact usage of 24809467b48Spatrick /// this is target-dependent, but it is typically used to adjust between 24909467b48Spatrick /// SP-relative and FP-relative offsets. E.G., if objects are accessed via 25009467b48Spatrick /// SP then OffsetAdjustment is zero; if FP is used, OffsetAdjustment is set 25109467b48Spatrick /// to the distance between the initial SP and the value in FP. For many 25209467b48Spatrick /// targets, this value is only used when generating debug info (via 25309467b48Spatrick /// TargetRegisterInfo::getFrameIndexReference); when generating code, the 25409467b48Spatrick /// corresponding adjustments are performed directly. 25509467b48Spatrick int OffsetAdjustment = 0; 25609467b48Spatrick 25709467b48Spatrick /// The prolog/epilog code inserter may process objects that require greater 25809467b48Spatrick /// alignment than the default alignment the target provides. 25909467b48Spatrick /// To handle this, MaxAlignment is set to the maximum alignment 26009467b48Spatrick /// needed by the objects on the current frame. If this is greater than the 26109467b48Spatrick /// native alignment maintained by the compiler, dynamic alignment code will 26209467b48Spatrick /// be needed. 26309467b48Spatrick /// 26409467b48Spatrick Align MaxAlignment; 26509467b48Spatrick 26609467b48Spatrick /// Set to true if this function adjusts the stack -- e.g., 26709467b48Spatrick /// when calling another function. This is only valid during and after 26809467b48Spatrick /// prolog/epilog code insertion. 26909467b48Spatrick bool AdjustsStack = false; 27009467b48Spatrick 27109467b48Spatrick /// Set to true if this function has any function calls. 27209467b48Spatrick bool HasCalls = false; 27309467b48Spatrick 27409467b48Spatrick /// The frame index for the stack protector. 27509467b48Spatrick int StackProtectorIdx = -1; 27609467b48Spatrick 277adae0cfdSpatrick struct ReturnProtector { 278adae0cfdSpatrick /// The register to use for return protector calculations 279adae0cfdSpatrick unsigned Register = 0; 280adae0cfdSpatrick /// Set to true if this function needs return protectors 281adae0cfdSpatrick bool Needed = false; 282adae0cfdSpatrick /// Does the return protector cookie need to be stored in frame 283adae0cfdSpatrick bool NeedsStore = true; 284adae0cfdSpatrick } RPI; 285adae0cfdSpatrick 28609467b48Spatrick /// The frame index for the function context. Used for SjLj exceptions. 28709467b48Spatrick int FunctionContextIdx = -1; 28809467b48Spatrick 28909467b48Spatrick /// This contains the size of the largest call frame if the target uses frame 29009467b48Spatrick /// setup/destroy pseudo instructions (as defined in the TargetFrameInfo 29109467b48Spatrick /// class). This information is important for frame pointer elimination. 29209467b48Spatrick /// It is only valid during and after prolog/epilog code insertion. 29309467b48Spatrick unsigned MaxCallFrameSize = ~0u; 29409467b48Spatrick 29509467b48Spatrick /// The number of bytes of callee saved registers that the target wants to 29609467b48Spatrick /// report for the current function in the CodeView S_FRAMEPROC record. 29709467b48Spatrick unsigned CVBytesOfCalleeSavedRegisters = 0; 29809467b48Spatrick 29909467b48Spatrick /// The prolog/epilog code inserter fills in this vector with each 30009467b48Spatrick /// callee saved register saved in either the frame or a different 30109467b48Spatrick /// register. Beyond its use by the prolog/ epilog code inserter, 30209467b48Spatrick /// this data is used for debug info and exception handling. 30309467b48Spatrick std::vector<CalleeSavedInfo> CSInfo; 30409467b48Spatrick 30509467b48Spatrick /// Has CSInfo been set yet? 30609467b48Spatrick bool CSIValid = false; 30709467b48Spatrick 30809467b48Spatrick /// References to frame indices which are mapped 30909467b48Spatrick /// into the local frame allocation block. <FrameIdx, LocalOffset> 31009467b48Spatrick SmallVector<std::pair<int, int64_t>, 32> LocalFrameObjects; 31109467b48Spatrick 31209467b48Spatrick /// Size of the pre-allocated local frame block. 31309467b48Spatrick int64_t LocalFrameSize = 0; 31409467b48Spatrick 31509467b48Spatrick /// Required alignment of the local object blob, which is the strictest 31609467b48Spatrick /// alignment of any object in it. 31709467b48Spatrick Align LocalFrameMaxAlign; 31809467b48Spatrick 31909467b48Spatrick /// Whether the local object blob needs to be allocated together. If not, 32009467b48Spatrick /// PEI should ignore the isPreAllocated flags on the stack objects and 32109467b48Spatrick /// just allocate them normally. 32209467b48Spatrick bool UseLocalStackAllocationBlock = false; 32309467b48Spatrick 32409467b48Spatrick /// True if the function dynamically adjusts the stack pointer through some 32509467b48Spatrick /// opaque mechanism like inline assembly or Win32 EH. 32609467b48Spatrick bool HasOpaqueSPAdjustment = false; 32709467b48Spatrick 32809467b48Spatrick /// True if the function contains operations which will lower down to 32909467b48Spatrick /// instructions which manipulate the stack pointer. 33009467b48Spatrick bool HasCopyImplyingStackAdjustment = false; 33109467b48Spatrick 33209467b48Spatrick /// True if the function contains a call to the llvm.vastart intrinsic. 33309467b48Spatrick bool HasVAStart = false; 33409467b48Spatrick 33509467b48Spatrick /// True if this is a varargs function that contains a musttail call. 33609467b48Spatrick bool HasMustTailInVarArgFunc = false; 33709467b48Spatrick 33809467b48Spatrick /// True if this function contains a tail call. If so immutable objects like 33909467b48Spatrick /// function arguments are no longer so. A tail call *can* override fixed 34009467b48Spatrick /// stack objects like arguments so we can't treat them as immutable. 34109467b48Spatrick bool HasTailCall = false; 34209467b48Spatrick 34309467b48Spatrick /// Not null, if shrink-wrapping found a better place for the prologue. 34409467b48Spatrick MachineBasicBlock *Save = nullptr; 34509467b48Spatrick /// Not null, if shrink-wrapping found a better place for the epilogue. 34609467b48Spatrick MachineBasicBlock *Restore = nullptr; 34709467b48Spatrick 34809467b48Spatrick public: 34909467b48Spatrick explicit MachineFrameInfo(unsigned StackAlignment, bool StackRealignable, 35009467b48Spatrick bool ForcedRealign) 35109467b48Spatrick : StackAlignment(assumeAligned(StackAlignment)), 35209467b48Spatrick StackRealignable(StackRealignable), ForcedRealign(ForcedRealign) {} 35309467b48Spatrick 35409467b48Spatrick /// Return true if there are any stack objects in this function. 35509467b48Spatrick bool hasStackObjects() const { return !Objects.empty(); } 35609467b48Spatrick 35709467b48Spatrick /// This method may be called any time after instruction 35809467b48Spatrick /// selection is complete to determine if the stack frame for this function 35909467b48Spatrick /// contains any variable sized objects. 36009467b48Spatrick bool hasVarSizedObjects() const { return HasVarSizedObjects; } 36109467b48Spatrick 36209467b48Spatrick /// Return the index for the stack protector object. 36309467b48Spatrick int getStackProtectorIndex() const { return StackProtectorIdx; } 36409467b48Spatrick void setStackProtectorIndex(int I) { StackProtectorIdx = I; } 36509467b48Spatrick bool hasStackProtectorIndex() const { return StackProtectorIdx != -1; } 36609467b48Spatrick 367adae0cfdSpatrick /// Get / Set return protector calculation register 368adae0cfdSpatrick unsigned getReturnProtectorRegister() const { return RPI.Register; } 369adae0cfdSpatrick void setReturnProtectorRegister(unsigned I) { RPI.Register = I; } 370adae0cfdSpatrick bool hasReturnProtectorRegister() const { return RPI.Register != 0; } 371adae0cfdSpatrick /// Get / Set if this frame needs a return protector 372adae0cfdSpatrick void setReturnProtectorNeeded(bool I) { RPI.Needed = I; } 373adae0cfdSpatrick bool getReturnProtectorNeeded() const { return RPI.Needed; } 374adae0cfdSpatrick /// Get / Set if the return protector cookie needs to be stored in frame 375adae0cfdSpatrick void setReturnProtectorNeedsStore(bool I) { RPI.NeedsStore = I; } 376adae0cfdSpatrick bool getReturnProtectorNeedsStore() const { return RPI.NeedsStore; } 377adae0cfdSpatrick 37809467b48Spatrick /// Return the index for the function context object. 37909467b48Spatrick /// This object is used for SjLj exceptions. 38009467b48Spatrick int getFunctionContextIndex() const { return FunctionContextIdx; } 38109467b48Spatrick void setFunctionContextIndex(int I) { FunctionContextIdx = I; } 38209467b48Spatrick 38309467b48Spatrick /// This method may be called any time after instruction 38409467b48Spatrick /// selection is complete to determine if there is a call to 38509467b48Spatrick /// \@llvm.frameaddress in this function. 38609467b48Spatrick bool isFrameAddressTaken() const { return FrameAddressTaken; } 38709467b48Spatrick void setFrameAddressIsTaken(bool T) { FrameAddressTaken = T; } 38809467b48Spatrick 38909467b48Spatrick /// This method may be called any time after 39009467b48Spatrick /// instruction selection is complete to determine if there is a call to 39109467b48Spatrick /// \@llvm.returnaddress in this function. 39209467b48Spatrick bool isReturnAddressTaken() const { return ReturnAddressTaken; } 39309467b48Spatrick void setReturnAddressIsTaken(bool s) { ReturnAddressTaken = s; } 39409467b48Spatrick 39509467b48Spatrick /// This method may be called any time after instruction 39609467b48Spatrick /// selection is complete to determine if there is a call to builtin 39709467b48Spatrick /// \@llvm.experimental.stackmap. 39809467b48Spatrick bool hasStackMap() const { return HasStackMap; } 39909467b48Spatrick void setHasStackMap(bool s = true) { HasStackMap = s; } 40009467b48Spatrick 40109467b48Spatrick /// This method may be called any time after instruction 40209467b48Spatrick /// selection is complete to determine if there is a call to builtin 40309467b48Spatrick /// \@llvm.experimental.patchpoint. 40409467b48Spatrick bool hasPatchPoint() const { return HasPatchPoint; } 40509467b48Spatrick void setHasPatchPoint(bool s = true) { HasPatchPoint = s; } 40609467b48Spatrick 40709467b48Spatrick /// Return the minimum frame object index. 40809467b48Spatrick int getObjectIndexBegin() const { return -NumFixedObjects; } 40909467b48Spatrick 41009467b48Spatrick /// Return one past the maximum frame object index. 41109467b48Spatrick int getObjectIndexEnd() const { return (int)Objects.size()-NumFixedObjects; } 41209467b48Spatrick 41309467b48Spatrick /// Return the number of fixed objects. 41409467b48Spatrick unsigned getNumFixedObjects() const { return NumFixedObjects; } 41509467b48Spatrick 41609467b48Spatrick /// Return the number of objects. 41709467b48Spatrick unsigned getNumObjects() const { return Objects.size(); } 41809467b48Spatrick 41909467b48Spatrick /// Map a frame index into the local object block 42009467b48Spatrick void mapLocalFrameObject(int ObjectIndex, int64_t Offset) { 42109467b48Spatrick LocalFrameObjects.push_back(std::pair<int, int64_t>(ObjectIndex, Offset)); 42209467b48Spatrick Objects[ObjectIndex + NumFixedObjects].PreAllocated = true; 42309467b48Spatrick } 42409467b48Spatrick 42509467b48Spatrick /// Get the local offset mapping for a for an object. 42609467b48Spatrick std::pair<int, int64_t> getLocalFrameObjectMap(int i) const { 42709467b48Spatrick assert (i >= 0 && (unsigned)i < LocalFrameObjects.size() && 42809467b48Spatrick "Invalid local object reference!"); 42909467b48Spatrick return LocalFrameObjects[i]; 43009467b48Spatrick } 43109467b48Spatrick 43209467b48Spatrick /// Return the number of objects allocated into the local object block. 43309467b48Spatrick int64_t getLocalFrameObjectCount() const { return LocalFrameObjects.size(); } 43409467b48Spatrick 43509467b48Spatrick /// Set the size of the local object blob. 43609467b48Spatrick void setLocalFrameSize(int64_t sz) { LocalFrameSize = sz; } 43709467b48Spatrick 43809467b48Spatrick /// Get the size of the local object blob. 43909467b48Spatrick int64_t getLocalFrameSize() const { return LocalFrameSize; } 44009467b48Spatrick 44109467b48Spatrick /// Required alignment of the local object blob, 44209467b48Spatrick /// which is the strictest alignment of any object in it. 44309467b48Spatrick void setLocalFrameMaxAlign(Align Alignment) { 44409467b48Spatrick LocalFrameMaxAlign = Alignment; 44509467b48Spatrick } 44609467b48Spatrick 44709467b48Spatrick /// Return the required alignment of the local object blob. 44809467b48Spatrick Align getLocalFrameMaxAlign() const { return LocalFrameMaxAlign; } 44909467b48Spatrick 45009467b48Spatrick /// Get whether the local allocation blob should be allocated together or 45109467b48Spatrick /// let PEI allocate the locals in it directly. 45209467b48Spatrick bool getUseLocalStackAllocationBlock() const { 45309467b48Spatrick return UseLocalStackAllocationBlock; 45409467b48Spatrick } 45509467b48Spatrick 45609467b48Spatrick /// setUseLocalStackAllocationBlock - Set whether the local allocation blob 45709467b48Spatrick /// should be allocated together or let PEI allocate the locals in it 45809467b48Spatrick /// directly. 45909467b48Spatrick void setUseLocalStackAllocationBlock(bool v) { 46009467b48Spatrick UseLocalStackAllocationBlock = v; 46109467b48Spatrick } 46209467b48Spatrick 46309467b48Spatrick /// Return true if the object was pre-allocated into the local block. 46409467b48Spatrick bool isObjectPreAllocated(int ObjectIdx) const { 46509467b48Spatrick assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() && 46609467b48Spatrick "Invalid Object Idx!"); 46709467b48Spatrick return Objects[ObjectIdx+NumFixedObjects].PreAllocated; 46809467b48Spatrick } 46909467b48Spatrick 47009467b48Spatrick /// Return the size of the specified object. 47109467b48Spatrick int64_t getObjectSize(int ObjectIdx) const { 47209467b48Spatrick assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() && 47309467b48Spatrick "Invalid Object Idx!"); 47409467b48Spatrick return Objects[ObjectIdx+NumFixedObjects].Size; 47509467b48Spatrick } 47609467b48Spatrick 47709467b48Spatrick /// Change the size of the specified stack object. 47809467b48Spatrick void setObjectSize(int ObjectIdx, int64_t Size) { 47909467b48Spatrick assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() && 48009467b48Spatrick "Invalid Object Idx!"); 48109467b48Spatrick Objects[ObjectIdx+NumFixedObjects].Size = Size; 48209467b48Spatrick } 48309467b48Spatrick 48409467b48Spatrick /// Return the alignment of the specified stack object. 485097a140dSpatrick Align getObjectAlign(int ObjectIdx) const { 48609467b48Spatrick assert(unsigned(ObjectIdx + NumFixedObjects) < Objects.size() && 48709467b48Spatrick "Invalid Object Idx!"); 488097a140dSpatrick return Objects[ObjectIdx + NumFixedObjects].Alignment; 48909467b48Spatrick } 49009467b48Spatrick 49109467b48Spatrick /// setObjectAlignment - Change the alignment of the specified stack object. 492097a140dSpatrick void setObjectAlignment(int ObjectIdx, Align Alignment) { 49309467b48Spatrick assert(unsigned(ObjectIdx + NumFixedObjects) < Objects.size() && 49409467b48Spatrick "Invalid Object Idx!"); 495097a140dSpatrick Objects[ObjectIdx + NumFixedObjects].Alignment = Alignment; 49609467b48Spatrick 49709467b48Spatrick // Only ensure max alignment for the default stack. 49809467b48Spatrick if (getStackID(ObjectIdx) == 0) 499097a140dSpatrick ensureMaxAlignment(Alignment); 500097a140dSpatrick } 501097a140dSpatrick 50209467b48Spatrick /// Return the underlying Alloca of the specified 50309467b48Spatrick /// stack object if it exists. Returns 0 if none exists. 50409467b48Spatrick const AllocaInst* getObjectAllocation(int ObjectIdx) const { 50509467b48Spatrick assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() && 50609467b48Spatrick "Invalid Object Idx!"); 50709467b48Spatrick return Objects[ObjectIdx+NumFixedObjects].Alloca; 50809467b48Spatrick } 50909467b48Spatrick 51009467b48Spatrick /// Return the assigned stack offset of the specified object 51109467b48Spatrick /// from the incoming stack pointer. 51209467b48Spatrick int64_t getObjectOffset(int ObjectIdx) const { 51309467b48Spatrick assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() && 51409467b48Spatrick "Invalid Object Idx!"); 51509467b48Spatrick assert(!isDeadObjectIndex(ObjectIdx) && 51609467b48Spatrick "Getting frame offset for a dead object?"); 51709467b48Spatrick return Objects[ObjectIdx+NumFixedObjects].SPOffset; 51809467b48Spatrick } 51909467b48Spatrick 52009467b48Spatrick bool isObjectZExt(int ObjectIdx) const { 52109467b48Spatrick assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() && 52209467b48Spatrick "Invalid Object Idx!"); 52309467b48Spatrick return Objects[ObjectIdx+NumFixedObjects].isZExt; 52409467b48Spatrick } 52509467b48Spatrick 52609467b48Spatrick void setObjectZExt(int ObjectIdx, bool IsZExt) { 52709467b48Spatrick assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() && 52809467b48Spatrick "Invalid Object Idx!"); 52909467b48Spatrick Objects[ObjectIdx+NumFixedObjects].isZExt = IsZExt; 53009467b48Spatrick } 53109467b48Spatrick 53209467b48Spatrick bool isObjectSExt(int ObjectIdx) const { 53309467b48Spatrick assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() && 53409467b48Spatrick "Invalid Object Idx!"); 53509467b48Spatrick return Objects[ObjectIdx+NumFixedObjects].isSExt; 53609467b48Spatrick } 53709467b48Spatrick 53809467b48Spatrick void setObjectSExt(int ObjectIdx, bool IsSExt) { 53909467b48Spatrick assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() && 54009467b48Spatrick "Invalid Object Idx!"); 54109467b48Spatrick Objects[ObjectIdx+NumFixedObjects].isSExt = IsSExt; 54209467b48Spatrick } 54309467b48Spatrick 54409467b48Spatrick /// Set the stack frame offset of the specified object. The 54509467b48Spatrick /// offset is relative to the stack pointer on entry to the function. 54609467b48Spatrick void setObjectOffset(int ObjectIdx, int64_t SPOffset) { 54709467b48Spatrick assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() && 54809467b48Spatrick "Invalid Object Idx!"); 54909467b48Spatrick assert(!isDeadObjectIndex(ObjectIdx) && 55009467b48Spatrick "Setting frame offset for a dead object?"); 55109467b48Spatrick Objects[ObjectIdx+NumFixedObjects].SPOffset = SPOffset; 55209467b48Spatrick } 55309467b48Spatrick 55409467b48Spatrick SSPLayoutKind getObjectSSPLayout(int ObjectIdx) const { 55509467b48Spatrick assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() && 55609467b48Spatrick "Invalid Object Idx!"); 55709467b48Spatrick return (SSPLayoutKind)Objects[ObjectIdx+NumFixedObjects].SSPLayout; 55809467b48Spatrick } 55909467b48Spatrick 56009467b48Spatrick void setObjectSSPLayout(int ObjectIdx, SSPLayoutKind Kind) { 56109467b48Spatrick assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() && 56209467b48Spatrick "Invalid Object Idx!"); 56309467b48Spatrick assert(!isDeadObjectIndex(ObjectIdx) && 56409467b48Spatrick "Setting SSP layout for a dead object?"); 56509467b48Spatrick Objects[ObjectIdx+NumFixedObjects].SSPLayout = Kind; 56609467b48Spatrick } 56709467b48Spatrick 56809467b48Spatrick /// Return the number of bytes that must be allocated to hold 56909467b48Spatrick /// all of the fixed size frame objects. This is only valid after 57009467b48Spatrick /// Prolog/Epilog code insertion has finalized the stack frame layout. 57109467b48Spatrick uint64_t getStackSize() const { return StackSize; } 57209467b48Spatrick 57309467b48Spatrick /// Set the size of the stack. 57409467b48Spatrick void setStackSize(uint64_t Size) { StackSize = Size; } 57509467b48Spatrick 57609467b48Spatrick /// Estimate and return the size of the stack frame. 57709467b48Spatrick uint64_t estimateStackSize(const MachineFunction &MF) const; 57809467b48Spatrick 57909467b48Spatrick /// Return the correction for frame offsets. 58009467b48Spatrick int getOffsetAdjustment() const { return OffsetAdjustment; } 58109467b48Spatrick 58209467b48Spatrick /// Set the correction for frame offsets. 58309467b48Spatrick void setOffsetAdjustment(int Adj) { OffsetAdjustment = Adj; } 58409467b48Spatrick 58509467b48Spatrick /// Return the alignment in bytes that this function must be aligned to, 58609467b48Spatrick /// which is greater than the default stack alignment provided by the target. 587097a140dSpatrick Align getMaxAlign() const { return MaxAlignment; } 58809467b48Spatrick 58909467b48Spatrick /// Make sure the function is at least Align bytes aligned. 59009467b48Spatrick void ensureMaxAlignment(Align Alignment); 591097a140dSpatrick 59209467b48Spatrick /// Return true if this function adjusts the stack -- e.g., 59309467b48Spatrick /// when calling another function. This is only valid during and after 59409467b48Spatrick /// prolog/epilog code insertion. 59509467b48Spatrick bool adjustsStack() const { return AdjustsStack; } 59609467b48Spatrick void setAdjustsStack(bool V) { AdjustsStack = V; } 59709467b48Spatrick 59809467b48Spatrick /// Return true if the current function has any function calls. 59909467b48Spatrick bool hasCalls() const { return HasCalls; } 60009467b48Spatrick void setHasCalls(bool V) { HasCalls = V; } 60109467b48Spatrick 60209467b48Spatrick /// Returns true if the function contains opaque dynamic stack adjustments. 60309467b48Spatrick bool hasOpaqueSPAdjustment() const { return HasOpaqueSPAdjustment; } 60409467b48Spatrick void setHasOpaqueSPAdjustment(bool B) { HasOpaqueSPAdjustment = B; } 60509467b48Spatrick 60609467b48Spatrick /// Returns true if the function contains operations which will lower down to 60709467b48Spatrick /// instructions which manipulate the stack pointer. 60809467b48Spatrick bool hasCopyImplyingStackAdjustment() const { 60909467b48Spatrick return HasCopyImplyingStackAdjustment; 61009467b48Spatrick } 61109467b48Spatrick void setHasCopyImplyingStackAdjustment(bool B) { 61209467b48Spatrick HasCopyImplyingStackAdjustment = B; 61309467b48Spatrick } 61409467b48Spatrick 61509467b48Spatrick /// Returns true if the function calls the llvm.va_start intrinsic. 61609467b48Spatrick bool hasVAStart() const { return HasVAStart; } 61709467b48Spatrick void setHasVAStart(bool B) { HasVAStart = B; } 61809467b48Spatrick 61909467b48Spatrick /// Returns true if the function is variadic and contains a musttail call. 62009467b48Spatrick bool hasMustTailInVarArgFunc() const { return HasMustTailInVarArgFunc; } 62109467b48Spatrick void setHasMustTailInVarArgFunc(bool B) { HasMustTailInVarArgFunc = B; } 62209467b48Spatrick 62309467b48Spatrick /// Returns true if the function contains a tail call. 62409467b48Spatrick bool hasTailCall() const { return HasTailCall; } 625*a0747c9fSpatrick void setHasTailCall(bool V = true) { HasTailCall = V; } 62609467b48Spatrick 62709467b48Spatrick /// Computes the maximum size of a callframe and the AdjustsStack property. 62809467b48Spatrick /// This only works for targets defining 62909467b48Spatrick /// TargetInstrInfo::getCallFrameSetupOpcode(), getCallFrameDestroyOpcode(), 63009467b48Spatrick /// and getFrameSize(). 63109467b48Spatrick /// This is usually computed by the prologue epilogue inserter but some 63209467b48Spatrick /// targets may call this to compute it earlier. 63309467b48Spatrick void computeMaxCallFrameSize(const MachineFunction &MF); 63409467b48Spatrick 63509467b48Spatrick /// Return the maximum size of a call frame that must be 63609467b48Spatrick /// allocated for an outgoing function call. This is only available if 63709467b48Spatrick /// CallFrameSetup/Destroy pseudo instructions are used by the target, and 63809467b48Spatrick /// then only during or after prolog/epilog code insertion. 63909467b48Spatrick /// 64009467b48Spatrick unsigned getMaxCallFrameSize() const { 64109467b48Spatrick // TODO: Enable this assert when targets are fixed. 64209467b48Spatrick //assert(isMaxCallFrameSizeComputed() && "MaxCallFrameSize not computed yet"); 64309467b48Spatrick if (!isMaxCallFrameSizeComputed()) 64409467b48Spatrick return 0; 64509467b48Spatrick return MaxCallFrameSize; 64609467b48Spatrick } 64709467b48Spatrick bool isMaxCallFrameSizeComputed() const { 64809467b48Spatrick return MaxCallFrameSize != ~0u; 64909467b48Spatrick } 65009467b48Spatrick void setMaxCallFrameSize(unsigned S) { MaxCallFrameSize = S; } 65109467b48Spatrick 65209467b48Spatrick /// Returns how many bytes of callee-saved registers the target pushed in the 65309467b48Spatrick /// prologue. Only used for debug info. 65409467b48Spatrick unsigned getCVBytesOfCalleeSavedRegisters() const { 65509467b48Spatrick return CVBytesOfCalleeSavedRegisters; 65609467b48Spatrick } 65709467b48Spatrick void setCVBytesOfCalleeSavedRegisters(unsigned S) { 65809467b48Spatrick CVBytesOfCalleeSavedRegisters = S; 65909467b48Spatrick } 66009467b48Spatrick 66109467b48Spatrick /// Create a new object at a fixed location on the stack. 66209467b48Spatrick /// All fixed objects should be created before other objects are created for 66309467b48Spatrick /// efficiency. By default, fixed objects are not pointed to by LLVM IR 66409467b48Spatrick /// values. This returns an index with a negative value. 66509467b48Spatrick int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, 66609467b48Spatrick bool isAliased = false); 66709467b48Spatrick 66809467b48Spatrick /// Create a spill slot at a fixed location on the stack. 66909467b48Spatrick /// Returns an index with a negative value. 67009467b48Spatrick int CreateFixedSpillStackObject(uint64_t Size, int64_t SPOffset, 67109467b48Spatrick bool IsImmutable = false); 67209467b48Spatrick 67309467b48Spatrick /// Returns true if the specified index corresponds to a fixed stack object. 67409467b48Spatrick bool isFixedObjectIndex(int ObjectIdx) const { 67509467b48Spatrick return ObjectIdx < 0 && (ObjectIdx >= -(int)NumFixedObjects); 67609467b48Spatrick } 67709467b48Spatrick 67809467b48Spatrick /// Returns true if the specified index corresponds 67909467b48Spatrick /// to an object that might be pointed to by an LLVM IR value. 68009467b48Spatrick bool isAliasedObjectIndex(int ObjectIdx) const { 68109467b48Spatrick assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() && 68209467b48Spatrick "Invalid Object Idx!"); 68309467b48Spatrick return Objects[ObjectIdx+NumFixedObjects].isAliased; 68409467b48Spatrick } 68509467b48Spatrick 68609467b48Spatrick /// Returns true if the specified index corresponds to an immutable object. 68709467b48Spatrick bool isImmutableObjectIndex(int ObjectIdx) const { 68809467b48Spatrick // Tail calling functions can clobber their function arguments. 68909467b48Spatrick if (HasTailCall) 69009467b48Spatrick return false; 69109467b48Spatrick assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() && 69209467b48Spatrick "Invalid Object Idx!"); 69309467b48Spatrick return Objects[ObjectIdx+NumFixedObjects].isImmutable; 69409467b48Spatrick } 69509467b48Spatrick 69609467b48Spatrick /// Marks the immutability of an object. 69709467b48Spatrick void setIsImmutableObjectIndex(int ObjectIdx, bool IsImmutable) { 69809467b48Spatrick assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() && 69909467b48Spatrick "Invalid Object Idx!"); 70009467b48Spatrick Objects[ObjectIdx+NumFixedObjects].isImmutable = IsImmutable; 70109467b48Spatrick } 70209467b48Spatrick 70309467b48Spatrick /// Returns true if the specified index corresponds to a spill slot. 70409467b48Spatrick bool isSpillSlotObjectIndex(int ObjectIdx) const { 70509467b48Spatrick assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() && 70609467b48Spatrick "Invalid Object Idx!"); 70709467b48Spatrick return Objects[ObjectIdx+NumFixedObjects].isSpillSlot; 70809467b48Spatrick } 70909467b48Spatrick 71009467b48Spatrick bool isStatepointSpillSlotObjectIndex(int ObjectIdx) const { 71109467b48Spatrick assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() && 71209467b48Spatrick "Invalid Object Idx!"); 71309467b48Spatrick return Objects[ObjectIdx+NumFixedObjects].isStatepointSpillSlot; 71409467b48Spatrick } 71509467b48Spatrick 71609467b48Spatrick /// \see StackID 71709467b48Spatrick uint8_t getStackID(int ObjectIdx) const { 71809467b48Spatrick return Objects[ObjectIdx+NumFixedObjects].StackID; 71909467b48Spatrick } 72009467b48Spatrick 72109467b48Spatrick /// \see StackID 72209467b48Spatrick void setStackID(int ObjectIdx, uint8_t ID) { 72309467b48Spatrick assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() && 72409467b48Spatrick "Invalid Object Idx!"); 72509467b48Spatrick Objects[ObjectIdx+NumFixedObjects].StackID = ID; 72609467b48Spatrick // If ID > 0, MaxAlignment may now be overly conservative. 72709467b48Spatrick // If ID == 0, MaxAlignment will need to be updated separately. 72809467b48Spatrick } 72909467b48Spatrick 73009467b48Spatrick /// Returns true if the specified index corresponds to a dead object. 73109467b48Spatrick bool isDeadObjectIndex(int ObjectIdx) const { 73209467b48Spatrick assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() && 73309467b48Spatrick "Invalid Object Idx!"); 73409467b48Spatrick return Objects[ObjectIdx+NumFixedObjects].Size == ~0ULL; 73509467b48Spatrick } 73609467b48Spatrick 73709467b48Spatrick /// Returns true if the specified index corresponds to a variable sized 73809467b48Spatrick /// object. 73909467b48Spatrick bool isVariableSizedObjectIndex(int ObjectIdx) const { 74009467b48Spatrick assert(unsigned(ObjectIdx + NumFixedObjects) < Objects.size() && 74109467b48Spatrick "Invalid Object Idx!"); 74209467b48Spatrick return Objects[ObjectIdx + NumFixedObjects].Size == 0; 74309467b48Spatrick } 74409467b48Spatrick 74509467b48Spatrick void markAsStatepointSpillSlotObjectIndex(int ObjectIdx) { 74609467b48Spatrick assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() && 74709467b48Spatrick "Invalid Object Idx!"); 74809467b48Spatrick Objects[ObjectIdx+NumFixedObjects].isStatepointSpillSlot = true; 74909467b48Spatrick assert(isStatepointSpillSlotObjectIndex(ObjectIdx) && "inconsistent"); 75009467b48Spatrick } 75109467b48Spatrick 75209467b48Spatrick /// Create a new statically sized stack object, returning 75309467b48Spatrick /// a nonnegative identifier to represent it. 75409467b48Spatrick int CreateStackObject(uint64_t Size, Align Alignment, bool isSpillSlot, 75509467b48Spatrick const AllocaInst *Alloca = nullptr, uint8_t ID = 0); 75609467b48Spatrick 75709467b48Spatrick /// Create a new statically sized stack object that represents a spill slot, 75809467b48Spatrick /// returning a nonnegative identifier to represent it. 75909467b48Spatrick int CreateSpillStackObject(uint64_t Size, Align Alignment); 76009467b48Spatrick 76109467b48Spatrick /// Remove or mark dead a statically sized stack object. 76209467b48Spatrick void RemoveStackObject(int ObjectIdx) { 76309467b48Spatrick // Mark it dead. 76409467b48Spatrick Objects[ObjectIdx+NumFixedObjects].Size = ~0ULL; 76509467b48Spatrick } 76609467b48Spatrick 76709467b48Spatrick /// Notify the MachineFrameInfo object that a variable sized object has been 76809467b48Spatrick /// created. This must be created whenever a variable sized object is 76909467b48Spatrick /// created, whether or not the index returned is actually used. 77009467b48Spatrick int CreateVariableSizedObject(Align Alignment, const AllocaInst *Alloca); 77109467b48Spatrick 77209467b48Spatrick /// Returns a reference to call saved info vector for the current function. 77309467b48Spatrick const std::vector<CalleeSavedInfo> &getCalleeSavedInfo() const { 77409467b48Spatrick return CSInfo; 77509467b48Spatrick } 77609467b48Spatrick /// \copydoc getCalleeSavedInfo() 77709467b48Spatrick std::vector<CalleeSavedInfo> &getCalleeSavedInfo() { return CSInfo; } 77809467b48Spatrick 77909467b48Spatrick /// Used by prolog/epilog inserter to set the function's callee saved 78009467b48Spatrick /// information. 781097a140dSpatrick void setCalleeSavedInfo(std::vector<CalleeSavedInfo> CSI) { 782097a140dSpatrick CSInfo = std::move(CSI); 78309467b48Spatrick } 78409467b48Spatrick 78509467b48Spatrick /// Has the callee saved info been calculated yet? 78609467b48Spatrick bool isCalleeSavedInfoValid() const { return CSIValid; } 78709467b48Spatrick 78809467b48Spatrick void setCalleeSavedInfoValid(bool v) { CSIValid = v; } 78909467b48Spatrick 79009467b48Spatrick MachineBasicBlock *getSavePoint() const { return Save; } 79109467b48Spatrick void setSavePoint(MachineBasicBlock *NewSave) { Save = NewSave; } 79209467b48Spatrick MachineBasicBlock *getRestorePoint() const { return Restore; } 79309467b48Spatrick void setRestorePoint(MachineBasicBlock *NewRestore) { Restore = NewRestore; } 79409467b48Spatrick 79509467b48Spatrick /// Return a set of physical registers that are pristine. 79609467b48Spatrick /// 79709467b48Spatrick /// Pristine registers hold a value that is useless to the current function, 79809467b48Spatrick /// but that must be preserved - they are callee saved registers that are not 79909467b48Spatrick /// saved. 80009467b48Spatrick /// 80109467b48Spatrick /// Before the PrologueEpilogueInserter has placed the CSR spill code, this 80209467b48Spatrick /// method always returns an empty set. 80309467b48Spatrick BitVector getPristineRegs(const MachineFunction &MF) const; 80409467b48Spatrick 80509467b48Spatrick /// Used by the MachineFunction printer to print information about 80609467b48Spatrick /// stack objects. Implemented in MachineFunction.cpp. 80709467b48Spatrick void print(const MachineFunction &MF, raw_ostream &OS) const; 80809467b48Spatrick 80909467b48Spatrick /// dump - Print the function to stderr. 81009467b48Spatrick void dump(const MachineFunction &MF) const; 81109467b48Spatrick }; 81209467b48Spatrick 81309467b48Spatrick } // End llvm namespace 81409467b48Spatrick 81509467b48Spatrick #endif 816