16 using namespace llvm::safestack;
18 #define DEBUG_TYPE "safestacklayout"
25 OS <<
"Stack regions:\n";
26 for (
unsigned i = 0;
i < Regions.
size(); ++
i) {
27 OS <<
" " <<
i <<
": [" << Regions[
i].Start <<
", " << Regions[
i].End
28 <<
"), range " << Regions[
i].Range <<
"\n";
30 OS <<
"Stack objects:\n";
31 for (
auto &
IT : ObjectOffsets) {
32 OS <<
" at " <<
IT.getSecond() <<
": " << *
IT.getFirst() <<
"\n";
38 StackObjects.
push_back({V, Size, Alignment, Range});
39 MaxAlignment = std::max(MaxAlignment, Alignment);
44 return alignTo(Offset + Size, Alignment) - Size;
47 void StackLayout::layoutObject(StackObject &Obj) {
51 unsigned LastRegionEnd = Regions.
empty() ? 0 : Regions.
back().End;
53 unsigned End = Start + Obj.Size;
55 ObjectOffsets[Obj.Handle] =
End;
59 DEBUG(
dbgs() <<
"Layout: size " << Obj.Size <<
", align " << Obj.Alignment
60 <<
", range " << Obj.Range <<
"\n");
61 assert(Obj.Alignment <= MaxAlignment);
63 unsigned End = Start + Obj.Size;
64 DEBUG(
dbgs() <<
" First candidate: " << Start <<
" .. " << End <<
"\n");
65 for (
const StackRegion &R : Regions) {
66 DEBUG(
dbgs() <<
" Examining region: " << R.Start <<
" .. " << R.End
67 <<
", range " << R.Range <<
"\n");
70 DEBUG(
dbgs() <<
" Does not intersect, skip.\n");
73 if (Obj.Range.Overlaps(R.Range)) {
76 End = Start + Obj.Size;
77 DEBUG(
dbgs() <<
" Overlaps. Next candidate: " << Start <<
" .. " << End
87 unsigned LastRegionEnd = Regions.empty() ? 0 : Regions.back().End;
88 if (End > LastRegionEnd) {
90 if (Start > LastRegionEnd) {
91 DEBUG(
dbgs() <<
" Creating gap region: " << LastRegionEnd <<
" .. "
93 Regions.emplace_back(LastRegionEnd, Start, StackColoring::LiveRange());
94 LastRegionEnd = Start;
96 DEBUG(
dbgs() <<
" Creating new region: " << LastRegionEnd <<
" .. " << End
97 <<
", range " << Obj.Range <<
"\n");
98 Regions.emplace_back(LastRegionEnd, End, Obj.Range);
103 for (
unsigned i = 0;
i < Regions.size(); ++
i) {
104 StackRegion &R = Regions[
i];
105 if (Start > R.Start && Start < R.End) {
107 R.Start = R0.End = Start;
108 Regions.insert(&R, R0);
111 if (End > R.Start && End < R.End) {
113 R0.End = R.Start =
End;
114 Regions.insert(&R, R0);
120 for (StackRegion &R : Regions) {
121 if (Start < R.End && End > R.Start)
122 R.Range.Join(Obj.Range);
127 ObjectOffsets[Obj.Handle] =
End;
137 if (StackObjects.
size() > 2)
138 std::stable_sort(StackObjects.
begin() + 1, StackObjects.
end(),
139 [](
const StackObject &a,
const StackObject &b) {
140 return a.Size > b.Size;
143 for (
auto &Obj : StackObjects)
static cl::opt< ITMode > IT(cl::desc("IT block support"), cl::Hidden, cl::init(DefaultIT), cl::ZeroOrMore, cl::values(clEnumValN(DefaultIT,"arm-default-it","Generate IT block based on arch"), clEnumValN(RestrictedIT,"arm-restrict-it","Disallow deprecated IT based on ARMv8"), clEnumValN(NoRestrictedIT,"arm-no-restrict-it","Allow IT blocks based on ARMv7")))
void push_back(const T &Elt)
This class represents a set of interesting instructions where an alloca is live.
void addObject(const Value *V, unsigned Size, unsigned Alignment, const StackColoring::LiveRange &Range)
Add an object to the stack frame.
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds...
uint64_t alignTo(uint64_t Value, uint64_t Align, uint64_t Skew=0)
Returns the next integer (mod 2**64) that is greater than or equal to Value and is a multiple of Alig...
static unsigned AdjustStackOffset(unsigned Offset, unsigned Size, unsigned Alignment)
LLVM_NODISCARD bool empty() const
initializer< Ty > init(const Ty &Val)
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
static const unsigned End
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void computeLayout()
Run the layout computation for all previously added objects.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
void emplace_back(ArgTypes &&...Args)
void print(raw_ostream &OS)
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
static cl::opt< bool > ClLayout("safe-stack-layout", cl::desc("enable safe stack layout"), cl::Hidden, cl::init(true))
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
This class implements an extremely fast bulk output stream that can only output to a stream...