-//===----------------- LLVMContextImpl.h - Implementation ------*- C++ -*--===//
+//===-- LLVMContextImpl.h - The LLVMContextImpl opaque class ----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
#ifndef LLVM_LLVMCONTEXT_IMPL_H
#define LLVM_LLVMCONTEXT_IMPL_H
+#include "ConstantsContext.h"
+#include "LeaksContext.h"
+#include "TypesContext.h"
#include "llvm/LLVMContext.h"
+#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/System/Mutex.h"
-#include "llvm/System/RWMutex.h"
+#include "llvm/Metadata.h"
+#include "llvm/Assembly/Writer.h"
+#include "llvm/Support/ValueHandle.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/StringMap.h"
-#include <map>
-
-template<class ValType, class TypeClass, class ConstantClass,
- bool HasLargeKey = false /*true for arrays and structs*/ >
-class ContextValueMap;
+#include <vector>
namespace llvm {
-template<class ValType>
-struct ConstantTraits;
class ConstantInt;
class ConstantFP;
-class MDString;
-class MDNode;
class LLVMContext;
class Type;
class Value;
static bool isEqual(const KeyTy &LHS, const KeyTy &RHS) {
return LHS == RHS;
}
- static bool isPod() { return false; }
};
struct DenseMapAPFloatKeyInfo {
static bool isEqual(const KeyTy &LHS, const KeyTy &RHS) {
return LHS == RHS;
}
- static bool isPod() { return false; }
};
+/// DebugRecVH - This is a CallbackVH used to keep the Scope -> index maps
+/// up to date as MDNodes mutate. This class is implemented in DebugLoc.cpp.
+class DebugRecVH : public CallbackVH {
+ /// Ctx - This is the LLVM Context being referenced.
+ LLVMContextImpl *Ctx;
+
+ /// Idx - The index into either ScopeRecordIdx or ScopeInlinedAtRecords that
+ /// this reference lives in. If this is zero, then it represents a
+ /// non-canonical entry that has no DenseMap value. This can happen due to
+ /// RAUW.
+ int Idx;
+public:
+ DebugRecVH(MDNode *n, LLVMContextImpl *ctx, int idx)
+ : CallbackVH(n), Ctx(ctx), Idx(idx) {}
+
+ MDNode *get() const {
+ return cast_or_null<MDNode>(getValPtr());
+ }
+
+ virtual void deleted();
+ virtual void allUsesReplacedWith(Value *VNew);
+};
+
class LLVMContextImpl {
- sys::SmartRWMutex<true> ConstantsLock;
+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;
+
+ LLVMContext::InlineAsmDiagHandlerTy InlineAsmDiagHandler;
+ void *InlineAsmDiagContext;
typedef DenseMap<DenseMapAPIntKeyInfo::KeyTy, ConstantInt*,
- DenseMapAPIntKeyInfo> IntMapTy;
+ DenseMapAPIntKeyInfo> IntMapTy;
IntMapTy IntConstants;
typedef DenseMap<DenseMapAPFloatKeyInfo::KeyTy, ConstantFP*,
- DenseMapAPFloatKeyInfo> FPMapTy;
+ DenseMapAPFloatKeyInfo> FPMapTy;
FPMapTy FPConstants;
StringMap<MDString*> MDStringCache;
FoldingSet<MDNode> MDNodeSet;
+ // MDNodes may be uniqued or not uniqued. When they're not uniqued, they
+ // aren't in the MDNodeSet, but they're still shared between objects, so no
+ // one object can destroy them. This set allows us to at least destroy them
+ // on Context destruction.
+ SmallPtrSet<MDNode*, 1> NonUniquedMDNodes;
+
+ ConstantUniqueMap<char, Type, ConstantAggregateZero> AggZeroConstants;
+
+ typedef ConstantUniqueMap<std::vector<Constant*>, ArrayType,
+ ConstantArray, true /*largekey*/> ArrayConstantsTy;
+ ArrayConstantsTy ArrayConstants;
- ContextValueMap<char, Type, ConstantAggregateZero> *AggZeroConstants;
+ typedef ConstantUniqueMap<std::vector<Constant*>, StructType,
+ ConstantStruct, true /*largekey*/> StructConstantsTy;
+ StructConstantsTy StructConstants;
+
+ typedef ConstantUniqueMap<std::vector<Constant*>, VectorType,
+ ConstantVector> VectorConstantsTy;
+ VectorConstantsTy VectorConstants;
+
+ ConstantUniqueMap<char, PointerType, ConstantPointerNull> NullPtrConstants;
+ ConstantUniqueMap<char, Type, UndefValue> UndefValueConstants;
+
+ DenseMap<std::pair<Function*, BasicBlock*> , BlockAddress*> BlockAddresses;
+ ConstantUniqueMap<ExprMapKeyType, Type, ConstantExpr> ExprConstants;
+
+ ConstantUniqueMap<InlineAsmKeyType, PointerType, InlineAsm> InlineAsms;
- LLVMContext &Context;
ConstantInt *TheTrueVal;
ConstantInt *TheFalseVal;
- LLVMContextImpl();
- LLVMContextImpl(const LLVMContextImpl&);
-public:
- LLVMContextImpl(LLVMContext &C);
- ~LLVMContextImpl();
+ LeakDetectorImpl<Value> LLVMObjects;
- /// Return a ConstantInt with the specified value and an implied Type. The
- /// type is the integer type that corresponds to the bit width of the value.
- ConstantInt *getConstantInt(const APInt &V);
+ // Basic type instances.
+ const Type VoidTy;
+ const Type LabelTy;
+ const Type FloatTy;
+ const Type DoubleTy;
+ const Type MetadataTy;
+ const Type X86_FP80Ty;
+ const Type FP128Ty;
+ const Type PPC_FP128Ty;
+ const Type X86_MMXTy;
+ const IntegerType Int1Ty;
+ const IntegerType Int8Ty;
+ const IntegerType Int16Ty;
+ const IntegerType Int32Ty;
+ const IntegerType Int64Ty;
+
+ // Concrete/Abstract TypeDescriptions - We lazily calculate type descriptions
+ // for types as they are needed. Because resolution of types must invalidate
+ // all of the abstract type descriptions, we keep them in a separate map to
+ // make this easy.
+ TypePrinting ConcreteTypeDescriptions;
+ TypePrinting AbstractTypeDescriptions;
- ConstantFP *getConstantFP(const APFloat &V);
+ TypeMap<ArrayValType, ArrayType> ArrayTypes;
+ TypeMap<VectorValType, VectorType> VectorTypes;
+ TypeMap<PointerValType, PointerType> PointerTypes;
+ TypeMap<FunctionValType, FunctionType> FunctionTypes;
+ TypeMap<StructValType, StructType> StructTypes;
+ TypeMap<IntegerValType, IntegerType> IntegerTypes;
+
+ // Opaque types are not structurally uniqued, so don't use TypeMap.
+ typedef SmallPtrSet<const OpaqueType*, 8> OpaqueTypesTy;
+ OpaqueTypesTy OpaqueTypes;
+
+ /// Used as an abstract type that will never be resolved.
+ OpaqueType *const AlwaysOpaqueTy;
+
+
+ /// ValueHandles - This map keeps track of all of the value handles that are
+ /// watching a Value*. The Value::HasValueHandle bit is used to know
+ // whether or not a value has an entry in this map.
+ typedef DenseMap<Value*, ValueHandleBase*> ValueHandlesTy;
+ ValueHandlesTy ValueHandles;
- MDString *getMDString(const char *StrBegin, const char *StrEnd);
+ /// CustomMDKindNames - Map to hold the metadata string to ID mapping.
+ StringMap<unsigned> CustomMDKindNames;
- MDNode *getMDNode(Value*const* Vals, unsigned NumVals);
+ typedef std::pair<unsigned, TrackingVH<MDNode> > MDPairTy;
+ typedef SmallVector<MDPairTy, 2> MDMapTy;
+
+ /// MetadataStore - Collection of per-instruction metadata used in this
+ /// context.
+ DenseMap<const Instruction *, MDMapTy> MetadataStore;
- ConstantAggregateZero *getConstantAggregateZero(const Type *Ty);
+ /// ScopeRecordIdx - This is the index in ScopeRecords for an MDNode scope
+ /// entry with no "inlined at" element.
+ DenseMap<MDNode*, int> ScopeRecordIdx;
- ConstantInt *getTrue() {
- if (TheTrueVal)
- return TheTrueVal;
- else
- return (TheTrueVal = Context.getConstantInt(IntegerType::get(1), 1));
- }
+ /// ScopeRecords - These are the actual mdnodes (in a value handle) for an
+ /// index. The ValueHandle ensures that ScopeRecordIdx stays up to date if
+ /// the MDNode is RAUW'd.
+ std::vector<DebugRecVH> ScopeRecords;
- ConstantInt *getFalse() {
- if (TheFalseVal)
- return TheFalseVal;
- else
- return (TheFalseVal = Context.getConstantInt(IntegerType::get(1), 0));
- }
+ /// ScopeInlinedAtIdx - This is the index in ScopeInlinedAtRecords for an
+ /// scope/inlined-at pair.
+ DenseMap<std::pair<MDNode*, MDNode*>, int> ScopeInlinedAtIdx;
+
+ /// ScopeInlinedAtRecords - These are the actual mdnodes (in value handles)
+ /// for an index. The ValueHandle ensures that ScopeINlinedAtIdx stays up
+ /// to date.
+ std::vector<std::pair<DebugRecVH, DebugRecVH> > ScopeInlinedAtRecords;
- void erase(MDString *M);
- void erase(MDNode *M);
- void erase(ConstantAggregateZero *Z);
+ int getOrAddScopeRecordIdxEntry(MDNode *N, int ExistingIdx);
+ int getOrAddScopeInlinedAtIdxEntry(MDNode *Scope, MDNode *IA,int ExistingIdx);
+
+ LLVMContextImpl(LLVMContext &C);
+ ~LLVMContextImpl();
};
}