LLVM API Documentation

GCMetadata.cpp

Go to the documentation of this file.
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 }