[llvm] 7688393 - [SandboxVec] Simple Instruction Interval class (#108882)

via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 19 17:18:44 PDT 2024


Author: vporpo
Date: 2024-09-19T17:18:40-07:00
New Revision: 76883932014bcce2efb57be062f901de26317707

URL: https://github.com/llvm/llvm-project/commit/76883932014bcce2efb57be062f901de26317707
DIFF: https://github.com/llvm/llvm-project/commit/76883932014bcce2efb57be062f901de26317707.diff

LOG: [SandboxVec] Simple Instruction Interval class (#108882)

An InstrInterval is a range of instructions in a block. The class will
eventually have an API for set operations, like union, intersection etc.

Added: 
    llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/InstrInterval.h
    llvm/unittests/Transforms/Vectorize/SandboxVectorizer/InstrIntervalTest.cpp

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

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/InstrInterval.h b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/InstrInterval.h
new file mode 100644
index 00000000000000..dcf9ca00ba11ac
--- /dev/null
+++ b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/InstrInterval.h
@@ -0,0 +1,111 @@
+//===- 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 
diff erence_type = std::ptr
diff _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 
diff erent 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!");
+  }
+  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));
+  }
+
+  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/unittests/Transforms/Vectorize/SandboxVectorizer/CMakeLists.txt b/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/CMakeLists.txt
index 10a730290608b7..86b1d968094cab 100644
--- a/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/CMakeLists.txt
+++ b/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/CMakeLists.txt
@@ -9,6 +9,7 @@ set(LLVM_LINK_COMPONENTS
 
 add_llvm_unittest(SandboxVectorizerTests
   DependencyGraphTest.cpp
+  InstrIntervalTest.cpp
   LegalityTest.cpp
   RegionTest.cpp
   )

diff  --git a/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/InstrIntervalTest.cpp b/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/InstrIntervalTest.cpp
new file mode 100644
index 00000000000000..9553158150525b
--- /dev/null
+++ b/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/InstrIntervalTest.cpp
@@ -0,0 +1,71 @@
+//===- InstrIntervalTest.cpp ----------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Transforms/Vectorize/SandboxVectorizer/InstrInterval.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 {
+  LLVMContext C;
+  std::unique_ptr<Module> M;
+
+  void parseIR(LLVMContext &C, const char *IR) {
+    SMDiagnostic Err;
+    M = parseAssemblyString(IR, Err, C);
+    if (!M)
+      Err.print("InstrIntervalTest", errs());
+  }
+};
+
+TEST_F(InstrIntervalTest, Basic) {
+  parseIR(C, R"IR(
+define void @foo(i8 %v0) {
+  %add0 = add i8 %v0, %v0
+  %add1 = add i8 %v0, %v0
+  %add2 = add i8 %v0, %v0
+  ret void
+}
+)IR");
+  Function &LLVMF = *M->getFunction("foo");
+  sandboxir::Context Ctx(C);
+  auto &F = *Ctx.createFunction(&LLVMF);
+  auto *BB = &*F.begin();
+  auto It = BB->begin();
+  auto *I0 = &*It++;
+  auto *I1 = &*It++;
+  auto *I2 = &*It++;
+  auto *Ret = &*It++;
+
+  sandboxir::InstrInterval Interval(I0, Ret);
+#ifndef NDEBUG
+  EXPECT_DEATH(sandboxir::InstrInterval(I1, I0), ".*before.*");
+#endif // NDEBUG
+  // Check empty().
+  EXPECT_FALSE(Interval.empty());
+  sandboxir::InstrInterval Empty;
+  EXPECT_TRUE(Empty.empty());
+  sandboxir::InstrInterval One(I0, I0);
+  EXPECT_FALSE(One.empty());
+  // Check contains().
+  for (auto &I : *BB) {
+    EXPECT_TRUE(Interval.contains(&I));
+    EXPECT_FALSE(Empty.contains(&I));
+  }
+  EXPECT_FALSE(One.contains(I1));
+  EXPECT_FALSE(One.contains(I2));
+  EXPECT_FALSE(One.contains(Ret));
+  // Check iterator.
+  auto BBIt = BB->begin();
+  for (auto &I : Interval)
+    EXPECT_EQ(&I, &*BBIt++);
+}


        


More information about the llvm-commits mailing list