diff --git a/llvm/include/llvm/ADT/STLExtras.h b/llvm/include/llvm/ADT/STLExtras.h --- a/llvm/include/llvm/ADT/STLExtras.h +++ b/llvm/include/llvm/ADT/STLExtras.h @@ -1812,6 +1812,14 @@ C.insert(C.end(), R.begin(), R.end()); } +/// Wrapper function to insert a range in an associative container. +/// +/// C.insert(R.begin(), R.end()); +template +inline void insert_range(Container &C, Range &&R) { + C.insert(R.begin(), R.end()); +} + /// Given a sequence container Cont, replace the range [ContIt, ContEnd) with /// the range [ValIt, ValEnd) (which is not from the same container). template diff --git a/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp b/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp --- a/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp +++ b/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp @@ -34,6 +34,7 @@ #include "llvm/ADT/Optional.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/ScopeExit.h" +#include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Statistic.h" @@ -186,7 +187,7 @@ // Simple byval argument? Just add all the struct element types. Type *AgTy = I->getParamByValType(); StructType *STy = cast(AgTy); - llvm::append_range(Params, STy->elements()); + append_range(Params, STy->elements()); ArgAttrVec.insert(ArgAttrVec.end(), STy->getNumElements(), AttributeSet()); ++NumByValArgsPromoted; @@ -573,26 +574,21 @@ // Now look at all loads of the argument. Remember the load instructions // for the aliasing check below. - SmallVector Worklist; - SmallPtrSet Visited; + SmallSetVector Worklist; SmallVector Loads; - auto AppendUsers = [&](Value *V) { - for (User *U : V->users()) - if (Visited.insert(U).second) - Worklist.push_back(U); - }; - AppendUsers(Arg); + + insert_range(Worklist, Arg->users()); while (!Worklist.empty()) { Value *V = Worklist.pop_back_val(); if (isa(V)) { - AppendUsers(V); + insert_range(Worklist, V->users()); continue; } if (auto *GEP = dyn_cast(V)) { if (!GEP->hasAllConstantIndices()) return false; - AppendUsers(V); + insert_range(Worklist, V->users()); continue; } diff --git a/llvm/unittests/ADT/STLExtrasTest.cpp b/llvm/unittests/ADT/STLExtrasTest.cpp --- a/llvm/unittests/ADT/STLExtrasTest.cpp +++ b/llvm/unittests/ADT/STLExtrasTest.cpp @@ -11,6 +11,7 @@ #include #include +#include #include using namespace llvm; @@ -379,6 +380,16 @@ EXPECT_EQ(3, V[2]); } +TEST(STLExtrasTest, InsertRange) { + auto InsertVals = {3, 4, 5}; + std::unordered_set S = {1, 2, 6}; + insert_range(S, InsertVals); + EXPECT_EQ(S.size(), 6u); + for (int I = 1; I <= 6; I++) { + EXPECT_NE(S.find(I), S.end()); + } +} + namespace some_namespace { struct some_struct { std::vector data;