diff options
Diffstat (limited to 'lib/VMCore')
-rw-r--r-- | lib/VMCore/ConstantFold.cpp | 6 | ||||
-rw-r--r-- | lib/VMCore/Constants.cpp | 137 | ||||
-rw-r--r-- | lib/VMCore/Core.cpp | 4 | ||||
-rw-r--r-- | lib/VMCore/LLVMContext.cpp | 45 | ||||
-rw-r--r-- | lib/VMCore/LLVMContextImpl.cpp | 111 | ||||
-rw-r--r-- | lib/VMCore/LLVMContextImpl.h | 12 |
6 files changed, 139 insertions, 176 deletions
diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp index 61616f2..3c0d94e 100644 --- a/lib/VMCore/ConstantFold.cpp +++ b/lib/VMCore/ConstantFold.cpp @@ -521,7 +521,7 @@ Constant *llvm::ConstantFoldInsertValueInstruction(LLVMContext &Context, if (isa<StructType>(AggTy)) return ConstantStruct::get(Ops); else - return Context.getConstantArray(cast<ArrayType>(AggTy), Ops); + return ConstantArray::get(cast<ArrayType>(AggTy), Ops); } if (isa<ConstantAggregateZero>(Agg)) { // Insertion of constant into aggregate zero @@ -550,7 +550,7 @@ Constant *llvm::ConstantFoldInsertValueInstruction(LLVMContext &Context, if (isa<StructType>(AggTy)) return ConstantStruct::get(Ops); else - return Context.getConstantArray(cast<ArrayType>(AggTy), Ops); + return ConstantArray::get(cast<ArrayType>(AggTy), Ops); } if (isa<ConstantStruct>(Agg) || isa<ConstantArray>(Agg)) { // Insertion of constant into aggregate constant @@ -567,7 +567,7 @@ Constant *llvm::ConstantFoldInsertValueInstruction(LLVMContext &Context, if (isa<StructType>(Agg->getType())) C = ConstantStruct::get(Ops); else - C = Context.getConstantArray(cast<ArrayType>(Agg->getType()), Ops); + C = ConstantArray::get(cast<ArrayType>(Agg->getType()), Ops); return C; } diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp index ecb6256..ec1bf13 100644 --- a/lib/VMCore/Constants.cpp +++ b/lib/VMCore/Constants.cpp @@ -375,6 +375,54 @@ ConstantArray::ConstantArray(const ArrayType *T, } } +Constant *ConstantArray::get(const ArrayType *Ty, + const std::vector<Constant*> &V) { + LLVMContextImpl *pImpl = Ty->getContext().pImpl; + // If this is an all-zero array, return a ConstantAggregateZero object + if (!V.empty()) { + Constant *C = V[0]; + if (!C->isNullValue()) { + // Implicitly locked. + return pImpl->ArrayConstants.getOrCreate(Ty, V); + } + for (unsigned i = 1, e = V.size(); i != e; ++i) + if (V[i] != C) { + // Implicitly locked. + return pImpl->ArrayConstants.getOrCreate(Ty, V); + } + } + + return Ty->getContext().getConstantAggregateZero(Ty); +} + + +Constant* ConstantArray::get(const ArrayType* T, Constant* const* Vals, + unsigned NumVals) { + // FIXME: make this the primary ctor method. + return get(T, std::vector<Constant*>(Vals, Vals+NumVals)); +} + +/// ConstantArray::get(const string&) - Return an array that is initialized to +/// contain the specified string. If length is zero then a null terminator is +/// added to the specified string so that it may be used in a natural way. +/// Otherwise, the length parameter specifies how much of the string to use +/// and it won't be null terminated. +/// +Constant* ConstantArray::get(const StringRef &Str, bool AddNull) { + std::vector<Constant*> ElementVals; + for (unsigned i = 0; i < Str.size(); ++i) + ElementVals.push_back(ConstantInt::get(Type::Int8Ty, Str[i])); + + // Add a null terminator to the string... + if (AddNull) { + ElementVals.push_back(ConstantInt::get(Type::Int8Ty, 0)); + } + + ArrayType *ATy = ArrayType::get(Type::Int8Ty, ElementVals.size()); + return get(ATy, ElementVals); +} + + ConstantStruct::ConstantStruct(const StructType *T, const std::vector<Constant*> &V) @@ -943,7 +991,7 @@ void ConstantAggregateZero::destroyConstant() { /// void ConstantArray::destroyConstant() { // Implicitly locked. - getType()->getContext().erase(this); + getType()->getContext().pImpl->ArrayConstants.remove(this); destroyConstantImpl(); } @@ -1907,12 +1955,91 @@ const char *ConstantExpr::getOpcodeName() const { /// single invocation handles all 1000 uses. Handling them one at a time would /// work, but would be really slow because it would have to unique each updated /// array instance. + +static std::vector<Constant*> getValType(ConstantArray *CA) { + std::vector<Constant*> Elements; + Elements.reserve(CA->getNumOperands()); + for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i) + Elements.push_back(cast<Constant>(CA->getOperand(i))); + return Elements; +} + + void ConstantArray::replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) { - Constant *Replacement = - getType()->getContext().replaceUsesOfWithOnConstant(this, From, To, U); - - if (!Replacement) return; + assert(isa<Constant>(To) && "Cannot make Constant refer to non-constant!"); + Constant *ToC = cast<Constant>(To); + + LLVMContext &Context = getType()->getContext(); + LLVMContextImpl *pImpl = Context.pImpl; + + std::pair<LLVMContextImpl::ArrayConstantsTy::MapKey, Constant*> Lookup; + Lookup.first.first = getType(); + Lookup.second = this; + + std::vector<Constant*> &Values = Lookup.first.second; + Values.reserve(getNumOperands()); // Build replacement array. + + // 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 = OperandList, *E = OperandList+getNumOperands(); O != E; ++O) { + Constant *Val = cast<Constant>(O->get()); + if (Val == From) { + Val = ToC; + ++NumUpdated; + } + Values.push_back(Val); + } + } else { + isAllZeros = true; + for (Use *O = OperandList, *E = OperandList+getNumOperands();O != E; ++O) { + Constant *Val = cast<Constant>(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(getType()); + } else { + // Check to see if we have this array type already. + sys::SmartScopedWriter<true> Writer(pImpl->ConstantsLock); + bool Exists; + LLVMContextImpl::ArrayConstantsTy::MapTy::iterator I = + pImpl->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! + pImpl->ArrayConstants.MoveConstantToNewSlot(this, 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 - OperandList; + assert(getOperand(OperandToUpdate) == From && + "ReplaceAllUsesWith broken!"); + setOperand(OperandToUpdate, ToC); + } else { + for (unsigned i = 0, e = getNumOperands(); i != e; ++i) + if (getOperand(i) == From) + setOperand(i, ToC); + } + return; + } + } // Otherwise, I do need to replace this with an existing value. assert(Replacement != this && "I didn't contain From!"); diff --git a/lib/VMCore/Core.cpp b/lib/VMCore/Core.cpp index 12f7c32..a262f40 100644 --- a/lib/VMCore/Core.cpp +++ b/lib/VMCore/Core.cpp @@ -402,13 +402,13 @@ LLVMValueRef LLVMConstString(const char *Str, unsigned Length, int DontNullTerminate) { /* Inverted the sense of AddNull because ', 0)' is a better mnemonic for null termination than ', 1)'. */ - return wrap(getGlobalContext().getConstantArray(std::string(Str, Length), + return wrap(ConstantArray::get(std::string(Str, Length), DontNullTerminate == 0)); } LLVMValueRef LLVMConstArray(LLVMTypeRef ElementTy, LLVMValueRef *ConstantVals, unsigned Length) { - return wrap(getGlobalContext().getConstantArray( + return wrap(ConstantArray::get( getGlobalContext().getArrayType(unwrap(ElementTy), Length), unwrap<Constant>(ConstantVals, Length), Length)); diff --git a/lib/VMCore/LLVMContext.cpp b/lib/VMCore/LLVMContext.cpp index 340ca95..97857c5 100644 --- a/lib/VMCore/LLVMContext.cpp +++ b/lib/VMCore/LLVMContext.cpp @@ -103,42 +103,6 @@ ConstantAggregateZero* LLVMContext::getConstantAggregateZero(const Type* Ty) { return pImpl->getConstantAggregateZero(Ty); } - -// ConstantArray accessors. -Constant* LLVMContext::getConstantArray(const ArrayType* T, - const std::vector<Constant*>& V) { - return pImpl->getConstantArray(T, V); -} - -Constant* LLVMContext::getConstantArray(const ArrayType* T, - Constant* const* Vals, - unsigned NumVals) { - // FIXME: make this the primary ctor method. - return getConstantArray(T, std::vector<Constant*>(Vals, Vals+NumVals)); -} - -/// ConstantArray::get(const string&) - Return an array that is initialized to -/// contain the specified string. If length is zero then a null terminator is -/// added to the specified string so that it may be used in a natural way. -/// Otherwise, the length parameter specifies how much of the string to use -/// and it won't be null terminated. -/// -Constant* LLVMContext::getConstantArray(const StringRef &Str, - bool AddNull) { - std::vector<Constant*> ElementVals; - for (unsigned i = 0; i < Str.size(); ++i) - ElementVals.push_back(ConstantInt::get(Type::Int8Ty, Str[i])); - - // Add a null terminator to the string... - if (AddNull) { - ElementVals.push_back(ConstantInt::get(Type::Int8Ty, 0)); - } - - ArrayType *ATy = getArrayType(Type::Int8Ty, ElementVals.size()); - return getConstantArray(ATy, ElementVals); -} - - // ConstantExpr accessors. Constant* LLVMContext::getConstantExpr(unsigned Opcode, Constant* C1, Constant* C2) { @@ -525,15 +489,6 @@ void LLVMContext::erase(ConstantAggregateZero *Z) { pImpl->erase(Z); } -void LLVMContext::erase(ConstantArray *C) { - pImpl->erase(C); -} - void LLVMContext::erase(ConstantVector *V) { pImpl->erase(V); } - -Constant *LLVMContext::replaceUsesOfWithOnConstant(ConstantArray *CA, - Value *From, Value *To, Use *U) { - return pImpl->replaceUsesOfWithOnConstant(CA, From, To, U); -} diff --git a/lib/VMCore/LLVMContextImpl.cpp b/lib/VMCore/LLVMContextImpl.cpp index 858ed15..72e415c 100644 --- a/lib/VMCore/LLVMContextImpl.cpp +++ b/lib/VMCore/LLVMContextImpl.cpp @@ -21,14 +21,6 @@ using namespace llvm; static char getValType(ConstantAggregateZero *CPZ) { return 0; } -static std::vector<Constant*> getValType(ConstantArray *CA) { - std::vector<Constant*> Elements; - Elements.reserve(CA->getNumOperands()); - for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i) - Elements.push_back(cast<Constant>(CA->getOperand(i))); - return Elements; -} - static std::vector<Constant*> getValType(ConstantVector *CP) { std::vector<Constant*> Elements; Elements.reserve(CP->getNumOperands()); @@ -85,25 +77,6 @@ LLVMContextImpl::getConstantAggregateZero(const Type *Ty) { return AggZeroConstants.getOrCreate(Ty, 0); } -Constant *LLVMContextImpl::getConstantArray(const ArrayType *Ty, - const std::vector<Constant*> &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); - } - } - - return Context.getConstantAggregateZero(Ty); -} - Constant *LLVMContextImpl::getConstantVector(const VectorType *Ty, const std::vector<Constant*> &V) { assert(!V.empty() && "Vectors can't be empty"); @@ -146,90 +119,6 @@ void LLVMContextImpl::erase(ConstantAggregateZero *Z) { AggZeroConstants.remove(Z); } -void LLVMContextImpl::erase(ConstantArray *C) { - ArrayConstants.remove(C); -} - void LLVMContextImpl::erase(ConstantVector *V) { VectorConstants.remove(V); } - -// *** RAUW helpers *** - -Constant *LLVMContextImpl::replaceUsesOfWithOnConstant(ConstantArray *CA, - Value *From, Value *To, Use *U) { - assert(isa<Constant>(To) && "Cannot make Constant refer to non-constant!"); - Constant *ToC = cast<Constant>(To); - - std::pair<ArrayConstantsTy::MapKey, Constant*> Lookup; - Lookup.first.first = CA->getType(); - Lookup.second = CA; - - std::vector<Constant*> &Values = Lookup.first.second; - Values.reserve(CA->getNumOperands()); // Build replacement array. - - // 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<Constant>(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<Constant>(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<true> 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; -}
\ No newline at end of file diff --git a/lib/VMCore/LLVMContextImpl.h b/lib/VMCore/LLVMContextImpl.h index 21fef39..eea495d 100644 --- a/lib/VMCore/LLVMContextImpl.h +++ b/lib/VMCore/LLVMContextImpl.h @@ -88,7 +88,7 @@ struct ConvertConstantType<ConstantArray, ArrayType> { std::vector<Constant*> C; for (unsigned i = 0, e = OldC->getNumOperands(); i != e; ++i) C.push_back(cast<Constant>(OldC->getOperand(i))); - Constant *New = NewTy->getContext().getConstantArray(NewTy, C); + Constant *New = ConstantArray::get(NewTy, C); assert(New != OldC && "Didn't replace constant??"); OldC->uncheckedReplaceAllUsesWith(New); OldC->destroyConstant(); // This constant is now dead, destroy it. @@ -459,6 +459,7 @@ class LLVMContextImpl { friend class ConstantInt; friend class ConstantFP; friend class ConstantStruct; + friend class ConstantArray; public: LLVMContextImpl(LLVMContext &C); @@ -468,9 +469,6 @@ public: ConstantAggregateZero *getConstantAggregateZero(const Type *Ty); - Constant *getConstantArray(const ArrayType *Ty, - const std::vector<Constant*> &V); - Constant *getConstantVector(const VectorType *Ty, const std::vector<Constant*> &V); @@ -491,13 +489,7 @@ public: void erase(MDString *M); void erase(MDNode *M); void erase(ConstantAggregateZero *Z); - void erase(ConstantArray *C); void erase(ConstantVector *V); - - // RAUW helpers - - Constant *replaceUsesOfWithOnConstant(ConstantArray *CA, Value *From, - Value *To, Use *U); }; } |