Skip to content

Commit 626f44f

Browse files
committed
[mlir] notify insertion of parent op first when cloning
When cloning and operation with a region, the builder was currently notifying about the insertion of the cloned operations inside the region before the operation itself. When using cloning inside rewrite pass, this could cause issues if a pattern is expected to be applied on a cloned parent operation before trying to apply patterns on the cloned operations it contains because the patterns are attempted in order of notifications for the cloned operations.
1 parent 511ba45 commit 626f44f

File tree

3 files changed

+15
-2
lines changed

3 files changed

+15
-2
lines changed

mlir/lib/IR/Builders.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,7 @@ LogicalResult OpBuilder::tryFold(Operation *op,
527527

528528
Operation *OpBuilder::clone(Operation &op, IRMapping &mapper) {
529529
Operation *newOp = op.clone(mapper);
530+
newOp = insert(newOp);
530531
// The `insert` call below handles the notification for inserting `newOp`
531532
// itself. But if `newOp` has any regions, we need to notify the listener
532533
// about any ops that got inserted inside those regions as part of cloning.
@@ -537,7 +538,7 @@ Operation *OpBuilder::clone(Operation &op, IRMapping &mapper) {
537538
for (Region &region : newOp->getRegions())
538539
region.walk(walkFn);
539540
}
540-
return insert(newOp);
541+
return newOp;
541542
}
542543

543544
Operation *OpBuilder::clone(Operation &op) {

mlir/test/IR/test-clone.mlir

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: mlir-opt -allow-unregistered-dialect %s -pass-pipeline="builtin.module(func.func(test-clone))" -split-input-file
1+
// RUN: mlir-opt -allow-unregistered-dialect %s -pass-pipeline="builtin.module(func.func(test-clone))" | FileCheck %s
22

33
module {
44
func.func @fixpoint(%arg1 : i32) -> i32 {
@@ -9,6 +9,10 @@ module {
99
}
1010
}
1111

12+
// CHECK: notifyOperationInserted: test.use
13+
// CHECK-NEXT: notifyOperationInserted: test.yield
14+
// CHECK-NEXT: notifyOperationInserted: func.return
15+
1216
// CHECK: func @fixpoint(%[[arg0:.+]]: i32) -> i32 {
1317
// CHECK-NEXT: %[[i0:.+]] = "test.use"(%[[arg0]]) ({
1418
// CHECK-NEXT: "test.yield"(%arg0) : (i32) -> ()

mlir/test/lib/IR/TestClone.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@ using namespace mlir;
1414

1515
namespace {
1616

17+
struct DumpNotifications : public OpBuilder::Listener {
18+
void notifyOperationInserted(Operation *op) override {
19+
llvm::outs() << "notifyOperationInserted: " << op->getName() << "\n";
20+
}
21+
};
22+
1723
/// This is a test pass which clones the body of a function. Specifically
1824
/// this pass replaces f(x) to instead return f(f(x)) in which the cloned body
1925
/// takes the result of the first operation return as an input.
@@ -50,6 +56,8 @@ struct ClonePass
5056
}
5157

5258
OpBuilder builder(op->getContext());
59+
DumpNotifications dumpNotifications;
60+
builder.setListener(&dumpNotifications);
5361
builder.setInsertionPointToEnd(&regionEntry);
5462
SmallVector<Operation *> toClone;
5563
for (Operation &inst : regionEntry)

0 commit comments

Comments
 (0)