1149178d9SEugene Zelenko //===- SafeStackLayout.h - SafeStack frame layout --------------*- C++ -*--===// 2a5da256fSEvgeniy Stepanov // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6a5da256fSEvgeniy Stepanov // 7a5da256fSEvgeniy Stepanov //===----------------------------------------------------------------------===// 8a5da256fSEvgeniy Stepanov 9a5da256fSEvgeniy Stepanov #ifndef LLVM_LIB_CODEGEN_SAFESTACKLAYOUT_H 10a5da256fSEvgeniy Stepanov #define LLVM_LIB_CODEGEN_SAFESTACKLAYOUT_H 11a5da256fSEvgeniy Stepanov 12149178d9SEugene Zelenko #include "llvm/ADT/DenseMap.h" 13149178d9SEugene Zelenko #include "llvm/ADT/SmallVector.h" 146754a0e2SVitaly Buka #include "llvm/Analysis/StackLifetime.h" 15a5da256fSEvgeniy Stepanov 16a5da256fSEvgeniy Stepanov namespace llvm { 17149178d9SEugene Zelenko 18149178d9SEugene Zelenko class raw_ostream; 19149178d9SEugene Zelenko class Value; 20149178d9SEugene Zelenko 21a5da256fSEvgeniy Stepanov namespace safestack { 22a5da256fSEvgeniy Stepanov 23a5da256fSEvgeniy Stepanov /// Compute the layout of an unsafe stack frame. 24a5da256fSEvgeniy Stepanov class StackLayout { 25eba7b268SArthur Eubanks Align MaxAlignment; 26a5da256fSEvgeniy Stepanov 27a5da256fSEvgeniy Stepanov struct StackRegion { 28a5da256fSEvgeniy Stepanov unsigned Start; 29a5da256fSEvgeniy Stepanov unsigned End; 30d812efb1SVitaly Buka StackLifetime::LiveRange Range; 31149178d9SEugene Zelenko StackRegionStackRegion32a5da256fSEvgeniy Stepanov StackRegion(unsigned Start, unsigned End, 33d812efb1SVitaly Buka const StackLifetime::LiveRange &Range) 34a5da256fSEvgeniy Stepanov : Start(Start), End(End), Range(Range) {} 35a5da256fSEvgeniy Stepanov }; 36149178d9SEugene Zelenko 37a5da256fSEvgeniy Stepanov /// The list of current stack regions, sorted by StackRegion::Start. 38a5da256fSEvgeniy Stepanov SmallVector<StackRegion, 16> Regions; 39a5da256fSEvgeniy Stepanov 40a5da256fSEvgeniy Stepanov struct StackObject { 41a5da256fSEvgeniy Stepanov const Value *Handle; 4205392466SArthur Eubanks unsigned Size; 43eba7b268SArthur Eubanks Align Alignment; 44d812efb1SVitaly Buka StackLifetime::LiveRange Range; 45a5da256fSEvgeniy Stepanov }; 46149178d9SEugene Zelenko 47a5da256fSEvgeniy Stepanov SmallVector<StackObject, 8> StackObjects; 48a5da256fSEvgeniy Stepanov 49a5da256fSEvgeniy Stepanov DenseMap<const Value *, unsigned> ObjectOffsets; 50eba7b268SArthur Eubanks DenseMap<const Value *, Align> ObjectAlignments; 51a5da256fSEvgeniy Stepanov 52a5da256fSEvgeniy Stepanov void layoutObject(StackObject &Obj); 53a5da256fSEvgeniy Stepanov 54a5da256fSEvgeniy Stepanov public: StackLayout(Align StackAlignment)55*c0e85f1cSGuillaume Chatelet StackLayout(Align StackAlignment) : MaxAlignment(StackAlignment) {} 56149178d9SEugene Zelenko 57a5da256fSEvgeniy Stepanov /// Add an object to the stack frame. Value pointer is opaque and used as a 58a5da256fSEvgeniy Stepanov /// handle to retrieve the object's offset in the frame later. 59eba7b268SArthur Eubanks void addObject(const Value *V, unsigned Size, Align Alignment, 60d812efb1SVitaly Buka const StackLifetime::LiveRange &Range); 61a5da256fSEvgeniy Stepanov 62a5da256fSEvgeniy Stepanov /// Run the layout computation for all previously added objects. 63a5da256fSEvgeniy Stepanov void computeLayout(); 64a5da256fSEvgeniy Stepanov 65a5da256fSEvgeniy Stepanov /// Returns the offset to the object start in the stack frame. getObjectOffset(const Value * V)66a5da256fSEvgeniy Stepanov unsigned getObjectOffset(const Value *V) { return ObjectOffsets[V]; } 67a5da256fSEvgeniy Stepanov 68095d7298SDaniel Neilson /// Returns the alignment of the object getObjectAlignment(const Value * V)69eba7b268SArthur Eubanks Align getObjectAlignment(const Value *V) { return ObjectAlignments[V]; } 70095d7298SDaniel Neilson 71a5da256fSEvgeniy Stepanov /// Returns the size of the entire frame. getFrameSize()72a5da256fSEvgeniy Stepanov unsigned getFrameSize() { return Regions.empty() ? 0 : Regions.back().End; } 73a5da256fSEvgeniy Stepanov 74a5da256fSEvgeniy Stepanov /// Returns the alignment of the frame. getFrameAlignment()75eba7b268SArthur Eubanks Align getFrameAlignment() { return MaxAlignment; } 76149178d9SEugene Zelenko 77a5da256fSEvgeniy Stepanov void print(raw_ostream &OS); 78a5da256fSEvgeniy Stepanov }; 79a5da256fSEvgeniy Stepanov 80149178d9SEugene Zelenko } // end namespace safestack 81149178d9SEugene Zelenko 82149178d9SEugene Zelenko } // end namespace llvm 83a5da256fSEvgeniy Stepanov 84a5da256fSEvgeniy Stepanov #endif // LLVM_LIB_CODEGEN_SAFESTACKLAYOUT_H 85