diff --git a/llvm/include/llvm/ADT/SmallVector.h b/llvm/include/llvm/ADT/SmallVector.h --- a/llvm/include/llvm/ADT/SmallVector.h +++ b/llvm/include/llvm/ADT/SmallVector.h @@ -1274,6 +1274,10 @@ typename std::remove_const()))>::type>::type; +template +using InlineSize = CalculateSmallVectorDefaultInlinedElements< + ValueTypeFromRangeType>; + /// Given a range of type R, iterate the entire range and return a /// SmallVector with elements of the vector. This is useful, for example, /// when you want to iterate a range and then sort the results. @@ -1281,14 +1285,23 @@ SmallVector, Size> to_vector(R &&Range) { return {std::begin(Range), std::end(Range)}; } + template -SmallVector, - CalculateSmallVectorDefaultInlinedElements< - ValueTypeFromRangeType>::value> +SmallVector, InlineSize::value> to_vector(R &&Range) { return {std::begin(Range), std::end(Range)}; } +template +SmallVector to_vector_of(R &&Range) { + return {std::begin(Range), std::end(Range)}; +} + +template +SmallVector::value> to_vector_of(R &&Range) { + return {std::begin(Range), std::end(Range)}; +} + } // end namespace llvm namespace std { diff --git a/llvm/include/llvm/IR/Metadata.h b/llvm/include/llvm/IR/Metadata.h --- a/llvm/include/llvm/IR/Metadata.h +++ b/llvm/include/llvm/IR/Metadata.h @@ -1345,9 +1345,8 @@ StorageType Storage, bool ShouldCreate = true); TempMDTuple cloneImpl() const { - ArrayRef Operands = operands(); - return getTemporary(getContext(), SmallVector( - Operands.begin(), Operands.end())); + return getTemporary(getContext(), + llvm::to_vector_of(operands())); } public: diff --git a/llvm/lib/Analysis/TypeBasedAliasAnalysis.cpp b/llvm/lib/Analysis/TypeBasedAliasAnalysis.cpp --- a/llvm/lib/Analysis/TypeBasedAliasAnalysis.cpp +++ b/llvm/lib/Analysis/TypeBasedAliasAnalysis.cpp @@ -811,8 +811,7 @@ return nullptr; // Otherwise, create TBAA with the new Len - ArrayRef MDOperands = MD->operands(); - SmallVector NextNodes(MDOperands.begin(), MDOperands.end()); + auto NextNodes = llvm::to_vector_of(MD->operands()); ConstantInt *PreviousSize = mdconst::extract(NextNodes[3]); // Don't create a new MDNode if it is the same length. diff --git a/llvm/lib/Linker/IRMover.cpp b/llvm/lib/Linker/IRMover.cpp --- a/llvm/lib/Linker/IRMover.cpp +++ b/llvm/lib/Linker/IRMover.cpp @@ -1362,10 +1362,9 @@ "Expected MDTuple when appending module flags"); if (DstValue->isDistinct()) return dyn_cast(DstValue); - ArrayRef DstOperands = DstValue->operands(); MDTuple *New = MDTuple::getDistinct( DstM.getContext(), - SmallVector(DstOperands.begin(), DstOperands.end())); + llvm::to_vector_of(DstValue->operands())); Metadata *FlagOps[] = {DstOp->getOperand(0), ID, New}; MDNode *Flag = MDTuple::getDistinct(DstM.getContext(), FlagOps); DstModFlags->setOperand(DstIndex, Flag); diff --git a/llvm/tools/llvm-rc/ResourceScriptStmt.h b/llvm/tools/llvm-rc/ResourceScriptStmt.h --- a/llvm/tools/llvm-rc/ResourceScriptStmt.h +++ b/llvm/tools/llvm-rc/ResourceScriptStmt.h @@ -817,7 +817,7 @@ VersionInfoFixed() : IsTypePresent(FtNumTypes, false) {} void setValue(VersionInfoFixedType Type, ArrayRef Value) { - FixedInfo[Type] = SmallVector(Value.begin(), Value.end()); + FixedInfo[Type] = llvm::to_vector_of(Value); IsTypePresent[Type] = true; } diff --git a/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp b/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp --- a/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp +++ b/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp @@ -125,7 +125,7 @@ return {}; ArrayRef BuildID(reinterpret_cast(Bytes.data()), Bytes.size()); - return SmallVector(BuildID.begin(), BuildID.end()); + return llvm::to_vector_of(BuildID); } static bool parseCommand(StringRef BinaryName, bool IsAddr2Line, diff --git a/llvm/unittests/ADT/SmallVectorTest.cpp b/llvm/unittests/ADT/SmallVectorTest.cpp --- a/llvm/unittests/ADT/SmallVectorTest.cpp +++ b/llvm/unittests/ADT/SmallVectorTest.cpp @@ -1134,6 +1134,87 @@ EXPECT_TRUE(makeArrayRef(V2).equals({4, 5, 3, 2})); } +TEST(SmallVectorTest, ToVector) { + { + std::vector v = {'a', 'b', 'c'}; + auto Vector = to_vector<4>(v); + ASSERT_EQ(4u, this->NumBuiltinElts(Vector)); + ASSERT_EQ(3u, Vector.size()); + for (size_t I = 0; I < v.size(); ++I) { + EXPECT_EQ(v[I], Vector[I]); + } + } + { + std::vector v = {'a', 'b', 'c'}; + auto Vector = to_vector(v); + ASSERT_NE(4u, this->NumBuiltinElts(Vector)); + ASSERT_EQ(3u, Vector.size()); + for (size_t I = 0; I < v.size(); ++I) { + EXPECT_EQ(v[I], Vector[I]); + } + } +} + +TEST(SmallVectorTest, ToVectorOf) { + struct Metadata { + int content; + }; + + class MDOperand { + public: + MDOperand(int content) : metadata{content} {} + operator Metadata *() { return get(); } + + private: + Metadata *get() { return &metadata; } + Metadata metadata; + }; + + std::vector Operands = {MDOperand(1), MDOperand(2), MDOperand(3)}; + { + llvm::SmallVector Metadatas = + llvm::to_vector_of(Operands); + + ASSERT_EQ(Operands.size(), Metadatas.size()); + for (size_t I = 0; I < Operands.size(); ++I) { + EXPECT_EQ(Operands[I]->get(), Metadatas[I]); + EXPECT_EQ(Operands[I], *Metadatas[I]); + } + } + { + ArrayRef ArrayOperands = Operands; + llvm::SmallVector Metadatas = + llvm::to_vector_of(ArrayOperands); + + ASSERT_EQ(ArrayOperands.size(), Metadatas.size()); + for (size_t I = 0; I < ArrayOperands.size(); ++I) { + EXPECT_EQ(ArrayOperands[I]->get(), Metadatas[I]); + EXPECT_EQ(ArrayOperands[I], *Metadatas[I]); + } + } + { + auto Metadatas = llvm::to_vector_of(Operands); + + ASSERT_EQ(Operands.size(), Metadatas.size()); + ASSERT_EQ(4u, this->NumBuiltinElts(Metadatas)); + for (size_t I = 0; I < Operands.size(); ++I) { + EXPECT_EQ(Operands[I]->get(), Metadatas[I]); + EXPECT_EQ(Operands[I], *Metadatas[I]); + } + } + { + ArrayRef ArrayOperands = Operands; + auto Metadatas = llvm::to_vector_of(ArrayOperands); + + ASSERT_EQ(ArrayOperands.size(), Metadatas.size()); + ASSERT_EQ(4u, this->NumBuiltinElts(Metadatas)); + for (size_t I = 0; I < ArrayOperands.size(); ++I) { + EXPECT_EQ(ArrayOperands[I]->get(), Metadatas[I]); + EXPECT_EQ(ArrayOperands[I], *Metadatas[I]); + } + } +} + template class SmallVectorReferenceInvalidationTest : public SmallVectorTestBase { protected: diff --git a/llvm/unittests/Analysis/VectorUtilsTest.cpp b/llvm/unittests/Analysis/VectorUtilsTest.cpp --- a/llvm/unittests/Analysis/VectorUtilsTest.cpp +++ b/llvm/unittests/Analysis/VectorUtilsTest.cpp @@ -507,8 +507,7 @@ } bool validParams(ArrayRef Parameters) { - Shape.Parameters = - SmallVector(Parameters.begin(), Parameters.end()); + Shape.Parameters = llvm::to_vector_of(Parameters); return Shape.hasValidParameterList(); } };