RFR: 8292660: C2: blocks made unreachable by NeverBranch-to-Goto conversion are removed incorrectly
Roberto Castañeda Lozano
rcastanedalo at openjdk.org
Tue Aug 23 10:24:12 UTC 2022
This changeset addresses three issues in the current removal of unreachable blocks after NeverBranch-to-goto conversion (introduced recently by [JDK-8292285](https://bugs.openjdk.org/browse/JDK-8292285)):
1. The [unreachable block removal and pre-order index update loop](https://github.com/openjdk/jdk/blob/7b5f9edb59ef763acca80724ca37f3624d720d06/src/hotspot/share/opto/block.cpp#L613-L621) skips the block next to the removed one, and iterates beyond the end of the block list (`PhaseCFG::_blocks`). Skipping blocks can lead to duplicate pre-order indices (`Block::_pre_order`) and/or pre-order indices greater than the size of the block list, causing problems in later transformations.
2. The [outer block traversal loop](https://github.com/openjdk/jdk/blob/7b5f9edb59ef763acca80724ca37f3624d720d06/src/hotspot/share/opto/block.cpp#L698-L729) iterates beyond the end of the block list whenever one or more unreachable blocks are removed.
3. Transitively unreachable blocks (such as B10 in the following example), arising in methods with multiple infinite loops, are not removed:

This changeset addresses issue 1 by decrementing the block count (`_number_of_blocks`) and block index (`i`) right after a block is removed from the block list, and issues 2 and 3 by decoupling NeverBranch-to-goto conversion from removal of unreachable code. Instead of removing the blocks eagerly, the removal is postponed to a second phase that works in an iterative worklist fashion, making it possible to remove transitively unreachable blocks such as B10 in the above example. For sanity, the changeset also ensures that reverse post-order indices (`Block::_rpo`) stay within the block list bounds, even though this does not seem to be assumed by any later transformation.
#### Testing
- tier1-3 (windows-x64, linux-x64, linux-aarch64, and macosx-x64; release and debug mode).
- tier4-5 (linux-x64; debug mode).
- tier1-3 (linux-x64; debug mode) using `-XX:-BlockLayoutByFrequency` (which interleaves NeverBranch-to-goto conversion with moving uncommon blocks to the end of the block list).
- fuzzing (~1 h. on each platform).
-------------
Commit messages:
- Remove quotes in comment
- Add test case with multiple infinite loops
- Postpone removal of unreachable blocks
Changes: https://git.openjdk.org/jdk/pull/9976/files
Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=9976&range=00
Issue: https://bugs.openjdk.org/browse/JDK-8292660
Stats: 127 lines in 3 files changed: 104 ins; 17 del; 6 mod
Patch: https://git.openjdk.org/jdk/pull/9976.diff
Fetch: git fetch https://git.openjdk.org/jdk pull/9976/head:pull/9976
PR: https://git.openjdk.org/jdk/pull/9976
More information about the hotspot-compiler-dev
mailing list