[llvm] [mlir] [mlir] support dialect attribute translation to LLVM IR (PR #75309)

Tobias Gysi via llvm-commits llvm-commits at lists.llvm.org
Wed Dec 13 04:39:46 PST 2023


================
@@ -50,6 +51,108 @@ class DINodeAttr;
 class LLVMFuncOp;
 class ComdatSelectorOp;
 
+namespace detail {
+/// A customized inserter for LLVM's IRBuilder that captures all LLVM IR
+/// instructions that are created for future reference.
+///
+/// This is intended to be used with the `CollectionScope` RAII object:
+///
+///     llvm::IRBuilder<..., InstructionCapturingInserter> builder;
+///     {
+///       InstructionCapturingInserter::CollectionScope scope(builder);
+///       // Call IRBuilder methods as usual.
+///
+///       // This will return a list of all instructions created by the builder,
+///       // in order of creation.
+///       builder.getInserter().getCapturedInstructions();
+///     }
+///     // This will return an empty list.
+///     builder.getInserter().getCapturedInstructions();
+///
+/// The capturing functionality is _disabled_ by default for performance
+/// consideration. It needs to be explicitly enabled, which is achieved by
+/// creating a `CollectionScope`.
+class InstructionCapturingInserter : public llvm::IRBuilderCallbackInserter {
+public:
+  /// Constructs the inserter.
+  InstructionCapturingInserter()
+      : llvm::IRBuilderCallbackInserter([this](llvm::Instruction *instruction) {
+          if (LLVM_LIKELY(enabled))
+            capturedInstructions.push_back(instruction);
+        }) {}
+
+  /// Returns the list of LLVM IR instructions captured since the last cleanup.
+  ArrayRef<llvm::Instruction *> getCapturedInstructions() const {
+    return capturedInstructions;
+  }
+
+  /// Clears the list of captured LLVM IR instructions.
+  void clearCapturedInstructions() { capturedInstructions.clear(); }
+
+  /// RAII object enabling the capture of created LLVM IR instructions.
+  class CollectionScope {
+  public:
+    /// Creates the scope for the given inserter.
+    explicit CollectionScope(InstructionCapturingInserter &reference)
+        : reference(reference) {
+      wasEnabled = reference.enabled;
+      if (wasEnabled)
+        previouslyCollectedInstructions.swap(reference.capturedInstructions);
+      reference.enable(true);
+    }
+
+    /// Creates the scope for the given `llvm::IRBuilder`.
+    template <typename Ty,
+              typename = std::enable_if_t<std::is_base_of_v<
+                  std::remove_reference_t<
+                      decltype(std::declval<Ty &>().getInserter())>,
+                  InstructionCapturingInserter>>>
+    explicit CollectionScope(Ty &builder)
+        : CollectionScope(builder.getInserter()) {}
+
+    /// Ends the scope.
+    ~CollectionScope() {
+      previouslyCollectedInstructions.swap(reference.capturedInstructions);
+      // If collection was enabled (likely in another, surrounding scope), keep
+      // the instructions collected in this scope.
+      if (wasEnabled) {
+        llvm::append_range(reference.capturedInstructions,
+                           previouslyCollectedInstructions);
+      }
+      reference.enable(wasEnabled);
+    }
+
+  private:
+    /// Back reference to the inserter.
+    InstructionCapturingInserter &reference;
+
+    /// List of instructions in the inserter prior to this scope.
+    SmallVector<llvm::Instruction *> previouslyCollectedInstructions;
+
+    /// Whether the inserter was enabled prior to this scope.
+    bool wasEnabled;
+  };
+
+  void enable(bool enabled) { this->enabled = enabled; }
----------------
gysit wrote:

```suggestion
  void setEnabled(bool enabled) { this->enabled = enabled; }
```
ultra nit: 

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


More information about the llvm-commits mailing list