diff --git a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/DependencyGraph.h b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/DependencyGraph.h index 0120d9cf51fe9..5437853c366ae 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 Instrs); + Interval extend(ArrayRef 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 1343f521b29bb..0000000000000 --- 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 - -namespace llvm::sandboxir { - -/// A simple iterator for iterating the interval. -template -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 ::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 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; - using const_iterator = InstrIntervalIterator; - 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 0000000000000..5c40d1eb28c7a --- /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 + +namespace llvm::sandboxir { + +/// A simple iterator for iterating the interval. +template 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 To is the BB terminator. + I = I != nullptr ? I->getPrevNode() : R.To; + return *this; + } + IntervalIterator operator--(int) { + auto ItCopy = *this; + --*this; + return ItCopy; + } + template ::value>> + T &operator*() { + return *I; + } + T &operator*() const { return *I; } +}; + +template 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 From!"); + } + Interval(ArrayRef Elems) { + assert(!Elems.empty() && "Expected non-empty Elems!"); + From = Elems[0]; + To = Elems[0]; + for (auto *I : drop_begin(Elems)) { + 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; + using const_iterator = IntervalIterator; + 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 139e581ce03d9..67b56451c7b59 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 Instrs) { +Interval DependencyGraph::extend(ArrayRef Instrs) { if (Instrs.empty()) return {}; // TODO: For now create a chain of dependencies. - InstrInterval Interval(Instrs); + Interval 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 86b1d968094ca..deb3cd398d02d 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 62% rename from llvm/unittests/Transforms/Vectorize/SandboxVectorizer/InstrIntervalTest.cpp rename to llvm/unittests/Transforms/Vectorize/SandboxVectorizer/IntervalTest.cpp index e22bb78a07d30..054da8c2a5d12 100644 --- a/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/InstrIntervalTest.cpp +++ b/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/IntervalTest.cpp @@ -1,4 +1,4 @@ -//===- InstrIntervalTest.cpp ----------------------------------------------===// +//===- IntervalTest.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,16 +6,15 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Transforms/Vectorize/SandboxVectorizer/InstrInterval.h" +#include "llvm/Transforms/Vectorize/SandboxVectorizer/Interval.h" #include "llvm/AsmParser/Parser.h" #include "llvm/SandboxIR/SandboxIR.h" #include "llvm/Support/SourceMgr.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 M; @@ -27,7 +26,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 +45,40 @@ define void @foo(i8 %v0) { auto *I2 = &*It++; auto *Ret = &*It++; - sandboxir::InstrInterval Interval(I0, Ret); + sandboxir::Interval Intvl(I0, Ret); #ifndef NDEBUG - EXPECT_DEATH(sandboxir::InstrInterval(I1, I0), ".*before.*"); + EXPECT_DEATH(sandboxir::Interval(I1, I0), + ".*before.*"); #endif // NDEBUG - // Check InstrInterval(ArrayRef), from(), to(). + // Check Interval(ArrayRef), from(), to(). { - sandboxir::InstrInterval Interval( + sandboxir::Interval Intvl( SmallVector({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 Intvl( SmallVector({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 Intvl( SmallVector({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 Empty; EXPECT_TRUE(Empty.empty()); - sandboxir::InstrInterval One(I0, I0); + sandboxir::Interval 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 +86,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++); }