X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FVMCore%2FLLVMContextImpl.cpp;h=a86363b632a35f80ffa1c09885d4c79d315f1d70;hb=3756e70af69096a82b367ee9667e7720ca2201e4;hp=edd76fc031ba9e6714cf456d72903a72b98068f9;hpb=03d7651c3652e1f0cc86e79b26585d86818da9cf;p=oota-llvm.git diff --git a/lib/VMCore/LLVMContextImpl.cpp b/lib/VMCore/LLVMContextImpl.cpp index edd76fc031b..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,351 +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; } - -static std::vector getValType(ConstantArray *CA) { - std::vector Elements; - Elements.reserve(CA->getNumOperands()); - for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i) - Elements.push_back(cast(CA->getOperand(i))); - return Elements; -} - -static std::vector getValType(ConstantStruct *CS) { - std::vector Elements; - Elements.reserve(CS->getNumOperands()); - for (unsigned i = 0, e = CS->getNumOperands(); i != e; ++i) - Elements.push_back(cast(CS->getOperand(i))); - return Elements; -} - -static std::vector getValType(ConstantVector *CP) { - std::vector Elements; - Elements.reserve(CP->getNumOperands()); - for (unsigned i = 0, e = CP->getNumOperands(); i != e; ++i) - Elements.push_back(CP->getOperand(i)); - return Elements; -} - - -LLVMContextImpl::LLVMContextImpl(LLVMContext &C) : - Context(C), TheTrueVal(0), TheFalseVal(0) { } - - -ConstantFP *LLVMContextImpl::getConstantFP(const APFloat &V) { - DenseMapAPFloatKeyInfo::KeyTy Key(V); - - 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; +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; +} + +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(); } - - return Slot; -} - -MDString *LLVMContextImpl::getMDString(const char *StrBegin, - unsigned StrLength) { - sys::SmartScopedWriter Writer(ConstantsLock); - StringMapEntry &Entry = - MDStringCache.GetOrCreateValue(StringRef(StrBegin, StrLength)); - MDString *&S = Entry.getValue(); - if (!S) S = new MDString(Entry.getKeyData(), - Entry.getKeyLength()); - - return S; -} - -MDNode *LLVMContextImpl::getMDNode(Value*const* Vals, unsigned NumVals) { - FoldingSetNodeID ID; - for (unsigned i = 0; i != NumVals; ++i) - ID.AddPointer(Vals[i]); - - 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 MDNode(Vals, NumVals); - MDNodeSet.InsertNode(N, InsertPoint); - } +}; + +// 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(); } - - return N; -} - -ConstantAggregateZero* -LLVMContextImpl::getConstantAggregateZero(const Type *Ty) { - assert((isa(Ty) || isa(Ty) || isa(Ty)) && - "Cannot create an aggregate zero of non-aggregate type!"); - - // Implicitly locked. - return AggZeroConstants.getOrCreate(Ty, 0); +}; } -Constant *LLVMContextImpl::getConstantArray(const ArrayType *Ty, - const std::vector &V) { - // If this is an all-zero array, return a ConstantAggregateZero object - if (!V.empty()) { - Constant *C = V[0]; - if (!C->isNullValue()) { - // Implicitly locked. - return ArrayConstants.getOrCreate(Ty, V); - } - for (unsigned i = 1, e = V.size(); i != e; ++i) - if (V[i] != C) { - // Implicitly locked. - return ArrayConstants.getOrCreate(Ty, V); - } - } +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 Modules(OwnedModules.begin(), OwnedModules.end()); + DeleteContainerPointers(Modules); - return Context.getConstantAggregateZero(Ty); -} - -Constant *LLVMContextImpl::getConstantStruct(const StructType *Ty, - const std::vector &V) { - // Create a ConstantAggregateZero value if all elements are zeros... - for (unsigned i = 0, e = V.size(); i != e; ++i) - if (!V[i]->isNullValue()) - // Implicitly locked. - return StructConstants.getOrCreate(Ty, V); - - return Context.getConstantAggregateZero(Ty); -} - -Constant *LLVMContextImpl::getConstantVector(const VectorType *Ty, - const std::vector &V) { - assert(!V.empty() && "Vectors can't be empty"); - // If this is an all-undef or alll-zero vector, return a - // ConstantAggregateZero or UndefValue. - Constant *C = V[0]; - bool isZero = C->isNullValue(); - bool isUndef = isa(C); - - if (isZero || isUndef) { - for (unsigned i = 1, e = V.size(); i != e; ++i) - if (V[i] != C) { - isZero = isUndef = false; - break; - } - } + // 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); - if (isZero) - return Context.getConstantAggregateZero(Ty); - if (isUndef) - return Context.getUndef(Ty); - - // Implicitly locked. - return VectorConstants.getOrCreate(Ty, V); -} - -// *** erase methods *** + 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; + + // 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."); -void LLVMContextImpl::erase(MDString *M) { - sys::SmartScopedWriter Writer(ConstantsLock); - MDStringCache.erase(MDStringCache.find(M->getString())); + // Destroy MDStrings. + DeleteContainerSeconds(MDStringCache); } -void LLVMContextImpl::erase(MDNode *M) { - sys::SmartScopedWriter Writer(ConstantsLock); - MDNodeSet.RemoveNode(M); -} +// ConstantsContext anchors +void UnaryConstantExpr::anchor() { } -void LLVMContextImpl::erase(ConstantAggregateZero *Z) { - AggZeroConstants.remove(Z); -} +void BinaryConstantExpr::anchor() { } -void LLVMContextImpl::erase(ConstantArray *C) { - ArrayConstants.remove(C); -} +void SelectConstantExpr::anchor() { } -void LLVMContextImpl::erase(ConstantStruct *S) { - StructConstants.remove(S); -} +void ExtractElementConstantExpr::anchor() { } -void LLVMContextImpl::erase(ConstantVector *V) { - VectorConstants.remove(V); -} +void InsertElementConstantExpr::anchor() { } -// *** RAUW helpers *** +void ShuffleVectorConstantExpr::anchor() { } -Constant *LLVMContextImpl::replaceUsesOfWithOnConstant(ConstantArray *CA, - Value *From, Value *To, Use *U) { - assert(isa(To) && "Cannot make Constant refer to non-constant!"); - Constant *ToC = cast(To); +void ExtractValueConstantExpr::anchor() { } - std::pair Lookup; - Lookup.first.first = CA->getType(); - Lookup.second = CA; +void InsertValueConstantExpr::anchor() { } - std::vector &Values = Lookup.first.second; - Values.reserve(CA->getNumOperands()); // Build replacement array. +void GetElementPtrConstantExpr::anchor() { } - // Fill values with the modified operands of the constant array. Also, - // compute whether this turns into an all-zeros array. - bool isAllZeros = false; - unsigned NumUpdated = 0; - if (!ToC->isNullValue()) { - for (Use *O = CA->OperandList, *E = CA->OperandList + CA->getNumOperands(); - O != E; ++O) { - Constant *Val = cast(O->get()); - if (Val == From) { - Val = ToC; - ++NumUpdated; - } - Values.push_back(Val); - } - } else { - isAllZeros = true; - for (Use *O = CA->OperandList, *E = CA->OperandList + CA->getNumOperands(); - O != E; ++O) { - Constant *Val = cast(O->get()); - if (Val == From) { - Val = ToC; - ++NumUpdated; - } - Values.push_back(Val); - if (isAllZeros) isAllZeros = Val->isNullValue(); - } - } - - Constant *Replacement = 0; - if (isAllZeros) { - Replacement = Context.getConstantAggregateZero(CA->getType()); - } else { - // Check to see if we have this array type already. - sys::SmartScopedWriter Writer(ConstantsLock); - bool Exists; - ArrayConstantsTy::MapTy::iterator I = - ArrayConstants.InsertOrGetItem(Lookup, Exists); - - if (Exists) { - Replacement = I->second; - } else { - // Okay, the new shape doesn't exist in the system yet. Instead of - // creating a new constant array, inserting it, replaceallusesof'ing the - // old with the new, then deleting the old... just update the current one - // in place! - ArrayConstants.MoveConstantToNewSlot(CA, I); - - // Update to the new value. Optimize for the case when we have a single - // operand that we're changing, but handle bulk updates efficiently. - if (NumUpdated == 1) { - unsigned OperandToUpdate = U - CA->OperandList; - assert(CA->getOperand(OperandToUpdate) == From && - "ReplaceAllUsesWith broken!"); - CA->setOperand(OperandToUpdate, ToC); - } else { - for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i) - if (CA->getOperand(i) == From) - CA->setOperand(i, ToC); - } - return 0; - } - } - - return Replacement; -} - -Constant *LLVMContextImpl::replaceUsesOfWithOnConstant(ConstantStruct *CS, - Value *From, Value *To, Use *U) { - assert(isa(To) && "Cannot make Constant refer to non-constant!"); - Constant *ToC = cast(To); - - unsigned OperandToUpdate = U - CS->OperandList; - assert(CS->getOperand(OperandToUpdate) == From && - "ReplaceAllUsesWith broken!"); - - std::pair Lookup; - Lookup.first.first = CS->getType(); - Lookup.second = CS; - std::vector &Values = Lookup.first.second; - Values.reserve(CS->getNumOperands()); // Build replacement struct. - - - // Fill values with the modified operands of the constant struct. Also, - // compute whether this turns into an all-zeros struct. - bool isAllZeros = false; - if (!ToC->isNullValue()) { - for (Use *O = CS->OperandList, *E = CS->OperandList + CS->getNumOperands(); - O != E; ++O) - Values.push_back(cast(O->get())); - } else { - isAllZeros = true; - for (Use *O = CS->OperandList, *E = CS->OperandList + CS->getNumOperands(); - O != E; ++O) { - Constant *Val = cast(O->get()); - Values.push_back(Val); - if (isAllZeros) isAllZeros = Val->isNullValue(); - } - } - Values[OperandToUpdate] = ToC; - - Constant *Replacement = 0; - if (isAllZeros) { - Replacement = Context.getConstantAggregateZero(CS->getType()); - } else { - // Check to see if we have this array type already. - sys::SmartScopedWriter Writer(ConstantsLock); - bool Exists; - StructConstantsTy::MapTy::iterator I = - StructConstants.InsertOrGetItem(Lookup, Exists); - - if (Exists) { - Replacement = I->second; - } else { - // Okay, the new shape doesn't exist in the system yet. Instead of - // creating a new constant struct, inserting it, replaceallusesof'ing the - // old with the new, then deleting the old... just update the current one - // in place! - StructConstants.MoveConstantToNewSlot(CS, I); - - // Update to the new value. - CS->setOperand(OperandToUpdate, ToC); - return 0; - } - } - - assert(Replacement != CS && "I didn't contain From!"); - - return Replacement; -} +void CompareConstantExpr::anchor() { }