1*9880d681SAndroid Build Coastguard Worker //===-- SafeStackLayout.h - SafeStack frame layout -------------*- C++ -*--===// 2*9880d681SAndroid Build Coastguard Worker // 3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure 4*9880d681SAndroid Build Coastguard Worker // 5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source 6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details. 7*9880d681SAndroid Build Coastguard Worker // 8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 9*9880d681SAndroid Build Coastguard Worker 10*9880d681SAndroid Build Coastguard Worker #ifndef LLVM_LIB_CODEGEN_SAFESTACKLAYOUT_H 11*9880d681SAndroid Build Coastguard Worker #define LLVM_LIB_CODEGEN_SAFESTACKLAYOUT_H 12*9880d681SAndroid Build Coastguard Worker 13*9880d681SAndroid Build Coastguard Worker #include "SafeStackColoring.h" 14*9880d681SAndroid Build Coastguard Worker 15*9880d681SAndroid Build Coastguard Worker namespace llvm { 16*9880d681SAndroid Build Coastguard Worker namespace safestack { 17*9880d681SAndroid Build Coastguard Worker 18*9880d681SAndroid Build Coastguard Worker /// Compute the layout of an unsafe stack frame. 19*9880d681SAndroid Build Coastguard Worker class StackLayout { 20*9880d681SAndroid Build Coastguard Worker unsigned MaxAlignment; 21*9880d681SAndroid Build Coastguard Worker 22*9880d681SAndroid Build Coastguard Worker struct StackRegion { 23*9880d681SAndroid Build Coastguard Worker unsigned Start; 24*9880d681SAndroid Build Coastguard Worker unsigned End; 25*9880d681SAndroid Build Coastguard Worker StackColoring::LiveRange Range; StackRegionStackRegion26*9880d681SAndroid Build Coastguard Worker StackRegion(unsigned Start, unsigned End, 27*9880d681SAndroid Build Coastguard Worker const StackColoring::LiveRange &Range) 28*9880d681SAndroid Build Coastguard Worker : Start(Start), End(End), Range(Range) {} 29*9880d681SAndroid Build Coastguard Worker }; 30*9880d681SAndroid Build Coastguard Worker /// The list of current stack regions, sorted by StackRegion::Start. 31*9880d681SAndroid Build Coastguard Worker SmallVector<StackRegion, 16> Regions; 32*9880d681SAndroid Build Coastguard Worker 33*9880d681SAndroid Build Coastguard Worker struct StackObject { 34*9880d681SAndroid Build Coastguard Worker const Value *Handle; 35*9880d681SAndroid Build Coastguard Worker unsigned Size, Alignment; 36*9880d681SAndroid Build Coastguard Worker StackColoring::LiveRange Range; 37*9880d681SAndroid Build Coastguard Worker }; 38*9880d681SAndroid Build Coastguard Worker SmallVector<StackObject, 8> StackObjects; 39*9880d681SAndroid Build Coastguard Worker 40*9880d681SAndroid Build Coastguard Worker DenseMap<const Value *, unsigned> ObjectOffsets; 41*9880d681SAndroid Build Coastguard Worker 42*9880d681SAndroid Build Coastguard Worker void layoutObject(StackObject &Obj); 43*9880d681SAndroid Build Coastguard Worker 44*9880d681SAndroid Build Coastguard Worker public: StackLayout(unsigned StackAlignment)45*9880d681SAndroid Build Coastguard Worker StackLayout(unsigned StackAlignment) : MaxAlignment(StackAlignment) {} 46*9880d681SAndroid Build Coastguard Worker /// Add an object to the stack frame. Value pointer is opaque and used as a 47*9880d681SAndroid Build Coastguard Worker /// handle to retrieve the object's offset in the frame later. 48*9880d681SAndroid Build Coastguard Worker void addObject(const Value *V, unsigned Size, unsigned Alignment, 49*9880d681SAndroid Build Coastguard Worker const StackColoring::LiveRange &Range); 50*9880d681SAndroid Build Coastguard Worker 51*9880d681SAndroid Build Coastguard Worker /// Run the layout computation for all previously added objects. 52*9880d681SAndroid Build Coastguard Worker void computeLayout(); 53*9880d681SAndroid Build Coastguard Worker 54*9880d681SAndroid Build Coastguard Worker /// Returns the offset to the object start in the stack frame. getObjectOffset(const Value * V)55*9880d681SAndroid Build Coastguard Worker unsigned getObjectOffset(const Value *V) { return ObjectOffsets[V]; } 56*9880d681SAndroid Build Coastguard Worker 57*9880d681SAndroid Build Coastguard Worker /// Returns the size of the entire frame. getFrameSize()58*9880d681SAndroid Build Coastguard Worker unsigned getFrameSize() { return Regions.empty() ? 0 : Regions.back().End; } 59*9880d681SAndroid Build Coastguard Worker 60*9880d681SAndroid Build Coastguard Worker /// Returns the alignment of the frame. getFrameAlignment()61*9880d681SAndroid Build Coastguard Worker unsigned getFrameAlignment() { return MaxAlignment; } 62*9880d681SAndroid Build Coastguard Worker void print(raw_ostream &OS); 63*9880d681SAndroid Build Coastguard Worker }; 64*9880d681SAndroid Build Coastguard Worker 65*9880d681SAndroid Build Coastguard Worker } // namespace safestack 66*9880d681SAndroid Build Coastguard Worker } // namespace llvm 67*9880d681SAndroid Build Coastguard Worker 68*9880d681SAndroid Build Coastguard Worker #endif // LLVM_LIB_CODEGEN_SAFESTACKLAYOUT_H 69