diff options
Diffstat (limited to 'contrib/llvm/lib/CodeGen/GCMetadata.cpp')
-rw-r--r-- | contrib/llvm/lib/CodeGen/GCMetadata.cpp | 127 |
1 files changed, 66 insertions, 61 deletions
diff --git a/contrib/llvm/lib/CodeGen/GCMetadata.cpp b/contrib/llvm/lib/CodeGen/GCMetadata.cpp index 6101c67..cba7f5f 100644 --- a/contrib/llvm/lib/CodeGen/GCMetadata.cpp +++ b/contrib/llvm/lib/CodeGen/GCMetadata.cpp @@ -24,23 +24,21 @@ using namespace llvm; namespace { - - class Printer : public FunctionPass { - static char ID; - raw_ostream &OS; - - public: - explicit Printer(raw_ostream &OS) : FunctionPass(ID), OS(OS) {} +class Printer : public FunctionPass { + static char ID; + raw_ostream &OS; - const char *getPassName() const override; - void getAnalysisUsage(AnalysisUsage &AU) const override; +public: + explicit Printer(raw_ostream &OS) : FunctionPass(ID), OS(OS) {} - bool runOnFunction(Function &F) override; - bool doFinalization(Module &M) override; - }; + const char *getPassName() const override; + void getAnalysisUsage(AnalysisUsage &AU) const override; -} + bool runOnFunction(Function &F) override; + bool doFinalization(Module &M) override; +}; +} // namespace INITIALIZE_PASS(GCModuleInfo, "collector-metadata", "Create Garbage Collector Module Metadata", false, false) @@ -48,7 +46,7 @@ INITIALIZE_PASS(GCModuleInfo, "collector-metadata", // ----------------------------------------------------------------------------- GCFunctionInfo::GCFunctionInfo(const Function &F, GCStrategy &S) - : F(F), S(S), FrameSize(~0LL) {} + : F(F), S(S), FrameSize(~0LL) {} GCFunctionInfo::~GCFunctionInfo() {} @@ -56,41 +54,19 @@ GCFunctionInfo::~GCFunctionInfo() {} char GCModuleInfo::ID = 0; -GCModuleInfo::GCModuleInfo() - : ImmutablePass(ID) { +GCModuleInfo::GCModuleInfo() : ImmutablePass(ID) { initializeGCModuleInfoPass(*PassRegistry::getPassRegistry()); } -GCStrategy *GCModuleInfo::getOrCreateStrategy(const Module *M, - const std::string &Name) { - strategy_map_type::iterator NMI = StrategyMap.find(Name); - if (NMI != StrategyMap.end()) - return NMI->getValue(); - - for (GCRegistry::iterator I = GCRegistry::begin(), - E = GCRegistry::end(); I != E; ++I) { - if (Name == I->getName()) { - std::unique_ptr<GCStrategy> S = I->instantiate(); - S->Name = Name; - StrategyMap[Name] = S.get(); - StrategyList.push_back(std::move(S)); - return StrategyList.back().get(); - } - } - - dbgs() << "unsupported GC: " << Name << "\n"; - llvm_unreachable(nullptr); -} - 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()); + + GCStrategy *S = getGCStrategy(F.getGC()); Functions.push_back(make_unique<GCFunctionInfo>(F, *S)); GCFunctionInfo *GFI = Functions.back().get(); FInfoMap[&F] = GFI; @@ -100,8 +76,7 @@ GCFunctionInfo &GCModuleInfo::getFunctionInfo(const Function &F) { void GCModuleInfo::clear() { Functions.clear(); FInfoMap.clear(); - StrategyMap.clear(); - StrategyList.clear(); + GCStrategyList.clear(); } // ----------------------------------------------------------------------------- @@ -112,7 +87,6 @@ FunctionPass *llvm::createGCInfoPrinter(raw_ostream &OS) { return new Printer(OS); } - const char *Printer::getPassName() const { return "Print Garbage Collector Information"; } @@ -125,42 +99,45 @@ void Printer::getAnalysisUsage(AnalysisUsage &AU) const { static const char *DescKind(GC::PointKind Kind) { switch (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()) return false; - + if (F.hasGC()) + return false; + GCFunctionInfo *FD = &getAnalysis<GCModuleInfo>().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) + 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::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);;) { + RE = FD->live_end(PI); + ;) { OS << " " << RI->Num; if (++RI == RE) break; OS << ","; } - + OS << " }\n"; } - + return false; } @@ -170,3 +147,31 @@ bool Printer::doFinalization(Module &M) { 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<GCStrategy> 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); +} |