//===-- CollectorMetadata.cpp - Garbage collector metadata ----------------===// // // The LLVM Compiler Infrastructure // // This file was developed by Gordon Henriksen and 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/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/Function.h" #include "llvm/Support/Compiler.h" using namespace llvm; namespace { class VISIBILITY_HIDDEN Printer : public MachineFunctionPass { static char ID; std::ostream &OS; public: Printer(std::ostream &OS = *cerr); const char *getPassName() const; void getAnalysisUsage(AnalysisUsage &AU) const; bool runOnMachineFunction(MachineFunction &MF); }; class VISIBILITY_HIDDEN Deleter : public MachineFunctionPass { static char ID; public: Deleter(); const char *getPassName() const; void getAnalysisUsage(AnalysisUsage &AU) const; bool runOnMachineFunction(MachineFunction &MF); bool doFinalization(Module &M); }; RegisterPass X("collector-metadata", "Create Garbage Collector Module Metadata"); } // ----------------------------------------------------------------------------- CollectorMetadata::CollectorMetadata(const Function &F) : F(F), FrameSize(~0LL) {} CollectorMetadata::~CollectorMetadata() {} // ----------------------------------------------------------------------------- char CollectorModuleMetadata::ID = 0; CollectorModuleMetadata::CollectorModuleMetadata() : ImmutablePass((intptr_t)&ID) {} CollectorModuleMetadata::~CollectorModuleMetadata() { clear(); } CollectorMetadata& CollectorModuleMetadata::insert(const Function *F) { assert(Map.find(F) == Map.end() && "Function GC metadata already exists!"); CollectorMetadata *FMD = new CollectorMetadata(*F); Functions.push_back(FMD); Map[F] = FMD; return *FMD; } CollectorMetadata* CollectorModuleMetadata::get(const Function *F) const { map_type::iterator I = Map.find(F); if (I == Map.end()) return 0; return I->second; } void CollectorModuleMetadata::clear() { for (iterator I = begin(), E = end(); I != E; ++I) delete *I; Functions.clear(); Map.clear(); } // ----------------------------------------------------------------------------- char Printer::ID = 0; Pass *llvm::createCollectorMetadataPrinter(std::ostream &OS) { return new Printer(OS); } Printer::Printer(std::ostream &OS) : MachineFunctionPass(intptr_t(&ID)), OS(OS) {} const char *Printer::getPassName() const { return "Print Garbage Collector Information"; } void Printer::getAnalysisUsage(AnalysisUsage &AU) const { MachineFunctionPass::getAnalysisUsage(AU); AU.setPreservesAll(); AU.addRequired(); } 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::runOnMachineFunction(MachineFunction &MF) { if (CollectorMetadata *FD = getAnalysis().get(MF.getFunction())) { 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; Pass *llvm::createCollectorMetadataDeleter() { return new Deleter(); } Deleter::Deleter() : MachineFunctionPass(intptr_t(&ID)) {} const char *Deleter::getPassName() const { return "Delete Garbage Collector Information"; } void Deleter::getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); AU.addRequired(); } bool Deleter::runOnMachineFunction(MachineFunction &MF) { return false; } bool Deleter::doFinalization(Module &M) { getAnalysis().clear(); return false; }