This patch extends the Region, Block and Operation visitors to also support pre-order walks.
We introduce a new template argument that dictates the walk order (only pre-order and
post-order are supported for now). The default order for Regions, Blocks and Operations is
post-order. Mixed orders (e.g., Region/Block pre-order + Operation post-order) could easily
be implemented, as shown in NumberOfExecutions.cpp.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
mlir/lib/IR/Visitors.cpp | ||
---|---|---|
39 | Walk implementation for Region and Block callbacks above seems to be already happening in pre-order. Is this expected? I found this a bit confusing since the traversal for Operation callbacks is in post-order by default.
WDYT? |
Looks mostly good. My main comment is that I would not use a boolean for the template argument, it is very ambiguous what true/false means. Can you use something like an enum instead?
mlir/lib/IR/Visitors.cpp | ||
---|---|---|
39 | I would ensure that everything has the same default behavior. So I think option 1 (If I'm reading that right). |
Please also see: https://github.com/tensorflow/tensorflow/blob/master/tensorflow/compiler/mlir/tensorflow/utils/visitor_util.h
Thanks for the pointer! It would be great to have something as generic as that visitor in the mlir repo!
Can you use something like an enum instead?
Sure!
mlir/lib/IR/Visitors.cpp | ||
---|---|---|
39 | Yes, that's #1. I'll give it a try. Hopefully, changing the current default behavior doesn't require too many changes. |
Very useful. Thanks!
mlir/lib/IR/Visitors.cpp | ||
---|---|---|
39 | I found this strange, too. I believe the liveness analysis, or at least its tests, depend on this behaviour. #1 sounds like the way to go. |
Addressing feedback:
- Use enum to encode walk order.
- Set region, block and operation walks to post-order by default.
- Adjust walks in Liveness and NumberOfExecutions to align with the new default traversal.
LGTM after resolving last comment.
mlir/lib/IR/Visitors.cpp | ||
---|---|---|
17 | Can you just pass the order as an extra parameter? These methods represent the internal implementation of the walk methods, so I'm fine with adding more parameters here. That would also remove all of the templates within this file. |
mlir/lib/IR/Visitors.cpp | ||
---|---|---|
86 | There is a typo here: op -> block. | |
91 | Side note: why aren't we using early increment here? This can be done in separate revision but it could be dangerous/annoying to have subtly different iterator invalidation semantics for these different versions. Also, I think these semantics aren't documented on the walk methods. We have the same issue at at least one more instance above as well. |
This is nice! Thanks. Just a typo I caught. I think we should fix the iteration invalidation semantics in a subsequent revision (I can do that if you want.)
- Passing order as an extra parameter.
- Fixing typo.
I'll commit this tomorrow if no further comments.
mlir/lib/IR/Visitors.cpp | ||
---|---|---|
86 | removed | |
91 | Good point! IIUC, the callback here is on the block. We invoke the callback before or after iterating over all the block's operations so the operation iteration wouldn't be invalidated even if the callback erased block's operations. It could invalidate the block iterator, though, if the block is erased... Yeah, it's a bit inconsistent. Maybe we should use early increments for all the region/block/operation iterators? I could quickly take care of it in a separate patch. |
This new diff introduces important changes to the previous version.
Hopefully, @rriddle/@frgossen/@bondhugula can take another look.
- Added new TestIRVisitors pass with basic testing for the IR visitors (I didn't feel very comfortable without it).
- Introduced 'Prune' as a new WalkResult. It should be used, for example, to skip the walk of an operation that has been erased in pre-order. Otherwise, the walk would recurse into the erased operation (thanks for reporting the issue, @sgrechanik!).
- Addressed @bondhugula's comment on early increment ranges. They are only needed for block and operation ranges since regions can't be directly erased (right?).
- Updated documentation to include erasure information and walk order information. The walk order information was misleading since it only refers to nested operations/block/regions. Operations in a block are always visited in lexicographical order regardless of the nesting order. Same for all the blocks in a region or all the regions in an op.
Please, let me know if the new doc makes more sense. We can iterate on it.
Thanks!
Can you separate out the prune functionality into a different commit?
I could commit the previous version of the patch as is (already approved) and then create a new review with the new changes. Would that work better?
If I removed only the prune part, the new testing pass would fail since we need the prune functionality for pre-order walks that erase ops.
Restoring previous approved version. I'll commit it if no more comments.
I'll create a separate review for the prune changes.
Can you just pass the order as an extra parameter? These methods represent the internal implementation of the walk methods, so I'm fine with adding more parameters here. That would also remove all of the templates within this file.