-
Notifications
You must be signed in to change notification settings - Fork 13.7k
Extend getBackwardSlice
to track values captured from above
#113478
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
`getBackwardsSlice` should track values captured by each op's region that it traverses, and follow those defs. However, there might be logic that depends on not traversing captured values so this change preserves the default behavior by hiding this logic behind the `omitUsesFromAbove` flag.
@llvm/pr-subscribers-mlir Author: Ian Wood (IanWood1) ChangesThis change modifies I'm looking for feedback on how to add this functionality (which I think should be default) without breaking users of Full diff: https://github.com/llvm/llvm-project/pull/113478.diff 2 Files Affected:
diff --git a/mlir/include/mlir/Analysis/SliceAnalysis.h b/mlir/include/mlir/Analysis/SliceAnalysis.h
index 99279fdfe427c8..a4f5d937cd51da 100644
--- a/mlir/include/mlir/Analysis/SliceAnalysis.h
+++ b/mlir/include/mlir/Analysis/SliceAnalysis.h
@@ -47,6 +47,11 @@ struct BackwardSliceOptions : public SliceOptions {
/// backward slice computation traverses block arguments and asserts that the
/// parent op has a single region with a single block.
bool omitBlockArguments = false;
+
+ /// When omitUsesFromAbove is true, the backward slice computation omits
+ /// traversing values that are captured from above.
+ /// TODO: this should default to `false` after users have been updated.
+ bool omitUsesFromAbove = true;
};
using ForwardSliceOptions = SliceOptions;
diff --git a/mlir/lib/Analysis/SliceAnalysis.cpp b/mlir/lib/Analysis/SliceAnalysis.cpp
index 2b1cf411ceeeeb..d07ae7b3ffa2c7 100644
--- a/mlir/lib/Analysis/SliceAnalysis.cpp
+++ b/mlir/lib/Analysis/SliceAnalysis.cpp
@@ -16,6 +16,7 @@
#include "mlir/IR/Operation.h"
#include "mlir/Interfaces/SideEffectInterfaces.h"
#include "mlir/Support/LLVM.h"
+#include "mlir/Transforms/RegionUtils.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
@@ -115,6 +116,19 @@ static void getBackwardSliceImpl(Operation *op,
}
}
+ // Visit values that are defined above.
+ if (!options.omitUsesFromAbove) {
+ visitUsedValuesDefinedAbove(op->getRegions(), [&](OpOperand *operand) {
+ if (Operation *definingOp = operand->get().getDefiningOp()) {
+ getBackwardSliceImpl(definingOp, backwardSlice, options);
+ return;
+ }
+ Operation *bbAargOwner =
+ cast<BlockArgument>(operand->get()).getOwner()->getParentOp();
+ getBackwardSliceImpl(bbAargOwner, backwardSlice, options);
+ });
+ }
+
backwardSlice->insert(op);
}
|
The reverted commit does not handle when the "consumer" uses a value defined above. See #18879 for the original issue. This is causing issue with ~15 onnx models. I have a PR (#18855) to fix this by including values used in an ops region in the backwards slice, but It is waiting on upstream changes to `getBackwardSlice`. Currently, the PR is using a wrapper around `getBackwardSlice` to acheive the same effect, but this will be updated once the upstream change lands (llvm/llvm-project#113478) Reverts #18551 --------- Signed-off-by: Ian Wood <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good to me. You should add a test though. There are examples of tests for getBackwardSlice
in mlir/test
folder.
mlir/lib/Analysis/SliceAnalysis.cpp
Outdated
getBackwardSliceImpl(definingOp, backwardSlice, options); | ||
return; | ||
} | ||
Operation *bbAargOwner = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Operation *bbAargOwner = | |
if (options.omitBlockArguments) | |
return; | |
Operation *bbAargOwner = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I realized that I was duplicating all the logic within the for loop going over the operands. Instead, I changed it to iterate over a SetVector of the operands + used values defined above, which decreases logic duplication. However, this does mean we have to allocate space to store the operands in the SetVector
. But maybe this is fine?
mlir/lib/Analysis/SliceAnalysis.cpp
Outdated
getUsedValuesDefinedAbove(op->getRegions(), valuesToFollow); | ||
} | ||
|
||
for (const auto &en : llvm::enumerate(valuesToFollow)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The way you can make it "free" when there are no regions is to define this code as a lambda that operates on an ValueRange
.
auto processValues = [&] (ValueRange valuesToFollow) {
...
};
And then dispatch like this:
processValues(op->getOperands());
if (!options.omitUsesFromAbove) {
SetVector<Value> valuesToFollow;
getUsedValuesDefinedAbove(op->getRegions(), valuesToFollow);
processValues(valuesToFollow);
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you, that's a good solution.
I tweaked it a bit to take a Value
so it can get passed to visitValuesDefinedAbove
which takes a lambda with an OpOperand*
arg. This prevents storing the values in a set (backwardSlice->count
ensures they are still only visited once)
The reverted commit does not handle when the "consumer" uses a value defined above. See #18879 for the original issue. This is causing issue with ~15 onnx models. I have a PR (#18855) to fix this by including values used in an ops region in the backwards slice, but It is waiting on upstream changes to `getBackwardSlice`. Currently, the PR is using a wrapper around `getBackwardSlice` to acheive the same effect, but this will be updated once the upstream change lands (llvm/llvm-project#113478) Reverts #18551 --------- Signed-off-by: Ian Wood <[email protected]> Signed-off-by: Elias Joseph <[email protected]>
I reverted because the mlir-nvidia bot was broken:
You should be able to reproduce with |
Also FYI this has caused a different failure with Bazel https://buildkite.com/llvm-project/upstream-bazel/builds/115143#0192e378-3caf-494c-8647-7f50d4a17f77 The fix is not trivial due to a dependency cycle. the |
Yeah, looks like I forgot to update the cmake deps and didn't catch cyclic dependency. Also, new PR here #114452 |
This commit fixes the failure in the original PR when building with shared libs. The problem is that `visitUsedValuesDefinedAbove` is defined in `MLIRTransformUtils`, but that lib depends on this lib (`MLIRAnalysis`). To fix, I dropped the use of `visitUsedValuesDefinedAbove` and use `Region::walk` to traverse values defined above. Reapplies PR #113478 Reverts PR #114432 This reverts commit a9a8351.
…13478) This change modifies `getBackwardSlice` to track values captures by the regions of each operation that it traverses. Ignoring values captured from a parent region may lead to an incomplete program slice. However, there seems to be logic that depends on not traversing captured values, so this change preserves the default behavior by hiding this logic behind the `omitUsesFromAbove` flag.
llvm#114432) Reverts llvm#113478 Bot is broken when building with shared libs.
This commit fixes the failure in the original PR when building with shared libs. The problem is that `visitUsedValuesDefinedAbove` is defined in `MLIRTransformUtils`, but that lib depends on this lib (`MLIRAnalysis`). To fix, I dropped the use of `visitUsedValuesDefinedAbove` and use `Region::walk` to traverse values defined above. Reapplies PR llvm#113478 Reverts PR llvm#114432 This reverts commit a9a8351.
…13478) This change modifies `getBackwardSlice` to track values captures by the regions of each operation that it traverses. Ignoring values captured from a parent region may lead to an incomplete program slice. However, there seems to be logic that depends on not traversing captured values, so this change preserves the default behavior by hiding this logic behind the `omitUsesFromAbove` flag.
llvm#114432) Reverts llvm#113478 Bot is broken when building with shared libs.
This commit fixes the failure in the original PR when building with shared libs. The problem is that `visitUsedValuesDefinedAbove` is defined in `MLIRTransformUtils`, but that lib depends on this lib (`MLIRAnalysis`). To fix, I dropped the use of `visitUsedValuesDefinedAbove` and use `Region::walk` to traverse values defined above. Reapplies PR llvm#113478 Reverts PR llvm#114432 This reverts commit a9a8351.
…g#18917) The reverted commit does not handle when the "consumer" uses a value defined above. See iree-org#18879 for the original issue. This is causing issue with ~15 onnx models. I have a PR (iree-org#18855) to fix this by including values used in an ops region in the backwards slice, but It is waiting on upstream changes to `getBackwardSlice`. Currently, the PR is using a wrapper around `getBackwardSlice` to acheive the same effect, but this will be updated once the upstream change lands (llvm/llvm-project#113478) Reverts iree-org#18551 --------- Signed-off-by: Ian Wood <[email protected]> Signed-off-by: Giacomo Serafini <[email protected]>
This PR reverts the changes in #5203 that prevents reordering across scf ops Passes `omitUsesFromAbove=false` introduced in llvm/llvm-project#113478 `mlir::getBackwardSlice()`. This ensures that the backward slice captures the values used from above, in ops with nested regions, like scf ops.
This change modifies
getBackwardSlice
to track values captures by the regions of each operation that it traverses. Ignoring values captured from a parent region may lead to an incomplete program slice. However, there seems to be logic that depends on not traversing captured values, so this change preserves the default behavior by hiding this logic behind theomitUsesFromAbove
flag.I'm looking for feedback on how to add this functionality (which I think should be default) without breaking users of
getBackwardSlice