[llvm] [SandboxIR] Boilerplate code (PR #95814)

via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 17 10:38:56 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-transforms

Author: vporpo (vporpo)

<details>
<summary>Changes</summary>

This is the first patch in a series of patches for the Sandbox Vectorizer project. For a detailed description of the project please refer to the RFC: https://discourse.llvm.org/t/rfc-sandbox-vectorizer-an-experimental-modular-vectorizer/79059

This patch adds some basic boilerplate code for the SandboxIR which includes parts of the `SBValue` class.

---
Full diff: https://github.com/llvm/llvm-project/pull/95814.diff


7 Files Affected:

- (added) llvm/include/llvm/Transforms/SandboxIR/SandboxIR.h (+129) 
- (added) llvm/include/llvm/Transforms/SandboxIR/SandboxIRValues.def (+29) 
- (modified) llvm/lib/Transforms/CMakeLists.txt (+1) 
- (added) llvm/lib/Transforms/SandboxIR/CMakeLists.txt (+11) 
- (added) llvm/lib/Transforms/SandboxIR/SandboxIR.cpp (+65) 
- (added) llvm/utils/gn/secondary/llvm/lib/Transforms/SandboxIR/BUILD.gn (+10) 
- (modified) utils/bazel/llvm-project-overlay/llvm/BUILD.bazel (+19) 


``````````diff
diff --git a/llvm/include/llvm/Transforms/SandboxIR/SandboxIR.h b/llvm/include/llvm/Transforms/SandboxIR/SandboxIR.h
new file mode 100644
index 0000000000000..753f42d313bb2
--- /dev/null
+++ b/llvm/include/llvm/Transforms/SandboxIR/SandboxIR.h
@@ -0,0 +1,129 @@
+//===- SandboxIR.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
+//
+//===----------------------------------------------------------------------===//
+//
+// Sandbox IR is a lightweight overlay transactional IR on top of LLVM IR.
+// Features:
+// - You can save/rollback the state of the IR at any time.
+// - Any changes made to Sandbox IR will automatically update the underlying
+//   LLVM IR so both IRs are always in sync.
+// - Feels like LLVM IR, similar API.
+//
+// SandboxIR forms a class hierarcy that resembles that of LLVM IR:
+//
+//          +- SBArgument   +- SBConstant     +- SBOpaqueInstruction
+//          |               |                 |
+// SBValue -+- SBUser ------+- SBInstruction -+- SBInsertElementInstruction
+//          |                                 |
+//          +- SBBasicBlock                   +- SBExtractElementInstruction
+//          |                                 |
+//          +- SBFunction                     +- SBShuffleVectorInstruction
+//                                            |
+//                                            +- SBStoreInstruction
+//                                            |
+//                                            +- SBLoadInstruction
+//                                            |
+//                                            +- SBCmpInstruction
+//                                            |
+//                                            +- SBCastInstruction
+//                                            |
+//                                            +- SBPHINode
+//                                            |
+//                                            +- SBSelectInstruction
+//                                            |
+//                                            +- SBBinaryOperator
+//                                            |
+//                                            +- SBUnaryOperator
+//
+// SBUse
+//
+#ifndef LLVM_TRANSFORMS_SANDBOXIR_SANDBOXIR_H
+#define LLVM_TRANSFORMS_SANDBOXIR_SANDBOXIR_H
+
+#include "llvm/IR/Value.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace llvm {
+
+class SBContext;
+
+/// A SBValue has users. This is the base class.
+class SBValue {
+public:
+  enum class ClassID : unsigned {
+#define DEF_VALUE(ID, CLASS) ID,
+#define DEF_USER(ID, CLASS) ID,
+#define DEF_INSTR(ID, OPC, CLASS) ID,
+#include "llvm/Transforms/SandboxIR/SandboxIRValues.def"
+  };
+
+protected:
+  static const char *getSubclassIDStr(ClassID ID) {
+    switch (ID) {
+      // clang-format off
+#define DEF_VALUE(ID, CLASS) case ClassID::ID: return #ID;
+#define DEF_USER(ID,  CLASS) case ClassID::ID: return #ID;
+#define DEF_INSTR(ID, OPC, CLASS) case ClassID::ID: return #ID;
+      // clang-format on
+#include "llvm/Transforms/SandboxIR/SandboxIRValues.def"
+    }
+    llvm_unreachable("Unimplemented ID");
+  }
+
+  /// For isa/dyn_cast.
+  ClassID SubclassID;
+#ifndef NDEBUG
+  /// A unique ID used for forming the name (used for debugging).
+  unsigned UID;
+#endif
+  /// The LLVM Value that corresponds to this SBValue.
+  /// NOTE: Some SBInstructions, like Packs, may include more than one value.
+  Value *Val = nullptr;
+  friend class ValueAttorney; // For Val
+
+  /// All values point to the context.
+  SBContext &Ctxt;
+  // This is used by eraseFromParent().
+  void clearValue() { Val = nullptr; }
+  template <typename ItTy, typename SBTy> friend class LLVMOpUserItToSBTy;
+
+public:
+  SBValue(ClassID SubclassID, Value *Val, SBContext &Ctxt);
+  virtual ~SBValue() = default;
+  ClassID getSubclassID() const { return SubclassID; }
+
+  Type *getType() const { return Val->getType(); }
+
+  SBContext &getContext() const;
+  virtual hash_code hashCommon() const {
+    return hash_combine(SubclassID, &Ctxt, Val);
+  }
+  virtual hash_code hash() const = 0;
+  friend hash_code hash_value(const SBValue &SBV) { return SBV.hash(); }
+#ifndef NDEBUG
+  /// Should crash if there is something wrong with the instruction.
+  virtual void verify() const = 0;
+  /// Returns the name in the form 'SB<number>.' like 'SB1.'
+  std::string getName() const;
+  virtual void dumpCommonHeader(raw_ostream &OS) const;
+  void dumpCommonFooter(raw_ostream &OS) const;
+  void dumpCommonPrefix(raw_ostream &OS) const;
+  void dumpCommonSuffix(raw_ostream &OS) const;
+  void printAsOperandCommon(raw_ostream &OS) const;
+  friend raw_ostream &operator<<(raw_ostream &OS, const SBValue &SBV) {
+    SBV.dump(OS);
+    return OS;
+  }
+  virtual void dump(raw_ostream &OS) const = 0;
+  LLVM_DUMP_METHOD virtual void dump() const = 0;
+  virtual void dumpVerbose(raw_ostream &OS) const = 0;
+  LLVM_DUMP_METHOD virtual void dumpVerbose() const = 0;
+#endif
+};
+} // namespace llvm
+
+#endif // LLVM_TRANSFORMS_SANDBOXIR_SANDBOXIR_H
diff --git a/llvm/include/llvm/Transforms/SandboxIR/SandboxIRValues.def b/llvm/include/llvm/Transforms/SandboxIR/SandboxIRValues.def
new file mode 100644
index 0000000000000..e33e8c8c5e07e
--- /dev/null
+++ b/llvm/include/llvm/Transforms/SandboxIR/SandboxIRValues.def
@@ -0,0 +1,29 @@
+//===- SandboxIRValues.def --------------------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+// clang-format off
+
+//        ClassID,                        Class
+// DEF_USER(Constant,                        SBConstant)
+
+// clang-format on
+#ifdef DEF_VALUE
+#undef DEF_VALUE
+#endif
+#ifdef DEF_USER
+#undef DEF_USER
+#endif
+#ifdef DEF_INSTR
+#undef DEF_INSTR
+#endif
+#ifdef OPCODES
+#undef OPCODES
+#endif
+#ifdef OP
+#undef OP
+#endif
diff --git a/llvm/lib/Transforms/CMakeLists.txt b/llvm/lib/Transforms/CMakeLists.txt
index 84a7e34147d08..d9857034ba1a9 100644
--- a/llvm/lib/Transforms/CMakeLists.txt
+++ b/llvm/lib/Transforms/CMakeLists.txt
@@ -10,3 +10,4 @@ add_subdirectory(ObjCARC)
 add_subdirectory(Coroutines)
 add_subdirectory(CFGuard)
 add_subdirectory(HipStdPar)
