diff --git a/llvm/include/llvm/DerivedTypes.h b/llvm/include/llvm/DerivedTypes.h index a8603acfbe2b..fb51430b481e 100644 --- a/llvm/include/llvm/DerivedTypes.h +++ b/llvm/include/llvm/DerivedTypes.h @@ -37,7 +37,7 @@ class DerivedType : public Type { friend class Type; protected: - explicit DerivedType(TypeID id) : Type(id) {} + explicit DerivedType(LLVMContext &C, TypeID id) : Type(C, id) {} /// notifyUsesThatTypeBecameConcrete - Notify AbstractTypeUsers of this type /// that the current type has transitioned from being abstract to being @@ -83,8 +83,11 @@ public: /// Int64Ty. /// @brief Integer representation type class IntegerType : public DerivedType { + friend class LLVMContextImpl; + protected: - explicit IntegerType(unsigned NumBits) : DerivedType(IntegerTyID) { + explicit IntegerType(LLVMContext &C, unsigned NumBits) : + DerivedType(C, IntegerTyID) { setSubclassData(NumBits); } friend class TypeMap; @@ -208,7 +211,8 @@ public: /// and VectorType class CompositeType : public DerivedType { protected: - inline explicit CompositeType(TypeID id) : DerivedType(id) { } + inline explicit CompositeType(LLVMContext &C, TypeID id) : + DerivedType(C, id) { } public: /// getTypeAtIndex - Given an index value into the type, return the type of @@ -236,7 +240,8 @@ class StructType : public CompositeType { friend class TypeMap; StructType(const StructType &); // Do not implement const StructType &operator=(const StructType &); // Do not implement - StructType(const std::vector &Types, bool isPacked); + StructType(LLVMContext &C, + const std::vector &Types, bool isPacked); public: /// StructType::get - This static method is the primary way to create a /// StructType. @@ -313,7 +318,7 @@ class SequentialType : public CompositeType { SequentialType* this_() { return this; } protected: SequentialType(TypeID TID, const Type *ElType) - : CompositeType(TID), ContainedType(ElType, this_()) { + : CompositeType(ElType->getContext(), TID), ContainedType(ElType, this_()) { ContainedTys = &ContainedType; NumContainedTys = 1; } @@ -493,12 +498,12 @@ public: class OpaqueType : public DerivedType { OpaqueType(const OpaqueType &); // DO NOT IMPLEMENT const OpaqueType &operator=(const OpaqueType &); // DO NOT IMPLEMENT - OpaqueType(); + OpaqueType(LLVMContext &C); public: /// OpaqueType::get - Static factory method for the OpaqueType class... /// - static OpaqueType *get() { - return new OpaqueType(); // All opaque types are distinct + static OpaqueType *get(LLVMContext &C) { + return new OpaqueType(C); // All opaque types are distinct } // Implement support for type inquiry through isa, cast, and dyn_cast: diff --git a/llvm/include/llvm/Type.h b/llvm/include/llvm/Type.h index 05a4e26c8bb4..b7516323c58a 100644 --- a/llvm/include/llvm/Type.h +++ b/llvm/include/llvm/Type.h @@ -109,6 +109,7 @@ private: /// Context - This refers to the LLVMContext in which this type was uniqued. LLVMContext &Context; + friend class LLVMContextImpl; const Type *getForwardedTypeInternal() const; @@ -117,8 +118,9 @@ private: void destroy() const; // const is a lie, this does "delete this"! protected: - explicit Type(TypeID id) : ID(id), Abstract(false), SubclassData(0), - RefCount(0), Context(getGlobalContext()), + explicit Type(LLVMContext &C, TypeID id) : + ID(id), Abstract(false), SubclassData(0), + RefCount(0), Context(C), ForwardType(0), NumContainedTys(0), ContainedTys(0) {} virtual ~Type() { diff --git a/llvm/lib/Analysis/PointerTracking.cpp b/llvm/lib/Analysis/PointerTracking.cpp index f2154f738892..d28e58e10135 100644 --- a/llvm/lib/Analysis/PointerTracking.cpp +++ b/llvm/lib/Analysis/PointerTracking.cpp @@ -104,12 +104,12 @@ const SCEV *PointerTracking::computeAllocationCount(Value *P, Constant *C = GV->getInitializer(); if (const ArrayType *ATy = dyn_cast(C->getType())) { Ty = ATy->getElementType(); - return SE->getConstant(Type::getInt32Ty(Ty->getContext()), + return SE->getConstant(Type::getInt32Ty(P->getContext()), ATy->getNumElements()); } } Ty = GV->getType(); - return SE->getConstant(Type::getInt32Ty(Ty->getContext()), 1); + return SE->getConstant(Type::getInt32Ty(P->getContext()), 1); //TODO: implement more tracking for globals } @@ -118,13 +118,13 @@ const SCEV *PointerTracking::computeAllocationCount(Value *P, Function *F = dyn_cast(CS.getCalledValue()->stripPointerCasts()); const Loop *L = LI->getLoopFor(CI->getParent()); if (F == callocFunc) { - Ty = Type::getInt8Ty(Ty->getContext()); + Ty = Type::getInt8Ty(P->getContext()); // calloc allocates arg0*arg1 bytes. return SE->getSCEVAtScope(SE->getMulExpr(SE->getSCEV(CS.getArgument(0)), SE->getSCEV(CS.getArgument(1))), L); } else if (F == reallocFunc) { - Ty = Type::getInt8Ty(Ty->getContext()); + Ty = Type::getInt8Ty(P->getContext()); // realloc allocates arg1 bytes. return SE->getSCEVAtScope(CS.getArgument(1), L); } diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index c3fd31ed4ce0..ec7bc650c45e 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -1150,7 +1150,7 @@ bool LLParser::ParseTypeRec(PATypeHolder &Result) { break; case lltok::kw_opaque: // TypeRec ::= 'opaque' - Result = OpaqueType::get(); + Result = OpaqueType::get(Context); Lex.Lex(); break; case lltok::lbrace: @@ -1180,7 +1180,7 @@ bool LLParser::ParseTypeRec(PATypeHolder &Result) { if (const Type *T = M->getTypeByName(Lex.getStrVal())) { Result = T; } else { - Result = OpaqueType::get(); + Result = OpaqueType::get(Context); ForwardRefTypes.insert(std::make_pair(Lex.getStrVal(), std::make_pair(Result, Lex.getLoc()))); @@ -1199,7 +1199,7 @@ bool LLParser::ParseTypeRec(PATypeHolder &Result) { if (I != ForwardRefTypeIDs.end()) Result = I->second.first; else { - Result = OpaqueType::get(); + Result = OpaqueType::get(Context); ForwardRefTypeIDs.insert(std::make_pair(Lex.getUIntVal(), std::make_pair(Result, Lex.getLoc()))); @@ -1212,7 +1212,7 @@ bool LLParser::ParseTypeRec(PATypeHolder &Result) { Lex.Lex(); unsigned Val; if (ParseUInt32(Val)) return true; - OpaqueType *OT = OpaqueType::get(); //Use temporary placeholder. + OpaqueType *OT = OpaqueType::get(Context); //Use temporary placeholder. UpRefs.push_back(UpRefRecord(Lex.getLoc(), Val, OT)); Result = OT; break; diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 168f32951d56..a1e6099b9f0e 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -358,7 +358,7 @@ const Type *BitcodeReader::getTypeByID(unsigned ID, bool isTypeTable) { // The type table allows forward references. Push as many Opaque types as // needed to get up to ID. while (TypeList.size() <= ID) - TypeList.push_back(OpaqueType::get()); + TypeList.push_back(OpaqueType::get(Context)); return TypeList.back().get(); } @@ -597,7 +597,7 @@ bool BitcodeReader::ParseTypeTable() { if (NumRecords == TypeList.size()) { // If this is a new type slot, just append it. - TypeList.push_back(ResultTy ? ResultTy : OpaqueType::get()); + TypeList.push_back(ResultTy ? ResultTy : OpaqueType::get(Context)); ++NumRecords; } else if (ResultTy == 0) { // Otherwise, this was forward referenced, so an opaque type was created, diff --git a/llvm/lib/CodeGen/ShadowStackGC.cpp b/llvm/lib/CodeGen/ShadowStackGC.cpp index 5b4cc7fe2696..18c49363fee6 100644 --- a/llvm/lib/CodeGen/ShadowStackGC.cpp +++ b/llvm/lib/CodeGen/ShadowStackGC.cpp @@ -279,7 +279,7 @@ bool ShadowStackGC::initializeCustomLowering(Module &M) { // FrameMap *Map; // Pointer to constant FrameMap. // void *Roots[]; // Stack roots (in-place array, so we pretend). // }; - OpaqueType *RecursiveTy = OpaqueType::get(); + OpaqueType *RecursiveTy = OpaqueType::get(M.getContext()); EltTys.clear(); EltTys.push_back(PointerType::getUnqual(RecursiveTy)); diff --git a/llvm/lib/Transforms/Utils/LowerInvoke.cpp b/llvm/lib/Transforms/Utils/LowerInvoke.cpp index b18a2307e1d4..4ecf6d7ba260 100644 --- a/llvm/lib/Transforms/Utils/LowerInvoke.cpp +++ b/llvm/lib/Transforms/Utils/LowerInvoke.cpp @@ -127,7 +127,7 @@ bool LowerInvoke::doInitialization(Module &M) { { // The type is recursive, so use a type holder. std::vector Elements; Elements.push_back(JmpBufTy); - OpaqueType *OT = OpaqueType::get(); + OpaqueType *OT = OpaqueType::get(M.getContext()); Elements.push_back(PointerType::getUnqual(OT)); PATypeHolder JBLType(StructType::get(M.getContext(), Elements)); OT->refineAbstractTypeTo(JBLType.get()); // Complete the cycle. diff --git a/llvm/lib/VMCore/Core.cpp b/llvm/lib/VMCore/Core.cpp index b2715d9d21a3..e8f47fdf2e4f 100644 --- a/llvm/lib/VMCore/Core.cpp +++ b/llvm/lib/VMCore/Core.cpp @@ -293,7 +293,7 @@ LLVMTypeRef LLVMLabelType(void) { } LLVMTypeRef LLVMOpaqueType(void) { - return wrap(OpaqueType::get()); + return wrap(OpaqueType::get(getGlobalContext())); } /*--.. Operations on type handles ..........................................--*/ diff --git a/llvm/lib/VMCore/LLVMContext.cpp b/llvm/lib/VMCore/LLVMContext.cpp index aa9dc3671a08..95ceeaee813f 100644 --- a/llvm/lib/VMCore/LLVMContext.cpp +++ b/llvm/lib/VMCore/LLVMContext.cpp @@ -27,7 +27,7 @@ LLVMContext& llvm::getGlobalContext() { return *GlobalContext; } -LLVMContext::LLVMContext() : pImpl(new LLVMContextImpl()) { } +LLVMContext::LLVMContext() : pImpl(new LLVMContextImpl(*this)) { } LLVMContext::~LLVMContext() { delete pImpl; } GetElementPtrConstantExpr::GetElementPtrConstantExpr diff --git a/llvm/lib/VMCore/LLVMContextImpl.h b/llvm/lib/VMCore/LLVMContextImpl.h index 30a7fc4af930..9c48fbe73019 100644 --- a/llvm/lib/VMCore/LLVMContextImpl.h +++ b/llvm/lib/VMCore/LLVMContextImpl.h @@ -137,8 +137,60 @@ public: TypeMap PointerTypes; TypeMap FunctionTypes; TypeMap StructTypes; + TypeMap IntegerTypes; - LLVMContextImpl() : TheTrueVal(0), TheFalseVal(0) { } + 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 IntegerType *Int1Ty; + const IntegerType *Int8Ty; + const IntegerType *Int16Ty; + const IntegerType *Int32Ty; + const IntegerType *Int64Ty; + + LLVMContextImpl(LLVMContext &C) : TheTrueVal(0), TheFalseVal(0), + VoidTy(new Type(C, Type::VoidTyID)), + LabelTy(new Type(C, Type::LabelTyID)), + FloatTy(new Type(C, Type::FloatTyID)), + DoubleTy(new Type(C, Type::DoubleTyID)), + MetadataTy(new Type(C, Type::MetadataTyID)), + X86_FP80Ty(new Type(C, Type::X86_FP80TyID)), + FP128Ty(new Type(C, Type::FP128TyID)), + PPC_FP128Ty(new Type(C, Type::PPC_FP128TyID)), + Int1Ty(new IntegerType(C, 1)), + Int8Ty(new IntegerType(C, 8)), + Int16Ty(new IntegerType(C, 16)), + Int32Ty(new IntegerType(C, 32)), + Int64Ty(new IntegerType(C, 64)) { } + + ~LLVMContextImpl() { + // In principle, we should delete the member types here. However, + // this causes destruction order issues with the types in the TypeMaps. + // For now, just leak this, which is at least not a regression from the + // previous behavior, though still undesirable. +#if 0 + delete VoidTy; + delete LabelTy; + delete FloatTy; + delete DoubleTy; + delete MetadataTy; + delete X86_FP80Ty; + delete FP128Ty; + delete PPC_FP128Ty; + + delete Int1Ty; + delete Int8Ty; + delete Int16Ty; + delete Int32Ty; + delete Int64Ty; +#endif + } }; } diff --git a/llvm/lib/VMCore/Type.cpp b/llvm/lib/VMCore/Type.cpp index 3072e838b500..93433a7d364b 100644 --- a/llvm/lib/VMCore/Type.cpp +++ b/llvm/lib/VMCore/Type.cpp @@ -315,75 +315,56 @@ const Type *StructType::getTypeAtIndex(unsigned Idx) const { // Primitive 'Type' data //===----------------------------------------------------------------------===// -namespace { - struct BuiltinIntegerType : public IntegerType { - explicit BuiltinIntegerType(unsigned W) : IntegerType(W) {} - }; -} - const Type *Type::getVoidTy(LLVMContext &C) { - static const Type *VoidTy = new Type(Type::VoidTyID); - return VoidTy; + return C.pImpl->VoidTy; } const Type *Type::getLabelTy(LLVMContext &C) { - static const Type *LabelTy = new Type(Type::LabelTyID); - return LabelTy; + return C.pImpl->LabelTy; } const Type *Type::getFloatTy(LLVMContext &C) { - static const Type *FloatTy = new Type(Type::FloatTyID); - return FloatTy; + return C.pImpl->FloatTy; } const Type *Type::getDoubleTy(LLVMContext &C) { - static const Type *DoubleTy = new Type(Type::DoubleTyID); - return DoubleTy; + return C.pImpl->DoubleTy; } const Type *Type::getMetadataTy(LLVMContext &C) { - static const Type *MetadataTy = new Type(Type::MetadataTyID); - return MetadataTy; + return C.pImpl->MetadataTy; } const Type *Type::getX86_FP80Ty(LLVMContext &C) { - static const Type *X86_FP80Ty = new Type(Type::X86_FP80TyID); - return X86_FP80Ty; + return C.pImpl->X86_FP80Ty; } const Type *Type::getFP128Ty(LLVMContext &C) { - static const Type *FP128Ty = new Type(Type::FP128TyID); - return FP128Ty; + return C.pImpl->FP128Ty; } const Type *Type::getPPC_FP128Ty(LLVMContext &C) { - static const Type *PPC_FP128Ty = new Type(Type::PPC_FP128TyID); - return PPC_FP128Ty; + return C.pImpl->PPC_FP128Ty; } const IntegerType *Type::getInt1Ty(LLVMContext &C) { - static const IntegerType *Int1Ty = new BuiltinIntegerType(1); - return Int1Ty; + return C.pImpl->Int1Ty; } const IntegerType *Type::getInt8Ty(LLVMContext &C) { - static const IntegerType *Int8Ty = new BuiltinIntegerType(8); - return Int8Ty; + return C.pImpl->Int8Ty; } const IntegerType *Type::getInt16Ty(LLVMContext &C) { - static const IntegerType *Int16Ty = new BuiltinIntegerType(16); - return Int16Ty; + return C.pImpl->Int16Ty; } const IntegerType *Type::getInt32Ty(LLVMContext &C) { - static const IntegerType *Int32Ty = new BuiltinIntegerType(32); - return Int32Ty; + return C.pImpl->Int32Ty; } const IntegerType *Type::getInt64Ty(LLVMContext &C) { - static const IntegerType *Int64Ty = new BuiltinIntegerType(64); - return Int64Ty; + return C.pImpl->Int64Ty; } //===----------------------------------------------------------------------===// @@ -430,7 +411,7 @@ bool FunctionType::isValidArgumentType(const Type *ArgTy) { FunctionType::FunctionType(const Type *Result, const std::vector &Params, bool IsVarArgs) - : DerivedType(FunctionTyID), isVarArgs(IsVarArgs) { + : DerivedType(Result->getContext(), FunctionTyID), isVarArgs(IsVarArgs) { ContainedTys = reinterpret_cast(this+1); NumContainedTys = Params.size() + 1; // + 1 for result type assert(isValidReturnType(Result) && "invalid return type for function"); @@ -450,8 +431,9 @@ FunctionType::FunctionType(const Type *Result, setAbstract(isAbstract); } -StructType::StructType(const std::vector &Types, bool isPacked) - : CompositeType(StructTyID) { +StructType::StructType(LLVMContext &C, + const std::vector &Types, bool isPacked) + : CompositeType(C, StructTyID) { ContainedTys = reinterpret_cast(this + 1); NumContainedTys = Types.size(); setSubclassData(isPacked); @@ -494,7 +476,7 @@ PointerType::PointerType(const Type *E, unsigned AddrSpace) setAbstract(E->isAbstract()); } -OpaqueType::OpaqueType() : DerivedType(OpaqueTyID) { +OpaqueType::OpaqueType(LLVMContext &C) : DerivedType(C, OpaqueTyID) { setAbstract(true); #ifdef DEBUG_MERGE_TYPES DOUT << "Derived new type: " << *this << "\n"; @@ -521,7 +503,7 @@ void DerivedType::dropAllTypeUses() { llvm_acquire_global_lock(); tmp = AlwaysOpaqueTy; if (!tmp) { - tmp = OpaqueType::get(); + tmp = OpaqueType::get(getContext()); PATypeHolder* tmp2 = new PATypeHolder(AlwaysOpaqueTy); sys::MemoryFence(); AlwaysOpaqueTy = tmp; @@ -531,7 +513,7 @@ void DerivedType::dropAllTypeUses() { llvm_release_global_lock(); } } else { - AlwaysOpaqueTy = OpaqueType::get(); + AlwaysOpaqueTy = OpaqueType::get(getContext()); Holder = new PATypeHolder(AlwaysOpaqueTy); } @@ -755,9 +737,6 @@ static bool TypeHasCycleThroughItself(const Type *Ty) { //===----------------------------------------------------------------------===// // Function Type Factory and Value Class... // - -static ManagedStatic > IntegerTypes; - const IntegerType *IntegerType::get(LLVMContext &C, unsigned NumBits) { assert(NumBits >= MIN_INT_BITS && "bitwidth too small"); assert(NumBits <= MAX_INT_BITS && "bitwidth too large"); @@ -772,6 +751,8 @@ const IntegerType *IntegerType::get(LLVMContext &C, unsigned NumBits) { default: break; } + + LLVMContextImpl *pImpl = C.pImpl; IntegerValType IVT(NumBits); IntegerType *ITy = 0; @@ -779,12 +760,12 @@ const IntegerType *IntegerType::get(LLVMContext &C, unsigned NumBits) { // First, see if the type is already in the table, for which // a reader lock suffices. sys::SmartScopedLock L(*TypeMapLock); - ITy = IntegerTypes->get(IVT); + ITy = pImpl->IntegerTypes.get(IVT); if (!ITy) { // Value not found. Derive a new type! - ITy = new IntegerType(NumBits); - IntegerTypes->add(IVT, ITy); + ITy = new IntegerType(C, NumBits); + pImpl->IntegerTypes.add(IVT, ITy); } #ifdef DEBUG_MERGE_TYPES DOUT << "Derived new type: " << *ITy << "\n"; @@ -918,7 +899,7 @@ StructType *StructType::get(LLVMContext &Context, // Value not found. Derive a new type! ST = (StructType*) operator new(sizeof(StructType) + sizeof(PATypeHandle) * ETypes.size()); - new (ST) StructType(ETypes, isPacked); + new (ST) StructType(Context, ETypes, isPacked); pImpl->StructTypes.add(STV, ST); } #ifdef DEBUG_MERGE_TYPES