GCMetadata.cpp revision f194af2c195199ed66d8a1a9df60acf69bb14410
1//===-- CollectorMetadata.cpp - Garbage collector metadata ----------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file implements the CollectorMetadata and CollectorModuleMetadata 11// classes. 12// 13//===----------------------------------------------------------------------===// 14 15#include "llvm/CodeGen/GCMetadata.h" 16#include "llvm/CodeGen/GCStrategy.h" 17#include "llvm/CodeGen/GCs.h" 18#include "llvm/CodeGen/MachineFrameInfo.h" 19#include "llvm/Pass.h" 20#include "llvm/CodeGen/Passes.h" 21#include "llvm/Function.h" 22#include "llvm/Support/Compiler.h" 23 24using namespace llvm; 25 26namespace { 27 28 class VISIBILITY_HIDDEN Printer : public FunctionPass { 29 static char ID; 30 std::ostream &OS; 31 32 public: 33 explicit Printer(std::ostream &OS = *cerr); 34 35 const char *getPassName() const; 36 void getAnalysisUsage(AnalysisUsage &AU) const; 37 38 bool runOnFunction(Function &F); 39 }; 40 41 class VISIBILITY_HIDDEN Deleter : public FunctionPass { 42 static char ID; 43 44 public: 45 Deleter(); 46 47 const char *getPassName() const; 48 void getAnalysisUsage(AnalysisUsage &AU) const; 49 50 bool runOnFunction(Function &F); 51 bool doFinalization(Module &M); 52 }; 53 54} 55 56static RegisterPass<CollectorModuleMetadata> 57X("collector-metadata", "Create Garbage Collector Module Metadata"); 58 59// ----------------------------------------------------------------------------- 60 61CollectorMetadata::CollectorMetadata(const Function &F, Collector &C) 62 : F(F), C(C), FrameSize(~0LL) {} 63 64CollectorMetadata::~CollectorMetadata() {} 65 66// ----------------------------------------------------------------------------- 67 68char CollectorModuleMetadata::ID = 0; 69 70CollectorModuleMetadata::CollectorModuleMetadata() 71 : ImmutablePass((intptr_t)&ID) {} 72 73CollectorModuleMetadata::~CollectorModuleMetadata() { 74 clear(); 75} 76 77Collector *CollectorModuleMetadata:: 78getOrCreateCollector(const Module *M, const std::string &Name) { 79 const char *Start = Name.c_str(); 80 81 collector_map_type::iterator NMI = NameMap.find(Start, Start + Name.size()); 82 if (NMI != NameMap.end()) 83 return NMI->getValue(); 84 85 for (CollectorRegistry::iterator I = CollectorRegistry::begin(), 86 E = CollectorRegistry::end(); I != E; ++I) { 87 if (strcmp(Start, I->getName()) == 0) { 88 Collector *C = I->instantiate(); 89 C->M = M; 90 C->Name = Name; 91 NameMap.GetOrCreateValue(Start, Start + Name.size()).setValue(C); 92 Collectors.push_back(C); 93 return C; 94 } 95 } 96 97 cerr << "unsupported collector: " << Name << "\n"; 98 abort(); 99} 100 101CollectorMetadata &CollectorModuleMetadata::get(const Function &F) { 102 assert(F.hasCollector()); 103 function_map_type::iterator I = Map.find(&F); 104 if (I != Map.end()) 105 return *I->second; 106 107 Collector *C = getOrCreateCollector(F.getParent(), F.getCollector()); 108 CollectorMetadata *MD = C->insertFunctionMetadata(F); 109 Map[&F] = MD; 110 return *MD; 111} 112 113void CollectorModuleMetadata::clear() { 114 Map.clear(); 115 NameMap.clear(); 116 117 for (iterator I = begin(), E = end(); I != E; ++I) 118 delete *I; 119 Collectors.clear(); 120} 121 122// ----------------------------------------------------------------------------- 123 124char Printer::ID = 0; 125 126FunctionPass *llvm::createCollectorMetadataPrinter(std::ostream &OS) { 127 return new Printer(OS); 128} 129 130Printer::Printer(std::ostream &OS) 131 : FunctionPass(intptr_t(&ID)), OS(OS) {} 132 133const char *Printer::getPassName() const { 134 return "Print Garbage Collector Information"; 135} 136 137void Printer::getAnalysisUsage(AnalysisUsage &AU) const { 138 FunctionPass::getAnalysisUsage(AU); 139 AU.setPreservesAll(); 140 AU.addRequired<CollectorModuleMetadata>(); 141} 142 143static const char *DescKind(GC::PointKind Kind) { 144 switch (Kind) { 145 default: assert(0 && "Unknown GC point kind"); 146 case GC::Loop: return "loop"; 147 case GC::Return: return "return"; 148 case GC::PreCall: return "pre-call"; 149 case GC::PostCall: return "post-call"; 150 } 151} 152 153bool Printer::runOnFunction(Function &F) { 154 if (F.hasCollector()) { 155 CollectorMetadata *FD = &getAnalysis<CollectorModuleMetadata>().get(F); 156 157 OS << "GC roots for " << FD->getFunction().getNameStart() << ":\n"; 158 for (CollectorMetadata::roots_iterator RI = FD->roots_begin(), 159 RE = FD->roots_end(); 160 RI != RE; ++RI) 161 OS << "\t" << RI->Num << "\t" << RI->StackOffset << "[sp]\n"; 162 163 OS << "GC safe points for " << FD->getFunction().getNameStart() << ":\n"; 164 for (CollectorMetadata::iterator PI = FD->begin(), 165 PE = FD->end(); PI != PE; ++PI) { 166 167 OS << "\tlabel " << PI->Num << ": " << DescKind(PI->Kind) << ", live = {"; 168 169 for (CollectorMetadata::live_iterator RI = FD->live_begin(PI), 170 RE = FD->live_end(PI);;) { 171 OS << " " << RI->Num; 172 if (++RI == RE) 173 break; 174 OS << ","; 175 } 176 177 OS << " }\n"; 178 } 179 } 180 181 return false; 182} 183 184// ----------------------------------------------------------------------------- 185 186char Deleter::ID = 0; 187 188FunctionPass *llvm::createCollectorMetadataDeleter() { 189 return new Deleter(); 190} 191 192Deleter::Deleter() : FunctionPass(intptr_t(&ID)) {} 193 194const char *Deleter::getPassName() const { 195 return "Delete Garbage Collector Information"; 196} 197 198void Deleter::getAnalysisUsage(AnalysisUsage &AU) const { 199 AU.setPreservesAll(); 200 AU.addRequired<CollectorModuleMetadata>(); 201} 202 203bool Deleter::runOnFunction(Function &MF) { 204 return false; 205} 206 207bool Deleter::doFinalization(Module &M) { 208 CollectorModuleMetadata *CMM = getAnalysisToUpdate<CollectorModuleMetadata>(); 209 assert(CMM && "Deleter didn't require CollectorModuleMetadata?!"); 210 CMM->clear(); 211 return false; 212} 213