xref: /openbsd-src/gnu/llvm/llvm/include/llvm/CodeGen/MachineFrameInfo.h (revision a0747c9f67a4ae71ccb71e62a28d1ea19e06a63c)
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