Clarify the ownership model of LLVMContext and Module. Namely, contexts own

modules are instantiated in them.  If the context is deleted, all of its owned
modules are also deleted.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@113374 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Owen Anderson 2010-09-08 18:03:32 +00:00
parent 1485cc2bb3
commit 30268be89d
5 changed files with 32 additions and 0 deletions

View File

@ -20,6 +20,7 @@ namespace llvm {
class LLVMContextImpl; class LLVMContextImpl;
class StringRef; class StringRef;
class Instruction; class Instruction;
class Module;
template <typename T> class SmallVectorImpl; template <typename T> class SmallVectorImpl;
/// This is an important class for using LLVM in a threaded context. It /// This is an important class for using LLVM in a threaded context. It
@ -37,6 +38,13 @@ public:
LLVMContext(); LLVMContext();
~LLVMContext(); ~LLVMContext();
/// addModule - Register a module as being instantiated in this context. If
/// the context is deleted, the module will be deleted as well.
void addModule(Module*);
/// removeModule - Unregister a module from this context.
void removeModule(Module*);
// Pinned metadata names, which always have the same value. This is a // Pinned metadata names, which always have the same value. This is a
// compile-time performance optimization, not a correctness optimization. // compile-time performance optimization, not a correctness optimization.
enum { enum {

View File

@ -34,6 +34,14 @@ LLVMContext::LLVMContext() : pImpl(new LLVMContextImpl(*this)) {
} }
LLVMContext::~LLVMContext() { delete pImpl; } LLVMContext::~LLVMContext() { delete pImpl; }
void LLVMContext::addModule(Module *M) {
pImpl->OwnedModules.insert(M);
}
void LLVMContext::removeModule(Module *M) {
pImpl->OwnedModules.erase(M);
}
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// Recoverable Backend Errors // Recoverable Backend Errors
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//

View File

@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "LLVMContextImpl.h" #include "LLVMContextImpl.h"
#include "llvm/Module.h"
#include <algorithm> #include <algorithm>
using namespace llvm; using namespace llvm;
@ -51,6 +52,15 @@ struct DropReferences {
} }
LLVMContextImpl::~LLVMContextImpl() { LLVMContextImpl::~LLVMContextImpl() {
// NOTE: We need to delete the contents of OwnedModules, but we have to
// duplicate it into a temporary vector, because the destructor of Module
// will try to remove itself from OwnedModules set. This would cause
// iterator invalidation if we iterated on the set directly.
std::vector<Module*> Modules(OwnedModules.begin(), OwnedModules.end());
for (std::vector<Module*>::iterator I = Modules.begin(), E = Modules.end();
I != E; ++I)
delete *I;
std::for_each(ExprConstants.map_begin(), ExprConstants.map_end(), std::for_each(ExprConstants.map_begin(), ExprConstants.map_end(),
DropReferences()); DropReferences());
std::for_each(ArrayConstants.map_begin(), ArrayConstants.map_end(), std::for_each(ArrayConstants.map_begin(), ArrayConstants.map_end(),

View File

@ -115,6 +115,10 @@ public:
class LLVMContextImpl { class LLVMContextImpl {
public: public:
/// OwnedModules - The set of modules instantiated in this context, and which
/// will be automatically deleted if this context is deleted.
SmallPtrSet<Module*, 4> OwnedModules;
void *InlineAsmDiagHandler, *InlineAsmDiagContext; void *InlineAsmDiagHandler, *InlineAsmDiagContext;
typedef DenseMap<DenseMapAPIntKeyInfo::KeyTy, ConstantInt*, typedef DenseMap<DenseMapAPIntKeyInfo::KeyTy, ConstantInt*,

View File

@ -62,9 +62,11 @@ Module::Module(StringRef MID, LLVMContext& C)
ValSymTab = new ValueSymbolTable(); ValSymTab = new ValueSymbolTable();
TypeSymTab = new TypeSymbolTable(); TypeSymTab = new TypeSymbolTable();
NamedMDSymTab = new StringMap<NamedMDNode *>(); NamedMDSymTab = new StringMap<NamedMDNode *>();
Context.addModule(this);
} }
Module::~Module() { Module::~Module() {
Context.removeModule(this);
dropAllReferences(); dropAllReferences();
GlobalList.clear(); GlobalList.clear();
FunctionList.clear(); FunctionList.clear();