-
Notifications
You must be signed in to change notification settings - Fork 13.4k
[VPlan] Consistently use ArrayRef<VPValue *> for operands in ctors (NFC) #137798
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-vectorizers @llvm/pr-subscribers-llvm-adt Author: Florian Hahn (fhahn) ChangesNow that there is an ArrayRef constructor taking iterator_ranges, use it Depends on #137796. Full diff: https://github.com/llvm/llvm-project/pull/137798.diff 4 Files Affected:
diff --git a/llvm/include/llvm/ADT/ArrayRef.h b/llvm/include/llvm/ADT/ArrayRef.h
index a1317423cdd1a..f2fc7b636a8f5 100644
--- a/llvm/include/llvm/ADT/ArrayRef.h
+++ b/llvm/include/llvm/ADT/ArrayRef.h
@@ -149,6 +149,19 @@ namespace llvm {
* = nullptr)
: Data(Vec.data()), Length(Vec.size()) {}
+ /// Construct an ArrayRef<T> from iterator_range<U*>. This uses SFINAE
+ /// to ensure that this is only used for iterator ranges of random access
+ /// iterators that can be converted.
+ template <typename U>
+ ArrayRef(const iterator_range<U *> &Range,
+ std::enable_if_t<std::is_base_of<std::random_access_iterator_tag,
+ typename std::iterator_traits<
+ decltype(Range.begin())>::
+ iterator_category>::value &&
+ std::is_convertible<U *, T const *>::value,
+ void> * = nullptr)
+ : Data(Range.begin()), Length(llvm::size(Range)) {}
+
/// @}
/// @name Simple Operations
/// @{
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
index 4684378687ef6..8541968b98834 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -8749,7 +8749,7 @@ VPWidenRecipe *VPRecipeBuilder::tryToWiden(Instruction *I,
Plan.getOrAddLiveIn(ConstantInt::get(I->getType(), 1u, false));
auto *SafeRHS = Builder.createSelect(Mask, Ops[1], One, I->getDebugLoc());
Ops[1] = SafeRHS;
- return new VPWidenRecipe(*I, make_range(Ops.begin(), Ops.end()));
+ return new VPWidenRecipe(*I, Ops);
}
[[fallthrough]];
}
@@ -8795,7 +8795,7 @@ VPWidenRecipe *VPRecipeBuilder::tryToWiden(Instruction *I,
// For other binops, the legacy cost model only checks the second operand.
NewOps[1] = GetConstantViaSCEV(NewOps[1]);
}
- return new VPWidenRecipe(*I, make_range(NewOps.begin(), NewOps.end()));
+ return new VPWidenRecipe(*I, NewOps);
}
case Instruction::ExtractValue: {
SmallVector<VPValue *> NewOps(Operands);
@@ -8804,7 +8804,7 @@ VPWidenRecipe *VPRecipeBuilder::tryToWiden(Instruction *I,
assert(EVI->getNumIndices() == 1 && "Expected one extractvalue index");
unsigned Idx = EVI->getIndices()[0];
NewOps.push_back(Plan.getOrAddLiveIn(ConstantInt::get(I32Ty, Idx, false)));
- return new VPWidenRecipe(*I, make_range(NewOps.begin(), NewOps.end()));
+ return new VPWidenRecipe(*I, NewOps);
}
};
}
@@ -8828,9 +8828,7 @@ VPRecipeBuilder::tryToWidenHistogram(const HistogramInfo *HI,
if (Legal->isMaskRequired(HI->Store))
HGramOps.push_back(getBlockInMask(HI->Store->getParent()));
- return new VPHistogramRecipe(Opcode,
- make_range(HGramOps.begin(), HGramOps.end()),
- HI->Store->getDebugLoc());
+ return new VPHistogramRecipe(Opcode, HGramOps, HI->Store->getDebugLoc());
}
VPReplicateRecipe *
@@ -8891,8 +8889,7 @@ VPRecipeBuilder::handleReplication(Instruction *I, ArrayRef<VPValue *> Operands,
assert((Range.Start.isScalar() || !IsUniform || !IsPredicated ||
(Range.Start.isScalable() && isa<IntrinsicInst>(I))) &&
"Should not predicate a uniform recipe");
- auto *Recipe = new VPReplicateRecipe(
- I, make_range(Operands.begin(), Operands.end()), IsUniform, BlockInMask);
+ auto *Recipe = new VPReplicateRecipe(I, Operands, IsUniform, BlockInMask);
return Recipe;
}
@@ -9081,12 +9078,10 @@ VPRecipeBase *VPRecipeBuilder::tryToCreateWidenRecipe(
return nullptr;
if (auto *GEP = dyn_cast<GetElementPtrInst>(Instr))
- return new VPWidenGEPRecipe(GEP,
- make_range(Operands.begin(), Operands.end()));
+ return new VPWidenGEPRecipe(GEP, Operands);
if (auto *SI = dyn_cast<SelectInst>(Instr)) {
- return new VPWidenSelectRecipe(
- *SI, make_range(Operands.begin(), Operands.end()));
+ return new VPWidenSelectRecipe(*SI, Operands);
}
if (auto *CI = dyn_cast<CastInst>(Instr)) {
@@ -9117,7 +9112,7 @@ VPRecipeBuilder::tryToCreatePartialReduction(Instruction *Reduction,
SmallVector<VPValue *, 2> Ops;
Ops.push_back(Plan.getOrAddLiveIn(Zero));
Ops.push_back(BinOp);
- BinOp = new VPWidenRecipe(*Reduction, make_range(Ops.begin(), Ops.end()));
+ BinOp = new VPWidenRecipe(*Reduction, Ops);
Builder.insert(BinOp->getDefiningRecipe());
ReductionOpcode = Instruction::Add;
}
diff --git a/llvm/lib/Transforms/Vectorize/VPlan.h b/llvm/lib/Transforms/Vectorize/VPlan.h
index 067a723a3aa4d..446fb117ec2f8 100644
--- a/llvm/lib/Transforms/Vectorize/VPlan.h
+++ b/llvm/lib/Transforms/Vectorize/VPlan.h
@@ -386,10 +386,6 @@ class VPRecipeBase : public ilist_node_with_parent<VPRecipeBase, VPBasicBlock>,
DebugLoc DL = {})
: VPDef(SC), VPUser(Operands), DL(DL) {}
- template <typename IterT>
- VPRecipeBase(const unsigned char SC, iterator_range<IterT> Operands,
- DebugLoc DL = {})
- : VPDef(SC), VPUser(Operands), DL(DL) {}
virtual ~VPRecipeBase() = default;
/// Clone the current recipe.
@@ -504,17 +500,12 @@ class VPRecipeBase : public ilist_node_with_parent<VPRecipeBase, VPBasicBlock>,
/// Note that VPRecipeBase must be inherited from before VPValue.
class VPSingleDefRecipe : public VPRecipeBase, public VPValue {
public:
- template <typename IterT>
- VPSingleDefRecipe(const unsigned char SC, IterT Operands, DebugLoc DL = {})
- : VPRecipeBase(SC, Operands, DL), VPValue(this) {}
-
VPSingleDefRecipe(const unsigned char SC, ArrayRef<VPValue *> Operands,
DebugLoc DL = {})
: VPRecipeBase(SC, Operands, DL), VPValue(this) {}
- template <typename IterT>
- VPSingleDefRecipe(const unsigned char SC, IterT Operands, Value *UV,
- DebugLoc DL = {})
+ VPSingleDefRecipe(const unsigned char SC, ArrayRef<VPValue *> Operands,
+ Value *UV, DebugLoc DL = {})
: VPRecipeBase(SC, Operands, DL), VPValue(this, UV) {}
static inline bool classof(const VPRecipeBase *R) {
@@ -648,15 +639,15 @@ class VPRecipeWithIRFlags : public VPSingleDefRecipe {
}
public:
- template <typename IterT>
- VPRecipeWithIRFlags(const unsigned char SC, IterT Operands, DebugLoc DL = {})
+ VPRecipeWithIRFlags(const unsigned char SC, ArrayRef<VPValue *> Operands,
+ DebugLoc DL = {})
: VPSingleDefRecipe(SC, Operands, DL) {
OpType = OperationType::Other;
AllFlags = 0;
}
- template <typename IterT>
- VPRecipeWithIRFlags(const unsigned char SC, IterT Operands, Instruction &I)
+ VPRecipeWithIRFlags(const unsigned char SC, ArrayRef<VPValue *> Operands,
+ Instruction &I)
: VPSingleDefRecipe(SC, Operands, &I, I.getDebugLoc()) {
if (auto *Op = dyn_cast<CmpInst>(&I)) {
OpType = OperationType::Cmp;
@@ -685,33 +676,28 @@ class VPRecipeWithIRFlags : public VPSingleDefRecipe {
}
}
- template <typename IterT>
- VPRecipeWithIRFlags(const unsigned char SC, IterT Operands,
+ VPRecipeWithIRFlags(const unsigned char SC, ArrayRef<VPValue *> Operands,
CmpInst::Predicate Pred, DebugLoc DL = {})
: VPSingleDefRecipe(SC, Operands, DL), OpType(OperationType::Cmp),
CmpPredicate(Pred) {}
- template <typename IterT>
- VPRecipeWithIRFlags(const unsigned char SC, IterT Operands,
+ VPRecipeWithIRFlags(const unsigned char SC, ArrayRef<VPValue *> Operands,
WrapFlagsTy WrapFlags, DebugLoc DL = {})
: VPSingleDefRecipe(SC, Operands, DL),
OpType(OperationType::OverflowingBinOp), WrapFlags(WrapFlags) {}
- template <typename IterT>
- VPRecipeWithIRFlags(const unsigned char SC, IterT Operands,
+ VPRecipeWithIRFlags(const unsigned char SC, ArrayRef<VPValue *> Operands,
FastMathFlags FMFs, DebugLoc DL = {})
: VPSingleDefRecipe(SC, Operands, DL), OpType(OperationType::FPMathOp),
FMFs(FMFs) {}
- template <typename IterT>
- VPRecipeWithIRFlags(const unsigned char SC, IterT Operands,
+ VPRecipeWithIRFlags(const unsigned char SC, ArrayRef<VPValue *> Operands,
DisjointFlagsTy DisjointFlags, DebugLoc DL = {})
: VPSingleDefRecipe(SC, Operands, DL), OpType(OperationType::DisjointOp),
DisjointFlags(DisjointFlags) {}
protected:
- template <typename IterT>
- VPRecipeWithIRFlags(const unsigned char SC, IterT Operands,
+ VPRecipeWithIRFlags(const unsigned char SC, ArrayRef<VPValue *> Operands,
GEPNoWrapFlags GEPFlags, DebugLoc DL = {})
: VPSingleDefRecipe(SC, Operands, DL), OpType(OperationType::GEPOp),
GEPFlags(GEPFlags) {}
@@ -1225,15 +1211,13 @@ class VPWidenRecipe : public VPRecipeWithIRFlags, public VPIRMetadata {
unsigned Opcode;
protected:
- template <typename IterT>
VPWidenRecipe(unsigned VPDefOpcode, Instruction &I,
- iterator_range<IterT> Operands)
+ ArrayRef<VPValue *> Operands)
: VPRecipeWithIRFlags(VPDefOpcode, Operands, I), VPIRMetadata(I),
Opcode(I.getOpcode()) {}
public:
- template <typename IterT>
- VPWidenRecipe(Instruction &I, iterator_range<IterT> Operands)
+ VPWidenRecipe(Instruction &I, ArrayRef<VPValue *> Operands)
: VPWidenRecipe(VPDef::VPWidenSC, I, Operands) {}
~VPWidenRecipe() override = default;
@@ -1466,8 +1450,7 @@ class VPHistogramRecipe : public VPRecipeBase {
unsigned Opcode;
public:
- template <typename IterT>
- VPHistogramRecipe(unsigned Opcode, iterator_range<IterT> Operands,
+ VPHistogramRecipe(unsigned Opcode, ArrayRef<VPValue *> Operands,
DebugLoc DL = {})
: VPRecipeBase(VPDef::VPHistogramSC, Operands, DL), Opcode(Opcode) {}
@@ -1503,8 +1486,7 @@ class VPHistogramRecipe : public VPRecipeBase {
/// A recipe for widening select instructions.
struct VPWidenSelectRecipe : public VPRecipeWithIRFlags, public VPIRMetadata {
- template <typename IterT>
- VPWidenSelectRecipe(SelectInst &I, iterator_range<IterT> Operands)
+ VPWidenSelectRecipe(SelectInst &I, ArrayRef<VPValue *> Operands)
: VPRecipeWithIRFlags(VPDef::VPWidenSelectSC, Operands, I),
VPIRMetadata(I) {}
@@ -1563,8 +1545,7 @@ class VPWidenGEPRecipe : public VPRecipeWithIRFlags {
}
public:
- template <typename IterT>
- VPWidenGEPRecipe(GetElementPtrInst *GEP, iterator_range<IterT> Operands)
+ VPWidenGEPRecipe(GetElementPtrInst *GEP, ArrayRef<VPValue *> Operands)
: VPRecipeWithIRFlags(VPDef::VPWidenGEPSC, Operands, *GEP) {
SmallVector<std::pair<unsigned, MDNode *>> Metadata;
(void)Metadata;
@@ -2487,7 +2468,7 @@ class VPReplicateRecipe : public VPRecipeWithIRFlags {
public:
template <typename IterT>
- VPReplicateRecipe(Instruction *I, iterator_range<IterT> Operands,
+ VPReplicateRecipe(Instruction *I, ArrayRef<VPValue *> Operands,
bool IsUniform, VPValue *Mask = nullptr)
: VPRecipeWithIRFlags(VPDef::VPReplicateSC, Operands, *I),
IsUniform(IsUniform), IsPredicated(Mask) {
diff --git a/llvm/unittests/ADT/ArrayRefTest.cpp b/llvm/unittests/ADT/ArrayRefTest.cpp
index fb25ee19c0b20..128efbea813d2 100644
--- a/llvm/unittests/ADT/ArrayRefTest.cpp
+++ b/llvm/unittests/ADT/ArrayRefTest.cpp
@@ -255,6 +255,26 @@ TEST(ArrayRefTest, ArrayRefFromStdArray) {
}
}
+TEST(ArrayRefTest, ArrayRefFromIteratorRange) {
+ std::array<int, 5> A1{{42, -5, 0, 1000000, -1000000}};
+ ArrayRef<int> A2 = make_range(A1.begin(), A1.end());
+
+ EXPECT_EQ(A1.size(), A2.size());
+ for (std::size_t i = 0; i < A1.size(); ++i) {
+ EXPECT_EQ(A1[i], A2[i]);
+ }
+}
+
+TEST(ArrayRefTest, ArrayRefFromIteratorConstRange) {
+ std::array<const int, 5> A1{{42, -5, 0, 1000000, -1000000}};
+ ArrayRef<const int> A2 = make_range(A1.begin(), A1.end());
+
+ EXPECT_EQ(A1.size(), A2.size());
+ for (std::size_t i = 0; i < A1.size(); ++i) {
+ EXPECT_EQ(A1[i], A2[i]);
+ }
+}
+
static_assert(std::is_trivially_copyable_v<ArrayRef<int>>,
"trivially copyable");
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks!
Add a new constructor to ArrayRef that takes an iterator_range with a random access iterator that can be converted. This can help to avoid creating unnecessary iterator_ranges for types where an ArrayRef can already be constructed. I will share a follow-up soon.
Now that there is an ArrayRef constructor taking iterator_ranges, use it consistently to slightly simplify code. Depends on llvm#137796.
f0bda8c
to
e928962
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Add a new constructor to ArrayRef that takes an iterator_range with a random access iterator that can be converted. This can help to avoid creating unnecessary iterator_ranges for types where an ArrayRef can already be constructed. To be used in llvm#137798. PR: llvm#137796
…FC) (llvm#137798) Now that there is an ArrayRef constructor taking iterator_ranges, use it consistently to slightly simplify code. Depends on llvm#137796. PR: llvm#137798
Add a new constructor to ArrayRef that takes an iterator_range with a random access iterator that can be converted. This can help to avoid creating unnecessary iterator_ranges for types where an ArrayRef can already be constructed. To be used in llvm#137798. PR: llvm#137796
…FC) (llvm#137798) Now that there is an ArrayRef constructor taking iterator_ranges, use it consistently to slightly simplify code. Depends on llvm#137796. PR: llvm#137798
Add a new constructor to ArrayRef that takes an iterator_range with a random access iterator that can be converted. This can help to avoid creating unnecessary iterator_ranges for types where an ArrayRef can already be constructed. To be used in llvm#137798. PR: llvm#137796
…FC) (llvm#137798) Now that there is an ArrayRef constructor taking iterator_ranges, use it consistently to slightly simplify code. Depends on llvm#137796. PR: llvm#137798
…(#137796) Add a new constructor to ArrayRef that takes an iterator_range with a random access iterator that can be converted. This can help to avoid creating unnecessary iterator_ranges for types where an ArrayRef can already be constructed. To be used in llvm/llvm-project#137798. PR: llvm/llvm-project#137796
…in ctors (NFC) (#137798) Now that there is an ArrayRef constructor taking iterator_ranges, use it consistently to slightly simplify code. Depends on llvm/llvm-project#137796. PR: llvm/llvm-project#137798
Add a new constructor to ArrayRef that takes an iterator_range with a random access iterator that can be converted. This can help to avoid creating unnecessary iterator_ranges for types where an ArrayRef can already be constructed. To be used in llvm#137798. PR: llvm#137796
…FC) (llvm#137798) Now that there is an ArrayRef constructor taking iterator_ranges, use it consistently to slightly simplify code. Depends on llvm#137796. PR: llvm#137798
Now that there is an ArrayRef constructor taking iterator_ranges, use it
consistently to slightly simplify code.
Depends on #137796.