+add_subdirectory(SandboxIR)
diff --git a/llvm/lib/Transforms/SandboxIR/CMakeLists.txt b/llvm/lib/Transforms/SandboxIR/CMakeLists.txt
new file mode 100644
index 0000000000000..225eca0cadd1a
--- /dev/null
+++ b/llvm/lib/Transforms/SandboxIR/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_llvm_component_library(LLVMSandboxIR
+  SandboxIR.cpp
+
+  ADDITIONAL_HEADER_DIRS
+  ${LLVM_MAIN_INCLUDE_DIR}/llvm/Transforms/SandboxIR
+
+  LINK_COMPONENTS
+  Core
+  Support
+  )
+
diff --git a/llvm/lib/Transforms/SandboxIR/SandboxIR.cpp b/llvm/lib/Transforms/SandboxIR/SandboxIR.cpp
new file mode 100644
index 0000000000000..5bd25083e80c3
--- /dev/null
+++ b/llvm/lib/Transforms/SandboxIR/SandboxIR.cpp
@@ -0,0 +1,65 @@
+//===- SandboxIR.cpp - A transactional overlay IR on top of LLVM IR -------===//
+//
+// 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/SandboxIR/SandboxIR.h"
+#include "llvm/Support/Debug.h"
+#include <sstream>
+
+using namespace llvm;
+
+SBValue::SBValue(ClassID SubclassID, Value *Val, SBContext &Ctxt)
+    : SubclassID(SubclassID), Val(Val), Ctxt(Ctxt) {
+#ifndef NDEBUG
+  UID = 0; // FIXME: Once SBContext is available.
+#endif
+}
+
+#ifndef NDEBUG
+std::string SBValue::getName() const {
+  std::stringstream SS;
+  SS << "SB" << UID << ".";
+  return SS.str();
+}
+
+void SBValue::dumpCommonHeader(raw_ostream &OS) const {
+  OS << getName() << " " << getSubclassIDStr(SubclassID) << " ";
+}
+
+void SBValue::dumpCommonFooter(raw_ostream &OS) const {
+  OS.indent(2) << "Val: ";
+  if (Val)
+    OS << *Val;
+  else
+    OS << "NULL";
+  OS << "\n";
+}
+
+void SBValue::dumpCommonPrefix(raw_ostream &OS) const {
+  if (Val)
+    OS << *Val;
+  else
+    OS << "NULL ";
+}
+
+void SBValue::dumpCommonSuffix(raw_ostream &OS) const {
+  OS << " ; " << getName() << " (" << getSubclassIDStr(SubclassID) << ") "
+     << this;
+}
+
+void SBValue::printAsOperandCommon(raw_ostream &OS) const {
+  if (Val)
+    Val->printAsOperand(OS);
+  else
+    OS << "NULL ";
+}
+
+void SBValue::dump() const {
+  dump(dbgs());
+  dbgs() << "\n";
+}
+#endif // NDEBUG
diff --git a/llvm/utils/gn/secondary/llvm/lib/Transforms/SandboxIR/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/Transforms/SandboxIR/BUILD.gn
new file mode 100644
index 0000000000000..01d62f20cf50f
--- /dev/null
+++ b/llvm/utils/gn/secondary/llvm/lib/Transforms/SandboxIR/BUILD.gn
@@ -0,0 +1,10 @@
+static_library("SandboxIR") {
+  output_name = "LLVMSandboxIR"
+  deps = [
+    "//llvm/lib/IR",
+    "//llvm/lib/Support",
+  ]
+  sources = [
+    "SandboxIR.cpp",
+  ]
+}
diff --git a/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel b/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel
index cf7ee18f0d068..6d99b210d0323 100644
--- a/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel
@@ -1467,6 +1467,23 @@ cc_library(
     ],
 )
 
+cc_library(
+    name = "SandboxIR",
+    srcs = glob([
+        "lib/Transforms/SandboxIR/*.cpp",
+    ]),
+    hdrs = glob([
+        "include/llvm/Transforms/SandboxIR/*.h",
+        "include/llvm/Transforms/SandboxIR/*.def",
+    ]),
+    copts = llvm_copts,
+    deps = [
+        ":Core",
+        ":Support",
+        ":config",
+    ],
+)
+
 cc_library(
     name = "Vectorize",
     srcs = glob([
@@ -1826,6 +1843,7 @@ cc_library(
         ":InstCombine",
         ":Instrumentation",
         ":ObjCARC",
+        ":SandboxIR",
         ":Scalar",
         ":Vectorize",
     ],
@@ -2658,6 +2676,7 @@ cc_library(
         ":Instrumentation",
         ":MC",
         ":ObjCARC",
+        ":SandboxIR",
         ":Scalar",
         ":Support",
         ":Target",

``````````

</details>


https://github.com/llvm/llvm-project/pull/95814


More information about the llvm-commits mailing list