GCMetadata.cpp revision 418b6e875f844261064c5dd43e76cb401117ac74
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.isDeclaration() && "Can only get GCFunctionInfo for a definition!"); 103 assert(F.hasCollector()); 104 105 function_map_type::iterator I = Map.find(&F); 106 if (I != Map.end()) 107 return *I->second; 108 109 Collector *C = getOrCreateCollector(F.getParent(), F.getCollector()); 110 CollectorMetadata *MD = C->insertFunctionMetadata(F); 111 Map[&F] = MD; 112 return *MD; 113} 114 115void CollectorModuleMetadata::clear() { 116 Map.clear(); 117 NameMap.clear(); 118 119 for (iterator I = begin(), E = end(); I != E; ++I) 120 delete *I; 121 Collectors.clear(); 122} 123 124// ----------------------------------------------------------------------------- 125 126char Printer::ID = 0; 127 128FunctionPass *llvm::createCollectorMetadataPrinter(std::ostream &OS) { 129 return new Printer(OS); 130} 131 132Printer::Printer(std::ostream &OS) 133 : FunctionPass(intptr_t(&ID)), OS(OS) {} 134 135const char *Printer::getPassName() const { 136 return "Print Garbage Collector Information"; 137} 138 139void Printer::getAnalysisUsage(AnalysisUsage &AU) const { 140 FunctionPass::getAnalysisUsage(AU); 141 AU.setPreservesAll(); 142 AU.addRequired<CollectorModuleMetadata>(); 143} 144 145static const char *DescKind(GC::PointKind Kind) { 146 switch (Kind) { 147 default: assert(0 && "Unknown GC point kind"); 148 case GC::Loop: return "loop"; 149 case GC::Return: return "return"; 150 case GC::PreCall: return "pre-call"; 151 case GC::PostCall: return "post-call"; 152 } 153} 154 155bool Printer::runOnFunction(Function &F) { 156 if (F.hasCollector()) { 157 CollectorMetadata *FD = &getAnalysis<CollectorModuleMetadata>().get(F); 158 159 OS << "GC roots for " << FD->getFunction().getNameStart() << ":\n"; 160 for (CollectorMetadata::roots_iterator RI = FD->roots_begin(), 161 RE = FD->roots_end(); 162 RI != RE; ++RI) 163 OS << "\t" << RI->Num << "\t" << RI->StackOffset << "[sp]\n"; 164 165 OS << "GC safe points for " << FD->getFunction().getNameStart() << ":\n"; 166 for (CollectorMetadata::iterator PI = FD->begin(), 167 PE = FD->end(); PI != PE; ++PI) { 168 169 OS << "\tlabel " << PI->Num << ": " << DescKind(PI->Kind) << ", live = {"; 170 171 for (CollectorMetadata::live_iterator RI = FD->live_begin(PI), 172 RE = FD->live_end(PI);;) { 173 OS << " " << RI->Num; 174 if (++RI == RE) 175 break; 176 OS << ","; 177 } 178 179 OS << " }\n"; 180 } 181 } 182 183 return false; 184} 185 186// ----------------------------------------------------------------------------- 187 188char Deleter::ID = 0; 189 190FunctionPass *llvm::createCollectorMetadataDeleter() { 191 return new Deleter(); 192} 193 194Deleter::Deleter() : FunctionPass(intptr_t(&ID)) {} 195 196const char *Deleter::getPassName() const { 197 return "Delete Garbage Collector Information"; 198} 199 200void Deleter::getAnalysisUsage(AnalysisUsage &AU) const { 201 AU.setPreservesAll(); 202 AU.addRequired<CollectorModuleMetadata>(); 203} 204 205bool Deleter::runOnFunction(Function &MF) { 206 return false; 207} 208 209bool Deleter::doFinalization(Module &M) { 210 CollectorModuleMetadata *CMM = getAnalysisToUpdate<CollectorModuleMetadata>(); 211 assert(CMM && "Deleter didn't require CollectorModuleMetadata?!"); 212 CMM->clear(); 213 return false; 214} 215