1193323Sed//===-- CodeGen/MachineFrameInfo.h - Abstract Stack Frame Rep. --*- C++ -*-===//
2193323Sed//
3193323Sed//                     The LLVM Compiler Infrastructure
4193323Sed//
5193323Sed// This file is distributed under the University of Illinois Open Source
6193323Sed// License. See LICENSE.TXT for details.
7193323Sed//
8193323Sed//===----------------------------------------------------------------------===//
9193323Sed//
10193323Sed// The file defines the MachineFrameInfo class.
11193323Sed//
12193323Sed//===----------------------------------------------------------------------===//
13193323Sed
14193323Sed#ifndef LLVM_CODEGEN_MACHINEFRAMEINFO_H
15193323Sed#define LLVM_CODEGEN_MACHINEFRAMEINFO_H
16193323Sed
17199481Srdivacky#include "llvm/ADT/SmallVector.h"
18218893Sdim#include "llvm/Support/DataTypes.h"
19193323Sed#include <cassert>
20193323Sed#include <vector>
21193323Sed
22193323Sednamespace llvm {
23198090Srdivackyclass raw_ostream;
24245431Sdimclass DataLayout;
25193323Sedclass TargetRegisterClass;
26193323Sedclass Type;
27193323Sedclass MachineFunction;
28198090Srdivackyclass MachineBasicBlock;
29218893Sdimclass TargetFrameLowering;
30263509Sdimclass TargetMachine;
31206274Srdivackyclass BitVector;
32245431Sdimclass Value;
33245431Sdimclass AllocaInst;
34193323Sed
35193323Sed/// The CalleeSavedInfo class tracks the information need to locate where a
36212904Sdim/// callee saved register is in the current frame.
37193323Sedclass CalleeSavedInfo {
38193323Sed  unsigned Reg;
39193323Sed  int FrameIdx;
40212904Sdim
41193323Sedpublic:
42210299Sed  explicit CalleeSavedInfo(unsigned R, int FI = 0)
43210299Sed  : Reg(R), FrameIdx(FI) {}
44212904Sdim
45193323Sed  // Accessors.
46193323Sed  unsigned getReg()                        const { return Reg; }
47193323Sed  int getFrameIdx()                        const { return FrameIdx; }
48193323Sed  void setFrameIdx(int FI)                       { FrameIdx = FI; }
49193323Sed};
50193323Sed
51193323Sed/// The MachineFrameInfo class represents an abstract stack frame until
52193323Sed/// prolog/epilog code is inserted.  This class is key to allowing stack frame
53193323Sed/// representation optimizations, such as frame pointer elimination.  It also
54193323Sed/// allows more mundane (but still important) optimizations, such as reordering
55193323Sed/// of abstract objects on the stack frame.
56193323Sed///
57193323Sed/// To support this, the class assigns unique integer identifiers to stack
58193323Sed/// objects requested clients.  These identifiers are negative integers for
59193323Sed/// fixed stack objects (such as arguments passed on the stack) or nonnegative
60193323Sed/// for objects that may be reordered.  Instructions which refer to stack
61193323Sed/// objects use a special MO_FrameIndex operand to represent these frame
62193323Sed/// indexes.
63193323Sed///
64193323Sed/// Because this class keeps track of all references to the stack frame, it
65193323Sed/// knows when a variable sized object is allocated on the stack.  This is the
66193323Sed/// sole condition which prevents frame pointer elimination, which is an
67193323Sed/// important optimization on register-poor architectures.  Because original
68193323Sed/// variable sized alloca's in the source program are the only source of
69193323Sed/// variable sized stack objects, it is safe to decide whether there will be
70193323Sed/// any variable sized objects before all stack objects are known (for
71193323Sed/// example, register allocator spill code never needs variable sized
72193323Sed/// objects).
73193323Sed///
74193323Sed/// When prolog/epilog code emission is performed, the final stack frame is
75193323Sed/// built and the machine instructions are modified to refer to the actual
76193323Sed/// stack offsets of the object, eliminating all MO_FrameIndex operands from
77193323Sed/// the program.
78193323Sed///
79193323Sed/// @brief Abstract Stack Frame Information
80193323Sedclass MachineFrameInfo {
81193323Sed
82193323Sed  // StackObject - Represent a single object allocated on the stack.
83193323Sed  struct StackObject {
84198396Srdivacky    // SPOffset - The offset of this object from the stack pointer on entry to
85198396Srdivacky    // the function.  This field has no meaning for a variable sized element.
86198396Srdivacky    int64_t SPOffset;
87212904Sdim
88193323Sed    // The size of this object on the stack. 0 means a variable sized object,
89193323Sed    // ~0ULL means a dead object.
90193323Sed    uint64_t Size;
91193323Sed
92193323Sed    // Alignment - The required alignment of this stack slot.
93193323Sed    unsigned Alignment;
94193323Sed
95193323Sed    // isImmutable - If true, the value of the stack object is set before
96193323Sed    // entering the function and is not modified inside the function. By
97193323Sed    // default, fixed objects are immutable unless marked otherwise.
98193323Sed    bool isImmutable;
99193323Sed
100212904Sdim    // isSpillSlot - If true the stack object is used as spill slot. It
101198396Srdivacky    // cannot alias any other memory objects.
102198396Srdivacky    bool isSpillSlot;
103198396Srdivacky
104212904Sdim    // MayNeedSP - If true the stack object triggered the creation of the stack
105212904Sdim    // protector. We should allocate this object right after the stack
106212904Sdim    // protector.
107212904Sdim    bool MayNeedSP;
108212904Sdim
109245431Sdim    /// Alloca - If this stack object is originated from an Alloca instruction
110245431Sdim    /// this value saves the original IR allocation. Can be NULL.
111245431Sdim    const AllocaInst *Alloca;
112245431Sdim
113212904Sdim    // PreAllocated - If true, the object was mapped into the local frame
114212904Sdim    // block and doesn't need additional handling for allocation beyond that.
115212904Sdim    bool PreAllocated;
116212904Sdim
117212904Sdim    StackObject(uint64_t Sz, unsigned Al, int64_t SP, bool IM,
118245431Sdim                bool isSS, bool NSP, const AllocaInst *Val)
119198396Srdivacky      : SPOffset(SP), Size(Sz), Alignment(Al), isImmutable(IM),
120245431Sdim        isSpillSlot(isSS), MayNeedSP(NSP), Alloca(Val), PreAllocated(false) {}
121193323Sed  };
122193323Sed
123263509Sdim  const TargetMachine &TM;
124263509Sdim
125193323Sed  /// Objects - The list of stack objects allocated...
126193323Sed  ///
127193323Sed  std::vector<StackObject> Objects;
128193323Sed
129193323Sed  /// NumFixedObjects - This contains the number of fixed objects contained on
130193323Sed  /// the stack.  Because fixed objects are stored at a negative index in the
131193323Sed  /// Objects list, this is also the index to the 0th object in the list.
132193323Sed  ///
133193323Sed  unsigned NumFixedObjects;
134193323Sed
135193323Sed  /// HasVarSizedObjects - This boolean keeps track of whether any variable
136193323Sed  /// sized objects have been allocated yet.
137193323Sed  ///
138193323Sed  bool HasVarSizedObjects;
139193323Sed
140193323Sed  /// FrameAddressTaken - This boolean keeps track of whether there is a call
141193323Sed  /// to builtin \@llvm.frameaddress.
142193323Sed  bool FrameAddressTaken;
143193323Sed
144208599Srdivacky  /// ReturnAddressTaken - This boolean keeps track of whether there is a call
145208599Srdivacky  /// to builtin \@llvm.returnaddress.
146208599Srdivacky  bool ReturnAddressTaken;
147208599Srdivacky
148193323Sed  /// StackSize - The prolog/epilog code inserter calculates the final stack
149193323Sed  /// offsets for all of the fixed size objects, updating the Objects list
150193323Sed  /// above.  It then updates StackSize to contain the number of bytes that need
151193323Sed  /// to be allocated on entry to the function.
152193323Sed  ///
153193323Sed  uint64_t StackSize;
154212904Sdim
155193323Sed  /// OffsetAdjustment - The amount that a frame offset needs to be adjusted to
156198090Srdivacky  /// have the actual offset from the stack/frame pointer.  The exact usage of
157198090Srdivacky  /// this is target-dependent, but it is typically used to adjust between
158198090Srdivacky  /// SP-relative and FP-relative offsets.  E.G., if objects are accessed via
159198090Srdivacky  /// SP then OffsetAdjustment is zero; if FP is used, OffsetAdjustment is set
160198090Srdivacky  /// to the distance between the initial SP and the value in FP.  For many
161198090Srdivacky  /// targets, this value is only used when generating debug info (via
162198090Srdivacky  /// TargetRegisterInfo::getFrameIndexOffset); when generating code, the
163198090Srdivacky  /// corresponding adjustments are performed directly.
164193323Sed  int OffsetAdjustment;
165212904Sdim
166212904Sdim  /// MaxAlignment - The prolog/epilog code inserter may process objects
167193323Sed  /// that require greater alignment than the default alignment the target
168212904Sdim  /// provides. To handle this, MaxAlignment is set to the maximum alignment
169193323Sed  /// needed by the objects on the current frame.  If this is greater than the
170193323Sed  /// native alignment maintained by the compiler, dynamic alignment code will
171193323Sed  /// be needed.
172193323Sed  ///
173193323Sed  unsigned MaxAlignment;
174193323Sed
175208599Srdivacky  /// AdjustsStack - Set to true if this function adjusts the stack -- e.g.,
176208599Srdivacky  /// when calling another function. This is only valid during and after
177208599Srdivacky  /// prolog/epilog code insertion.
178208599Srdivacky  bool AdjustsStack;
179208599Srdivacky
180208599Srdivacky  /// HasCalls - Set to true if this function has any function calls.
181193323Sed  bool HasCalls;
182193323Sed
183193323Sed  /// StackProtectorIdx - The frame index for the stack protector.
184193323Sed  int StackProtectorIdx;
185193323Sed
186226890Sdim  /// FunctionContextIdx - The frame index for the function context. Used for
187226890Sdim  /// SjLj exceptions.
188226890Sdim  int FunctionContextIdx;
189226890Sdim
190193323Sed  /// MaxCallFrameSize - This contains the size of the largest call frame if the
191193323Sed  /// target uses frame setup/destroy pseudo instructions (as defined in the
192193323Sed  /// TargetFrameInfo class).  This information is important for frame pointer
193193323Sed  /// elimination.  If is only valid during and after prolog/epilog code
194193323Sed  /// insertion.
195193323Sed  ///
196193323Sed  unsigned MaxCallFrameSize;
197212904Sdim
198193323Sed  /// CSInfo - The prolog/epilog code inserter fills in this vector with each
199193323Sed  /// callee saved register saved in the frame.  Beyond its use by the prolog/
200193323Sed  /// epilog code inserter, this data used for debug info and exception
201193323Sed  /// handling.
202193323Sed  std::vector<CalleeSavedInfo> CSInfo;
203198090Srdivacky
204198090Srdivacky  /// CSIValid - Has CSInfo been set yet?
205198090Srdivacky  bool CSIValid;
206198090Srdivacky
207212904Sdim  /// LocalFrameObjects - References to frame indices which are mapped
208212904Sdim  /// into the local frame allocation block. <FrameIdx, LocalOffset>
209212904Sdim  SmallVector<std::pair<int, int64_t>, 32> LocalFrameObjects;
210212904Sdim
211212904Sdim  /// LocalFrameSize - Size of the pre-allocated local frame block.
212212904Sdim  int64_t LocalFrameSize;
213212904Sdim
214212904Sdim  /// Required alignment of the local object blob, which is the strictest
215212904Sdim  /// alignment of any object in it.
216212904Sdim  unsigned LocalFrameMaxAlign;
217212904Sdim
218212904Sdim  /// Whether the local object blob needs to be allocated together. If not,
219212904Sdim  /// PEI should ignore the isPreAllocated flags on the stack objects and
220212904Sdim  /// just allocate them normally.
221212904Sdim  bool UseLocalStackAllocationBlock;
222212904Sdim
223252723Sdim  /// Whether the "realign-stack" option is on.
224252723Sdim  bool RealignOption;
225263509Sdim
226263765Sdim  /// True if the function includes inline assembly that adjusts the stack
227263765Sdim  /// pointer.
228263765Sdim  bool HasInlineAsmWithSPAdjust;
229263765Sdim
230263509Sdim  const TargetFrameLowering *getFrameLowering() const;
231193323Sedpublic:
232263509Sdim    explicit MachineFrameInfo(const TargetMachine &TM, bool RealignOpt)
233263509Sdim    : TM(TM), RealignOption(RealignOpt) {
234193323Sed    StackSize = NumFixedObjects = OffsetAdjustment = MaxAlignment = 0;
235193323Sed    HasVarSizedObjects = false;
236193323Sed    FrameAddressTaken = false;
237208599Srdivacky    ReturnAddressTaken = false;
238208599Srdivacky    AdjustsStack = false;
239193323Sed    HasCalls = false;
240193323Sed    StackProtectorIdx = -1;
241226890Sdim    FunctionContextIdx = -1;
242193323Sed    MaxCallFrameSize = 0;
243198090Srdivacky    CSIValid = false;
244212904Sdim    LocalFrameSize = 0;
245212904Sdim    LocalFrameMaxAlign = 0;
246212904Sdim    UseLocalStackAllocationBlock = false;
247263765Sdim    HasInlineAsmWithSPAdjust = false;
248193323Sed  }
249193323Sed
250193323Sed  /// hasStackObjects - Return true if there are any stack objects in this
251193323Sed  /// function.
252193323Sed  ///
253193323Sed  bool hasStackObjects() const { return !Objects.empty(); }
254193323Sed
255193323Sed  /// hasVarSizedObjects - This method may be called any time after instruction
256193323Sed  /// selection is complete to determine if the stack frame for this function
257193323Sed  /// contains any variable sized objects.
258193323Sed  ///
259193323Sed  bool hasVarSizedObjects() const { return HasVarSizedObjects; }
260193323Sed
261193323Sed  /// getStackProtectorIndex/setStackProtectorIndex - Return the index for the
262193323Sed  /// stack protector object.
263193323Sed  ///
264193323Sed  int getStackProtectorIndex() const { return StackProtectorIdx; }
265193323Sed  void setStackProtectorIndex(int I) { StackProtectorIdx = I; }
266193323Sed
267226890Sdim  /// getFunctionContextIndex/setFunctionContextIndex - Return the index for the
268226890Sdim  /// function context object. This object is used for SjLj exceptions.
269226890Sdim  int getFunctionContextIndex() const { return FunctionContextIdx; }
270226890Sdim  void setFunctionContextIndex(int I) { FunctionContextIdx = I; }
271226890Sdim
272193323Sed  /// isFrameAddressTaken - This method may be called any time after instruction
273193323Sed  /// selection is complete to determine if there is a call to
274193323Sed  /// \@llvm.frameaddress in this function.
275193323Sed  bool isFrameAddressTaken() const { return FrameAddressTaken; }
276193323Sed  void setFrameAddressIsTaken(bool T) { FrameAddressTaken = T; }
277193323Sed
278212904Sdim  /// isReturnAddressTaken - This method may be called any time after
279212904Sdim  /// instruction selection is complete to determine if there is a call to
280208599Srdivacky  /// \@llvm.returnaddress in this function.
281208599Srdivacky  bool isReturnAddressTaken() const { return ReturnAddressTaken; }
282208599Srdivacky  void setReturnAddressIsTaken(bool s) { ReturnAddressTaken = s; }
283208599Srdivacky
284193323Sed  /// getObjectIndexBegin - Return the minimum frame object index.
285193323Sed  ///
286193323Sed  int getObjectIndexBegin() const { return -NumFixedObjects; }
287193323Sed
288193323Sed  /// getObjectIndexEnd - Return one past the maximum frame object index.
289193323Sed  ///
290193323Sed  int getObjectIndexEnd() const { return (int)Objects.size()-NumFixedObjects; }
291193323Sed
292212904Sdim  /// getNumFixedObjects - Return the number of fixed objects.
293193323Sed  unsigned getNumFixedObjects() const { return NumFixedObjects; }
294193323Sed
295212904Sdim  /// getNumObjects - Return the number of objects.
296193323Sed  ///
297193323Sed  unsigned getNumObjects() const { return Objects.size(); }
298193323Sed
299212904Sdim  /// mapLocalFrameObject - Map a frame index into the local object block
300212904Sdim  void mapLocalFrameObject(int ObjectIndex, int64_t Offset) {
301212904Sdim    LocalFrameObjects.push_back(std::pair<int, int64_t>(ObjectIndex, Offset));
302212904Sdim    Objects[ObjectIndex + NumFixedObjects].PreAllocated = true;
303212904Sdim  }
304212904Sdim
305212904Sdim  /// getLocalFrameObjectMap - Get the local offset mapping for a for an object
306212904Sdim  std::pair<int, int64_t> getLocalFrameObjectMap(int i) {
307212904Sdim    assert (i >= 0 && (unsigned)i < LocalFrameObjects.size() &&
308212904Sdim            "Invalid local object reference!");
309212904Sdim    return LocalFrameObjects[i];
310212904Sdim  }
311212904Sdim
312212904Sdim  /// getLocalFrameObjectCount - Return the number of objects allocated into
313212904Sdim  /// the local object block.
314212904Sdim  int64_t getLocalFrameObjectCount() { return LocalFrameObjects.size(); }
315212904Sdim
316212904Sdim  /// setLocalFrameSize - Set the size of the local object blob.
317212904Sdim  void setLocalFrameSize(int64_t sz) { LocalFrameSize = sz; }
318212904Sdim
319212904Sdim  /// getLocalFrameSize - Get the size of the local object blob.
320212904Sdim  int64_t getLocalFrameSize() const { return LocalFrameSize; }
321212904Sdim
322212904Sdim  /// setLocalFrameMaxAlign - Required alignment of the local object blob,
323212904Sdim  /// which is the strictest alignment of any object in it.
324212904Sdim  void setLocalFrameMaxAlign(unsigned Align) { LocalFrameMaxAlign = Align; }
325212904Sdim
326212904Sdim  /// getLocalFrameMaxAlign - Return the required alignment of the local
327212904Sdim  /// object blob.
328212904Sdim  unsigned getLocalFrameMaxAlign() const { return LocalFrameMaxAlign; }
329212904Sdim
330212904Sdim  /// getUseLocalStackAllocationBlock - Get whether the local allocation blob
331212904Sdim  /// should be allocated together or let PEI allocate the locals in it
332212904Sdim  /// directly.
333212904Sdim  bool getUseLocalStackAllocationBlock() {return UseLocalStackAllocationBlock;}
334212904Sdim
335212904Sdim  /// setUseLocalStackAllocationBlock - Set whether the local allocation blob
336212904Sdim  /// should be allocated together or let PEI allocate the locals in it
337212904Sdim  /// directly.
338212904Sdim  void setUseLocalStackAllocationBlock(bool v) {
339212904Sdim    UseLocalStackAllocationBlock = v;
340212904Sdim  }
341212904Sdim
342212904Sdim  /// isObjectPreAllocated - Return true if the object was pre-allocated into
343212904Sdim  /// the local block.
344212904Sdim  bool isObjectPreAllocated(int ObjectIdx) const {
345212904Sdim    assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
346212904Sdim           "Invalid Object Idx!");
347212904Sdim    return Objects[ObjectIdx+NumFixedObjects].PreAllocated;
348212904Sdim  }
349212904Sdim
350193323Sed  /// getObjectSize - Return the size of the specified object.
351193323Sed  ///
352193323Sed  int64_t getObjectSize(int ObjectIdx) const {
353193323Sed    assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
354193323Sed           "Invalid Object Idx!");
355193323Sed    return Objects[ObjectIdx+NumFixedObjects].Size;
356193323Sed  }
357193323Sed
358193323Sed  /// setObjectSize - Change the size of the specified stack object.
359193323Sed  void setObjectSize(int ObjectIdx, int64_t Size) {
360193323Sed    assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
361193323Sed           "Invalid Object Idx!");
362193323Sed    Objects[ObjectIdx+NumFixedObjects].Size = Size;
363193323Sed  }
364193323Sed
365193323Sed  /// getObjectAlignment - Return the alignment of the specified stack object.
366193323Sed  unsigned getObjectAlignment(int ObjectIdx) const {
367193323Sed    assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
368193323Sed           "Invalid Object Idx!");
369193323Sed    return Objects[ObjectIdx+NumFixedObjects].Alignment;
370193323Sed  }
371193323Sed
372193323Sed  /// setObjectAlignment - Change the alignment of the specified stack object.
373193323Sed  void setObjectAlignment(int ObjectIdx, unsigned Align) {
374193323Sed    assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
375193323Sed           "Invalid Object Idx!");
376193323Sed    Objects[ObjectIdx+NumFixedObjects].Alignment = Align;
377245431Sdim    ensureMaxAlignment(Align);
378193323Sed  }
379193323Sed
380245431Sdim  /// getObjectAllocation - Return the underlying Alloca of the specified
381245431Sdim  /// stack object if it exists. Returns 0 if none exists.
382245431Sdim  const AllocaInst* getObjectAllocation(int ObjectIdx) const {
383245431Sdim    assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
384245431Sdim           "Invalid Object Idx!");
385245431Sdim    return Objects[ObjectIdx+NumFixedObjects].Alloca;
386245431Sdim  }
387245431Sdim
388212904Sdim  /// NeedsStackProtector - Returns true if the object may need stack
389212904Sdim  /// protectors.
390212904Sdim  bool MayNeedStackProtector(int ObjectIdx) const {
391212904Sdim    assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
392212904Sdim           "Invalid Object Idx!");
393212904Sdim    return Objects[ObjectIdx+NumFixedObjects].MayNeedSP;
394212904Sdim  }
395212904Sdim
396193323Sed  /// getObjectOffset - Return the assigned stack offset of the specified object
397193323Sed  /// from the incoming stack pointer.
398193323Sed  ///
399193323Sed  int64_t getObjectOffset(int ObjectIdx) const {
400193323Sed    assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
401193323Sed           "Invalid Object Idx!");
402193323Sed    assert(!isDeadObjectIndex(ObjectIdx) &&
403193323Sed           "Getting frame offset for a dead object?");
404193323Sed    return Objects[ObjectIdx+NumFixedObjects].SPOffset;
405193323Sed  }
406193323Sed
407193323Sed  /// setObjectOffset - Set the stack frame offset of the specified object.  The
408193323Sed  /// offset is relative to the stack pointer on entry to the function.
409193323Sed  ///
410193323Sed  void setObjectOffset(int ObjectIdx, int64_t SPOffset) {
411193323Sed    assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
412193323Sed           "Invalid Object Idx!");
413193323Sed    assert(!isDeadObjectIndex(ObjectIdx) &&
414193323Sed           "Setting frame offset for a dead object?");
415193323Sed    Objects[ObjectIdx+NumFixedObjects].SPOffset = SPOffset;
416193323Sed  }
417193323Sed
418193323Sed  /// getStackSize - Return the number of bytes that must be allocated to hold
419193323Sed  /// all of the fixed size frame objects.  This is only valid after
420193323Sed  /// Prolog/Epilog code insertion has finalized the stack frame layout.
421193323Sed  ///
422193323Sed  uint64_t getStackSize() const { return StackSize; }
423193323Sed
424193323Sed  /// setStackSize - Set the size of the stack...
425193323Sed  ///
426193323Sed  void setStackSize(uint64_t Size) { StackSize = Size; }
427212904Sdim
428252723Sdim  /// Estimate and return the size of the stack frame.
429252723Sdim  unsigned estimateStackSize(const MachineFunction &MF) const;
430252723Sdim
431193323Sed  /// getOffsetAdjustment - Return the correction for frame offsets.
432193323Sed  ///
433193323Sed  int getOffsetAdjustment() const { return OffsetAdjustment; }
434212904Sdim
435193323Sed  /// setOffsetAdjustment - Set the correction for frame offsets.
436193323Sed  ///
437193323Sed  void setOffsetAdjustment(int Adj) { OffsetAdjustment = Adj; }
438193323Sed
439212904Sdim  /// getMaxAlignment - Return the alignment in bytes that this function must be
440212904Sdim  /// aligned to, which is greater than the default stack alignment provided by
441193323Sed  /// the target.
442193323Sed  ///
443193323Sed  unsigned getMaxAlignment() const { return MaxAlignment; }
444212904Sdim
445245431Sdim  /// ensureMaxAlignment - Make sure the function is at least Align bytes
446245431Sdim  /// aligned.
447252723Sdim  void ensureMaxAlignment(unsigned Align);
448200581Srdivacky
449208599Srdivacky  /// AdjustsStack - Return true if this function adjusts the stack -- e.g.,
450208599Srdivacky  /// when calling another function. This is only valid during and after
451208599Srdivacky  /// prolog/epilog code insertion.
452208599Srdivacky  bool adjustsStack() const { return AdjustsStack; }
453208599Srdivacky  void setAdjustsStack(bool V) { AdjustsStack = V; }
454208599Srdivacky
455208599Srdivacky  /// hasCalls - Return true if the current function has any function calls.
456193323Sed  bool hasCalls() const { return HasCalls; }
457193323Sed  void setHasCalls(bool V) { HasCalls = V; }
458193323Sed
459263765Sdim  /// Returns true if the function contains any stack-adjusting inline assembly.
460263765Sdim  bool hasInlineAsmWithSPAdjust() const { return HasInlineAsmWithSPAdjust; }
461263765Sdim  void setHasInlineAsmWithSPAdjust(bool B) { HasInlineAsmWithSPAdjust = B; }
462263765Sdim
463193323Sed  /// getMaxCallFrameSize - Return the maximum size of a call frame that must be
464193323Sed  /// allocated for an outgoing function call.  This is only available if
465193323Sed  /// CallFrameSetup/Destroy pseudo instructions are used by the target, and
466193323Sed  /// then only during or after prolog/epilog code insertion.
467193323Sed  ///
468193323Sed  unsigned getMaxCallFrameSize() const { return MaxCallFrameSize; }
469193323Sed  void setMaxCallFrameSize(unsigned S) { MaxCallFrameSize = S; }
470193323Sed
471193323Sed  /// CreateFixedObject - Create a new object at a fixed location on the stack.
472193323Sed  /// All fixed objects should be created before other objects are created for
473193323Sed  /// efficiency. By default, fixed objects are immutable. This returns an
474193323Sed  /// index with a negative value.
475193323Sed  ///
476210299Sed  int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool Immutable);
477212904Sdim
478212904Sdim
479193323Sed  /// isFixedObjectIndex - Returns true if the specified index corresponds to a
480193323Sed  /// fixed stack object.
481193323Sed  bool isFixedObjectIndex(int ObjectIdx) const {
482193323Sed    return ObjectIdx < 0 && (ObjectIdx >= -(int)NumFixedObjects);
483193323Sed  }
484193323Sed
485193323Sed  /// isImmutableObjectIndex - Returns true if the specified index corresponds
486193323Sed  /// to an immutable object.
487193323Sed  bool isImmutableObjectIndex(int ObjectIdx) const {
488193323Sed    assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
489193323Sed           "Invalid Object Idx!");
490193323Sed    return Objects[ObjectIdx+NumFixedObjects].isImmutable;
491193323Sed  }
492193323Sed
493198396Srdivacky  /// isSpillSlotObjectIndex - Returns true if the specified index corresponds
494198396Srdivacky  /// to a spill slot..
495198396Srdivacky  bool isSpillSlotObjectIndex(int ObjectIdx) const {
496198396Srdivacky    assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
497198396Srdivacky           "Invalid Object Idx!");
498235633Sdim    return Objects[ObjectIdx+NumFixedObjects].isSpillSlot;
499198396Srdivacky  }
500198396Srdivacky
501193323Sed  /// isDeadObjectIndex - Returns true if the specified index corresponds to
502193323Sed  /// a dead object.
503193323Sed  bool isDeadObjectIndex(int ObjectIdx) const {
504193323Sed    assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
505193323Sed           "Invalid Object Idx!");
506193323Sed    return Objects[ObjectIdx+NumFixedObjects].Size == ~0ULL;
507193323Sed  }
508193323Sed
509212904Sdim  /// CreateStackObject - Create a new statically sized stack object, returning
510212904Sdim  /// a nonnegative identifier to represent it.
511193323Sed  ///
512212904Sdim  int CreateStackObject(uint64_t Size, unsigned Alignment, bool isSS,
513252723Sdim                        bool MayNeedSP = false, const AllocaInst *Alloca = 0);
514193323Sed
515212904Sdim  /// CreateSpillStackObject - Create a new statically sized stack object that
516212904Sdim  /// represents a spill slot, returning a nonnegative identifier to represent
517212904Sdim  /// it.
518199481Srdivacky  ///
519252723Sdim  int CreateSpillStackObject(uint64_t Size, unsigned Alignment);
520199481Srdivacky
521193323Sed  /// RemoveStackObject - Remove or mark dead a statically sized stack object.
522193323Sed  ///
523193323Sed  void RemoveStackObject(int ObjectIdx) {
524193323Sed    // Mark it dead.
525193323Sed    Objects[ObjectIdx+NumFixedObjects].Size = ~0ULL;
526193323Sed  }
527193323Sed
528193323Sed  /// CreateVariableSizedObject - Notify the MachineFrameInfo object that a
529193323Sed  /// variable sized object has been created.  This must be created whenever a
530193323Sed  /// variable sized object is created, whether or not the index returned is
531193323Sed  /// actually used.
532193323Sed  ///
533263765Sdim  int CreateVariableSizedObject(unsigned Alignment, const AllocaInst *Alloca);
534199481Srdivacky
535193323Sed  /// getCalleeSavedInfo - Returns a reference to call saved info vector for the
536193323Sed  /// current function.
537193323Sed  const std::vector<CalleeSavedInfo> &getCalleeSavedInfo() const {
538193323Sed    return CSInfo;
539193323Sed  }
540193323Sed
541193323Sed  /// setCalleeSavedInfo - Used by prolog/epilog inserter to set the function's
542193323Sed  /// callee saved information.
543212904Sdim  void setCalleeSavedInfo(const std::vector<CalleeSavedInfo> &CSI) {
544193323Sed    CSInfo = CSI;
545193323Sed  }
546193323Sed
547198090Srdivacky  /// isCalleeSavedInfoValid - Has the callee saved info been calculated yet?
548198090Srdivacky  bool isCalleeSavedInfoValid() const { return CSIValid; }
549198090Srdivacky
550198090Srdivacky  void setCalleeSavedInfoValid(bool v) { CSIValid = v; }
551198090Srdivacky
552198090Srdivacky  /// getPristineRegs - Return a set of physical registers that are pristine on
553198090Srdivacky  /// entry to the MBB.
554198090Srdivacky  ///
555198090Srdivacky  /// Pristine registers hold a value that is useless to the current function,
556198090Srdivacky  /// but that must be preserved - they are callee saved registers that have not
557198090Srdivacky  /// been saved yet.
558198090Srdivacky  ///
559198090Srdivacky  /// Before the PrologueEpilogueInserter has placed the CSR spill code, this
560198090Srdivacky  /// method always returns an empty set.
561198090Srdivacky  BitVector getPristineRegs(const MachineBasicBlock *MBB) const;
562198090Srdivacky
563193323Sed  /// print - Used by the MachineFunction printer to print information about
564212904Sdim  /// stack objects. Implemented in MachineFunction.cpp
565193323Sed  ///
566198090Srdivacky  void print(const MachineFunction &MF, raw_ostream &OS) const;
567193323Sed
568198090Srdivacky  /// dump - Print the function to stderr.
569193323Sed  void dump(const MachineFunction &MF) const;
570193323Sed};
571193323Sed
572193323Sed} // End llvm namespace
573193323Sed
574193323Sed#endif
575