[Mlir-commits] [mlir] [mlir] Add `requiresVisitingMutatedDefs` and `visitMutatedDefs` to `PromotableOpInterface` (PR #86792)
Fabian Mora
llvmlistbot at llvm.org
Wed Mar 27 06:10:21 PDT 2024
https://github.com/fabianmcg updated https://github.com/llvm/llvm-project/pull/86792
>From e3b7f23fa27f6c28f017b62639675be1926a834f Mon Sep 17 00:00:00 2001
From: Fabian Mora <fmora.dev at gmail.com>
Date: Wed, 27 Mar 2024 11:55:39 +0000
Subject: [PATCH 1/2] [mlir] Add `requiresVisitingMutatedDefs` and
`visitMutatedDefs` to `PromotableOpInterface`
Add `requiresVisitingMutatedDefs` and `visitMutatedDefs` methods to
`PromotableOpInterface`. These methods allow `PromotableOpInterface` ops to
transforms definitions mutated by a `store`.
This change is necessary to correctly handle the promotion of
`LLVM_DbgDeclareOp`.
---
.../mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td | 6 ++++--
.../mlir/Interfaces/MemorySlotInterfaces.td | 21 +++++++++++++++++++
mlir/lib/Dialect/LLVMIR/IR/LLVMMemorySlot.cpp | 19 ++++++++++-------
mlir/lib/Transforms/Mem2Reg.cpp | 14 ++++++++++++-
4 files changed, 50 insertions(+), 10 deletions(-)
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
index f4bac9376f2ea0..d3857fbe06e355 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td
@@ -562,8 +562,10 @@ class LLVM_DbgIntrOp<string name, string argName, list<Trait> traits = []>
}];
}
-def LLVM_DbgDeclareOp : LLVM_DbgIntrOp<"dbg.declare", "addr",
- [DeclareOpInterfaceMethods<PromotableOpInterface>]> {
+def LLVM_DbgDeclareOp : LLVM_DbgIntrOp<"dbg.declare", "addr", [
+ DeclareOpInterfaceMethods<PromotableOpInterface, [
+ "requiresVisitingMutatedDefs", "visitMutatedDefs"
+ ]>]> {
let summary = "Describes how the address relates to a source language variable.";
let arguments = (ins
LLVM_AnyPointer:$addr,
diff --git a/mlir/include/mlir/Interfaces/MemorySlotInterfaces.td b/mlir/include/mlir/Interfaces/MemorySlotInterfaces.td
index e10e2d4e104c3e..af120eb059aebf 100644
--- a/mlir/include/mlir/Interfaces/MemorySlotInterfaces.td
+++ b/mlir/include/mlir/Interfaces/MemorySlotInterfaces.td
@@ -229,6 +229,27 @@ def PromotableOpInterface : OpInterface<"PromotableOpInterface"> {
(ins "const ::llvm::SmallPtrSetImpl<mlir::OpOperand *> &":$blockingUses,
"::mlir::RewriterBase &":$rewriter)
>,
+ InterfaceMethod<[{
+ Checks whether the operation requires visiting the mutated
+ definitions by a store operation.
+ }], "bool", "requiresVisitingMutatedDefs", (ins), [{}],
+ [{ return false; }]
+ >,
+ InterfaceMethod<[{
+ Visits all the mutated definitions by a store operation.
+
+ This method will only be called after all blocking issues haven been
+ scheduled for removal and if `requiresVisitingMutatedDefs` returned
+ true.
+
+ The rewriter is located after the promotable operation on call. All IR
+ mutations must happen through the rewriter. During the transformation,
+ *no operation should be deleted*.
+ }],
+ "void", "visitMutatedDefs",
+ (ins "::llvm::ArrayRef<std::pair<::mlir::Operation*, ::mlir::Value>>":$mutatedDefs,
+ "::mlir::RewriterBase &":$rewriter), [{}], [{ return; }]
+ >,
];
}
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMMemorySlot.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMMemorySlot.cpp
index f171bf7cc4bec3..b5c5f4454dede9 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMMemorySlot.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMMemorySlot.cpp
@@ -166,13 +166,6 @@ bool LLVM::StoreOp::canUsesBeRemoved(
DeletionKind LLVM::StoreOp::removeBlockingUses(
const MemorySlot &slot, const SmallPtrSetImpl<OpOperand *> &blockingUses,
RewriterBase &rewriter, Value reachingDefinition) {
- // `canUsesBeRemoved` checked this blocking use must be the stored slot
- // pointer.
- for (Operation *user : slot.ptr.getUsers())
- if (auto declareOp = dyn_cast<LLVM::DbgDeclareOp>(user))
- rewriter.create<LLVM::DbgValueOp>(declareOp->getLoc(), getValue(),
- declareOp.getVarInfo(),
- declareOp.getLocationExpr());
return DeletionKind::Delete;
}
@@ -405,6 +398,18 @@ DeletionKind LLVM::DbgValueOp::removeBlockingUses(
return DeletionKind::Keep;
}
+bool LLVM::DbgDeclareOp::requiresVisitingMutatedDefs() { return true; }
+
+void LLVM::DbgDeclareOp::visitMutatedDefs(
+ ArrayRef<std::pair<Operation *, Value>> definitions,
+ RewriterBase &rewriter) {
+ for (auto [op, value] : definitions) {
+ rewriter.setInsertionPointAfter(op);
+ rewriter.create<LLVM::DbgValueOp>(getLoc(), value, getVarInfo(),
+ getLocationExpr());
+ }
+}
+
//===----------------------------------------------------------------------===//
// Interfaces for GEPOp
//===----------------------------------------------------------------------===//
diff --git a/mlir/lib/Transforms/Mem2Reg.cpp b/mlir/lib/Transforms/Mem2Reg.cpp
index 80e3b790163297..3aca5eb19ff5af 100644
--- a/mlir/lib/Transforms/Mem2Reg.cpp
+++ b/mlir/lib/Transforms/Mem2Reg.cpp
@@ -202,6 +202,7 @@ class MemorySlotPromoter {
/// Contains the reaching definition at this operation. Reaching definitions
/// are only computed for promotable memory operations with blocking uses.
DenseMap<PromotableMemOpInterface, Value> reachingDefs;
+ DenseMap<PromotableMemOpInterface, Value> mutatedValues;
DominanceInfo &dominance;
MemorySlotPromotionInfo info;
const Mem2RegStatistics &statistics;
@@ -438,6 +439,7 @@ Value MemorySlotPromoter::computeReachingDefInBlock(Block *block,
assert(stored && "a memory operation storing to a slot must provide a "
"new definition of the slot");
reachingDef = stored;
+ mutatedValues[memOp] = stored;
}
}
}
@@ -552,6 +554,8 @@ void MemorySlotPromoter::removeBlockingUses() {
dominanceSort(usersToRemoveUses, *slot.ptr.getParentBlock()->getParent());
llvm::SmallVector<Operation *> toErase;
+ llvm::SmallVector<std::pair<Operation *, Value>> mutatedDefinitions;
+ llvm::SmallVector<PromotableOpInterface> visitMutatedDefinitions;
for (Operation *toPromote : llvm::reverse(usersToRemoveUses)) {
if (auto toPromoteMemOp = dyn_cast<PromotableMemOpInterface>(toPromote)) {
Value reachingDef = reachingDefs.lookup(toPromoteMemOp);
@@ -565,7 +569,9 @@ void MemorySlotPromoter::removeBlockingUses() {
slot, info.userToBlockingUses[toPromote], rewriter,
reachingDef) == DeletionKind::Delete)
toErase.push_back(toPromote);
-
+ if (toPromoteMemOp.storesTo(slot))
+ if (Value mutatedValue = mutatedValues[toPromoteMemOp])
+ mutatedDefinitions.push_back({toPromoteMemOp, mutatedValue});
continue;
}
@@ -574,6 +580,12 @@ void MemorySlotPromoter::removeBlockingUses() {
if (toPromoteBasic.removeBlockingUses(info.userToBlockingUses[toPromote],
rewriter) == DeletionKind::Delete)
toErase.push_back(toPromote);
+ if (toPromoteBasic.requiresVisitingMutatedDefs())
+ visitMutatedDefinitions.push_back(toPromoteBasic);
+ }
+ for (PromotableOpInterface op : visitMutatedDefinitions) {
+ rewriter.setInsertionPointAfter(op);
+ op.visitMutatedDefs(mutatedDefinitions, rewriter);
}
for (Operation *toEraseOp : toErase)
>From 9e85edd6c7ad0d9b5abf3031a25f3d067d9183fc Mon Sep 17 00:00:00 2001
From: Fabian Mora <fmora.dev at gmail.com>
Date: Wed, 27 Mar 2024 09:10:14 -0400
Subject: [PATCH 2/2] Update
mlir/include/mlir/Interfaces/MemorySlotInterfaces.td
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: Théo Degioanni <30992420+Moxinilian at users.noreply.github.com>
---
mlir/include/mlir/Interfaces/MemorySlotInterfaces.td | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mlir/include/mlir/Interfaces/MemorySlotInterfaces.td b/mlir/include/mlir/Interfaces/MemorySlotInterfaces.td
index af120eb059aebf..abc333f3b10f4c 100644
--- a/mlir/include/mlir/Interfaces/MemorySlotInterfaces.td
+++ b/mlir/include/mlir/Interfaces/MemorySlotInterfaces.td
@@ -238,7 +238,7 @@ def PromotableOpInterface : OpInterface<"PromotableOpInterface"> {
InterfaceMethod<[{
Visits all the mutated definitions by a store operation.
- This method will only be called after all blocking issues haven been
+ This method will only be called after all blocking uses have been
scheduled for removal and if `requiresVisitingMutatedDefs` returned
true.
More information about the Mlir-commits
mailing list