1*9880d681SAndroid Build Coastguard Worker //===-- GCMetadata.h - Garbage collector metadata ---------------*- 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 // This file declares the GCFunctionInfo and GCModuleInfo classes, which are 11*9880d681SAndroid Build Coastguard Worker // used as a communication channel from the target code generator to the target 12*9880d681SAndroid Build Coastguard Worker // garbage collectors. This interface allows code generators and garbage 13*9880d681SAndroid Build Coastguard Worker // collectors to be developed independently. 14*9880d681SAndroid Build Coastguard Worker // 15*9880d681SAndroid Build Coastguard Worker // The GCFunctionInfo class logs the data necessary to build a type accurate 16*9880d681SAndroid Build Coastguard Worker // stack map. The code generator outputs: 17*9880d681SAndroid Build Coastguard Worker // 18*9880d681SAndroid Build Coastguard Worker // - Safe points as specified by the GCStrategy's NeededSafePoints. 19*9880d681SAndroid Build Coastguard Worker // - Stack offsets for GC roots, as specified by calls to llvm.gcroot 20*9880d681SAndroid Build Coastguard Worker // 21*9880d681SAndroid Build Coastguard Worker // As a refinement, liveness analysis calculates the set of live roots at each 22*9880d681SAndroid Build Coastguard Worker // safe point. Liveness analysis is not presently performed by the code 23*9880d681SAndroid Build Coastguard Worker // generator, so all roots are assumed live. 24*9880d681SAndroid Build Coastguard Worker // 25*9880d681SAndroid Build Coastguard Worker // GCModuleInfo simply collects GCFunctionInfo instances for each Function as 26*9880d681SAndroid Build Coastguard Worker // they are compiled. This accretion is necessary for collectors which must emit 27*9880d681SAndroid Build Coastguard Worker // a stack map for the compilation unit as a whole. Therefore, GCFunctionInfo 28*9880d681SAndroid Build Coastguard Worker // outlives the MachineFunction from which it is derived and must not refer to 29*9880d681SAndroid Build Coastguard Worker // any code generator data structures. 30*9880d681SAndroid Build Coastguard Worker // 31*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===// 32*9880d681SAndroid Build Coastguard Worker 33*9880d681SAndroid Build Coastguard Worker #ifndef LLVM_CODEGEN_GCMETADATA_H 34*9880d681SAndroid Build Coastguard Worker #define LLVM_CODEGEN_GCMETADATA_H 35*9880d681SAndroid Build Coastguard Worker 36*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/DenseMap.h" 37*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SmallVector.h" 38*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/StringMap.h" 39*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/GCStrategy.h" 40*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/DebugLoc.h" 41*9880d681SAndroid Build Coastguard Worker #include "llvm/Pass.h" 42*9880d681SAndroid Build Coastguard Worker #include <memory> 43*9880d681SAndroid Build Coastguard Worker #include <utility> 44*9880d681SAndroid Build Coastguard Worker 45*9880d681SAndroid Build Coastguard Worker namespace llvm { 46*9880d681SAndroid Build Coastguard Worker class AsmPrinter; 47*9880d681SAndroid Build Coastguard Worker class Constant; 48*9880d681SAndroid Build Coastguard Worker class MCSymbol; 49*9880d681SAndroid Build Coastguard Worker 50*9880d681SAndroid Build Coastguard Worker /// GCPoint - Metadata for a collector-safe point in machine code. 51*9880d681SAndroid Build Coastguard Worker /// 52*9880d681SAndroid Build Coastguard Worker struct GCPoint { 53*9880d681SAndroid Build Coastguard Worker GC::PointKind Kind; ///< The kind of the safe point. 54*9880d681SAndroid Build Coastguard Worker MCSymbol *Label; ///< A label. 55*9880d681SAndroid Build Coastguard Worker DebugLoc Loc; 56*9880d681SAndroid Build Coastguard Worker GCPointGCPoint57*9880d681SAndroid Build Coastguard Worker GCPoint(GC::PointKind K, MCSymbol *L, DebugLoc DL) 58*9880d681SAndroid Build Coastguard Worker : Kind(K), Label(L), Loc(std::move(DL)) {} 59*9880d681SAndroid Build Coastguard Worker }; 60*9880d681SAndroid Build Coastguard Worker 61*9880d681SAndroid Build Coastguard Worker /// GCRoot - Metadata for a pointer to an object managed by the garbage 62*9880d681SAndroid Build Coastguard Worker /// collector. 63*9880d681SAndroid Build Coastguard Worker struct GCRoot { 64*9880d681SAndroid Build Coastguard Worker int Num; ///< Usually a frame index. 65*9880d681SAndroid Build Coastguard Worker int StackOffset; ///< Offset from the stack pointer. 66*9880d681SAndroid Build Coastguard Worker const Constant *Metadata; ///< Metadata straight from the call 67*9880d681SAndroid Build Coastguard Worker ///< to llvm.gcroot. 68*9880d681SAndroid Build Coastguard Worker GCRootGCRoot69*9880d681SAndroid Build Coastguard Worker GCRoot(int N, const Constant *MD) : Num(N), StackOffset(-1), Metadata(MD) {} 70*9880d681SAndroid Build Coastguard Worker }; 71*9880d681SAndroid Build Coastguard Worker 72*9880d681SAndroid Build Coastguard Worker /// Garbage collection metadata for a single function. Currently, this 73*9880d681SAndroid Build Coastguard Worker /// information only applies to GCStrategies which use GCRoot. 74*9880d681SAndroid Build Coastguard Worker class GCFunctionInfo { 75*9880d681SAndroid Build Coastguard Worker public: 76*9880d681SAndroid Build Coastguard Worker typedef std::vector<GCPoint>::iterator iterator; 77*9880d681SAndroid Build Coastguard Worker typedef std::vector<GCRoot>::iterator roots_iterator; 78*9880d681SAndroid Build Coastguard Worker typedef std::vector<GCRoot>::const_iterator live_iterator; 79*9880d681SAndroid Build Coastguard Worker 80*9880d681SAndroid Build Coastguard Worker private: 81*9880d681SAndroid Build Coastguard Worker const Function &F; 82*9880d681SAndroid Build Coastguard Worker GCStrategy &S; 83*9880d681SAndroid Build Coastguard Worker uint64_t FrameSize; 84*9880d681SAndroid Build Coastguard Worker std::vector<GCRoot> Roots; 85*9880d681SAndroid Build Coastguard Worker std::vector<GCPoint> SafePoints; 86*9880d681SAndroid Build Coastguard Worker 87*9880d681SAndroid Build Coastguard Worker // FIXME: Liveness. A 2D BitVector, perhaps? 88*9880d681SAndroid Build Coastguard Worker // 89*9880d681SAndroid Build Coastguard Worker // BitVector Liveness; 90*9880d681SAndroid Build Coastguard Worker // 91*9880d681SAndroid Build Coastguard Worker // bool islive(int point, int root) = 92*9880d681SAndroid Build Coastguard Worker // Liveness[point * SafePoints.size() + root] 93*9880d681SAndroid Build Coastguard Worker // 94*9880d681SAndroid Build Coastguard Worker // The bit vector is the more compact representation where >3.2% of roots 95*9880d681SAndroid Build Coastguard Worker // are live per safe point (1.5% on 64-bit hosts). 96*9880d681SAndroid Build Coastguard Worker 97*9880d681SAndroid Build Coastguard Worker public: 98*9880d681SAndroid Build Coastguard Worker GCFunctionInfo(const Function &F, GCStrategy &S); 99*9880d681SAndroid Build Coastguard Worker ~GCFunctionInfo(); 100*9880d681SAndroid Build Coastguard Worker 101*9880d681SAndroid Build Coastguard Worker /// getFunction - Return the function to which this metadata applies. 102*9880d681SAndroid Build Coastguard Worker /// getFunction()103*9880d681SAndroid Build Coastguard Worker const Function &getFunction() const { return F; } 104*9880d681SAndroid Build Coastguard Worker 105*9880d681SAndroid Build Coastguard Worker /// getStrategy - Return the GC strategy for the function. 106*9880d681SAndroid Build Coastguard Worker /// getStrategy()107*9880d681SAndroid Build Coastguard Worker GCStrategy &getStrategy() { return S; } 108*9880d681SAndroid Build Coastguard Worker 109*9880d681SAndroid Build Coastguard Worker /// addStackRoot - Registers a root that lives on the stack. Num is the 110*9880d681SAndroid Build Coastguard Worker /// stack object ID for the alloca (if the code generator is 111*9880d681SAndroid Build Coastguard Worker // using MachineFrameInfo). addStackRoot(int Num,const Constant * Metadata)112*9880d681SAndroid Build Coastguard Worker void addStackRoot(int Num, const Constant *Metadata) { 113*9880d681SAndroid Build Coastguard Worker Roots.push_back(GCRoot(Num, Metadata)); 114*9880d681SAndroid Build Coastguard Worker } 115*9880d681SAndroid Build Coastguard Worker 116*9880d681SAndroid Build Coastguard Worker /// removeStackRoot - Removes a root. removeStackRoot(roots_iterator position)117*9880d681SAndroid Build Coastguard Worker roots_iterator removeStackRoot(roots_iterator position) { 118*9880d681SAndroid Build Coastguard Worker return Roots.erase(position); 119*9880d681SAndroid Build Coastguard Worker } 120*9880d681SAndroid Build Coastguard Worker 121*9880d681SAndroid Build Coastguard Worker /// addSafePoint - Notes the existence of a safe point. Num is the ID of the 122*9880d681SAndroid Build Coastguard Worker /// label just prior to the safe point (if the code generator is using 123*9880d681SAndroid Build Coastguard Worker /// MachineModuleInfo). addSafePoint(GC::PointKind Kind,MCSymbol * Label,const DebugLoc & DL)124*9880d681SAndroid Build Coastguard Worker void addSafePoint(GC::PointKind Kind, MCSymbol *Label, const DebugLoc &DL) { 125*9880d681SAndroid Build Coastguard Worker SafePoints.emplace_back(Kind, Label, DL); 126*9880d681SAndroid Build Coastguard Worker } 127*9880d681SAndroid Build Coastguard Worker 128*9880d681SAndroid Build Coastguard Worker /// getFrameSize/setFrameSize - Records the function's frame size. 129*9880d681SAndroid Build Coastguard Worker /// getFrameSize()130*9880d681SAndroid Build Coastguard Worker uint64_t getFrameSize() const { return FrameSize; } setFrameSize(uint64_t S)131*9880d681SAndroid Build Coastguard Worker void setFrameSize(uint64_t S) { FrameSize = S; } 132*9880d681SAndroid Build Coastguard Worker 133*9880d681SAndroid Build Coastguard Worker /// begin/end - Iterators for safe points. 134*9880d681SAndroid Build Coastguard Worker /// begin()135*9880d681SAndroid Build Coastguard Worker iterator begin() { return SafePoints.begin(); } end()136*9880d681SAndroid Build Coastguard Worker iterator end() { return SafePoints.end(); } size()137*9880d681SAndroid Build Coastguard Worker size_t size() const { return SafePoints.size(); } 138*9880d681SAndroid Build Coastguard Worker 139*9880d681SAndroid Build Coastguard Worker /// roots_begin/roots_end - Iterators for all roots in the function. 140*9880d681SAndroid Build Coastguard Worker /// roots_begin()141*9880d681SAndroid Build Coastguard Worker roots_iterator roots_begin() { return Roots.begin(); } roots_end()142*9880d681SAndroid Build Coastguard Worker roots_iterator roots_end() { return Roots.end(); } roots_size()143*9880d681SAndroid Build Coastguard Worker size_t roots_size() const { return Roots.size(); } 144*9880d681SAndroid Build Coastguard Worker 145*9880d681SAndroid Build Coastguard Worker /// live_begin/live_end - Iterators for live roots at a given safe point. 146*9880d681SAndroid Build Coastguard Worker /// live_begin(const iterator & p)147*9880d681SAndroid Build Coastguard Worker live_iterator live_begin(const iterator &p) { return roots_begin(); } live_end(const iterator & p)148*9880d681SAndroid Build Coastguard Worker live_iterator live_end(const iterator &p) { return roots_end(); } live_size(const iterator & p)149*9880d681SAndroid Build Coastguard Worker size_t live_size(const iterator &p) const { return roots_size(); } 150*9880d681SAndroid Build Coastguard Worker }; 151*9880d681SAndroid Build Coastguard Worker 152*9880d681SAndroid Build Coastguard Worker /// An analysis pass which caches information about the entire Module. 153*9880d681SAndroid Build Coastguard Worker /// Records both the function level information used by GCRoots and a 154*9880d681SAndroid Build Coastguard Worker /// cache of the 'active' gc strategy objects for the current Module. 155*9880d681SAndroid Build Coastguard Worker class GCModuleInfo : public ImmutablePass { 156*9880d681SAndroid Build Coastguard Worker /// An owning list of all GCStrategies which have been created 157*9880d681SAndroid Build Coastguard Worker SmallVector<std::unique_ptr<GCStrategy>, 1> GCStrategyList; 158*9880d681SAndroid Build Coastguard Worker /// A helper map to speedup lookups into the above list 159*9880d681SAndroid Build Coastguard Worker StringMap<GCStrategy*> GCStrategyMap; 160*9880d681SAndroid Build Coastguard Worker 161*9880d681SAndroid Build Coastguard Worker public: 162*9880d681SAndroid Build Coastguard Worker /// Lookup the GCStrategy object associated with the given gc name. 163*9880d681SAndroid Build Coastguard Worker /// Objects are owned internally; No caller should attempt to delete the 164*9880d681SAndroid Build Coastguard Worker /// returned objects. 165*9880d681SAndroid Build Coastguard Worker GCStrategy *getGCStrategy(const StringRef Name); 166*9880d681SAndroid Build Coastguard Worker 167*9880d681SAndroid Build Coastguard Worker /// List of per function info objects. In theory, Each of these 168*9880d681SAndroid Build Coastguard Worker /// may be associated with a different GC. 169*9880d681SAndroid Build Coastguard Worker typedef std::vector<std::unique_ptr<GCFunctionInfo>> FuncInfoVec; 170*9880d681SAndroid Build Coastguard Worker funcinfo_begin()171*9880d681SAndroid Build Coastguard Worker FuncInfoVec::iterator funcinfo_begin() { return Functions.begin(); } funcinfo_end()172*9880d681SAndroid Build Coastguard Worker FuncInfoVec::iterator funcinfo_end() { return Functions.end(); } 173*9880d681SAndroid Build Coastguard Worker 174*9880d681SAndroid Build Coastguard Worker private: 175*9880d681SAndroid Build Coastguard Worker /// Owning list of all GCFunctionInfos associated with this Module 176*9880d681SAndroid Build Coastguard Worker FuncInfoVec Functions; 177*9880d681SAndroid Build Coastguard Worker 178*9880d681SAndroid Build Coastguard Worker /// Non-owning map to bypass linear search when finding the GCFunctionInfo 179*9880d681SAndroid Build Coastguard Worker /// associated with a particular Function. 180*9880d681SAndroid Build Coastguard Worker typedef DenseMap<const Function *, GCFunctionInfo *> finfo_map_type; 181*9880d681SAndroid Build Coastguard Worker finfo_map_type FInfoMap; 182*9880d681SAndroid Build Coastguard Worker 183*9880d681SAndroid Build Coastguard Worker public: 184*9880d681SAndroid Build Coastguard Worker typedef SmallVector<std::unique_ptr<GCStrategy>,1>::const_iterator iterator; 185*9880d681SAndroid Build Coastguard Worker 186*9880d681SAndroid Build Coastguard Worker static char ID; 187*9880d681SAndroid Build Coastguard Worker 188*9880d681SAndroid Build Coastguard Worker GCModuleInfo(); 189*9880d681SAndroid Build Coastguard Worker 190*9880d681SAndroid Build Coastguard Worker /// clear - Resets the pass. Any pass, which uses GCModuleInfo, should 191*9880d681SAndroid Build Coastguard Worker /// call it in doFinalization(). 192*9880d681SAndroid Build Coastguard Worker /// 193*9880d681SAndroid Build Coastguard Worker void clear(); 194*9880d681SAndroid Build Coastguard Worker 195*9880d681SAndroid Build Coastguard Worker /// begin/end - Iterators for used strategies. 196*9880d681SAndroid Build Coastguard Worker /// begin()197*9880d681SAndroid Build Coastguard Worker iterator begin() const { return GCStrategyList.begin(); } end()198*9880d681SAndroid Build Coastguard Worker iterator end() const { return GCStrategyList.end(); } 199*9880d681SAndroid Build Coastguard Worker 200*9880d681SAndroid Build Coastguard Worker /// get - Look up function metadata. This is currently assumed 201*9880d681SAndroid Build Coastguard Worker /// have the side effect of initializing the associated GCStrategy. That 202*9880d681SAndroid Build Coastguard Worker /// will soon change. 203*9880d681SAndroid Build Coastguard Worker GCFunctionInfo &getFunctionInfo(const Function &F); 204*9880d681SAndroid Build Coastguard Worker }; 205*9880d681SAndroid Build Coastguard Worker } 206*9880d681SAndroid Build Coastguard Worker 207*9880d681SAndroid Build Coastguard Worker #endif 208