Skip to content
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

[TIR][Transform] Optional data-flow analysis in RemoveNoOp #13217

Merged
merged 2 commits into from
Nov 25, 2022

Conversation

Lunderberg
Copy link
Contributor

Previously, RemoveNoOp would remove statements that could be locally analyzed as having no effect (e.g. For with empty loop extents). This commit adds opt-in use of data-flow analysis to identify two types of statements that are no-ops based on their context:

  • Buffer stores that are overwritten without ever being read.

    buf[i] = 5 # Overwritten by next statement
    buf[i] = 10
  • Storing a value that is already known to be present.

    buf[0:16] = T.ramp(0, 16, 1)
    buf[5] = 5 # Previous load already stored this value

@tvm-bot
Copy link
Collaborator

tvm-bot commented Oct 27, 2022

Thanks for contributing to TVM! Please refer to the contributing guidelines https://tvm.apache.org/docs/contribute/ for useful information and tips. Please request code reviews from Reviewers by @-ing them in a comment.

Generated by tvm-bot

@Lunderberg
Copy link
Contributor Author

This PR is currently a draft, as its branch includes #13130. To maintain independent commits, this will be rebased onto main later.

@Lunderberg Lunderberg force-pushed the dataflow_remove_no_op branch 2 times, most recently from 118693c to bf5df93 Compare October 31, 2022 15:09
@Lunderberg Lunderberg force-pushed the dataflow_remove_no_op branch from bf5df93 to 9344280 Compare November 4, 2022 21:42
@Lunderberg
Copy link
Contributor Author

@tvm-bot rerun

@Lunderberg Lunderberg force-pushed the dataflow_remove_no_op branch 2 times, most recently from 606f744 to 2467e29 Compare November 17, 2022 17:35
@Lunderberg Lunderberg marked this pull request as ready for review November 17, 2022 17:36
@masahi
Copy link
Member

masahi commented Nov 21, 2022

@tvm-bot rerun

Previously, `RemoveNoOp` would remove statements that could be locally
analyzed as having no effect (e.g. `For` with empty loop extents).
This commit adds opt-in use of data-flow analysis to identify
two types of statements that are no-ops based on their context:

* Buffer stores that are overwritten without ever being read.

  ```python
  buf[i] = 5 # Overwritten by next statement
  buf[i] = 10
  ```

* Storing a value that is already known to be present.

  ```python
  buf[0:16] = T.ramp(0, 16, 1)
  buf[5] = 5 # Previous load already stored this value
  ```
@Lunderberg Lunderberg force-pushed the dataflow_remove_no_op branch from 2467e29 to aa4206d Compare November 22, 2022 17:57
@Lunderberg
Copy link
Contributor Author

Looks like it's currently a compile-time failure, though I'm not sure why. I found a missing #include <algorithm>, which hadn't been caught by include_what_you_use, but I'd expect that to cause other issues if it were the problem. Rebasing onto main in case there were CI-related changes since the previous rebase.

@Lunderberg
Copy link
Contributor Author

It made it past the compilation stage, so the rebase resolved that issue. Still running into the crash in test_te_schedule_ops.py, due to a double free or corruption. Valgrind complains quite loudly about invalid reads. Other than some caused by the python interpreter's malloc, valgrind is silent when run on main, so it's definitely something triggered by this PR in particular.

@Lunderberg
Copy link
Contributor Author

Found it!

The std::unordered_map<const VarNode*, Range> var_range_map_ has a non-owning const VarNode*. When this is used for arith::EvalSet, it converts it to an owning Map<Var, Range> using GetRef<Var>(var_ptr). However, there's no guarantee that the Var still exists by that point. If extent is negative, then the loop variable in var_range_map_ is never removed. If there are no other references to the loop variable, then the map will hold a dangling pointer, and the next loop to be examined will have invalid memory access.

Moving the update of var_range_map_ to be after the check for negative extents instead of before avoids these dangling pointers, and passes local valgrind checks.

Copy link
Member

@masahi masahi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very cool feature and interesting test cases!

@masahi masahi merged commit 101e3a4 into apache:main Nov 25, 2022
@Lunderberg Lunderberg deleted the dataflow_remove_no_op branch November 28, 2022 14:14
Lunderberg added a commit to Lunderberg/tvm that referenced this pull request Apr 7, 2023
This simplification was introduced in
apache#13217, and was erroneously removed
in apache#13933.  This commit re-enables
this simplification, and adds unit tests to prevent any future
regression.
areusch pushed a commit that referenced this pull request Apr 7, 2023
This simplification was introduced in
#13217, and was erroneously removed
in #13933.  This commit re-enables
this simplification, and adds unit tests to prevent any future
regression.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants