[llvm] [SandboxVec][Interval] Convert InstrInterval class to a class template (PR #110021)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 25 11:10:07 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: vporpo (vporpo)
<details>
<summary>Changes</summary>
This patch converts InstrInterval class to a class template and renames InstrInterval to Itnerval.
This change will allow us to reuse the Interval for dependency graph nodes.
---
Full diff: https://github.com/llvm/llvm-project/pull/110021.diff
6 Files Affected:
- (modified) llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/DependencyGraph.h (+2-2)
- (removed) llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/InstrInterval.h (-124)
- (added) llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Interval.h (+125)
- (modified) llvm/lib/Transforms/Vectorize/SandboxVectorizer/DependencyGraph.cpp (+2-2)
- (modified) llvm/unittests/Transforms/Vectorize/SandboxVectorizer/CMakeLists.txt (+1-1)
- (renamed) llvm/unittests/Transforms/Vectorize/SandboxVectorizer/IntervalTest.cpp (+21-20)
``````````diff
diff --git a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/DependencyGraph.h b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/DependencyGraph.h
index 0120d9cf51fe9f..5437853c366ae6 100644
--- a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/DependencyGraph.h
+++ b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/DependencyGraph.h
@@ -25,7 +25,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/SandboxIR/SandboxIR.h"
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/InstrInterval.h"
+#include "llvm/Transforms/Vectorize/SandboxVectorizer/Interval.h"
namespace llvm::sandboxir {
@@ -85,7 +85,7 @@ class DependencyGraph {
}
/// Build/extend the dependency graph such that it includes \p Instrs. Returns
/// the interval spanning \p Instrs.
- InstrInterval extend(ArrayRef<Instruction *> Instrs);
+ Interval<Instruction> extend(ArrayRef<Instruction *> Instrs);
#ifndef NDEBUG
void print(raw_ostream &OS) const;
LLVM_DUMP_METHOD void dump() const;
diff --git a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/InstrInterval.h b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/InstrInterval.h
deleted file mode 100644
index 1343f521b29bb4..00000000000000
--- a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/InstrInterval.h
+++ /dev/null
@@ -1,124 +0,0 @@
-//===- InstrInterval.h ------------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// The InstrInterval class is an interval of instructions in a block.
-// It provides an API for some basic operations on the interval, including some
-// simple set operations, like union, interseciton and others.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_INSTRINTERVAL_H
-#define LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_INSTRINTERVAL_H
-
-#include "llvm/SandboxIR/SandboxIR.h"
-#include <iterator>
-
-namespace llvm::sandboxir {
-
-/// A simple iterator for iterating the interval.
-template <typename DerefType, typename InstrIntervalType>
-class InstrIntervalIterator {
- sandboxir::Instruction *I;
- InstrIntervalType &R;
-
-public:
- using difference_type = std::ptrdiff_t;
- using value_type = sandboxir::Instruction;
- using pointer = value_type *;
- using reference = sandboxir::Instruction &;
- using iterator_category = std::bidirectional_iterator_tag;
-
- InstrIntervalIterator(sandboxir::Instruction *I, InstrIntervalType &R)
- : I(I), R(R) {}
- bool operator==(const InstrIntervalIterator &Other) const {
- assert(&R == &Other.R && "Iterators belong to different regions!");
- return Other.I == I;
- }
- bool operator!=(const InstrIntervalIterator &Other) const {
- return !(*this == Other);
- }
- InstrIntervalIterator &operator++() {
- assert(I != nullptr && "already at end()!");
- I = I->getNextNode();
- return *this;
- }
- InstrIntervalIterator operator++(int) {
- auto ItCopy = *this;
- ++*this;
- return ItCopy;
- }
- InstrIntervalIterator &operator--() {
- // `I` is nullptr for end() when ToI is the BB terminator.
- I = I != nullptr ? I->getPrevNode() : R.ToI;
- return *this;
- }
- InstrIntervalIterator operator--(int) {
- auto ItCopy = *this;
- --*this;
- return ItCopy;
- }
- template <typename T =
- std::enable_if<std::is_same<DerefType, Instruction *&>::value>>
- sandboxir::Instruction &operator*() {
- return *I;
- }
- DerefType operator*() const { return *I; }
-};
-
-class InstrInterval {
- Instruction *FromI;
- Instruction *ToI;
-
-public:
- InstrInterval() : FromI(nullptr), ToI(nullptr) {}
- InstrInterval(Instruction *FromI, Instruction *ToI) : FromI(FromI), ToI(ToI) {
- assert((FromI == ToI || FromI->comesBefore(ToI)) &&
- "FromI should come before TopI!");
- }
- InstrInterval(ArrayRef<Instruction *> Instrs) {
- assert(!Instrs.empty() && "Expected non-empty Instrs!");
- FromI = Instrs[0];
- ToI = Instrs[0];
- for (auto *I : drop_begin(Instrs)) {
- if (I->comesBefore(FromI))
- FromI = I;
- else if (ToI->comesBefore(I))
- ToI = I;
- }
- }
- bool empty() const {
- assert(((FromI == nullptr && ToI == nullptr) ||
- (FromI != nullptr && ToI != nullptr)) &&
- "Either none or both should be null");
- return FromI == nullptr;
- }
- bool contains(Instruction *I) const {
- if (empty())
- return false;
- return (FromI == I || FromI->comesBefore(I)) &&
- (I == ToI || I->comesBefore(ToI));
- }
- Instruction *top() const { return FromI; }
- Instruction *bottom() const { return ToI; }
-
- using iterator =
- InstrIntervalIterator<sandboxir::Instruction &, InstrInterval>;
- using const_iterator = InstrIntervalIterator<const sandboxir::Instruction &,
- const InstrInterval>;
- iterator begin() { return iterator(FromI, *this); }
- iterator end() {
- return iterator(ToI != nullptr ? ToI->getNextNode() : nullptr, *this);
- }
- const_iterator begin() const { return const_iterator(FromI, *this); }
- const_iterator end() const {
- return const_iterator(ToI != nullptr ? ToI->getNextNode() : nullptr, *this);
- }
-};
-} // namespace llvm::sandboxir
-
-#endif // LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_INSTRINTERVAL_H
diff --git a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Interval.h b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Interval.h
new file mode 100644
index 00000000000000..a6ddc0dd5b1a4d
--- /dev/null
+++ b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Interval.h
@@ -0,0 +1,125 @@
+//===- Interval.h -----------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// The Interval class is a generic interval of ordered objects that implement:
+// - T * T::getPrevNode()
+// - T * T::getNextNode()
+// - bool T::comesBefore(const T *) const
+//
+// This is currently used for Instruction intervals.
+// It provides an API for some basic operations on the interval, including some
+// simple set operations, like union, interseciton and others.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_INSTRINTERVAL_H
+#define LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_INSTRINTERVAL_H
+
+#include "llvm/SandboxIR/SandboxIR.h"
+#include <iterator>
+
+namespace llvm::sandboxir {
+
+/// A simple iterator for iterating the interval.
+template <typename T, typename IntervalType> class IntervalIterator {
+ T *I;
+ IntervalType &R;
+
+public:
+ using difference_type = std::ptrdiff_t;
+ using value_type = T;
+ using pointer = value_type *;
+ using reference = T &;
+ using iterator_category = std::bidirectional_iterator_tag;
+
+ IntervalIterator(T *I, IntervalType &R) : I(I), R(R) {}
+ bool operator==(const IntervalIterator &Other) const {
+ assert(&R == &Other.R && "Iterators belong to different regions!");
+ return Other.I == I;
+ }
+ bool operator!=(const IntervalIterator &Other) const {
+ return !(*this == Other);
+ }
+ IntervalIterator &operator++() {
+ assert(I != nullptr && "already at end()!");
+ I = I->getNextNode();
+ return *this;
+ }
+ IntervalIterator operator++(int) {
+ auto ItCopy = *this;
+ ++*this;
+ return ItCopy;
+ }
+ IntervalIterator &operator--() {
+ // `I` is nullptr for end() when ToI is the BB terminator.
+ I = I != nullptr ? I->getPrevNode() : R.ToI;
+ return *this;
+ }
+ IntervalIterator operator--(int) {
+ auto ItCopy = *this;
+ --*this;
+ return ItCopy;
+ }
+ template <typename HT = std::enable_if<std::is_same<T, T *&>::value>>
+ T &operator*() {
+ return *I;
+ }
+ T &operator*() const { return *I; }
+};
+
+template <typename T> class Interval {
+ T *From;
+ T *To;
+
+public:
+ Interval() : From(nullptr), To(nullptr) {}
+ Interval(T *From, T *To) : From(From), To(To) {
+ assert((From == To || From->comesBefore(To)) &&
+ "From should come before TopI!");
+ }
+ Interval(ArrayRef<T *> Instrs) {
+ assert(!Instrs.empty() && "Expected non-empty Instrs!");
+ From = Instrs[0];
+ To = Instrs[0];
+ for (auto *I : drop_begin(Instrs)) {
+ if (I->comesBefore(From))
+ From = I;
+ else if (To->comesBefore(I))
+ To = I;
+ }
+ }
+ bool empty() const {
+ assert(((From == nullptr && To == nullptr) ||
+ (From != nullptr && To != nullptr)) &&
+ "Either none or both should be null");
+ return From == nullptr;
+ }
+ bool contains(T *I) const {
+ if (empty())
+ return false;
+ return (From == I || From->comesBefore(I)) &&
+ (I == To || I->comesBefore(To));
+ }
+ T *top() const { return From; }
+ T *bottom() const { return To; }
+
+ using iterator = IntervalIterator<T, Interval>;
+ using const_iterator = IntervalIterator<const T, const Interval>;
+ iterator begin() { return iterator(From, *this); }
+ iterator end() {
+ return iterator(To != nullptr ? To->getNextNode() : nullptr, *this);
+ }
+ const_iterator begin() const { return const_iterator(From, *this); }
+ const_iterator end() const {
+ return const_iterator(To != nullptr ? To->getNextNode() : nullptr, *this);
+ }
+};
+
+} // namespace llvm::sandboxir
+
+#endif // LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_INSTRINTERVAL_H
diff --git a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/DependencyGraph.cpp b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/DependencyGraph.cpp
index 139e581ce03d96..67b56451c7b594 100644
--- a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/DependencyGraph.cpp
+++ b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/DependencyGraph.cpp
@@ -31,11 +31,11 @@ void DGNode::dump() const {
}
#endif // NDEBUG
-InstrInterval DependencyGraph::extend(ArrayRef<Instruction *> Instrs) {
+Interval<Instruction> DependencyGraph::extend(ArrayRef<Instruction *> Instrs) {
if (Instrs.empty())
return {};
// TODO: For now create a chain of dependencies.
- InstrInterval Interval(Instrs);
+ Interval<Instruction> Interval(Instrs);
auto *TopI = Interval.top();
auto *BotI = Interval.bottom();
DGNode *LastN = getOrCreateNode(TopI);
diff --git a/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/CMakeLists.txt b/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/CMakeLists.txt
index 86b1d968094cab..deb3cd398d02d2 100644
--- a/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/CMakeLists.txt
+++ b/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/CMakeLists.txt
@@ -9,7 +9,7 @@ set(LLVM_LINK_COMPONENTS
add_llvm_unittest(SandboxVectorizerTests
DependencyGraphTest.cpp
- InstrIntervalTest.cpp
+ IntervalTest.cpp
LegalityTest.cpp
RegionTest.cpp
)
diff --git a/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/InstrIntervalTest.cpp b/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/IntervalTest.cpp
similarity index 65%
rename from llvm/unittests/Transforms/Vectorize/SandboxVectorizer/InstrIntervalTest.cpp
rename to llvm/unittests/Transforms/Vectorize/SandboxVectorizer/IntervalTest.cpp
index e22bb78a07d300..bf6c200e26a60c 100644
--- a/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/InstrIntervalTest.cpp
+++ b/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/IntervalTest.cpp
@@ -6,16 +6,16 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/InstrInterval.h"
#include "llvm/AsmParser/Parser.h"
#include "llvm/SandboxIR/SandboxIR.h"
#include "llvm/Support/SourceMgr.h"
+#include "llvm/Transforms/Vectorize/SandboxVectorizer/Interval.h"
#include "gmock/gmock-matchers.h"
#include "gtest/gtest.h"
using namespace llvm;
-struct InstrIntervalTest : public testing::Test {
+struct IntervalTest : public testing::Test {
LLVMContext C;
std::unique_ptr<Module> M;
@@ -27,7 +27,7 @@ struct InstrIntervalTest : public testing::Test {
}
};
-TEST_F(InstrIntervalTest, Basic) {
+TEST_F(IntervalTest, Basic) {
parseIR(C, R"IR(
define void @foo(i8 %v0) {
%add0 = add i8 %v0, %v0
@@ -46,39 +46,40 @@ define void @foo(i8 %v0) {
auto *I2 = &*It++;
auto *Ret = &*It++;
- sandboxir::InstrInterval Interval(I0, Ret);
+ sandboxir::Interval<sandboxir::Instruction> Intvl(I0, Ret);
#ifndef NDEBUG
- EXPECT_DEATH(sandboxir::InstrInterval(I1, I0), ".*before.*");
+ EXPECT_DEATH(sandboxir::Interval<sandboxir::Instruction>(I1, I0),
+ ".*before.*");
#endif // NDEBUG
- // Check InstrInterval(ArrayRef), from(), to().
+ // Check Interval<sandboxir::Instruction>(ArrayRef), from(), to().
{
- sandboxir::InstrInterval Interval(
+ sandboxir::Interval<sandboxir::Instruction> Intvl(
SmallVector<sandboxir::Instruction *>({I0, Ret}));
- EXPECT_EQ(Interval.top(), I0);
- EXPECT_EQ(Interval.bottom(), Ret);
+ EXPECT_EQ(Intvl.top(), I0);
+ EXPECT_EQ(Intvl.bottom(), Ret);
}
{
- sandboxir::InstrInterval Interval(
+ sandboxir::Interval<sandboxir::Instruction> Intvl(
SmallVector<sandboxir::Instruction *>({Ret, I0}));
- EXPECT_EQ(Interval.top(), I0);
- EXPECT_EQ(Interval.bottom(), Ret);
+ EXPECT_EQ(Intvl.top(), I0);
+ EXPECT_EQ(Intvl.bottom(), Ret);
}
{
- sandboxir::InstrInterval Interval(
+ sandboxir::Interval<sandboxir::Instruction> Intvl(
SmallVector<sandboxir::Instruction *>({I0, I0}));
- EXPECT_EQ(Interval.top(), I0);
- EXPECT_EQ(Interval.bottom(), I0);
+ EXPECT_EQ(Intvl.top(), I0);
+ EXPECT_EQ(Intvl.bottom(), I0);
}
// Check empty().
- EXPECT_FALSE(Interval.empty());
- sandboxir::InstrInterval Empty;
+ EXPECT_FALSE(Intvl.empty());
+ sandboxir::Interval<sandboxir::Instruction> Empty;
EXPECT_TRUE(Empty.empty());
- sandboxir::InstrInterval One(I0, I0);
+ sandboxir::Interval<sandboxir::Instruction> One(I0, I0);
EXPECT_FALSE(One.empty());
// Check contains().
for (auto &I : *BB) {
- EXPECT_TRUE(Interval.contains(&I));
+ EXPECT_TRUE(Intvl.contains(&I));
EXPECT_FALSE(Empty.contains(&I));
}
EXPECT_FALSE(One.contains(I1));
@@ -86,6 +87,6 @@ define void @foo(i8 %v0) {
EXPECT_FALSE(One.contains(Ret));
// Check iterator.
auto BBIt = BB->begin();
- for (auto &I : Interval)
+ for (auto &I : Intvl)
EXPECT_EQ(&I, &*BBIt++);
}
``````````
</details>
https://github.com/llvm/llvm-project/pull/110021
More information about the llvm-commits
mailing list