Skip to content

Commit 3c66a51

Browse files
authored
[SandboxVec][Interval] Convert InstrInterval class to a class template (#110021)
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.
1 parent 5a6dc61 commit 3c66a51

File tree

6 files changed

+152
-151
lines changed

6 files changed

+152
-151
lines changed

llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/DependencyGraph.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
#include "llvm/ADT/DenseMap.h"
2626
#include "llvm/ADT/iterator_range.h"
2727
#include "llvm/SandboxIR/SandboxIR.h"
28-
#include "llvm/Transforms/Vectorize/SandboxVectorizer/InstrInterval.h"
28+
#include "llvm/Transforms/Vectorize/SandboxVectorizer/Interval.h"
2929

3030
namespace llvm::sandboxir {
3131

@@ -85,7 +85,7 @@ class DependencyGraph {
8585
}
8686
/// Build/extend the dependency graph such that it includes \p Instrs. Returns
8787
/// the interval spanning \p Instrs.
88-
InstrInterval extend(ArrayRef<Instruction *> Instrs);
88+
Interval<Instruction> extend(ArrayRef<Instruction *> Instrs);
8989
#ifndef NDEBUG
9090
void print(raw_ostream &OS) const;
9191
LLVM_DUMP_METHOD void dump() const;

llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/InstrInterval.h

Lines changed: 0 additions & 124 deletions
This file was deleted.
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
//===- Interval.h -----------------------------------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// The Interval class is a generic interval of ordered objects that implement:
10+
// - T * T::getPrevNode()
11+
// - T * T::getNextNode()
12+
// - bool T::comesBefore(const T *) const
13+
//
14+
// This is currently used for Instruction intervals.
15+
// It provides an API for some basic operations on the interval, including some
16+
// simple set operations, like union, interseciton and others.
17+
//
18+
//===----------------------------------------------------------------------===//
19+
20+
#ifndef LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_INSTRINTERVAL_H
21+
#define LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_INSTRINTERVAL_H
22+
23+
#include "llvm/SandboxIR/SandboxIR.h"
24+
#include <iterator>
25+
26+
namespace llvm::sandboxir {
27+
28+
/// A simple iterator for iterating the interval.
29+
template <typename T, typename IntervalType> class IntervalIterator {
30+
T *I;
31+
IntervalType &R;
32+
33+
public:
34+
using difference_type = std::ptrdiff_t;
35+
using value_type = T;
36+
using pointer = value_type *;
37+
using reference = T &;
38+
using iterator_category = std::bidirectional_iterator_tag;
39+
40+
IntervalIterator(T *I, IntervalType &R) : I(I), R(R) {}
41+
bool operator==(const IntervalIterator &Other) const {
42+
assert(&R == &Other.R && "Iterators belong to different regions!");
43+
return Other.I == I;
44+
}
45+
bool operator!=(const IntervalIterator &Other) const {
46+
return !(*this == Other);
47+
}
48+
IntervalIterator &operator++() {
49+
assert(I != nullptr && "already at end()!");
50+
I = I->getNextNode();
51+
return *this;
52+
}
53+
IntervalIterator operator++(int) {
54+
auto ItCopy = *this;
55+
++*this;
56+
return ItCopy;
57+
}
58+
IntervalIterator &operator--() {
59+
// `I` is nullptr for end() when To is the BB terminator.
60+
I = I != nullptr ? I->getPrevNode() : R.To;
61+
return *this;
62+
}
63+
IntervalIterator operator--(int) {
64+
auto ItCopy = *this;
65+
--*this;
66+
return ItCopy;
67+
}
68+
template <typename HT = std::enable_if<std::is_same<T, T *&>::value>>
69+
T &operator*() {
70+
return *I;
71+
}
72+
T &operator*() const { return *I; }
73+
};
74+
75+
template <typename T> class Interval {
76+
T *From;
77+
T *To;
78+
79+
public:
80+
Interval() : From(nullptr), To(nullptr) {}
81+
Interval(T *From, T *To) : From(From), To(To) {
82+
assert((From == To || From->comesBefore(To)) &&
83+
"From should come before From!");
84+
}
85+
Interval(ArrayRef<T *> Elems) {
86+
assert(!Elems.empty() && "Expected non-empty Elems!");
87+
From = Elems[0];
88+
To = Elems[0];
89+
for (auto *I : drop_begin(Elems)) {
90+
if (I->comesBefore(From))
91+
From = I;
92+
else if (To->comesBefore(I))
93+
To = I;
94+
}
95+
}
96+
bool empty() const {
97+
assert(((From == nullptr && To == nullptr) ||
98+
(From != nullptr && To != nullptr)) &&
99+
"Either none or both should be null");
100+
return From == nullptr;
101+
}
102+
bool contains(T *I) const {
103+
if (empty())
104+
return false;
105+
return (From == I || From->comesBefore(I)) &&
106+
(I == To || I->comesBefore(To));
107+
}
108+
T *top() const { return From; }
109+
T *bottom() const { return To; }
110+
111+
using iterator = IntervalIterator<T, Interval>;
112+
using const_iterator = IntervalIterator<const T, const Interval>;
113+
iterator begin() { return iterator(From, *this); }
114+
iterator end() {
115+
return iterator(To != nullptr ? To->getNextNode() : nullptr, *this);
116+
}
117+
const_iterator begin() const { return const_iterator(From, *this); }
118+
const_iterator end() const {
119+
return const_iterator(To != nullptr ? To->getNextNode() : nullptr, *this);
120+
}
121+
};
122+
123+
} // namespace llvm::sandboxir
124+
125+
#endif // LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_INSTRINTERVAL_H

llvm/lib/Transforms/Vectorize/SandboxVectorizer/DependencyGraph.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,11 @@ void DGNode::dump() const {
3131
}
3232
#endif // NDEBUG
3333

34-
InstrInterval DependencyGraph::extend(ArrayRef<Instruction *> Instrs) {
34+
Interval<Instruction> DependencyGraph::extend(ArrayRef<Instruction *> Instrs) {
3535
if (Instrs.empty())
3636
return {};
3737
// TODO: For now create a chain of dependencies.
38-
InstrInterval Interval(Instrs);
38+
Interval<Instruction> Interval(Instrs);
3939
auto *TopI = Interval.top();
4040
auto *BotI = Interval.bottom();
4141
DGNode *LastN = getOrCreateNode(TopI);

llvm/unittests/Transforms/Vectorize/SandboxVectorizer/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ set(LLVM_LINK_COMPONENTS
99

1010
add_llvm_unittest(SandboxVectorizerTests
1111
DependencyGraphTest.cpp
12-
InstrIntervalTest.cpp
12+
IntervalTest.cpp
1313
LegalityTest.cpp
1414
RegionTest.cpp
1515
)
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,20 @@
1-
//===- InstrIntervalTest.cpp ----------------------------------------------===//
1+
//===- IntervalTest.cpp ---------------------------------------------------===//
22
//
33
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
44
// See https://llvm.org/LICENSE.txt for license information.
55
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66
//
77
//===----------------------------------------------------------------------===//
88

9-
#include "llvm/Transforms/Vectorize/SandboxVectorizer/InstrInterval.h"
9+
#include "llvm/Transforms/Vectorize/SandboxVectorizer/Interval.h"
1010
#include "llvm/AsmParser/Parser.h"
1111
#include "llvm/SandboxIR/SandboxIR.h"
1212
#include "llvm/Support/SourceMgr.h"
13-
#include "gmock/gmock-matchers.h"
1413
#include "gtest/gtest.h"
1514

1615
using namespace llvm;
1716

18-
struct InstrIntervalTest : public testing::Test {
17+
struct IntervalTest : public testing::Test {
1918
LLVMContext C;
2019
std::unique_ptr<Module> M;
2120

@@ -27,7 +26,7 @@ struct InstrIntervalTest : public testing::Test {
2726
}
2827
};
2928

30-
TEST_F(InstrIntervalTest, Basic) {
29+
TEST_F(IntervalTest, Basic) {
3130
parseIR(C, R"IR(
3231
define void @foo(i8 %v0) {
3332
%add0 = add i8 %v0, %v0
@@ -46,46 +45,47 @@ define void @foo(i8 %v0) {
4645
auto *I2 = &*It++;
4746
auto *Ret = &*It++;
4847

49-
sandboxir::InstrInterval Interval(I0, Ret);
48+
sandboxir::Interval<sandboxir::Instruction> Intvl(I0, Ret);
5049
#ifndef NDEBUG
51-
EXPECT_DEATH(sandboxir::InstrInterval(I1, I0), ".*before.*");
50+
EXPECT_DEATH(sandboxir::Interval<sandboxir::Instruction>(I1, I0),
51+
".*before.*");
5252
#endif // NDEBUG
53-
// Check InstrInterval(ArrayRef), from(), to().
53+
// Check Interval<sandboxir::Instruction>(ArrayRef), from(), to().
5454
{
55-
sandboxir::InstrInterval Interval(
55+
sandboxir::Interval<sandboxir::Instruction> Intvl(
5656
SmallVector<sandboxir::Instruction *>({I0, Ret}));
57-
EXPECT_EQ(Interval.top(), I0);
58-
EXPECT_EQ(Interval.bottom(), Ret);
57+
EXPECT_EQ(Intvl.top(), I0);
58+
EXPECT_EQ(Intvl.bottom(), Ret);
5959
}
6060
{
61-
sandboxir::InstrInterval Interval(
61+
sandboxir::Interval<sandboxir::Instruction> Intvl(
6262
SmallVector<sandboxir::Instruction *>({Ret, I0}));
63-
EXPECT_EQ(Interval.top(), I0);
64-
EXPECT_EQ(Interval.bottom(), Ret);
63+
EXPECT_EQ(Intvl.top(), I0);
64+
EXPECT_EQ(Intvl.bottom(), Ret);
6565
}
6666
{
67-
sandboxir::InstrInterval Interval(
67+
sandboxir::Interval<sandboxir::Instruction> Intvl(
6868
SmallVector<sandboxir::Instruction *>({I0, I0}));
69-
EXPECT_EQ(Interval.top(), I0);
70-
EXPECT_EQ(Interval.bottom(), I0);
69+
EXPECT_EQ(Intvl.top(), I0);
70+
EXPECT_EQ(Intvl.bottom(), I0);
7171
}
7272

7373
// Check empty().
74-
EXPECT_FALSE(Interval.empty());
75-
sandboxir::InstrInterval Empty;
74+
EXPECT_FALSE(Intvl.empty());
75+
sandboxir::Interval<sandboxir::Instruction> Empty;
7676
EXPECT_TRUE(Empty.empty());
77-
sandboxir::InstrInterval One(I0, I0);
77+
sandboxir::Interval<sandboxir::Instruction> One(I0, I0);
7878
EXPECT_FALSE(One.empty());
7979
// Check contains().
8080
for (auto &I : *BB) {
81-
EXPECT_TRUE(Interval.contains(&I));
81+
EXPECT_TRUE(Intvl.contains(&I));
8282
EXPECT_FALSE(Empty.contains(&I));
8383
}
8484
EXPECT_FALSE(One.contains(I1));
8585
EXPECT_FALSE(One.contains(I2));
8686
EXPECT_FALSE(One.contains(Ret));
8787
// Check iterator.
8888
auto BBIt = BB->begin();
89-
for (auto &I : Interval)
89+
for (auto &I : Intvl)
9090
EXPECT_EQ(&I, &*BBIt++);
9191
}

0 commit comments

Comments
 (0)