[Mlir-commits] [mlir] [mlir] Add a utility method to move operation dependencies. (PR #129975)
Ian Wood
llvmlistbot at llvm.org
Wed Mar 5 22:00:06 PST 2025
================
@@ -1054,3 +1057,65 @@ LogicalResult mlir::simplifyRegions(RewriterBase &rewriter,
return success(eliminatedBlocks || eliminatedOpsOrArgs ||
mergedIdenticalBlocks || droppedRedundantArguments);
}
+
+//===---------------------------------------------------------------------===//
+// Move operation dependencies
+//===---------------------------------------------------------------------===//
+
+LogicalResult mlir::moveOperationDependencies(RewriterBase &rewriter,
+ Operation *op,
+ Operation *insertionPoint,
+ DominanceInfo &dominance) {
+ // Currently unsupported case where the op and insertion point are
+ // in different basic blocks.
+ if (op->getBlock() != insertionPoint->getBlock()) {
+ return rewriter.notifyMatchFailure(
+ op, "unsupported caes where operation and insertion point are not in "
+ "the sme basic block");
+ }
+
+ // Find the backward slice of operation for each `Value` the operation
+ // depends on. Prune the slice to only include operations not already
+ // dominated by the `insertionPoint`
+ BackwardSliceOptions options;
+ options.inclusive = true;
+ options.filter = [&](Operation *sliceBoundaryOp) {
+ return !dominance.properlyDominates(sliceBoundaryOp, insertionPoint);
+ };
+ llvm::SetVector<Operation *> slice;
+
+ // Get the defined slice for operands.
+ for (Value operand : op->getOperands()) {
+ getBackwardSlice(operand, &slice, options);
+ }
+ auto regions = op->getRegions();
+ if (!regions.empty()) {
----------------
IanWood1 wrote:
I think this needs to be iterative. A chain of >1 "uses from above" will cause the transform to produce invalid IR:
```mlir
func.func @move_region_dependencies() -> f32 {
%0 = "before"() : () -> (f32)
%1 = "moved_op"() ({
"yield"(%0) : (f32) -> ()
}) : () -> (f32)
%2 = "foo"() ({
"yield"(%1) : (f32) -> ()
}) : () -> (f32)
return %2 : f32
}
module attributes {transform.with_named_sequence} {
transform.named_sequence @__transform_main(%arg0 : !transform.any_op {transform.readonly}) {
%op1 = transform.structured.match ops{["foo"]} in %arg0
: (!transform.any_op) -> !transform.any_op
%op2 = transform.structured.match ops{["before"]} in %arg0
: (!transform.any_op) -> !transform.any_op
transform.test.move_operand_deps %op1 before %op2
: !transform.any_op, !transform.any_op
transform.yield
}
}
```
`options.omitUsesFromAbove=false` could also work but you might hit the assert [here](https://github.com/llvm/llvm-project/blob/a6ccda28f7569c1a03620d7520de7cfadc11f4a5/mlir/lib/Analysis/SliceAnalysis.cpp#L109-L110).
Maybe this assert could just be removed and assume the user handles it with the filter function. The other overload of `getBackwardSlice` doesn't do this check on the initial `Value` see: https://github.com/llvm/llvm-project/blob/a6ccda28f7569c1a03620d7520de7cfadc11f4a5/mlir/lib/Analysis/SliceAnalysis.cpp#L156-L157
https://github.com/llvm/llvm-project/pull/129975
More information about the Mlir-commits
mailing list