LLVM API Documentation
00001 //===-- GCMetadata.cpp - Garbage collector metadata -----------------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements the GCFunctionInfo class and GCModuleInfo pass. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "llvm/CodeGen/GCMetadata.h" 00015 #include "llvm/CodeGen/GCStrategy.h" 00016 #include "llvm/CodeGen/MachineFrameInfo.h" 00017 #include "llvm/Pass.h" 00018 #include "llvm/CodeGen/Passes.h" 00019 #include "llvm/Function.h" 00020 #include "llvm/Support/Compiler.h" 00021 00022 using namespace llvm; 00023 00024 namespace { 00025 00026 class VISIBILITY_HIDDEN Printer : public FunctionPass { 00027 static char ID; 00028 std::ostream &OS; 00029 00030 public: 00031 explicit Printer(std::ostream &OS = *cerr); 00032 00033 const char *getPassName() const; 00034 void getAnalysisUsage(AnalysisUsage &AU) const; 00035 00036 bool runOnFunction(Function &F); 00037 }; 00038 00039 class VISIBILITY_HIDDEN Deleter : public FunctionPass { 00040 static char ID; 00041 00042 public: 00043 Deleter(); 00044 00045 const char *getPassName() const; 00046 void getAnalysisUsage(AnalysisUsage &AU) const; 00047 00048 bool runOnFunction(Function &F); 00049 bool doFinalization(Module &M); 00050 }; 00051 00052 } 00053 00054 static RegisterPass<GCModuleInfo> 00055 X("collector-metadata", "Create Garbage Collector Module Metadata"); 00056 00057 // ----------------------------------------------------------------------------- 00058 00059 GCFunctionInfo::GCFunctionInfo(const Function &F, GCStrategy &S) 00060 : F(F), S(S), FrameSize(~0LL) {} 00061 00062 GCFunctionInfo::~GCFunctionInfo() {} 00063 00064 // ----------------------------------------------------------------------------- 00065 00066 char GCModuleInfo::ID = 0; 00067 00068 GCModuleInfo::GCModuleInfo() 00069 : ImmutablePass(&ID) {} 00070 00071 GCModuleInfo::~GCModuleInfo() { 00072 clear(); 00073 } 00074 00075 GCStrategy *GCModuleInfo::getOrCreateStrategy(const Module *M, 00076 const std::string &Name) { 00077 const char *Start = Name.c_str(); 00078 00079 strategy_map_type::iterator NMI = 00080 StrategyMap.find(Start, Start + Name.size()); 00081 if (NMI != StrategyMap.end()) 00082 return NMI->getValue(); 00083 00084 for (GCRegistry::iterator I = GCRegistry::begin(), 00085 E = GCRegistry::end(); I != E; ++I) { 00086 if (strcmp(Start, I->getName()) == 0) { 00087 GCStrategy *S = I->instantiate(); 00088 S->M = M; 00089 S->Name = Name; 00090 StrategyMap.GetOrCreateValue(Start, Start + Name.size()).setValue(S); 00091 StrategyList.push_back(S); 00092 return S; 00093 } 00094 } 00095 00096 cerr << "unsupported GC: " << Name << "\n"; 00097 abort(); 00098 } 00099 00100 GCFunctionInfo &GCModuleInfo::getFunctionInfo(const Function &F) { 00101 assert(!F.isDeclaration() && "Can only get GCFunctionInfo for a definition!"); 00102 assert(F.hasGC()); 00103 00104 finfo_map_type::iterator I = FInfoMap.find(&F); 00105 if (I != FInfoMap.end()) 00106 return *I->second; 00107 00108 GCStrategy *S = getOrCreateStrategy(F.getParent(), F.getGC()); 00109 GCFunctionInfo *GFI = S->insertFunctionInfo(F); 00110 FInfoMap[&F] = GFI; 00111 return *GFI; 00112 } 00113 00114 void GCModuleInfo::clear() { 00115 FInfoMap.clear(); 00116 StrategyMap.clear(); 00117 00118 for (iterator I = begin(), E = end(); I != E; ++I) 00119 delete *I; 00120 StrategyList.clear(); 00121 } 00122 00123 // ----------------------------------------------------------------------------- 00124 00125 char Printer::ID = 0; 00126 00127 FunctionPass *llvm::createGCInfoPrinter(std::ostream &OS) { 00128 return new Printer(OS); 00129 } 00130 00131 Printer::Printer(std::ostream &OS) 00132 : FunctionPass(intptr_t(&ID)), OS(OS) {} 00133 00134 const char *Printer::getPassName() const { 00135 return "Print Garbage Collector Information"; 00136 } 00137 00138 void Printer::getAnalysisUsage(AnalysisUsage &AU) const { 00139 FunctionPass::getAnalysisUsage(AU); 00140 AU.setPreservesAll(); 00141 AU.addRequired<GCModuleInfo>(); 00142 } 00143 00144 static const char *DescKind(GC::PointKind Kind) { 00145 switch (Kind) { 00146 default: assert(0 && "Unknown GC point kind"); 00147 case GC::Loop: return "loop"; 00148 case GC::Return: return "return"; 00149 case GC::PreCall: return "pre-call"; 00150 case GC::PostCall: return "post-call"; 00151 } 00152 } 00153 00154 bool Printer::runOnFunction(Function &F) { 00155 if (!F.hasGC()) { 00156 GCFunctionInfo *FD = &getAnalysis<GCModuleInfo>().getFunctionInfo(F); 00157 00158 OS << "GC roots for " << FD->getFunction().getNameStart() << ":\n"; 00159 for (GCFunctionInfo::roots_iterator RI = FD->roots_begin(), 00160 RE = FD->roots_end(); RI != RE; ++RI) 00161 OS << "\t" << RI->Num << "\t" << RI->StackOffset << "[sp]\n"; 00162 00163 OS << "GC safe points for " << FD->getFunction().getNameStart() << ":\n"; 00164 for (GCFunctionInfo::iterator PI = FD->begin(), 00165 PE = FD->end(); PI != PE; ++PI) { 00166 00167 OS << "\tlabel " << PI->Num << ": " << DescKind(PI->Kind) << ", live = {"; 00168 00169 for (GCFunctionInfo::live_iterator RI = FD->live_begin(PI), 00170 RE = FD->live_end(PI);;) { 00171 OS << " " << RI->Num; 00172 if (++RI == RE) 00173 break; 00174 OS << ","; 00175 } 00176 00177 OS << " }\n"; 00178 } 00179 } 00180 00181 return false; 00182 } 00183 00184 // ----------------------------------------------------------------------------- 00185 00186 char Deleter::ID = 0; 00187 00188 FunctionPass *llvm::createGCInfoDeleter() { 00189 return new Deleter(); 00190 } 00191 00192 Deleter::Deleter() : FunctionPass(intptr_t(&ID)) {} 00193 00194 const char *Deleter::getPassName() const { 00195 return "Delete Garbage Collector Information"; 00196 } 00197 00198 void Deleter::getAnalysisUsage(AnalysisUsage &AU) const { 00199 AU.setPreservesAll(); 00200 AU.addRequired<GCModuleInfo>(); 00201 } 00202 00203 bool Deleter::runOnFunction(Function &MF) { 00204 return false; 00205 } 00206 00207 bool Deleter::doFinalization(Module &M) { 00208 GCModuleInfo *GMI = getAnalysisIfAvailable<GCModuleInfo>(); 00209 assert(GMI && "Deleter didn't require GCModuleInfo?!"); 00210 GMI->clear(); 00211 return false; 00212 }