X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FVMCore%2FLLVMContextImpl.cpp;h=a86363b632a35f80ffa1c09885d4c79d315f1d70;hb=3756e70af69096a82b367ee9667e7720ca2201e4;hp=c72e3cbf5df0e6ce601d6bc00aff4244e81d04cd;hpb=16e298f98024bcff5c7219a96cac216114c30dad;p=oota-llvm.git diff --git a/lib/VMCore/LLVMContextImpl.cpp b/lib/VMCore/LLVMContextImpl.cpp index c72e3cbf5df..a86363b632a 100644 --- a/lib/VMCore/LLVMContextImpl.cpp +++ b/lib/VMCore/LLVMContextImpl.cpp @@ -1,4 +1,4 @@ -//===--------------- LLVMContextImpl.cpp - Implementation ------*- C++ -*--===// +//===-- LLVMContextImpl.cpp - Implement LLVMContextImpl -------------------===// // // The LLVM Compiler Infrastructure // @@ -7,424 +7,134 @@ // //===----------------------------------------------------------------------===// // -// This file implements LLVMContextImpl, the opaque implementation -// of LLVMContext. +// This file implements the opaque LLVMContextImpl. // //===----------------------------------------------------------------------===// #include "LLVMContextImpl.h" -#include "llvm/Constants.h" -#include "llvm/DerivedTypes.h" -#include "llvm/LLVMContext.h" -#include "llvm/MDNode.h" +#include "llvm/Attributes.h" +#include "llvm/Module.h" +#include "llvm/ADT/STLExtras.h" +#include using namespace llvm; -static char getValType(ConstantAggregateZero *CPZ) { return 0; } - -namespace llvm { -template -struct VISIBILITY_HIDDEN ConstantTraits< std::vector > { - static unsigned uses(const std::vector& v) { - return v.size(); - } -}; - -template -struct VISIBILITY_HIDDEN ConstantCreator { - static ConstantClass *create(const TypeClass *Ty, const ValType &V) { - return new(ConstantTraits::uses(V)) ConstantClass(Ty, V); - } -}; - -template -struct VISIBILITY_HIDDEN ConvertConstantType { - static void convert(ConstantClass *OldC, const TypeClass *NewTy) { - llvm_unreachable("This type cannot be converted!"); - } -}; - -// ConstantAggregateZero does not take extra "value" argument... -template -struct ConstantCreator { - static ConstantAggregateZero *create(const Type *Ty, const ValType &V){ - return new ConstantAggregateZero(Ty); - } -}; - -template<> -struct ConvertConstantType { - static void convert(ConstantAggregateZero *OldC, const Type *NewTy) { - // Make everyone now use a constant of the new type... - Constant *New = NewTy->getContext().getConstantAggregateZero(NewTy); - assert(New != OldC && "Didn't replace constant??"); - OldC->uncheckedReplaceAllUsesWith(New); - OldC->destroyConstant(); // This constant is now dead, destroy it. - } -}; +LLVMContextImpl::LLVMContextImpl(LLVMContext &C) + : TheTrueVal(0), TheFalseVal(0), + VoidTy(C, Type::VoidTyID), + LabelTy(C, Type::LabelTyID), + HalfTy(C, Type::HalfTyID), + FloatTy(C, Type::FloatTyID), + DoubleTy(C, Type::DoubleTyID), + MetadataTy(C, Type::MetadataTyID), + X86_FP80Ty(C, Type::X86_FP80TyID), + FP128Ty(C, Type::FP128TyID), + PPC_FP128Ty(C, Type::PPC_FP128TyID), + X86_MMXTy(C, Type::X86_MMXTyID), + Int1Ty(C, 1), + Int8Ty(C, 8), + Int16Ty(C, 16), + Int32Ty(C, 32), + Int64Ty(C, 64) { + InlineAsmDiagHandler = 0; + InlineAsmDiagContext = 0; + NamedStructTypesUniqueID = 0; } - -template -class VISIBILITY_HIDDEN ContextValueMap : public AbstractTypeUser { -public: - typedef std::pair MapKey; - typedef std::map MapTy; - typedef std::map InverseMapTy; - typedef std::map AbstractTypeMapTy; -private: - /// Map - This is the main map from the element descriptor to the Constants. - /// This is the primary way we avoid creating two of the same shape - /// constant. - MapTy Map; - - /// InverseMap - If "HasLargeKey" is true, this contains an inverse mapping - /// from the constants to their element in Map. This is important for - /// removal of constants from the array, which would otherwise have to scan - /// through the map with very large keys. - InverseMapTy InverseMap; - - /// AbstractTypeMap - Map for abstract type constants. - /// - AbstractTypeMapTy AbstractTypeMap; - - /// ValueMapLock - Mutex for this map. - sys::SmartMutex ValueMapLock; - -public: - // NOTE: This function is not locked. It is the caller's responsibility - // to enforce proper synchronization. - typename MapTy::iterator map_end() { return Map.end(); } - - /// InsertOrGetItem - Return an iterator for the specified element. - /// If the element exists in the map, the returned iterator points to the - /// entry and Exists=true. If not, the iterator points to the newly - /// inserted entry and returns Exists=false. Newly inserted entries have - /// I->second == 0, and should be filled in. - /// NOTE: This function is not locked. It is the caller's responsibility - // to enforce proper synchronization. - typename MapTy::iterator InsertOrGetItem(std::pair - &InsertVal, - bool &Exists) { - std::pair IP = Map.insert(InsertVal); - Exists = !IP.second; - return IP.first; - } - -private: - typename MapTy::iterator FindExistingElement(ConstantClass *CP) { - if (HasLargeKey) { - typename InverseMapTy::iterator IMI = InverseMap.find(CP); - assert(IMI != InverseMap.end() && IMI->second != Map.end() && - IMI->second->second == CP && - "InverseMap corrupt!"); - return IMI->second; - } - - typename MapTy::iterator I = - Map.find(MapKey(static_cast(CP->getRawType()), - getValType(CP))); - if (I == Map.end() || I->second != CP) { - // FIXME: This should not use a linear scan. If this gets to be a - // performance problem, someone should look at this. - for (I = Map.begin(); I != Map.end() && I->second != CP; ++I) - /* empty */; - } - return I; - } - - ConstantClass* Create(const TypeClass *Ty, const ValType &V, - typename MapTy::iterator I) { - ConstantClass* Result = - ConstantCreator::create(Ty, V); - - assert(Result->getType() == Ty && "Type specified is not correct!"); - I = Map.insert(I, std::make_pair(MapKey(Ty, V), Result)); - - if (HasLargeKey) // Remember the reverse mapping if needed. - InverseMap.insert(std::make_pair(Result, I)); - // If the type of the constant is abstract, make sure that an entry - // exists for it in the AbstractTypeMap. - if (Ty->isAbstract()) { - typename AbstractTypeMapTy::iterator TI = - AbstractTypeMap.find(Ty); - - if (TI == AbstractTypeMap.end()) { - // Add ourselves to the ATU list of the type. - cast(Ty)->addAbstractTypeUser(this); - - AbstractTypeMap.insert(TI, std::make_pair(Ty, I)); - } - } - - return Result; - } -public: - - /// getOrCreate - Return the specified constant from the map, creating it if - /// necessary. - ConstantClass *getOrCreate(const TypeClass *Ty, const ValType &V) { - sys::SmartScopedLock Lock(ValueMapLock); - MapKey Lookup(Ty, V); - ConstantClass* Result = 0; - - typename MapTy::iterator I = Map.find(Lookup); - // Is it in the map? - if (I != Map.end()) - Result = static_cast(I->second); - - if (!Result) { - // If no preexisting value, create one now... - Result = Create(Ty, V, I); - } - - return Result; - } - - void remove(ConstantClass *CP) { - sys::SmartScopedLock Lock(ValueMapLock); - typename MapTy::iterator I = FindExistingElement(CP); - assert(I != Map.end() && "Constant not found in constant table!"); - assert(I->second == CP && "Didn't find correct element?"); - - if (HasLargeKey) // Remember the reverse mapping if needed. - InverseMap.erase(CP); - - // Now that we found the entry, make sure this isn't the entry that - // the AbstractTypeMap points to. - const TypeClass *Ty = static_cast(I->first.first); - if (Ty->isAbstract()) { - assert(AbstractTypeMap.count(Ty) && - "Abstract type not in AbstractTypeMap?"); - typename MapTy::iterator &ATMEntryIt = AbstractTypeMap[Ty]; - if (ATMEntryIt == I) { - // Yes, we are removing the representative entry for this type. - // See if there are any other entries of the same type. - typename MapTy::iterator TmpIt = ATMEntryIt; - - // First check the entry before this one... - if (TmpIt != Map.begin()) { - --TmpIt; - if (TmpIt->first.first != Ty) // Not the same type, move back... - ++TmpIt; - } - - // If we didn't find the same type, try to move forward... - if (TmpIt == ATMEntryIt) { - ++TmpIt; - if (TmpIt == Map.end() || TmpIt->first.first != Ty) - --TmpIt; // No entry afterwards with the same type - } - - // If there is another entry in the map of the same abstract type, - // update the AbstractTypeMap entry now. - if (TmpIt != ATMEntryIt) { - ATMEntryIt = TmpIt; - } else { - // Otherwise, we are removing the last instance of this type - // from the table. Remove from the ATM, and from user list. - cast(Ty)->removeAbstractTypeUser(this); - AbstractTypeMap.erase(Ty); - } - } - } - - Map.erase(I); - } - - - /// MoveConstantToNewSlot - If we are about to change C to be the element - /// specified by I, update our internal data structures to reflect this - /// fact. - /// NOTE: This function is not locked. It is the responsibility of the - /// caller to enforce proper synchronization if using this method. - void MoveConstantToNewSlot(ConstantClass *C, typename MapTy::iterator I) { - // First, remove the old location of the specified constant in the map. - typename MapTy::iterator OldI = FindExistingElement(C); - assert(OldI != Map.end() && "Constant not found in constant table!"); - assert(OldI->second == C && "Didn't find correct element?"); - - // If this constant is the representative element for its abstract type, - // update the AbstractTypeMap so that the representative element is I. - if (C->getType()->isAbstract()) { - typename AbstractTypeMapTy::iterator ATI = - AbstractTypeMap.find(C->getType()); - assert(ATI != AbstractTypeMap.end() && - "Abstract type not in AbstractTypeMap?"); - if (ATI->second == OldI) - ATI->second = I; - } - - // Remove the old entry from the map. - Map.erase(OldI); - - // Update the inverse map so that we know that this constant is now - // located at descriptor I. - if (HasLargeKey) { - assert(I->second == C && "Bad inversemap entry!"); - InverseMap[C] = I; - } - } - - void refineAbstractType(const DerivedType *OldTy, const Type *NewTy) { - sys::SmartScopedLock Lock(ValueMapLock); - typename AbstractTypeMapTy::iterator I = - AbstractTypeMap.find(cast(OldTy)); - - assert(I != AbstractTypeMap.end() && - "Abstract type not in AbstractTypeMap?"); - - // Convert a constant at a time until the last one is gone. The last one - // leaving will remove() itself, causing the AbstractTypeMapEntry to be - // eliminated eventually. - do { - ConvertConstantType::convert( - static_cast(I->second->second), - cast(NewTy)); - - I = AbstractTypeMap.find(cast(OldTy)); - } while (I != AbstractTypeMap.end()); - } - - // If the type became concrete without being refined to any other existing - // type, we just remove ourselves from the ATU list. - void typeBecameConcrete(const DerivedType *AbsTy) { - AbsTy->removeAbstractTypeUser(this); +namespace { +struct DropReferences { + // Takes the value_type of a ConstantUniqueMap's internal map, whose 'second' + // is a Constant*. + template + void operator()(const PairT &P) { + P.second->dropAllReferences(); } +}; - void dump() const { - DOUT << "Constant.cpp: ValueMap\n"; +// Temporary - drops pair.first instead of second. +struct DropFirst { + // Takes the value_type of a ConstantUniqueMap's internal map, whose 'second' + // is a Constant*. + template + void operator()(const PairT &P) { + P.first->dropAllReferences(); } }; - -LLVMContextImpl::LLVMContextImpl(LLVMContext &C) : - Context(C), TheTrueVal(0), TheFalseVal(0) { - AggZeroConstants = new ContextValueMap(); } LLVMContextImpl::~LLVMContextImpl() { - delete AggZeroConstants; -} - -// Get a ConstantInt from an APInt. Note that the value stored in the DenseMap -// as the key, is a DenseMapAPIntKeyInfo::KeyTy which has provided the -// operator== and operator!= to ensure that the DenseMap doesn't attempt to -// compare APInt's of different widths, which would violate an APInt class -// invariant which generates an assertion. -ConstantInt *LLVMContextImpl::getConstantInt(const APInt& V) { - // Get the corresponding integer type for the bit width of the value. - const IntegerType *ITy = Context.getIntegerType(V.getBitWidth()); - // get an existing value or the insertion position - DenseMapAPIntKeyInfo::KeyTy Key(V, ITy); + // 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 Modules(OwnedModules.begin(), OwnedModules.end()); + DeleteContainerPointers(Modules); - ConstantsLock.reader_acquire(); - ConstantInt *&Slot = IntConstants[Key]; - ConstantsLock.reader_release(); - - if (!Slot) { - sys::SmartScopedWriter Writer(ConstantsLock); - ConstantInt *&NewSlot = IntConstants[Key]; - if (!Slot) { - NewSlot = new ConstantInt(ITy, V); - } - - return NewSlot; - } else { - return Slot; - } -} - -ConstantFP *LLVMContextImpl::getConstantFP(const APFloat &V) { - DenseMapAPFloatKeyInfo::KeyTy Key(V); + // Free the constants. This is important to do here to ensure that they are + // freed before the LeakDetector is torn down. + std::for_each(ExprConstants.map_begin(), ExprConstants.map_end(), + DropReferences()); + std::for_each(ArrayConstants.map_begin(), ArrayConstants.map_end(), + DropFirst()); + std::for_each(StructConstants.map_begin(), StructConstants.map_end(), + DropFirst()); + std::for_each(VectorConstants.map_begin(), VectorConstants.map_end(), + DropFirst()); + ExprConstants.freeConstants(); + ArrayConstants.freeConstants(); + StructConstants.freeConstants(); + VectorConstants.freeConstants(); + DeleteContainerSeconds(CAZConstants); + DeleteContainerSeconds(CPNConstants); + DeleteContainerSeconds(UVConstants); + InlineAsms.freeConstants(); + DeleteContainerSeconds(IntConstants); + DeleteContainerSeconds(FPConstants); - ConstantsLock.reader_acquire(); - ConstantFP *&Slot = FPConstants[Key]; - ConstantsLock.reader_release(); - - if (!Slot) { - sys::SmartScopedWriter Writer(ConstantsLock); - ConstantFP *&NewSlot = FPConstants[Key]; - if (!NewSlot) { - const Type *Ty; - if (&V.getSemantics() == &APFloat::IEEEsingle) - Ty = Type::FloatTy; - else if (&V.getSemantics() == &APFloat::IEEEdouble) - Ty = Type::DoubleTy; - else if (&V.getSemantics() == &APFloat::x87DoubleExtended) - Ty = Type::X86_FP80Ty; - else if (&V.getSemantics() == &APFloat::IEEEquad) - Ty = Type::FP128Ty; - else { - assert(&V.getSemantics() == &APFloat::PPCDoubleDouble && - "Unknown FP format"); - Ty = Type::PPC_FP128Ty; - } - NewSlot = new ConstantFP(Ty, V); - } - - return NewSlot; - } + for (StringMap::iterator I = CDSConstants.begin(), + E = CDSConstants.end(); I != E; ++I) + delete I->second; + CDSConstants.clear(); + + // Destroy attributes. + for (FoldingSetIterator I = AttrsSet.begin(), + E = AttrsSet.end(); I != E; ++I) + delete &*I; - return Slot; + // Destroy MDNodes. ~MDNode can move and remove nodes between the MDNodeSet + // and the NonUniquedMDNodes sets, so copy the values out first. + SmallVector MDNodes; + MDNodes.reserve(MDNodeSet.size() + NonUniquedMDNodes.size()); + for (FoldingSetIterator I = MDNodeSet.begin(), E = MDNodeSet.end(); + I != E; ++I) + MDNodes.push_back(&*I); + MDNodes.append(NonUniquedMDNodes.begin(), NonUniquedMDNodes.end()); + for (SmallVectorImpl::iterator I = MDNodes.begin(), + E = MDNodes.end(); I != E; ++I) + (*I)->destroy(); + assert(MDNodeSet.empty() && NonUniquedMDNodes.empty() && + "Destroying all MDNodes didn't empty the Context's sets."); + + // Destroy MDStrings. + DeleteContainerSeconds(MDStringCache); } -MDString *LLVMContextImpl::getMDString(const char *StrBegin, - const char *StrEnd) { - sys::SmartScopedWriter Writer(ConstantsLock); - StringMapEntry &Entry = MDStringCache.GetOrCreateValue( - StrBegin, StrEnd); - MDString *&S = Entry.getValue(); - if (!S) S = new MDString(Entry.getKeyData(), - Entry.getKeyData() + Entry.getKeyLength()); - - return S; -} +// ConstantsContext anchors +void UnaryConstantExpr::anchor() { } -MDNode *LLVMContextImpl::getMDNode(Value*const* Vals, unsigned NumVals) { - FoldingSetNodeID ID; - for (unsigned i = 0; i != NumVals; ++i) - ID.AddPointer(Vals[i]); +void BinaryConstantExpr::anchor() { } - ConstantsLock.reader_acquire(); - void *InsertPoint; - MDNode *N = MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint); - ConstantsLock.reader_release(); - - if (!N) { - sys::SmartScopedWriter Writer(ConstantsLock); - N = MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint); - if (!N) { - // InsertPoint will have been set by the FindNodeOrInsertPos call. - N = new(0) MDNode(Vals, NumVals); - MDNodeSet.InsertNode(N, InsertPoint); - } - } +void SelectConstantExpr::anchor() { } - return N; -} +void ExtractElementConstantExpr::anchor() { } -ConstantAggregateZero* -LLVMContextImpl::getConstantAggregateZero(const Type *Ty) { - assert((isa(Ty) || isa(Ty) || isa(Ty)) && - "Cannot create an aggregate zero of non-aggregate type!"); +void InsertElementConstantExpr::anchor() { } - // Implicitly locked. - return AggZeroConstants->getOrCreate(Ty, 0); -} +void ShuffleVectorConstantExpr::anchor() { } -// *** erase methods *** +void ExtractValueConstantExpr::anchor() { } -void LLVMContextImpl::erase(MDString *M) { - sys::SmartScopedWriter Writer(ConstantsLock); - MDStringCache.erase(MDStringCache.find(M->StrBegin, M->StrEnd)); -} +void InsertValueConstantExpr::anchor() { } -void LLVMContextImpl::erase(MDNode *M) { - sys::SmartScopedWriter Writer(ConstantsLock); - MDNodeSet.RemoveNode(M); -} +void GetElementPtrConstantExpr::anchor() { } -void LLVMContextImpl::erase(ConstantAggregateZero *Z) { - AggZeroConstants->remove(Z); -} +void CompareConstantExpr::anchor() { }