X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FGCMetadata.cpp;h=c8116a453d2dc6567309e6dafece6d0d3a7aab87;hb=3808efa2e6e2da057c29c4fdc4ef083a244f9371;hp=efb89e128e4d1aa99c2d87d73a4338adb04ce609;hpb=5eca075b74d62c621b160aa216b4cd50829a2cc7;p=oota-llvm.git diff --git a/lib/CodeGen/GCMetadata.cpp b/lib/CodeGen/GCMetadata.cpp index efb89e128e4..c8116a453d2 100644 --- a/lib/CodeGen/GCMetadata.cpp +++ b/lib/CodeGen/GCMetadata.cpp @@ -14,50 +14,39 @@ #include "llvm/CodeGen/GCMetadata.h" #include "llvm/CodeGen/GCStrategy.h" #include "llvm/CodeGen/MachineFrameInfo.h" -#include "llvm/Pass.h" #include "llvm/CodeGen/Passes.h" -#include "llvm/Function.h" -#include "llvm/Support/Compiler.h" - +#include "llvm/IR/Function.h" +#include "llvm/MC/MCSymbol.h" +#include "llvm/Pass.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.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); - }; - + +class Printer : public FunctionPass { + static char ID; + raw_ostream &OS; + +public: + explicit Printer(raw_ostream &OS) : FunctionPass(ID), OS(OS) {} + + const char *getPassName() const override; + void getAnalysisUsage(AnalysisUsage &AU) const override; + + bool runOnFunction(Function &F) override; + bool doFinalization(Module &M) override; +}; } -static RegisterPass -X("collector-metadata", "Create Garbage Collector Module Metadata"); +INITIALIZE_PASS(GCModuleInfo, "collector-metadata", + "Create Garbage Collector Module Metadata", false, false) // ----------------------------------------------------------------------------- GCFunctionInfo::GCFunctionInfo(const Function &F, GCStrategy &S) - : F(F), S(S), FrameSize(~0LL) {} + : F(F), S(S), FrameSize(~0LL) {} GCFunctionInfo::~GCFunctionInfo() {} @@ -65,72 +54,39 @@ GCFunctionInfo::~GCFunctionInfo() {} char GCModuleInfo::ID = 0; -GCModuleInfo::GCModuleInfo() - : ImmutablePass((intptr_t)&ID) {} - -GCModuleInfo::~GCModuleInfo() { - clear(); -} - -GCStrategy *GCModuleInfo::getOrCreateStrategy(const Module *M, - const std::string &Name) { - const char *Start = Name.c_str(); - - strategy_map_type::iterator NMI = - StrategyMap.find(Start, Start + Name.size()); - if (NMI != StrategyMap.end()) - return NMI->getValue(); - - for (GCRegistry::iterator I = GCRegistry::begin(), - E = GCRegistry::end(); I != E; ++I) { - if (strcmp(Start, I->getName()) == 0) { - GCStrategy *S = I->instantiate(); - S->M = M; - S->Name = Name; - StrategyMap.GetOrCreateValue(Start, Start + Name.size()).setValue(S); - StrategyList.push_back(S); - return S; - } - } - - cerr << "unsupported GC: " << Name << "\n"; - abort(); +GCModuleInfo::GCModuleInfo() : ImmutablePass(ID) { + initializeGCModuleInfoPass(*PassRegistry::getPassRegistry()); } GCFunctionInfo &GCModuleInfo::getFunctionInfo(const Function &F) { assert(!F.isDeclaration() && "Can only get GCFunctionInfo for a definition!"); assert(F.hasGC()); - + finfo_map_type::iterator I = FInfoMap.find(&F); if (I != FInfoMap.end()) return *I->second; - - GCStrategy *S = getOrCreateStrategy(F.getParent(), F.getGC()); - GCFunctionInfo *GFI = S->insertFunctionInfo(F); + + GCStrategy *S = getGCStrategy(F.getGC()); + Functions.push_back(make_unique(F, *S)); + GCFunctionInfo *GFI = Functions.back().get(); FInfoMap[&F] = GFI; return *GFI; } void GCModuleInfo::clear() { + Functions.clear(); FInfoMap.clear(); - StrategyMap.clear(); - - for (iterator I = begin(), E = end(); I != E; ++I) - delete *I; - StrategyList.clear(); + GCStrategyList.clear(); } // ----------------------------------------------------------------------------- char Printer::ID = 0; -FunctionPass *llvm::createGCInfoPrinter(std::ostream &OS) { +FunctionPass *llvm::createGCInfoPrinter(raw_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"; } @@ -143,70 +99,79 @@ void Printer::getAnalysisUsage(AnalysisUsage &AU) const { 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"; + case GC::PreCall: + return "pre-call"; + case GC::PostCall: + return "post-call"; } + llvm_unreachable("Invalid point kind"); } bool Printer::runOnFunction(Function &F) { - if (!F.hasGC()) { - GCFunctionInfo *FD = &getAnalysis().getFunctionInfo(F); - - OS << "GC roots for " << FD->getFunction().getNameStart() << ":\n"; - for (GCFunctionInfo::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 (GCFunctionInfo::iterator PI = FD->begin(), - PE = FD->end(); PI != PE; ++PI) { - - OS << "\tlabel " << PI->Num << ": " << DescKind(PI->Kind) << ", live = {"; - - for (GCFunctionInfo::live_iterator RI = FD->live_begin(PI), - RE = FD->live_end(PI);;) { - OS << " " << RI->Num; - if (++RI == RE) - break; - OS << ","; - } - - OS << " }\n"; + if (F.hasGC()) + return false; + + GCFunctionInfo *FD = &getAnalysis().getFunctionInfo(F); + + OS << "GC roots for " << FD->getFunction().getName() << ":\n"; + for (GCFunctionInfo::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().getName() << ":\n"; + for (GCFunctionInfo::iterator PI = FD->begin(), PE = FD->end(); PI != PE; + ++PI) { + + OS << "\t" << PI->Label->getName() << ": " << DescKind(PI->Kind) + << ", live = {"; + + for (GCFunctionInfo::live_iterator RI = FD->live_begin(PI), + RE = FD->live_end(PI); + ;) { + OS << " " << RI->Num; + if (++RI == RE) + break; + OS << ","; } - } - - return false; -} - -// ----------------------------------------------------------------------------- - -char Deleter::ID = 0; - -FunctionPass *llvm::createGCInfoDeleter() { - 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(); -} + OS << " }\n"; + } -bool Deleter::runOnFunction(Function &MF) { return false; } -bool Deleter::doFinalization(Module &M) { - GCModuleInfo *GMI = getAnalysisToUpdate(); - assert(GMI && "Deleter didn't require GCModuleInfo?!"); +bool Printer::doFinalization(Module &M) { + GCModuleInfo *GMI = getAnalysisIfAvailable(); + assert(GMI && "Printer didn't require GCModuleInfo?!"); GMI->clear(); return false; } + +GCStrategy *GCModuleInfo::getGCStrategy(const StringRef Name) { + // TODO: Arguably, just doing a linear search would be faster for small N + auto NMI = GCStrategyMap.find(Name); + if (NMI != GCStrategyMap.end()) + return NMI->getValue(); + + for (auto& Entry : GCRegistry::entries()) { + if (Name == Entry.getName()) { + std::unique_ptr S = Entry.instantiate(); + S->Name = Name; + GCStrategyMap[Name] = S.get(); + GCStrategyList.push_back(std::move(S)); + return GCStrategyList.back().get(); + } + } + + if (GCRegistry::begin() == GCRegistry::end()) { + // In normal operation, the registry should not be empty. There should + // be the builtin GCs if nothing else. The most likely scenario here is + // that we got here without running the initializers used by the Registry + // itself and it's registration mechanism. + const std::string error = ("unsupported GC: " + Name).str() + + " (did you remember to link and initialize the CodeGen library?)"; + report_fatal_error(error); + } else + report_fatal_error(std::string("unsupported GC: ") + Name); +}