Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[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

Merged
merged 7 commits into from
May 1, 2025

Conversation

fhahn
Copy link
Contributor

@fhahn fhahn commented Apr 29, 2025

Now that there is an ArrayRef constructor taking iterator_ranges, use it
consistently to slightly simplify code.

Depends on #137796.

@llvmbot
Copy link
Member

llvmbot commented Apr 29, 2025

@llvm/pr-subscribers-vectorizers
@llvm/pr-subscribers-llvm-transforms

@llvm/pr-subscribers-llvm-adt

Author: Florian Hahn (fhahn)

Changes

Now that there is an ArrayRef constructor taking iterator_ranges, use it
consistently to slightly simplify code.

Depends on #137796.


Full diff: https://github.com/llvm/llvm-project/pull/137798.diff

4 Files Affected:

  • (modified) llvm/include/llvm/ADT/ArrayRef.h (+13)
  • (modified) llvm/lib/Transforms/Vectorize/LoopVectorize.cpp (+8-13)
  • (modified) llvm/lib/Transforms/Vectorize/VPlan.h (+17-36)
  • (modified) llvm/unittests/ADT/ArrayRefTest.cpp (+20)
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");
 

Copy link
Contributor

@artagnon artagnon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks!

fhahn added 5 commits April 29, 2025 18:32
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.
@fhahn fhahn force-pushed the vplan-constructors-arrayref branch from f0bda8c to e928962 Compare April 29, 2025 18:26
fhahn added a commit that referenced this pull request Apr 30, 2025
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
#137798.


PR: #137796
Copy link
Contributor

@lukel97 lukel97 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@fhahn fhahn merged commit 8d02529 into llvm:main May 1, 2025
9 of 11 checks passed
@fhahn fhahn deleted the vplan-constructors-arrayref branch May 1, 2025 20:19
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
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
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
…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
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
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
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
…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
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
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
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
…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
llvm-sync bot pushed a commit to arm/arm-toolchain that referenced this pull request May 6, 2025
…(#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
llvm-sync bot pushed a commit to arm/arm-toolchain that referenced this pull request May 6, 2025
…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
GeorgeARM pushed a commit to GeorgeARM/llvm-project that referenced this pull request May 7, 2025
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
GeorgeARM pushed a commit to GeorgeARM/llvm-project that referenced this pull request May 7, 2025
…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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants