Index: llvm/trunk/include/llvm/CodeGen/GCMetadata.h =================================================================== --- llvm/trunk/include/llvm/CodeGen/GCMetadata.h +++ llvm/trunk/include/llvm/CodeGen/GCMetadata.h @@ -160,22 +160,37 @@ size_t live_size(const iterator &p) const { return roots_size(); } }; - /// An analysis pass which caches information about the entire Module. /// Records both the function level information used by GCRoots and a /// cache of the 'active' gc strategy objects for the current Module. class GCModuleInfo : public ImmutablePass { typedef StringMap strategy_map_type; typedef std::vector> list_type; - typedef DenseMap finfo_map_type; strategy_map_type StrategyMap; list_type StrategyList; - finfo_map_type FInfoMap; GCStrategy *getOrCreateStrategy(const Module *M, const std::string &Name); public: + /// List of per function info objects. In theory, Each of these + /// may be associated with a different GC. + typedef std::vector> FuncInfoVec; + + FuncInfoVec::iterator funcinfo_begin() { return Functions.begin(); } + FuncInfoVec::iterator funcinfo_end() { return Functions.end(); } + + + private: + /// Owning list of all GCFunctionInfos associated with this Module + FuncInfoVec Functions; + + /// Non-owning map to bypass linear search when finding the GCFunctionInfo + /// associated with a particular Function. + typedef DenseMap finfo_map_type; + finfo_map_type FInfoMap; + public: + typedef list_type::const_iterator iterator; static char ID; @@ -192,8 +207,9 @@ iterator begin() const { return StrategyList.begin(); } iterator end() const { return StrategyList.end(); } - /// get - Look up function metadata. - /// + /// get - Look up function metadata. This is currently assumed + /// have the side effect of initializing the associated GCStrategy. That + /// will soon change. GCFunctionInfo &getFunctionInfo(const Function &F); }; Index: llvm/trunk/include/llvm/CodeGen/GCMetadataPrinter.h =================================================================== --- llvm/trunk/include/llvm/CodeGen/GCMetadataPrinter.h +++ llvm/trunk/include/llvm/CodeGen/GCMetadataPrinter.h @@ -32,16 +32,11 @@ /// defaults from Registry. typedef Registry GCMetadataPrinterRegistry; - /// GCMetadataPrinter - Emits GC metadata as assembly code. - /// + /// GCMetadataPrinter - Emits GC metadata as assembly code. Instances are + /// created, managed, and owned by the AsmPrinter. class GCMetadataPrinter { - public: - typedef GCStrategy::list_type list_type; - typedef GCStrategy::iterator iterator; - private: GCStrategy *S; - friend class AsmPrinter; protected: @@ -56,13 +51,14 @@ public: GCStrategy &getStrategy() { return *S; } - /// begin/end - Iterate over the collected function metadata. - iterator begin() { return S->begin(); } - iterator end() { return S->end(); } - - /// beginAssembly/finishAssembly - Emit module metadata as assembly code. - virtual void beginAssembly(Module &M, AsmPrinter &AP); - virtual void finishAssembly(Module &M, AsmPrinter &AP); + /// Called before the assembly for the module is generated by + /// the AsmPrinter (but after target specific hooks.) + virtual void beginAssembly(Module &M, GCModuleInfo &Info, + AsmPrinter &AP) {} + /// Called after the assembly for the module is generated by + /// the AsmPrinter (but before target specific hooks) + virtual void finishAssembly(Module &M, GCModuleInfo &Info, + AsmPrinter &AP) {} virtual ~GCMetadataPrinter(); }; Index: llvm/trunk/include/llvm/CodeGen/GCStrategy.h =================================================================== --- llvm/trunk/include/llvm/CodeGen/GCStrategy.h +++ llvm/trunk/include/llvm/CodeGen/GCStrategy.h @@ -55,16 +55,10 @@ /// through the GCModuleInfo analysis pass. They are owned by the analysis /// pass and recreated every time that pass is invalidated. class GCStrategy { - public: - typedef std::vector> list_type; - typedef list_type::iterator iterator; - private: friend class GCModuleInfo; std::string Name; - list_type Functions; - protected: unsigned NeededSafePoints; ///< Bitmask of required safe points. bool CustomReadBarriers; ///< Default is to insert loads. @@ -126,15 +120,6 @@ /// the back-end (assembler, JIT, or otherwise). bool usesMetadata() const { return UsesMetadata; } - /// begin/end - Iterators for function metadata. - /// - iterator begin() { return Functions.begin(); } - iterator end() { return Functions.end(); } - - /// insertFunctionMetadata - Creates metadata for a function. - /// - GCFunctionInfo *insertFunctionInfo(const Function &F); - /// initializeCustomLowering/performCustomLowering - If any of the actions /// are set to custom, performCustomLowering must be overriden to transform /// the corresponding actions to LLVM IR. initializeCustomLowering is Index: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp =================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -210,7 +210,7 @@ assert(MI && "AsmPrinter didn't require GCModuleInfo?"); for (auto &I : *MI) if (GCMetadataPrinter *MP = GetOrCreateGCPrinter(*I)) - MP->beginAssembly(M, *this); + MP->beginAssembly(M, *MI, *this); // Emit module-level inline asm if it exists. if (!M.getModuleInlineAsm().empty()) { @@ -985,7 +985,7 @@ assert(MI && "AsmPrinter didn't require GCModuleInfo?"); for (GCModuleInfo::iterator I = MI->end(), E = MI->begin(); I != E; ) if (GCMetadataPrinter *MP = GetOrCreateGCPrinter(**--I)) - MP->finishAssembly(M, *this); + MP->finishAssembly(M, *MI, *this); // Emit llvm.ident metadata in an '.ident' directive. EmitModuleIdents(M); Index: llvm/trunk/lib/CodeGen/AsmPrinter/ErlangGCPrinter.cpp =================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/ErlangGCPrinter.cpp +++ llvm/trunk/lib/CodeGen/AsmPrinter/ErlangGCPrinter.cpp @@ -36,8 +36,8 @@ class ErlangGCPrinter : public GCMetadataPrinter { public: - void beginAssembly(Module &M, AsmPrinter &AP) override; - void finishAssembly(Module &M, AsmPrinter &AP) override; + void finishAssembly(Module &M, GCModuleInfo &Info, + AsmPrinter &AP) override; }; } @@ -47,9 +47,8 @@ void llvm::linkErlangGCPrinter() { } -void ErlangGCPrinter::beginAssembly(Module &M, AsmPrinter &AP) { } - -void ErlangGCPrinter::finishAssembly(Module &M, AsmPrinter &AP) { +void ErlangGCPrinter::finishAssembly(Module &M, GCModuleInfo &Info, + AsmPrinter &AP) { MCStreamer &OS = AP.OutStreamer; unsigned IntPtrSize = AP.TM.getSubtargetImpl()->getDataLayout()->getPointerSize(); @@ -60,9 +59,13 @@ SectionKind::getDataRel())); // For each function... - for (iterator FI = begin(), FE = end(); FI != FE; ++FI) { + for (GCModuleInfo::FuncInfoVec::iterator FI = Info.funcinfo_begin(), + IE = Info.funcinfo_end(); + FI != IE; ++FI) { GCFunctionInfo &MD = **FI; - + if (MD.getStrategy().getName() != getStrategy().getName()) + // this function is managed by some other GC + continue; /** A compact GC layout. Emit this data structure: * * struct { Index: llvm/trunk/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp =================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp +++ llvm/trunk/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp @@ -34,8 +34,10 @@ class OcamlGCMetadataPrinter : public GCMetadataPrinter { public: - void beginAssembly(Module &M, AsmPrinter &AP) override; - void finishAssembly(Module &M, AsmPrinter &AP) override; + void beginAssembly(Module &M, GCModuleInfo &Info, + AsmPrinter &AP) override; + void finishAssembly(Module &M, GCModuleInfo &Info, + AsmPrinter &AP) override; }; } @@ -67,7 +69,8 @@ AP.OutStreamer.EmitLabel(Sym); } -void OcamlGCMetadataPrinter::beginAssembly(Module &M, AsmPrinter &AP) { +void OcamlGCMetadataPrinter::beginAssembly(Module &M, GCModuleInfo &Info, + AsmPrinter &AP) { AP.OutStreamer.SwitchSection(AP.getObjFileLowering().getTextSection()); EmitCamlGlobal(M, AP, "code_begin"); @@ -91,7 +94,8 @@ /// (FrameSize and LiveOffsets would overflow). FrameTablePrinter will abort if /// either condition is detected in a function which uses the GC. /// -void OcamlGCMetadataPrinter::finishAssembly(Module &M, AsmPrinter &AP) { +void OcamlGCMetadataPrinter::finishAssembly(Module &M, GCModuleInfo &Info, + AsmPrinter &AP) { unsigned IntPtrSize = AP.TM.getSubtargetImpl()->getDataLayout()->getPointerSize(); @@ -108,8 +112,12 @@ EmitCamlGlobal(M, AP, "frametable"); int NumDescriptors = 0; - for (iterator I = begin(), IE = end(); I != IE; ++I) { + for (GCModuleInfo::FuncInfoVec::iterator I = Info.funcinfo_begin(), + IE = Info.funcinfo_end(); I != IE; ++I) { GCFunctionInfo &FI = **I; + if (FI.getStrategy().getName() != getStrategy().getName()) + // this function is managed by some other GC + continue; for (GCFunctionInfo::iterator J = FI.begin(), JE = FI.end(); J != JE; ++J) { NumDescriptors++; } @@ -122,8 +130,12 @@ AP.EmitInt16(NumDescriptors); AP.EmitAlignment(IntPtrSize == 4 ? 2 : 3); - for (iterator I = begin(), IE = end(); I != IE; ++I) { + for (GCModuleInfo::FuncInfoVec::iterator I = Info.funcinfo_begin(), + IE = Info.funcinfo_end(); I != IE; ++I) { GCFunctionInfo &FI = **I; + if (FI.getStrategy().getName() != getStrategy().getName()) + // this function is managed by some other GC + continue; uint64_t FrameSize = FI.getFrameSize(); if (FrameSize >= 1<<16) { Index: llvm/trunk/lib/CodeGen/GCMetadata.cpp =================================================================== --- llvm/trunk/lib/CodeGen/GCMetadata.cpp +++ llvm/trunk/lib/CodeGen/GCMetadata.cpp @@ -91,12 +91,14 @@ return *I->second; GCStrategy *S = getOrCreateStrategy(F.getParent(), F.getGC()); - GCFunctionInfo *GFI = S->insertFunctionInfo(F); + 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(); StrategyList.clear(); Index: llvm/trunk/lib/CodeGen/GCMetadataPrinter.cpp =================================================================== --- llvm/trunk/lib/CodeGen/GCMetadataPrinter.cpp +++ llvm/trunk/lib/CodeGen/GCMetadataPrinter.cpp @@ -17,11 +17,3 @@ GCMetadataPrinter::GCMetadataPrinter() { } GCMetadataPrinter::~GCMetadataPrinter() { } - -void GCMetadataPrinter::beginAssembly(Module &M, AsmPrinter &AP) { - // Default is no action. -} - -void GCMetadataPrinter::finishAssembly(Module &M, AsmPrinter &AP) { - // Default is no action. -} Index: llvm/trunk/lib/CodeGen/GCStrategy.cpp =================================================================== --- llvm/trunk/lib/CodeGen/GCStrategy.cpp +++ llvm/trunk/lib/CodeGen/GCStrategy.cpp @@ -115,12 +115,6 @@ llvm_unreachable(nullptr); } - -GCFunctionInfo *GCStrategy::insertFunctionInfo(const Function &F) { - Functions.push_back(make_unique(F, *this)); - return Functions.back().get(); -} - // ----------------------------------------------------------------------------- INITIALIZE_PASS_BEGIN(LowerIntrinsics, "gc-lowering", "GC Lowering",