From b065b06c12dba6001b8140df2744d0c856ef6ea1 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 20 Jun 2011 04:01:31 +0000 Subject: [PATCH] Revamp the "ConstantStruct::get" methods. Previously, these were scattered all over the place in different styles and variants. Standardize on two preferred entrypoints: one that takes a StructType and ArrayRef, and one that takes StructType and varargs. In cases where there isn't a struct type convenient, we now add a ConstantStruct::getAnon method (whose name will make more sense after a few more patches land). It would be "really really nice" if the ConstantStruct::get and ConstantVector::get methods didn't make temporary std::vectors. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@133412 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Constants.h | 31 ++++++-- lib/Analysis/ConstantFolding.cpp | 2 +- lib/AsmParser/LLParser.cpp | 8 +- lib/Bitcode/Reader/BitcodeReader.cpp | 6 +- lib/CodeGen/ShadowStackGC.cpp | 16 ++-- lib/Transforms/IPO/GlobalOpt.cpp | 78 +++++++++---------- .../InstCombine/InstCombineCalls.cpp | 17 ++-- .../Instrumentation/ProfilingUtils.cpp | 3 +- lib/VMCore/ConstantFold.cpp | 6 +- lib/VMCore/Constants.cpp | 66 ++++++++-------- lib/VMCore/Core.cpp | 7 +- tools/bugpoint/ExtractFunction.cpp | 15 ++-- unittests/VMCore/DerivedTypesTest.cpp | 2 +- 13 files changed, 144 insertions(+), 113 deletions(-) diff --git a/include/llvm/Constants.h b/include/llvm/Constants.h index eabc3a50aa0..268f920ad79 100644 --- a/include/llvm/Constants.h +++ b/include/llvm/Constants.h @@ -422,14 +422,29 @@ protected: ConstantStruct(const StructType *T, const std::vector &Val); public: // ConstantStruct accessors - static Constant *get(const StructType *T, const std::vector &V); - static Constant *get(LLVMContext &Context, - const std::vector &V, bool Packed); - static Constant *get(LLVMContext &Context, - Constant *const *Vals, unsigned NumVals, bool Packed); - static Constant *get(LLVMContext &Context, bool Packed, - Constant * Val, ...) END_WITH_NULL; - + static Constant *get(const StructType *T, ArrayRef V); + static Constant *get(const StructType *T, ...) END_WITH_NULL; + + /// getAnon - Return an anonymous struct that has the specified + /// elements. If the struct is possibly empty, then you must specify a + /// context. + static Constant *getAnon(ArrayRef V, bool Packed = false) { + return get(getTypeForElements(V, Packed), V); + } + static Constant *getAnon(LLVMContext &Ctx, + ArrayRef V, bool Packed = false) { + return get(getTypeForElements(Ctx, V, Packed), V); + } + + /// getTypeForElements - Return an anonymous struct type to use for a constant + /// with the specified set of elements. The list must not be empty. + static StructType *getTypeForElements(ArrayRef V, + bool Packed = false); + /// getTypeForElements - This version of the method allows an empty list. + static StructType *getTypeForElements(LLVMContext &Ctx, + ArrayRef V, + bool Packed = false); + /// Transparently provide more efficient getOperand methods. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant); diff --git a/lib/Analysis/ConstantFolding.cpp b/lib/Analysis/ConstantFolding.cpp index 08a6065b31a..b5fafd685cd 100644 --- a/lib/Analysis/ConstantFolding.cpp +++ b/lib/Analysis/ConstantFolding.cpp @@ -1399,7 +1399,7 @@ llvm::ConstantFoldCall(Function *F, ConstantInt::get(F->getContext(), Res), ConstantInt::get(Type::getInt1Ty(F->getContext()), Overflow) }; - return ConstantStruct::get(F->getContext(), Ops, 2, false); + return ConstantStruct::get(cast(F->getReturnType()), Ops); } } } diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index 7b7e785547e..170ec44391f 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -1987,8 +1987,8 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { ParseToken(lltok::rbrace, "expected end of struct constant")) return true; - ID.ConstantVal = ConstantStruct::get(Context, Elts.data(), - Elts.size(), false); + // FIXME: Get this type from context instead of reconstructing it! + ID.ConstantVal = ConstantStruct::getAnon(Context, Elts); ID.Kind = ValID::t_Constant; return false; } @@ -2007,8 +2007,8 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { return true; if (isPackedStruct) { - ID.ConstantVal = - ConstantStruct::get(Context, Elts.data(), Elts.size(), true); + // FIXME: Get this type from context instead of reconstructing it! + ID.ConstantVal = ConstantStruct::getAnon(Context, Elts, true); ID.Kind = ValID::t_Constant; return false; } diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index 88c157532a5..ff67bc92fe1 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -292,11 +292,9 @@ void BitcodeReaderValueList::ResolveConstantForwardRefs() { // Make the new constant. Constant *NewC; if (ConstantArray *UserCA = dyn_cast(UserC)) { - NewC = ConstantArray::get(UserCA->getType(), &NewOps[0], - NewOps.size()); + NewC = ConstantArray::get(UserCA->getType(), &NewOps[0], NewOps.size()); } else if (ConstantStruct *UserCS = dyn_cast(UserC)) { - NewC = ConstantStruct::get(Context, &NewOps[0], NewOps.size(), - UserCS->getType()->isPacked()); + NewC = ConstantStruct::get(UserCS->getType(), NewOps); } else if (isa(UserC)) { NewC = ConstantVector::get(NewOps); } else { diff --git a/lib/CodeGen/ShadowStackGC.cpp b/lib/CodeGen/ShadowStackGC.cpp index 6ab0cb03c06..94dc3ed4755 100644 --- a/lib/CodeGen/ShadowStackGC.cpp +++ b/lib/CodeGen/ShadowStackGC.cpp @@ -194,7 +194,7 @@ Constant *ShadowStackGC::GetFrameMap(Function &F) { // Truncate the ShadowStackDescriptor if some metadata is null. unsigned NumMeta = 0; - SmallVector Metadata; + SmallVector Metadata; for (unsigned I = 0; I != Roots.size(); ++I) { Constant *C = cast(Roots[I].first->getArgOperand(1)); if (!C->isNullValue()) @@ -202,19 +202,23 @@ Constant *ShadowStackGC::GetFrameMap(Function &F) { Metadata.push_back(ConstantExpr::getBitCast(C, VoidPtr)); } + const Type *Int32Ty = Type::getInt32Ty(F.getContext()); + Constant *BaseElts[] = { - ConstantInt::get(Type::getInt32Ty(F.getContext()), Roots.size(), false), - ConstantInt::get(Type::getInt32Ty(F.getContext()), NumMeta, false), + ConstantInt::get(Int32Ty, Roots.size(), false), + ConstantInt::get(Int32Ty, NumMeta, false), }; Constant *DescriptorElts[] = { - ConstantStruct::get(F.getContext(), BaseElts, 2, false), + ConstantStruct::get(StructType::get(Int32Ty, Int32Ty, NULL), BaseElts), ConstantArray::get(ArrayType::get(VoidPtr, NumMeta), Metadata.begin(), NumMeta) }; - Constant *FrameMap = ConstantStruct::get(F.getContext(), DescriptorElts, 2, - false); + Constant *FrameMap = + ConstantStruct::get(StructType::get(DescriptorElts[0]->getType(), + DescriptorElts[1]->getType(), NULL), + DescriptorElts); std::string TypeName("gc_map."); TypeName += utostr(NumMeta); diff --git a/lib/Transforms/IPO/GlobalOpt.cpp b/lib/Transforms/IPO/GlobalOpt.cpp index cdf7b76dd08..4ac721dd060 100644 --- a/lib/Transforms/IPO/GlobalOpt.cpp +++ b/lib/Transforms/IPO/GlobalOpt.cpp @@ -1999,9 +1999,13 @@ static std::vector ParseGlobalCtors(GlobalVariable *GV) { static GlobalVariable *InstallGlobalCtors(GlobalVariable *GCL, const std::vector &Ctors) { // If we made a change, reassemble the initializer list. - std::vector CSVals; - CSVals.push_back(ConstantInt::get(Type::getInt32Ty(GCL->getContext()),65535)); - CSVals.push_back(0); + Constant *CSVals[2]; + CSVals[0] = ConstantInt::get(Type::getInt32Ty(GCL->getContext()), 65535); + CSVals[1] = 0; + + const StructType *StructTy = + cast ( + cast(GCL->getType()->getElementType())->getElementType()); // Create the new init list. std::vector CAList; @@ -2016,12 +2020,10 @@ static GlobalVariable *InstallGlobalCtors(GlobalVariable *GCL, CSVals[0] = ConstantInt::get(Type::getInt32Ty(GCL->getContext()), 0x7fffffff); } - CAList.push_back(ConstantStruct::get(GCL->getContext(), CSVals, false)); + CAList.push_back(ConstantStruct::get(StructTy, CSVals)); } // Create the array initializer. - const Type *StructTy = - cast(GCL->getType()->getElementType())->getElementType(); Constant *CA = ConstantArray::get(ArrayType::get(StructTy, CAList.size()), CAList); @@ -2218,42 +2220,40 @@ static Constant *EvaluateStoreInto(Constant *Init, Constant *Val, Elts[Idx] = EvaluateStoreInto(Elts[Idx], Val, Addr, OpNo+1); // Return the modified struct. - return ConstantStruct::get(Init->getContext(), &Elts[0], Elts.size(), - STy->isPacked()); - } else { - ConstantInt *CI = cast(Addr->getOperand(OpNo)); - const SequentialType *InitTy = cast(Init->getType()); - - uint64_t NumElts; - if (const ArrayType *ATy = dyn_cast(InitTy)) - NumElts = ATy->getNumElements(); - else - NumElts = cast(InitTy)->getNumElements(); - + return ConstantStruct::get(STy, Elts); + } + + ConstantInt *CI = cast(Addr->getOperand(OpNo)); + const SequentialType *InitTy = cast(Init->getType()); - // Break up the array into elements. - if (ConstantArray *CA = dyn_cast(Init)) { - for (User::op_iterator i = CA->op_begin(), e = CA->op_end(); i != e; ++i) - Elts.push_back(cast(*i)); - } else if (ConstantVector *CV = dyn_cast(Init)) { - for (User::op_iterator i = CV->op_begin(), e = CV->op_end(); i != e; ++i) - Elts.push_back(cast(*i)); - } else if (isa(Init)) { - Elts.assign(NumElts, Constant::getNullValue(InitTy->getElementType())); - } else { - assert(isa(Init) && "This code is out of sync with " - " ConstantFoldLoadThroughGEPConstantExpr"); - Elts.assign(NumElts, UndefValue::get(InitTy->getElementType())); - } + uint64_t NumElts; + if (const ArrayType *ATy = dyn_cast(InitTy)) + NumElts = ATy->getNumElements(); + else + NumElts = cast(InitTy)->getNumElements(); + + // Break up the array into elements. + if (ConstantArray *CA = dyn_cast(Init)) { + for (User::op_iterator i = CA->op_begin(), e = CA->op_end(); i != e; ++i) + Elts.push_back(cast(*i)); + } else if (ConstantVector *CV = dyn_cast(Init)) { + for (User::op_iterator i = CV->op_begin(), e = CV->op_end(); i != e; ++i) + Elts.push_back(cast(*i)); + } else if (isa(Init)) { + Elts.assign(NumElts, Constant::getNullValue(InitTy->getElementType())); + } else { + assert(isa(Init) && "This code is out of sync with " + " ConstantFoldLoadThroughGEPConstantExpr"); + Elts.assign(NumElts, UndefValue::get(InitTy->getElementType())); + } - assert(CI->getZExtValue() < NumElts); - Elts[CI->getZExtValue()] = - EvaluateStoreInto(Elts[CI->getZExtValue()], Val, Addr, OpNo+1); + assert(CI->getZExtValue() < NumElts); + Elts[CI->getZExtValue()] = + EvaluateStoreInto(Elts[CI->getZExtValue()], Val, Addr, OpNo+1); - if (Init->getType()->isArrayTy()) - return ConstantArray::get(cast(InitTy), Elts); - return ConstantVector::get(Elts); - } + if (Init->getType()->isArrayTy()) + return ConstantArray::get(cast(InitTy), Elts); + return ConstantVector::get(Elts); } /// CommitValueTo - We have decided that Addr (which satisfies the predicate diff --git a/lib/Transforms/InstCombine/InstCombineCalls.cpp b/lib/Transforms/InstCombine/InstCombineCalls.cpp index ef67701921f..455cd0a69d5 100644 --- a/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -412,7 +412,8 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) { UndefValue::get(LHS->getType()), ConstantInt::getTrue(II->getContext()) }; - Constant *Struct = ConstantStruct::get(II->getContext(), V, 2, false); + const StructType *ST = cast(II->getType()); + Constant *Struct = ConstantStruct::get(ST, V); return InsertValueInst::Create(Struct, Add, 0); } @@ -425,7 +426,8 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) { UndefValue::get(LHS->getType()), ConstantInt::getFalse(II->getContext()) }; - Constant *Struct = ConstantStruct::get(II->getContext(), V, 2, false); + const StructType *ST = cast(II->getType()); + Constant *Struct = ConstantStruct::get(ST, V); return InsertValueInst::Create(Struct, Add, 0); } } @@ -452,7 +454,8 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) { UndefValue::get(II->getArgOperand(0)->getType()), ConstantInt::getFalse(II->getContext()) }; - Constant *Struct = ConstantStruct::get(II->getContext(), V, 2, false); + Constant *Struct = + ConstantStruct::get(cast(II->getType()), V); return InsertValueInst::Create(Struct, II->getArgOperand(0), 0); } } @@ -472,7 +475,8 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) { UndefValue::get(II->getArgOperand(0)->getType()), ConstantInt::getFalse(II->getContext()) }; - Constant *Struct = ConstantStruct::get(II->getContext(), V, 2, false); + Constant *Struct = + ConstantStruct::get(cast(II->getType()), V); return InsertValueInst::Create(Struct, II->getArgOperand(0), 0); } } @@ -503,7 +507,7 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) { UndefValue::get(LHS->getType()), Builder->getFalse() }; - Constant *Struct = ConstantStruct::get(II->getContext(), V, 2, false); + Constant *Struct = ConstantStruct::get(cast(II->getType()),V); return InsertValueInst::Create(Struct, Mul, 0); } } // FALL THROUGH @@ -532,7 +536,8 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) { UndefValue::get(II->getArgOperand(0)->getType()), ConstantInt::getFalse(II->getContext()) }; - Constant *Struct = ConstantStruct::get(II->getContext(), V, 2, false); + Constant *Struct = + ConstantStruct::get(cast(II->getType()), V); return InsertValueInst::Create(Struct, II->getArgOperand(0), 0); } } diff --git a/lib/Transforms/Instrumentation/ProfilingUtils.cpp b/lib/Transforms/Instrumentation/ProfilingUtils.cpp index 7435bc37fbe..4224ee303f0 100644 --- a/lib/Transforms/Instrumentation/ProfilingUtils.cpp +++ b/lib/Transforms/Instrumentation/ProfilingUtils.cpp @@ -164,7 +164,8 @@ void llvm::InsertProfilingShutdownCall(Function *Callee, Module *Mod) { GlobalVariable *GlobalDtors = new GlobalVariable( *Mod, ArrayType::get(GlobalDtorElemTy, 1), false, GlobalValue::AppendingLinkage, NULL, "llvm.global_dtors"); - dtors.push_back(ConstantStruct::get(Mod->getContext(), Elem, 2, false)); + + dtors.push_back(ConstantStruct::get(GlobalDtorElemTy, Elem)); GlobalDtors->setInitializer(ConstantArray::get( cast(GlobalDtors->getType()->getElementType()), dtors)); } diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp index 9985adaf576..e5ab15dbe16 100644 --- a/lib/VMCore/ConstantFold.cpp +++ b/lib/VMCore/ConstantFold.cpp @@ -942,7 +942,7 @@ Constant *llvm::ConstantFoldInsertValueInstruction(Constant *Agg, } if (const StructType* ST = dyn_cast(AggTy)) - return ConstantStruct::get(ST->getContext(), Ops, ST->isPacked()); + return ConstantStruct::get(ST, Ops); return ConstantArray::get(cast(AggTy), Ops); } @@ -973,7 +973,7 @@ Constant *llvm::ConstantFoldInsertValueInstruction(Constant *Agg, } if (const StructType *ST = dyn_cast(AggTy)) - return ConstantStruct::get(ST->getContext(), Ops, ST->isPacked()); + return ConstantStruct::get(ST, Ops); return ConstantArray::get(cast(AggTy), Ops); } @@ -988,7 +988,7 @@ Constant *llvm::ConstantFoldInsertValueInstruction(Constant *Agg, } if (const StructType* ST = dyn_cast(Agg->getType())) - return ConstantStruct::get(ST->getContext(), Ops, ST->isPacked()); + return ConstantStruct::get(ST, Ops); return ConstantArray::get(cast(Agg->getType()), Ops); } diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp index 0cf6c4ed82d..22d43a7d581 100644 --- a/lib/VMCore/Constants.cpp +++ b/lib/VMCore/Constants.cpp @@ -621,6 +621,27 @@ Constant *ConstantArray::get(LLVMContext &Context, StringRef Str, return get(ATy, ElementVals); } +/// getTypeForElements - Return an anonymous struct type to use for a constant +/// with the specified set of elements. The list must not be empty. +StructType *ConstantStruct::getTypeForElements(LLVMContext &Context, + ArrayRef V, + bool Packed) { + SmallVector EltTypes; + for (unsigned i = 0, e = V.size(); i != e; ++i) + EltTypes.push_back(V[i]->getType()); + + return StructType::get(Context, EltTypes, Packed); +} + + +StructType *ConstantStruct::getTypeForElements(ArrayRef V, + bool Packed) { + assert(!V.empty() && + "ConstantStruct::getTypeForElements cannot be called on empty list"); + return getTypeForElements(V[0]->getContext(), V, Packed); +} + + ConstantStruct::ConstantStruct(const StructType *T, const std::vector &V) : Constant(T, ConstantStructVal, @@ -639,45 +660,28 @@ ConstantStruct::ConstantStruct(const StructType *T, } // ConstantStruct accessors. -Constant *ConstantStruct::get(const StructType* T, - const std::vector& V) { - LLVMContextImpl* pImpl = T->getContext().pImpl; +Constant *ConstantStruct::get(const StructType *ST, ArrayRef V) { + assert(ST->getNumElements() == V.size() && + "Incorrect # elements specified to ConstantStruct::get"); - // Create a ConstantAggregateZero value if all elements are zeros... + // Create a ConstantAggregateZero value if all elements are zeros. for (unsigned i = 0, e = V.size(); i != e; ++i) - if (!V[i]->isNullValue()) - return pImpl->StructConstants.getOrCreate(T, V); - - return ConstantAggregateZero::get(T); -} - -Constant *ConstantStruct::get(LLVMContext &Context, - const std::vector& V, bool packed) { - std::vector StructEls; - StructEls.reserve(V.size()); - for (unsigned i = 0, e = V.size(); i != e; ++i) - StructEls.push_back(V[i]->getType()); - return get(StructType::get(Context, StructEls, packed), V); -} + if (!V[i]->isNullValue()) { + // FIXME: Eliminate temporary std::vector here! + return ST->getContext().pImpl->StructConstants.getOrCreate(ST, V.vec()); + } -Constant *ConstantStruct::get(LLVMContext &Context, - Constant *const *Vals, unsigned NumVals, - bool Packed) { - // FIXME: make this the primary ctor method. - return get(Context, std::vector(Vals, Vals+NumVals), Packed); + return ConstantAggregateZero::get(ST); } -Constant* ConstantStruct::get(LLVMContext &Context, bool Packed, - Constant * Val, ...) { +Constant* ConstantStruct::get(const StructType *T, ...) { va_list ap; - std::vector Values; - va_start(ap, Val); - while (Val) { + SmallVector Values; + va_start(ap, T); + while (Constant *Val = va_arg(ap, llvm::Constant*)) Values.push_back(Val); - Val = va_arg(ap, llvm::Constant*); - } va_end(ap); - return get(Context, Values, Packed); + return get(T, Values); } ConstantVector::ConstantVector(const VectorType *T, diff --git a/lib/VMCore/Core.cpp b/lib/VMCore/Core.cpp index 92f944027a7..16ccc7b8938 100644 --- a/lib/VMCore/Core.cpp +++ b/lib/VMCore/Core.cpp @@ -612,9 +612,10 @@ LLVMValueRef LLVMConstStringInContext(LLVMContextRef C, const char *Str, LLVMValueRef LLVMConstStructInContext(LLVMContextRef C, LLVMValueRef *ConstantVals, unsigned Count, LLVMBool Packed) { - return wrap(ConstantStruct::get(*unwrap(C), - unwrap(ConstantVals, Count), - Count, Packed != 0)); + Constant **Elements = unwrap(ConstantVals, Count); + return wrap(ConstantStruct::getAnon(*unwrap(C), + ArrayRef(Elements, Count), + Packed != 0)); } LLVMValueRef LLVMConstString(const char *Str, unsigned Length, diff --git a/tools/bugpoint/ExtractFunction.cpp b/tools/bugpoint/ExtractFunction.cpp index 593765cb70f..e22841aca48 100644 --- a/tools/bugpoint/ExtractFunction.cpp +++ b/tools/bugpoint/ExtractFunction.cpp @@ -175,13 +175,16 @@ void llvm::DeleteFunctionBody(Function *F) { static Constant *GetTorInit(std::vector > &TorList) { assert(!TorList.empty() && "Don't create empty tor list!"); std::vector ArrayElts; + const Type *Int32Ty = Type::getInt32Ty(TorList[0].first->getContext()); + + const StructType *STy = + StructType::get(Int32Ty, TorList[0].first->getType(), NULL); for (unsigned i = 0, e = TorList.size(); i != e; ++i) { - std::vector Elts; - Elts.push_back(ConstantInt::get( - Type::getInt32Ty(TorList[i].first->getContext()), TorList[i].second)); - Elts.push_back(TorList[i].first); - ArrayElts.push_back(ConstantStruct::get(TorList[i].first->getContext(), - Elts, false)); + Constant *Elts[] = { + ConstantInt::get(Int32Ty, TorList[i].second), + TorList[i].first + }; + ArrayElts.push_back(ConstantStruct::get(STy, Elts)); } return ConstantArray::get(ArrayType::get(ArrayElts[0]->getType(), ArrayElts.size()), diff --git a/unittests/VMCore/DerivedTypesTest.cpp b/unittests/VMCore/DerivedTypesTest.cpp index 956215726cd..d0ba0264aac 100644 --- a/unittests/VMCore/DerivedTypesTest.cpp +++ b/unittests/VMCore/DerivedTypesTest.cpp @@ -60,7 +60,7 @@ static void PR7658() { v2.push_back(ConstantPointerNull::get(p4)); } - WeakVH CS = ConstantStruct::get(ctx, v2, false); // { i32 14, opaque* null, opaque* null} + WeakVH CS = ConstantStruct::getAnon(ctx, v2, false); // { i32 14, opaque* null, opaque* null} StructType *s2 = StructType::get(ctx, t2); PATypeHolder h2(s2); -- 2.34.1