diff --git a/examples/BrainF/BrainF.cpp b/examples/BrainF/BrainF.cpp index 97a9b0579e0..e47365bfa16 100644 --- a/examples/BrainF/BrainF.cpp +++ b/examples/BrainF/BrainF.cpp @@ -125,7 +125,7 @@ void BrainF::header(LLVMContext& C) { { //@aberrormsg = internal constant [%d x i8] c"\00" Constant *msg_0 = - C.getConstantArray("Error: The head has left the tape.", true); + ConstantArray::get("Error: The head has left the tape.", true); GlobalVariable *aberrormsg = new GlobalVariable( *module, diff --git a/include/llvm/Constants.h b/include/llvm/Constants.h index af7187d95fe..442472acb3d 100644 --- a/include/llvm/Constants.h +++ b/include/llvm/Constants.h @@ -327,10 +327,22 @@ class ConstantArray : public Constant { friend struct ConstantCreator >; ConstantArray(const ConstantArray &); // DO NOT IMPLEMENT - friend class LLVMContextImpl; protected: ConstantArray(const ArrayType *T, const std::vector &Val); public: + // ConstantArray accessors + static Constant* get(const ArrayType* T, const std::vector& V); + static Constant* get(const ArrayType* T, Constant* const* Vals, + unsigned NumVals); + + /// This method constructs a ConstantArray and initializes it with a text + /// string. The default behavior (AddNull==true) causes a null terminator to + /// be placed at the end of the array. This effectively increases the length + /// of the array by one (you've been warned). However, in some situations + /// this is not desired so if AddNull==false then the string is copied without + /// null termination. + static Constant* get(const StringRef &Initializer, bool AddNull = true); + /// Transparently provide more efficient getOperand methods. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant); diff --git a/include/llvm/LLVMContext.h b/include/llvm/LLVMContext.h index 8465e4d95a3..03de906c14a 100644 --- a/include/llvm/LLVMContext.h +++ b/include/llvm/LLVMContext.h @@ -58,6 +58,7 @@ class LLVMContext { friend class ConstantInt; friend class ConstantFP; friend class ConstantStruct; + friend class ConstantArray; public: LLVMContext(); ~LLVMContext(); @@ -82,21 +83,6 @@ public: // ConstantAggregateZero accessors ConstantAggregateZero* getConstantAggregateZero(const Type* Ty); - - // ConstantArray accessors - Constant* getConstantArray(const ArrayType* T, - const std::vector& V); - Constant* getConstantArray(const ArrayType* T, Constant* const* Vals, - unsigned NumVals); - - /// This method constructs a ConstantArray and initializes it with a text - /// string. The default behavior (AddNull==true) causes a null terminator to - /// be placed at the end of the array. This effectively increases the length - /// of the array by one (you've been warned). However, in some situations - /// this is not desired so if AddNull==false then the string is copied without - /// null termination. - Constant* getConstantArray(const StringRef &Initializer, - bool AddNull = true); // ConstantExpr accessors Constant* getConstantExpr(unsigned Opcode, Constant* C1, Constant* C2); @@ -225,12 +211,7 @@ public: void erase(MDString *M); void erase(MDNode *M); void erase(ConstantAggregateZero *Z); - void erase(ConstantArray *Z); void erase(ConstantVector *V); - - // RAUW helpers - Constant *replaceUsesOfWithOnConstant(ConstantArray *CA, - Value *From, Value *To, Use *U); }; /// FOR BACKWARDS COMPATIBILITY - Returns a global context. diff --git a/include/llvm/Support/IRBuilder.h b/include/llvm/Support/IRBuilder.h index d22bc3d1038..12439d44866 100644 --- a/include/llvm/Support/IRBuilder.h +++ b/include/llvm/Support/IRBuilder.h @@ -413,7 +413,7 @@ public: return CreateConstGEP2_32(Ptr, 0, Idx, Name); } Value *CreateGlobalString(const char *Str = "", const char *Name = "") { - Constant *StrConstant = Context.getConstantArray(Str, true); + Constant *StrConstant = ConstantArray::get(Str, true); Module &M = *BB->getParent()->getParent(); GlobalVariable *gv = new GlobalVariable(M, StrConstant->getType(), diff --git a/lib/Analysis/DebugInfo.cpp b/lib/Analysis/DebugInfo.cpp index 47a561bc29c..ff411a69355 100644 --- a/lib/Analysis/DebugInfo.cpp +++ b/lib/Analysis/DebugInfo.cpp @@ -499,7 +499,7 @@ Constant *DIFactory::GetStringConstant(const std::string &String) { return Slot = VMContext.getConstantPointerNull(DestTy); // Construct string as an llvm constant. - Constant *ConstStr = VMContext.getConstantArray(String); + Constant *ConstStr = ConstantArray::get(String); // Otherwise create and return a new string global. GlobalVariable *StrGV = new GlobalVariable(M, ConstStr->getType(), true, @@ -521,7 +521,7 @@ DIArray DIFactory::GetOrCreateArray(DIDescriptor *Tys, unsigned NumTys) { for (unsigned i = 0; i != NumTys; ++i) Elts.push_back(getCastToEmpty(Tys[i])); - Constant *Init = VMContext.getConstantArray(VMContext.getArrayType(EmptyStructPtr, + Constant *Init = ConstantArray::get(VMContext.getArrayType(EmptyStructPtr, Elts.size()), Elts.data(), Elts.size()); // If we already have this array, just return the uniqued version. diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index 6a4e5c1950b..fc58dbccc6d 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -1811,13 +1811,13 @@ bool LLParser::ParseValID(ValID &ID) { " is not of type '" +Elts[0]->getType()->getDescription()); } - ID.ConstantVal = Context.getConstantArray(ATy, Elts.data(), Elts.size()); + ID.ConstantVal = ConstantArray::get(ATy, Elts.data(), Elts.size()); ID.Kind = ValID::t_Constant; return false; } case lltok::kw_c: // c "foo" Lex.Lex(); - ID.ConstantVal = Context.getConstantArray(Lex.getStrVal(), false); + ID.ConstantVal = ConstantArray::get(Lex.getStrVal(), false); if (ParseToken(lltok::StringConstant, "expected string")) return true; ID.Kind = ValID::t_Constant; return false; diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index 2c4aab1dfdd..117a8758d04 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -288,7 +288,7 @@ void BitcodeReaderValueList::ResolveConstantForwardRefs() { // Make the new constant. Constant *NewC; if (ConstantArray *UserCA = dyn_cast(UserC)) { - NewC = Context.getConstantArray(UserCA->getType(), &NewOps[0], + NewC = ConstantArray::get(UserCA->getType(), &NewOps[0], NewOps.size()); } else if (ConstantStruct *UserCS = dyn_cast(UserC)) { NewC = ConstantStruct::get(&NewOps[0], NewOps.size(), @@ -930,7 +930,7 @@ bool BitcodeReader::ParseConstants() { const Type *EltTy = ATy->getElementType(); for (unsigned i = 0; i != Size; ++i) Elts.push_back(ValueList.getConstantFwdRef(Record[i], EltTy)); - V = Context.getConstantArray(ATy, Elts); + V = ConstantArray::get(ATy, Elts); } else if (const VectorType *VTy = dyn_cast(CurTy)) { const Type *EltTy = VTy->getElementType(); for (unsigned i = 0; i != Size; ++i) @@ -952,7 +952,7 @@ bool BitcodeReader::ParseConstants() { std::vector Elts; for (unsigned i = 0; i != Size; ++i) Elts.push_back(ConstantInt::get(EltTy, Record[i])); - V = Context.getConstantArray(ATy, Elts); + V = ConstantArray::get(ATy, Elts); break; } case bitc::CST_CODE_CSTRING: { // CSTRING: [values] @@ -967,7 +967,7 @@ bool BitcodeReader::ParseConstants() { for (unsigned i = 0; i != Size; ++i) Elts.push_back(ConstantInt::get(EltTy, Record[i])); Elts.push_back(Context.getNullValue(EltTy)); - V = Context.getConstantArray(ATy, Elts); + V = ConstantArray::get(ATy, Elts); break; } case bitc::CST_CODE_CE_BINOP: { // CE_BINOP: [opcode, opval, opval] diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 1ed1585544c..aacd9e847aa 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -5812,7 +5812,7 @@ SDValue DAGCombiner::SimplifySelectCC(DebugLoc DL, SDValue N0, SDValue N1, const TargetData &TD = *TLI.getTargetData(); // Create a ConstantArray of the two constants. - Constant *CA = DAG.getContext()->getConstantArray( + Constant *CA = ConstantArray::get( DAG.getContext()->getArrayType(FPTy, 2), Elts, 2); SDValue CPIdx = DAG.getConstantPool(CA, TLI.getPointerTy(), TD.getPrefTypeAlignment(FPTy)); diff --git a/lib/CodeGen/ShadowStackGC.cpp b/lib/CodeGen/ShadowStackGC.cpp index 9d141e9c823..801a99bdb07 100644 --- a/lib/CodeGen/ShadowStackGC.cpp +++ b/lib/CodeGen/ShadowStackGC.cpp @@ -209,7 +209,7 @@ Constant *ShadowStackGC::GetFrameMap(Function &F) { Constant *DescriptorElts[] = { ConstantStruct::get(BaseElts, 2), - Context.getConstantArray(Context.getArrayType(VoidPtr, NumMeta), + ConstantArray::get(Context.getArrayType(VoidPtr, NumMeta), Metadata.begin(), NumMeta) }; diff --git a/lib/Linker/LinkModules.cpp b/lib/Linker/LinkModules.cpp index a2009ec4665..0e9976f1ca9 100644 --- a/lib/Linker/LinkModules.cpp +++ b/lib/Linker/LinkModules.cpp @@ -369,7 +369,7 @@ static Value *RemapOperand(const Value *In, Operands[i] =cast(RemapOperand(CPA->getOperand(i), ValueMap, Context)); Result = - Context.getConstantArray(cast(CPA->getType()), Operands); + ConstantArray::get(cast(CPA->getType()), Operands); } else if (const ConstantStruct *CPS = dyn_cast(CPV)) { std::vector Operands(CPS->getNumOperands()); for (unsigned i = 0, e = CPS->getNumOperands(); i != e; ++i) @@ -1186,7 +1186,7 @@ static bool LinkAppendingVars(Module *M, for (unsigned i = 0, e = T2->getNumElements(); i != e; ++i) Inits.push_back(CV); } - NG->setInitializer(Context.getConstantArray(NewType, Inits)); + NG->setInitializer(ConstantArray::get(NewType, Inits)); Inits.clear(); // Replace any uses of the two global variables with uses of the new diff --git a/lib/Target/XCore/XCoreTargetObjectFile.cpp b/lib/Target/XCore/XCoreTargetObjectFile.cpp index 89880c29f45..964ec82d576 100644 --- a/lib/Target/XCore/XCoreTargetObjectFile.cpp +++ b/lib/Target/XCore/XCoreTargetObjectFile.cpp @@ -29,4 +29,4 @@ XCoreTargetObjectFile::XCoreTargetObjectFile(bool isXS1A) { else ReadOnlySection = getOrCreateSection("\t.cp.rodata", false, SectionKind::ReadOnly); -} \ No newline at end of file +} diff --git a/lib/Transforms/IPO/ExtractGV.cpp b/lib/Transforms/IPO/ExtractGV.cpp index 57cd1ca1d63..2767f431943 100644 --- a/lib/Transforms/IPO/ExtractGV.cpp +++ b/lib/Transforms/IPO/ExtractGV.cpp @@ -110,7 +110,7 @@ namespace { AUGs.push_back(Context.getConstantExprBitCast(*GI, SBP)); } ArrayType *AT = Context.getArrayType(SBP, AUGs.size()); - Constant *Init = Context.getConstantArray(AT, AUGs); + Constant *Init = ConstantArray::get(AT, AUGs); GlobalValue *gv = new GlobalVariable(M, AT, false, GlobalValue::AppendingLinkage, Init, "llvm.used"); diff --git a/lib/Transforms/IPO/GlobalOpt.cpp b/lib/Transforms/IPO/GlobalOpt.cpp index 2989e2827fc..bf01812bd7c 100644 --- a/lib/Transforms/IPO/GlobalOpt.cpp +++ b/lib/Transforms/IPO/GlobalOpt.cpp @@ -1968,7 +1968,7 @@ static GlobalVariable *InstallGlobalCtors(GlobalVariable *GCL, // Create the array initializer. const Type *StructTy = cast(GCL->getType()->getElementType())->getElementType(); - Constant *CA = Context.getConstantArray(ArrayType::get(StructTy, + Constant *CA = ConstantArray::get(ArrayType::get(StructTy, CAList.size()), CAList); // If we didn't change the number of elements, don't create a new GV. @@ -2094,7 +2094,7 @@ static Constant *EvaluateStoreInto(Constant *Init, Constant *Val, assert(CI->getZExtValue() < ATy->getNumElements()); Elts[CI->getZExtValue()] = EvaluateStoreInto(Elts[CI->getZExtValue()], Val, Addr, OpNo+1, Context); - return Context.getConstantArray(ATy, Elts); + return ConstantArray::get(ATy, Elts); } } diff --git a/lib/Transforms/Scalar/SimplifyLibCalls.cpp b/lib/Transforms/Scalar/SimplifyLibCalls.cpp index 0bf583a52ab..506ba1fdb6d 100644 --- a/lib/Transforms/Scalar/SimplifyLibCalls.cpp +++ b/lib/Transforms/Scalar/SimplifyLibCalls.cpp @@ -1290,7 +1290,7 @@ struct VISIBILITY_HIDDEN PrintFOpt : public LibCallOptimization { // Create a string literal with no \n on it. We expect the constant merge // pass to be run after this pass, to merge duplicate strings. FormatStr.erase(FormatStr.end()-1); - Constant *C = Context->getConstantArray(FormatStr, true); + Constant *C = ConstantArray::get(FormatStr, true); C = new GlobalVariable(*Callee->getParent(), C->getType(), true, GlobalVariable::InternalLinkage, C, "str"); EmitPutS(C, B); diff --git a/lib/Transforms/Utils/LowerInvoke.cpp b/lib/Transforms/Utils/LowerInvoke.cpp index 6a56bbe973d..b75b2ef4f5a 100644 --- a/lib/Transforms/Utils/LowerInvoke.cpp +++ b/lib/Transforms/Utils/LowerInvoke.cpp @@ -183,7 +183,7 @@ void LowerInvoke::createAbortMessage(Module *M) { // The abort message for expensive EH support tells the user that the // program 'unwound' without an 'invoke' instruction. Constant *Msg = - Context.getConstantArray("ERROR: Exception thrown, but not caught!\n"); + ConstantArray::get("ERROR: Exception thrown, but not caught!\n"); AbortMessageLength = Msg->getNumOperands()-1; // don't include \0 GlobalVariable *MsgGV = new GlobalVariable(*M, Msg->getType(), true, @@ -195,7 +195,7 @@ void LowerInvoke::createAbortMessage(Module *M) { // The abort message for cheap EH support tells the user that EH is not // enabled. Constant *Msg = - Context.getConstantArray("Exception handler needed, but not enabled." + ConstantArray::get("Exception handler needed, but not enabled." "Recompile program with -enable-correct-eh-support.\n"); AbortMessageLength = Msg->getNumOperands()-1; // don't include \0 diff --git a/lib/Transforms/Utils/ValueMapper.cpp b/lib/Transforms/Utils/ValueMapper.cpp index 643805a2f91..673bb0b58e0 100644 --- a/lib/Transforms/Utils/ValueMapper.cpp +++ b/lib/Transforms/Utils/ValueMapper.cpp @@ -56,7 +56,7 @@ Value *llvm::MapValue(const Value *V, ValueMapTy &VM, LLVMContext &Context) { Values.push_back(cast(MV)); for (++i; i != e; ++i) Values.push_back(cast(MapValue(*i, VM, Context))); - return VM[V] = Context.getConstantArray(CA->getType(), Values); + return VM[V] = ConstantArray::get(CA->getType(), Values); } } return VM[V] = C; diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp index 61616f245ad..3c0d94e4e3a 100644 --- a/lib/VMCore/ConstantFold.cpp +++ b/lib/VMCore/ConstantFold.cpp @@ -521,7 +521,7 @@ Constant *llvm::ConstantFoldInsertValueInstruction(LLVMContext &Context, if (isa(AggTy)) return ConstantStruct::get(Ops); else - return Context.getConstantArray(cast(AggTy), Ops); + return ConstantArray::get(cast(AggTy), Ops); } if (isa(Agg)) { // Insertion of constant into aggregate zero @@ -550,7 +550,7 @@ Constant *llvm::ConstantFoldInsertValueInstruction(LLVMContext &Context, if (isa(AggTy)) return ConstantStruct::get(Ops); else - return Context.getConstantArray(cast(AggTy), Ops); + return ConstantArray::get(cast(AggTy), Ops); } if (isa(Agg) || isa(Agg)) { // Insertion of constant into aggregate constant @@ -567,7 +567,7 @@ Constant *llvm::ConstantFoldInsertValueInstruction(LLVMContext &Context, if (isa(Agg->getType())) C = ConstantStruct::get(Ops); else - C = Context.getConstantArray(cast(Agg->getType()), Ops); + C = ConstantArray::get(cast(Agg->getType()), Ops); return C; } diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp index ecb62568a2e..ec1bf13e5d2 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 &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(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 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 &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 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; +} + + void ConstantArray::replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) { - Constant *Replacement = - getType()->getContext().replaceUsesOfWithOnConstant(this, From, To, U); - - if (!Replacement) return; + assert(isa(To) && "Cannot make Constant refer to non-constant!"); + Constant *ToC = cast(To); + + LLVMContext &Context = getType()->getContext(); + LLVMContextImpl *pImpl = Context.pImpl; + + std::pair Lookup; + Lookup.first.first = getType(); + Lookup.second = this; + + std::vector &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(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(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 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 12f7c3223bc..a262f40c496 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(ConstantVals, Length), Length)); diff --git a/lib/VMCore/LLVMContext.cpp b/lib/VMCore/LLVMContext.cpp index 340ca9557a2..97857c5dda7 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& 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(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 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 858ed15d9b1..72e415cd66b 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 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(ConstantVector *CP) { std::vector 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 &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 &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(To) && "Cannot make Constant refer to non-constant!"); - Constant *ToC = cast(To); - - std::pair Lookup; - Lookup.first.first = CA->getType(); - Lookup.second = CA; - - std::vector &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(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; -} \ No newline at end of file diff --git a/lib/VMCore/LLVMContextImpl.h b/lib/VMCore/LLVMContextImpl.h index 21fef39683d..eea495d1dbe 100644 --- a/lib/VMCore/LLVMContextImpl.h +++ b/lib/VMCore/LLVMContextImpl.h @@ -88,7 +88,7 @@ struct ConvertConstantType { std::vector C; for (unsigned i = 0, e = OldC->getNumOperands(); i != e; ++i) C.push_back(cast(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 &V); - Constant *getConstantVector(const VectorType *Ty, const std::vector &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); }; } diff --git a/tools/bugpoint/ExtractFunction.cpp b/tools/bugpoint/ExtractFunction.cpp index 145942c8867..c2159dea4b0 100644 --- a/tools/bugpoint/ExtractFunction.cpp +++ b/tools/bugpoint/ExtractFunction.cpp @@ -189,7 +189,7 @@ static Constant *GetTorInit(std::vector > &TorList) { Elts.push_back(TorList[i].first); ArrayElts.push_back(ConstantStruct::get(Elts)); } - return Context.getConstantArray(Context.getArrayType(ArrayElts[0]->getType(), + return ConstantArray::get(Context.getArrayType(ArrayElts[0]->getType(), ArrayElts.size()), ArrayElts); } diff --git a/tools/bugpoint/Miscompilation.cpp b/tools/bugpoint/Miscompilation.cpp index d7be3c909e1..7c7d5a3e357 100644 --- a/tools/bugpoint/Miscompilation.cpp +++ b/tools/bugpoint/Miscompilation.cpp @@ -709,7 +709,7 @@ static void CleanupAndPrepareModules(BugDriver &BD, Module *&Test, // Don't forward functions which are external in the test module too. if (TestFn && !TestFn->isDeclaration()) { // 1. Add a string constant with its name to the global file - Constant *InitArray = Context.getConstantArray(F->getName()); + Constant *InitArray = ConstantArray::get(F->getName()); GlobalVariable *funcName = new GlobalVariable(*Safe, InitArray->getType(), true /*isConstant*/, GlobalValue::InternalLinkage, InitArray,