21#define DEBUG_TYPE "safestacklayout"
28 OS <<
"Stack regions:\n";
29 for (
unsigned i = 0; i < Regions.
size(); ++i) {
30 OS <<
" " << i <<
": [" << Regions[i].Start <<
", " << Regions[i].End
31 <<
"), range " << Regions[i].Range <<
"\n";
33 OS <<
"Stack objects:\n";
34 for (
auto &
IT : ObjectOffsets) {
35 OS <<
" at " <<
IT.getSecond() <<
": " << *
IT.getFirst() <<
"\n";
42 ObjectAlignments[V] = Alignment;
43 MaxAlignment = std::max(MaxAlignment, Alignment);
51void StackLayout::layoutObject(StackObject &Obj) {
55 unsigned LastRegionEnd = Regions.
empty() ? 0 : Regions.
back().End;
57 unsigned End = Start + Obj.Size;
59 ObjectOffsets[Obj.Handle] =
End;
64 << Obj.Alignment.value() <<
", range " << Obj.Range
66 assert(Obj.Alignment <= MaxAlignment);
68 unsigned End = Start + Obj.Size;
70 for (
const StackRegion &R : Regions) {
72 <<
", range " <<
R.Range <<
"\n");
78 if (Obj.Range.overlaps(
R.Range)) {
81 End = Start + Obj.Size;
82 LLVM_DEBUG(
dbgs() <<
" Overlaps. Next candidate: " << Start <<
" .. "
92 unsigned LastRegionEnd = Regions.empty() ? 0 : Regions.back().End;
93 if (
End > LastRegionEnd) {
95 if (Start > LastRegionEnd) {
96 LLVM_DEBUG(
dbgs() <<
" Creating gap region: " << LastRegionEnd <<
" .. "
99 LastRegionEnd = Start;
101 LLVM_DEBUG(
dbgs() <<
" Creating new region: " << LastRegionEnd <<
" .. "
102 <<
End <<
", range " << Obj.Range <<
"\n");
103 Regions.emplace_back(LastRegionEnd,
End, Obj.Range);
108 for (
unsigned i = 0; i < Regions.size(); ++i) {
109 StackRegion &
R = Regions[i];
110 if (Start >
R.Start && Start <
R.End) {
112 R.Start = R0.End = Start;
113 Regions.insert(&R, R0);
118 R0.End =
R.Start =
End;
119 Regions.insert(&R, R0);
125 for (StackRegion &R : Regions) {
126 if (Start < R.End && End >
R.Start)
127 R.Range.join(Obj.Range);
132 ObjectOffsets[Obj.Handle] =
End;
142 if (StackObjects.
size() > 2)
144 [](
const StackObject &a,
const StackObject &b) {
145 return a.Size > b.Size;
148 for (
auto &Obj : StackObjects)
static cl::opt< ITMode > IT(cl::desc("IT block support"), cl::Hidden, cl::init(DefaultIT), cl::values(clEnumValN(DefaultIT, "arm-default-it", "Generate any type of IT block"), clEnumValN(RestrictedIT, "arm-restrict-it", "Disallow complex IT blocks")))
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
static void AdjustStackOffset(MachineFrameInfo &MFI, int FrameIdx, bool StackGrowsDown, int64_t &Offset, Align &MaxAlign)
AdjustStackOffset - Helper function used to adjust the stack frame offset.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static cl::opt< bool > ClLayout("safe-stack-layout", cl::desc("enable safe stack layout"), cl::Hidden, cl::init(true))
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
This class represents a set of interesting instructions where an alloca is live.
LLVM Value Representation.
This class implements an extremely fast bulk output stream that can only output to a stream.
void computeLayout()
Run the layout computation for all previously added objects.
void print(raw_ostream &OS)
void addObject(const Value *V, unsigned Size, Align Alignment, const StackLifetime::LiveRange &Range)
Add an object to the stack frame.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
void stable_sort(R &&Range)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
This struct is a compact representation of a valid (non-zero power of two) alignment.