[llvm] 9fdb3bb - [SandboxVec][VecUtils][NFC] BndlRef helper class (#223074)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Sep 14 11:07:28 PDT 2026
Author: vporpo
Date: 2026-09-14T11:07:22-07:00
New Revision: 9fdb3bbd29ea03834f325373efe5ee0ea9fe4061
URL: https://github.com/llvm/llvm-project/commit/9fdb3bbd29ea03834f325373efe5ee0ea9fe4061
DIFF: https://github.com/llvm/llvm-project/commit/9fdb3bbd29ea03834f325373efe5ee0ea9fe4061.diff
LOG: [SandboxVec][VecUtils][NFC] BndlRef helper class (#223074)
During debugging we need to be able to easily print a bundle of
instructions or values. Up until now we would use VecUtils::dump(Bndl).
But a much nicer API would be Bndl.dump().
To support such an API this patch is introducing BndlRef, a subclass of
ArrayRef with the additional feature of supporting print(OS) and dump()
for Value and Instruction contents.
Added:
Modified:
llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/InstrMaps.h
llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/BundleVec.h
llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/VecUtils.h
llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/BundleVec.cpp
llvm/lib/Transforms/Vectorize/SandboxVectorizer/VecUtils.cpp
llvm/unittests/Transforms/Vectorize/SandboxVectorizer/VecUtilsTest.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/InstrMaps.h b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/InstrMaps.h
index 45b6d1405a8b3..32d63fc0452a4 100644
--- a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/InstrMaps.h
+++ b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/InstrMaps.h
@@ -32,7 +32,7 @@ struct Action {
unsigned Depth;
SmallVector<Action *> Operands;
Value *Vec = nullptr;
- Action(const LegalityResult *LR, ArrayRef<Value *> B, ArrayRef<Value *> UB,
+ Action(const LegalityResult *LR, BndlRef<Value *> B, BndlRef<Value *> UB,
unsigned Depth)
: LegalityRes(LR), Bndl(B), UserBndl(UB), Depth(Depth) {}
#ifndef NDEBUG
@@ -84,7 +84,7 @@ class InstrMaps {
return It2->second;
}
/// Update the map to reflect that \p Origs got vectorized into \p Vec.
- void registerVector(ArrayRef<Value *> Origs, Action *Vec) {
+ void registerVector(BndlRef<Value *> Origs, Action *Vec) {
auto &OrigToLaneMap = VectorToOrigLaneMap[Vec];
unsigned Lane = 0;
for (Value *Orig : Origs) {
diff --git a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/BundleVec.h b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/BundleVec.h
index 62ff4a527d1f7..de9bea6d38a73 100644
--- a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/BundleVec.h
+++ b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/BundleVec.h
@@ -54,7 +54,7 @@ class LLVM_ABI BundleVec final : public RegionPass {
/// Creates and returns a vector instruction that replaces the instructions in
/// \p Bndl. \p Operands are the already vectorized operands.
- Value *createVectorInstr(ArrayRef<Value *> Bndl, ArrayRef<Value *> Operands);
+ Value *createVectorInstr(BndlRef<Value *> Bndl, BndlRef<Value *> Operands);
/// Creates a shuffle instruction that shuffles \p VecOp according to \p Mask.
/// \p UserBB is the block of the user bundle.
@@ -62,7 +62,7 @@ class LLVM_ABI BundleVec final : public RegionPass {
BasicBlock *UserBB);
/// Packs all elements of \p ToPack into a vector and returns that vector. \p
/// UserBB is the block of the user bundle.
- Value *createPack(ArrayRef<Value *> ToPack, BasicBlock *UserBB);
+ Value *createPack(BndlRef<Value *> ToPack, BasicBlock *UserBB);
/// Helper class describing how(if) to vectorize the code.
class ActionsVector {
@@ -89,16 +89,16 @@ class LLVM_ABI BundleVec final : public RegionPass {
/// Recursively try to vectorize \p Bndl. \p UserBndl identifies the
/// users that this recursive call originates from.
- Action *vectorizeRec(ArrayRef<Value *> Bndl, ArrayRef<Value *> UserBndl,
+ Action *vectorizeRec(BndlRef<Value *> Bndl, BndlRef<Value *> UserBndl,
unsigned Depth, LegalityAnalysis &Legality);
/// If the values in \p Bndl have external users, then emit unpacks and
/// connect them to the users. \p Vec is the vectorized form of \p Bndl.
- void emitUnpacksForExternalUses(const ArrayRef<Value *> Bndl, Value *Vec);
+ void emitUnpacksForExternalUses(BndlRef<Value *> Bndl, Value *Vec);
/// Generate vector instructions based on `Actions` and return the last vector
/// created.
Value *emitVectors();
/// Entry point for vectorization starting from \p Seeds.
- bool tryVectorize(ArrayRef<Value *> Seeds, LegalityAnalysis &Legality);
+ bool tryVectorize(BndlRef<Value *> Seeds, LegalityAnalysis &Legality);
public:
BundleVec(StringRef AuxArg) : RegionPass("bundle-vec") {
diff --git a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/VecUtils.h b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/VecUtils.h
index 80e266d1c3022..b904d497faf68 100644
--- a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/VecUtils.h
+++ b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/VecUtils.h
@@ -453,6 +453,49 @@ class VecUtils {
#endif // NDEBUG
};
+/// An ArrayRef of Values or Instructions that we can print/dump for debugging.
+/// It is mainly used for the vectorizer's instr/value bundles.
+template <typename T> class BndlRef : public ArrayRef<T> {
+public:
+ // Inherit constructors.
+ using ArrayRef<T>::ArrayRef;
+
+#ifndef NDEBUG
+ /// Helper dump function for debugging.
+ void print(raw_ostream &OS) const {
+ for (const auto &[Idx, Val] : enumerate(*this))
+ OS << Idx << ". " << *Val << "\n";
+ }
+ LLVM_DUMP_METHOD void dump() const;
+#endif // NDEBUG
+};
+
+/// @name BndlRef Deduction guides
+/// @{
+/// Deduction guide to construct a BndlRef from a single element.
+template <typename T> BndlRef(const T &OneElt) -> BndlRef<T>;
+/// Deduction guide to construct a BndlRef from a pointer and length
+template <typename T> BndlRef(const T *data, size_t length) -> BndlRef<T>;
+/// Deduction guide to construct a BndlRef from a range
+template <typename T> BndlRef(const T *data, const T *end) -> BndlRef<T>;
+/// Deduction guide to construct a BndlRef from a SmallVector
+template <typename T> BndlRef(const SmallVectorImpl<T> &Vec) -> BndlRef<T>;
+/// Deduction guide to construct a BndlRef from a SmallVector
+template <typename T, unsigned N>
+BndlRef(const SmallVector<T, N> &Vec) -> BndlRef<T>;
+/// Deduction guide to construct a BndlRef from a std::vector
+template <typename T> BndlRef(const std::vector<T> &Vec) -> BndlRef<T>;
+/// Deduction guide to construct a BndlRef from a std::array
+template <typename T, std::size_t N>
+BndlRef(const std::array<T, N> &Vec) -> BndlRef<T>;
+/// Deduction guide to construct a BndlRef from an BndlRef (const)
+template <typename T> BndlRef(const BndlRef<T> &Vec) -> BndlRef<T>;
+/// Deduction guide to construct a BndlRef from an BndlRef
+template <typename T> BndlRef(BndlRef<T> &Vec) -> BndlRef<T>;
+/// Deduction guide to construct a BndlRef from a C array.
+template <typename T, size_t N> BndlRef(const T (&Arr)[N]) -> BndlRef<T>;
+/// @}
+
} // namespace sandboxir
} // namespace llvm
diff --git a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/BundleVec.cpp b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/BundleVec.cpp
index 5f4ca6fe12686..80dd30896b00b 100644
--- a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/BundleVec.cpp
+++ b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/BundleVec.cpp
@@ -41,7 +41,7 @@ static cl::opt<unsigned long>
namespace sandboxir {
-static BundleTy getOperand(ArrayRef<Value *> Bndl, unsigned OpIdx) {
+static BundleTy getOperand(BndlRef<Value *> Bndl, unsigned OpIdx) {
BundleTy Operands;
for (Value *BndlV : Bndl) {
auto *BndlI = cast<Instruction>(BndlV);
@@ -50,10 +50,10 @@ static BundleTy getOperand(ArrayRef<Value *> Bndl, unsigned OpIdx) {
return Operands;
}
-Value *BundleVec::createVectorInstr(ArrayRef<Value *> Bndl,
- ArrayRef<Value *> Operands) {
- auto CreateVectorInstr = [](ArrayRef<Value *> Bndl,
- ArrayRef<Value *> Operands) -> Value * {
+Value *BundleVec::createVectorInstr(BndlRef<Value *> Bndl,
+ BndlRef<Value *> Operands) {
+ auto CreateVectorInstr = [](BndlRef<Value *> Bndl,
+ BndlRef<Value *> Operands) -> Value * {
assert(all_of(Bndl, [](auto *V) { return isa<Instruction>(V); }) &&
"Expect Instructions!");
auto &Ctx = Bndl[0]->getContext();
@@ -169,7 +169,7 @@ Value *BundleVec::createShuffle(Value *VecOp, const ShuffleMask &Mask,
VecOp->getContext(), "VShuf");
}
-Value *BundleVec::createPack(ArrayRef<Value *> ToPack, BasicBlock *UserBB) {
+Value *BundleVec::createPack(BndlRef<Value *> ToPack, BasicBlock *UserBB) {
BasicBlock::iterator WhereIt =
VecUtils::getInsertPointAfterInstrs(ToPack, UserBB);
@@ -221,8 +221,8 @@ Value *BundleVec::createPack(ArrayRef<Value *> ToPack, BasicBlock *UserBB) {
return LastInsert;
}
-Action *BundleVec::vectorizeRec(ArrayRef<Value *> Bndl,
- ArrayRef<Value *> UserBndl, unsigned Depth,
+Action *BundleVec::vectorizeRec(BndlRef<Value *> Bndl,
+ BndlRef<Value *> UserBndl, unsigned Depth,
LegalityAnalysis &Legality) {
bool StopForDebug =
DebugBndlCnt++ >= StopBundle && StopBundle != StopBundleDisabled;
@@ -239,8 +239,8 @@ Action *BundleVec::vectorizeRec(ArrayRef<Value *> Bndl,
if (LegalityRes.getSubclassID() != LegalityResultID::Widen)
return nullptr;
- auto ActionPtr = std::make_unique<Action>(&LegalityRes, Bndl,
- ArrayRef<Value *>(), Depth);
+ auto ActionPtr =
+ std::make_unique<Action>(&LegalityRes, Bndl, BndlRef<Value *>(), Depth);
Action *Action = ActionPtr.get();
IMaps->registerVector(Bndl, Action);
Actions.push_back(std::move(ActionPtr));
@@ -309,8 +309,7 @@ void BundleVec::ActionsVector::print(raw_ostream &OS) const {
void BundleVec::ActionsVector::dump() const { print(dbgs()); }
#endif // NDEBUG
-void BundleVec::emitUnpacksForExternalUses(const ArrayRef<Value *> Bndl,
- Value *Vec) {
+void BundleVec::emitUnpacksForExternalUses(BndlRef<Value *> Bndl, Value *Vec) {
// Find where we should emit the unpacks.
BasicBlock::iterator WhereIt;
if (auto *VecI = dyn_cast<Instruction>(Vec)) {
@@ -350,8 +349,8 @@ void BundleVec::emitUnpacksForExternalUses(const ArrayRef<Value *> Bndl,
Value *BundleVec::emitVectors() {
Value *NewVec = nullptr;
for (const auto &ActionPtr : Actions) {
- ArrayRef<Value *> Bndl = ActionPtr->Bndl;
- ArrayRef<Value *> UserBndl = ActionPtr->UserBndl;
+ BndlRef<Value *> Bndl = ActionPtr->Bndl;
+ BndlRef<Value *> UserBndl = ActionPtr->UserBndl;
const LegalityResult &LegalityRes = *ActionPtr->LegalityRes;
unsigned Depth = ActionPtr->Depth;
auto *UserBB = !UserBndl.empty()
@@ -512,7 +511,7 @@ Value *BundleVec::emitVectors() {
return NewVec;
}
-bool BundleVec::tryVectorize(ArrayRef<Value *> Bndl,
+bool BundleVec::tryVectorize(BndlRef<Value *> Bndl,
LegalityAnalysis &Legality) {
Change = false;
if (LLVM_UNLIKELY(InvocationCnt++ >= StopAt && StopAt != StopAtDisabled))
diff --git a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/VecUtils.cpp b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/VecUtils.cpp
index abf3d79966d8f..e5caeb68764d6 100644
--- a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/VecUtils.cpp
+++ b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/VecUtils.cpp
@@ -159,6 +159,15 @@ template <typename T> static void dumpImpl(ArrayRef<T *> Bndl) {
}
void VecUtils::dump(ArrayRef<Value *> Bndl) { dumpImpl(Bndl); }
void VecUtils::dump(ArrayRef<Instruction *> Bndl) { dumpImpl(Bndl); }
+
+template <typename T> void BndlRef<T>::dump() const {
+ print(dbgs());
+ dbgs() << "\n";
+}
+// Explicit instantiation for commonly used types.
+template class BndlRef<Instruction *>;
+template class BndlRef<Value *>;
+
#endif // NDEBUG
} // namespace llvm::sandboxir
diff --git a/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/VecUtilsTest.cpp b/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/VecUtilsTest.cpp
index b4f40a1eee201..a2d6b2cba3ac0 100644
--- a/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/VecUtilsTest.cpp
+++ b/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/VecUtilsTest.cpp
@@ -1299,3 +1299,38 @@ define void @vectorized_seed_user(ptr %p) {
sandboxir::VecUtils::getNextUserBundles({Ld0, Ld1}, IMaps, Claimed)
.empty());
}
+
+TEST_F(VecUtilsTest, BndlRef) {
+ parseIR(R"IR(
+define void @vectorized_seed_user(i8 %v0, i8 %v1) {
+entry:
+ %add0 = add i8 %v0, 0
+ %add1 = add i8 %v1, 1
+ ret void
+}
+)IR");
+ sandboxir::Context Ctx(C);
+ auto *F = Ctx.createFunction(M->getFunction("vectorized_seed_user"));
+ auto &BB = getBasicBlockByName(*F, "entry");
+ auto It = BB.begin();
+ auto *Ld0 = cast<sandboxir::Instruction>(&*It++);
+ auto *Ld1 = cast<sandboxir::Instruction>(&*It++);
+ std::string Str;
+ raw_string_ostream SS(Str);
+
+ SmallVector<sandboxir::Value *> ValuesVec(
+ {static_cast<sandboxir::Value *>(Ld0),
+ static_cast<sandboxir::Value *>(Ld1)});
+ sandboxir::BndlRef ValuesBndl(ValuesVec);
+ Str.clear();
+ ValuesBndl.print(SS);
+ EXPECT_THAT(Str, testing::MatchesRegex("0. *%add0 = add i8 %v0, 0 .*\n"
+ "1. *%add1 = add i8 %v1, 1 .*\n"));
+
+ SmallVector<sandboxir::Instruction *> InstrsVec({Ld0, Ld1});
+ sandboxir::BndlRef InstrsBndl(InstrsVec);
+ Str.clear();
+ ValuesBndl.print(SS);
+ EXPECT_THAT(Str, testing::MatchesRegex("0. *%add0 = add i8 %v0, 0 .*\n"
+ "1. *%add1 = add i8 %v1, 1 .*\n"));
+}
More information about the llvm-commits
mailing list