| //===-- CollectorMetadata.cpp - Garbage collector metadata ----------------===// | 
 | // | 
 | //                     The LLVM Compiler Infrastructure | 
 | // | 
 | // This file is distributed under the University of Illinois Open Source | 
 | // License. See LICENSE.TXT for details. | 
 | // | 
 | //===----------------------------------------------------------------------===// | 
 | // | 
 | // This file implements the CollectorMetadata and CollectorModuleMetadata | 
 | // classes. | 
 | // | 
 | //===----------------------------------------------------------------------===// | 
 |  | 
 | #include "llvm/CodeGen/CollectorMetadata.h" | 
 | #include "llvm/CodeGen/Collector.h" | 
 | #include "llvm/CodeGen/Collectors.h" | 
 | #include "llvm/CodeGen/MachineFrameInfo.h" | 
 | #include "llvm/Pass.h" | 
 | #include "llvm/CodeGen/Passes.h" | 
 | #include "llvm/Function.h" | 
 | #include "llvm/Support/Compiler.h" | 
 |  | 
 | using namespace llvm; | 
 |  | 
 | namespace { | 
 |    | 
 |   class VISIBILITY_HIDDEN Printer : public FunctionPass { | 
 |     static char ID; | 
 |     std::ostream &OS; | 
 |      | 
 |   public: | 
 |     explicit Printer(std::ostream &OS = *cerr); | 
 |      | 
 |     const char *getPassName() const; | 
 |     void getAnalysisUsage(AnalysisUsage &AU) const; | 
 |      | 
 |     bool runOnFunction(Function &F); | 
 |   }; | 
 |    | 
 |   class VISIBILITY_HIDDEN Deleter : public FunctionPass { | 
 |     static char ID; | 
 |      | 
 |   public: | 
 |     Deleter(); | 
 |      | 
 |     const char *getPassName() const; | 
 |     void getAnalysisUsage(AnalysisUsage &AU) const; | 
 |      | 
 |     bool runOnFunction(Function &F); | 
 |     bool doFinalization(Module &M); | 
 |   }; | 
 |    | 
 | } | 
 |  | 
 | static RegisterPass<CollectorModuleMetadata> | 
 | X("collector-metadata", "Create Garbage Collector Module Metadata"); | 
 |  | 
 | // ----------------------------------------------------------------------------- | 
 |  | 
 | CollectorMetadata::CollectorMetadata(const Function &F, Collector &C) | 
 |   : F(F), C(C), FrameSize(~0LL) {} | 
 |  | 
 | CollectorMetadata::~CollectorMetadata() {} | 
 |  | 
 | // ----------------------------------------------------------------------------- | 
 |  | 
 | char CollectorModuleMetadata::ID = 0; | 
 |  | 
 | CollectorModuleMetadata::CollectorModuleMetadata() | 
 |   : ImmutablePass((intptr_t)&ID) {} | 
 |  | 
 | CollectorModuleMetadata::~CollectorModuleMetadata() { | 
 |   clear(); | 
 | } | 
 |  | 
 | Collector *CollectorModuleMetadata:: | 
 | getOrCreateCollector(const Module *M, const std::string &Name) { | 
 |   const char *Start = Name.c_str(); | 
 |    | 
 |   collector_map_type::iterator NMI = NameMap.find(Start, Start + Name.size()); | 
 |   if (NMI != NameMap.end()) | 
 |     return NMI->getValue(); | 
 |    | 
 |   for (CollectorRegistry::iterator I = CollectorRegistry::begin(), | 
 |                                    E = CollectorRegistry::end(); I != E; ++I) { | 
 |     if (strcmp(Start, I->getName()) == 0) { | 
 |       Collector *C = I->instantiate(); | 
 |       C->M = M; | 
 |       C->Name = Name; | 
 |       NameMap.GetOrCreateValue(Start, Start + Name.size()).setValue(C); | 
 |       Collectors.push_back(C); | 
 |       return C; | 
 |     } | 
 |   } | 
 |    | 
 |   cerr << "unsupported collector: " << Name << "\n"; | 
 |   abort(); | 
 | } | 
 |  | 
 | CollectorMetadata &CollectorModuleMetadata::get(const Function &F) { | 
 |   assert(F.hasCollector()); | 
 |   function_map_type::iterator I = Map.find(&F); | 
 |   if (I != Map.end()) | 
 |     return *I->second; | 
 |      | 
 |   Collector *C = getOrCreateCollector(F.getParent(), F.getCollector()); | 
 |   CollectorMetadata *MD = C->insertFunctionMetadata(F); | 
 |   Map[&F] = MD; | 
 |   return *MD; | 
 | } | 
 |  | 
 | void CollectorModuleMetadata::clear() { | 
 |   Map.clear(); | 
 |   NameMap.clear(); | 
 |    | 
 |   for (iterator I = begin(), E = end(); I != E; ++I) | 
 |     delete *I; | 
 |   Collectors.clear(); | 
 | } | 
 |  | 
 | // ----------------------------------------------------------------------------- | 
 |  | 
 | char Printer::ID = 0; | 
 |  | 
 | FunctionPass *llvm::createCollectorMetadataPrinter(std::ostream &OS) { | 
 |   return new Printer(OS); | 
 | } | 
 |  | 
 | Printer::Printer(std::ostream &OS) | 
 |   : FunctionPass(intptr_t(&ID)), OS(OS) {} | 
 |  | 
 | const char *Printer::getPassName() const { | 
 |   return "Print Garbage Collector Information"; | 
 | } | 
 |  | 
 | void Printer::getAnalysisUsage(AnalysisUsage &AU) const { | 
 |   FunctionPass::getAnalysisUsage(AU); | 
 |   AU.setPreservesAll(); | 
 |   AU.addRequired<CollectorModuleMetadata>(); | 
 | } | 
 |  | 
 | static const char *DescKind(GC::PointKind Kind) { | 
 |   switch (Kind) { | 
 |     default: assert(0 && "Unknown GC point kind"); | 
 |     case GC::Loop:     return "loop"; | 
 |     case GC::Return:   return "return"; | 
 |     case GC::PreCall:  return "pre-call"; | 
 |     case GC::PostCall: return "post-call"; | 
 |   } | 
 | } | 
 |  | 
 | bool Printer::runOnFunction(Function &F) { | 
 |   if (F.hasCollector()) { | 
 |     CollectorMetadata *FD = &getAnalysis<CollectorModuleMetadata>().get(F); | 
 |      | 
 |     OS << "GC roots for " << FD->getFunction().getNameStart() << ":\n"; | 
 |     for (CollectorMetadata::roots_iterator RI = FD->roots_begin(), | 
 |                                            RE = FD->roots_end(); | 
 |                                            RI != RE; ++RI) | 
 |       OS << "\t" << RI->Num << "\t" << RI->StackOffset << "[sp]\n"; | 
 |      | 
 |     OS << "GC safe points for " << FD->getFunction().getNameStart() << ":\n"; | 
 |     for (CollectorMetadata::iterator PI = FD->begin(), | 
 |                                      PE = FD->end(); PI != PE; ++PI) { | 
 |        | 
 |       OS << "\tlabel " << PI->Num << ": " << DescKind(PI->Kind) << ", live = {"; | 
 |        | 
 |       for (CollectorMetadata::live_iterator RI = FD->live_begin(PI), | 
 |                                             RE = FD->live_end(PI);;) { | 
 |         OS << " " << RI->Num; | 
 |         if (++RI == RE) | 
 |           break; | 
 |         OS << ","; | 
 |       } | 
 |        | 
 |       OS << " }\n"; | 
 |     } | 
 |   } | 
 |    | 
 |   return false; | 
 | } | 
 |  | 
 | // ----------------------------------------------------------------------------- | 
 |  | 
 | char Deleter::ID = 0; | 
 |  | 
 | FunctionPass *llvm::createCollectorMetadataDeleter() { | 
 |   return new Deleter(); | 
 | } | 
 |  | 
 | Deleter::Deleter() : FunctionPass(intptr_t(&ID)) {} | 
 |  | 
 | const char *Deleter::getPassName() const { | 
 |   return "Delete Garbage Collector Information"; | 
 | } | 
 |  | 
 | void Deleter::getAnalysisUsage(AnalysisUsage &AU) const { | 
 |   AU.setPreservesAll(); | 
 |   AU.addRequired<CollectorModuleMetadata>(); | 
 | } | 
 |  | 
 | bool Deleter::runOnFunction(Function &MF) { | 
 |   return false; | 
 | } | 
 |  | 
 | bool Deleter::doFinalization(Module &M) { | 
 |   CollectorModuleMetadata *CMM = getAnalysisToUpdate<CollectorModuleMetadata>(); | 
 |   assert(CMM && "Deleter didn't require CollectorModuleMetadata?!"); | 
 |   CMM->clear(); | 
 |   return false; | 
 | } |