RFR: 8355970: C2: Add command line option to print the compile phases
Manuel Hässig
mhaessig at openjdk.org
Mon May 12 13:08:24 UTC 2025
This PR introduces the flag `-XX:PrintPhaseLevel` that works like the flag `-XX:PrintIdealGraphLevel` and prints the name phases of a C2 compilation (essentially what we have in the left side bar in IGV) to the terminal. This allows redirecting the output to a file and comparing phase decisions between two compilations. Further, it is useful in conjunction with loop opts tracing to immediately see in which phase a certain optimization happened.
<details>
<summary>Output with `-XX:PrintPhaseLevel=2`</summary>
> java-fastdebug -Xbatch -XX:CompileCommand=compileonly,TestLoop.test10 -XX:CompileCommand=printcompilation,TestLoop.test* -XX:PrintPhaseLevel=2 TestLoop.java
CompileCommand: compileonly TestLoop.test10 bool compileonly = true
CompileCommand: PrintCompilation TestLoop.test* bool PrintCompilation = true
3577 98 % b 3 TestLoop::test10 @ 2 (64 bytes)
3584 99 b 3 TestLoop::test10 (64 bytes)
3648 100 % b 4 TestLoop::test10 @ 2 (64 bytes)
1. After Parsing
2. Iter GVN 1
3. Incremental Inline
4. Incremental Boxing Inline
5. Before Loop Optimizations
6. PhaseIdealLoop 1
7. PhaseIdealLoop 2
8. PhaseIdealLoop 3
9. Before PhaseCCP 1
10. PhaseCCP 1
11. Iter GVN 2
12. PhaseIdealLoop iterations
13. After Loop Optimizations
14. After Macro Expansion
15. Barrier expand
16. Optimize finished
17. Before matching
18. After matching
19. Global code motion
20. Register Allocation
21. Final Code
3668 103 b 4 TestLoop::test10 (64 bytes)
1. After Parsing
2. Iter GVN 1
3. Incremental Inline
4. Incremental Boxing Inline
5. Before Loop Optimizations
6. PhaseIdealLoop 1
7. PhaseIdealLoop 2
8. PhaseIdealLoop 3
9. Before PhaseCCP 1
10. PhaseCCP 1
11. Iter GVN 2
12. PhaseIdealLoop iterations
13. PhaseIdealLoop iterations 2
14. PhaseIdealLoop iterations 3
15. PhaseIdealLoop iterations 4
16. PhaseIdealLoop iterations 5
17. PhaseIdealLoop iterations 6
18. PhaseIdealLoop iterations 7
19. PhaseIdealLoop iterations 8
20. PhaseIdealLoop iterations 9
21. After Loop Optimizations
22. After Macro Expansion
23. Barrier expand
24. Optimize finished
25. Before matching
26. After matching
27. Global code motion
28. Register Allocation
29. Final Code
</details>
<details>
<summary>Output with `-XX:PrintPhaseLevel=2` in conjunction with loop opt tracing</summary>
> java-fastdebug -Xbatch -XX:CompileCommand=compileonly,TestLoop.test* -XX:CompileCommand=printcompilation,TestLoop.test* -XX:+TraceNewVectors -XX:+TraceLoopOpts -XX:PrintPhaseLevel=2 TestLoop.java
CompileCommand: compileonly TestLoop.test* bool compileonly = true
CompileCommand: PrintCompilation TestLoop.test* bool PrintCompilation = true
3016 98 % b 3 TestLoop::test10 @ 2 (64 bytes)
3040 99 b 3 TestLoop::test10 (64 bytes)
3097 100 % b 4 TestLoop::test10 @ 2 (64 bytes)
1. After Parsing
2. Iter GVN 1
3. Incremental Inline
4. Incremental Boxing Inline
5. Before Loop Optimizations
Loop: N0/N0 has_sfpt
Loop: N1894/N1845 limit_check profile_predicated predicated sfpts={ 1845 }
Predicate IC Loop: N1894/N1845 limit_check profile_predicated predicated sfpts={ 1845 }
Predicate IC Loop: N1894/N1845 limit_check profile_predicated predicated sfpts={ 1845 }
Predicate IC Loop: N1894/N1845 limit_check profile_predicated predicated sfpts={ 1845 }
Predicate IC Loop: N1894/N1845 limit_check profile_predicated predicated sfpts={ 1845 }
Predicate IC Loop: N1894/N1845 limit_check profile_predicated predicated sfpts={ 1845 }
Predicate IC Loop: N1894/N1845 limit_check profile_predicated predicated sfpts={ 1845 }
Predicate IC Loop: N1894/N1845 limit_check profile_predicated predicated sfpts={ 1845 }
Predicate IC Loop: N1894/N1845 limit_check profile_predicated predicated sfpts={ 1845 }
Predicate IC Loop: N1894/N1845 limit_check profile_predicated predicated sfpts={ 1845 }
Predicate IC Loop: N1894/N1845 limit_check profile_predicated predicated sfpts={ 1845 }
Predicate IC Loop: N1894/N1845 limit_check profile_predicated predicated sfpts={ 1845 }
Predicate IC Loop: N1894/N1845 limit_check profile_predicated predicated sfpts={ 1845 }
Predicate IC Loop: N1894/N1845 limit_check profile_predicated predicated sfpts={ 1845 }
Predicate IC Loop: N1894/N1845 limit_check profile_predicated predicated sfpts={ 1845 }
Predicate IC Loop: N1894/N1845 limit_check profile_predicated predicated sfpts={ 1845 }
Predicate IC Loop: N1894/N1845 limit_check profile_predicated predicated sfpts={ 1845 }
Predicate IC Loop: N1894/N1845 limit_check profile_predicated predicated sfpts={ 1845 }
6. PhaseIdealLoop 1
Loop: N0/N0 has_sfpt
Loop: N1894/N1845 limit_check profile_predicated predicated sfpts={ 1845 }
7. PhaseIdealLoop 2
Loop: N0/N0 has_sfpt
Loop: N1894/N1845 limit_check profile_predicated predicated sfpts={ 1845 }
8. PhaseIdealLoop 3
9. Before PhaseCCP 1
10. PhaseCCP 1
11. Iter GVN 2
Loop: N0/N0 has_sfpt
Loop: N1894/N1845 limit_check profile_predicated predicated sfpts={ 1845 }
PredicatesOff
12. PhaseIdealLoop iterations
Loop: N0/N0 has_sfpt
Loop: N1894/N1845 profile_predicated predicated sfpts={ 1845 }
13. After Loop Optimizations
14. After Macro Expansion
15. Barrier expand
16. Optimize finished
17. Before matching
18. After matching
19. Global code motion
20. Register Allocation
21. Final Code
3126 103 b 4 TestLoop::test10 (64 bytes)
1. After Parsing
2. Iter GVN 1
3. Incremental Inline
4. Incremental Boxing Inline
5. Before Loop Optimizations
Loop: N0/N0 has_sfpt
Loop: N1912/N1855 limit_check profile_predicated predicated sfpts={ 1777 }
6. PhaseIdealLoop 1
Counted Loop: N1924/N1855 limit_check profile_predicated predicated sfpts={ 1777 }
Loop: N0/N0 has_sfpt
Loop: N1924/N1855 limit_check profile_predicated predicated sfpts={ 1777 }
Predicate IC Loop: N1924/N1855 limit_check profile_predicated predicated sfpts={ 1777 }
Predicate IC Loop: N1924/N1855 limit_check profile_predicated predicated sfpts={ 1777 }
Predicate IC Loop: N1924/N1855 limit_check profile_predicated predicated sfpts={ 1777 }
Predicate IC Loop: N1924/N1855 limit_check profile_predicated predicated sfpts={ 1777 }
Predicate IC Loop: N1924/N1855 limit_check profile_predicated predicated sfpts={ 1777 }
Predicate IC Loop: N1924/N1855 limit_check profile_predicated predicated sfpts={ 1777 }
Predicate IC Loop: N1924/N1855 limit_check profile_predicated predicated sfpts={ 1777 }
Predicate IC Loop: N1924/N1855 limit_check profile_predicated predicated sfpts={ 1777 }
Predicate IC Loop: N1924/N1855 limit_check profile_predicated predicated sfpts={ 1777 }
Predicate IC Loop: N1924/N1855 limit_check profile_predicated predicated sfpts={ 1777 }
Predicate IC Loop: N1924/N1855 limit_check profile_predicated predicated sfpts={ 1777 }
Predicate IC Loop: N1924/N1855 limit_check profile_predicated predicated sfpts={ 1777 }
Predicate IC Loop: N1924/N1855 limit_check profile_predicated predicated sfpts={ 1777 }
Predicate IC Loop: N1924/N1855 limit_check profile_predicated predicated sfpts={ 1777 }
Predicate IC Loop: N1924/N1855 limit_check profile_predicated predicated sfpts={ 1777 }
Predicate IC Loop: N1924/N1855 limit_check profile_predicated predicated sfpts={ 1777 }
7. PhaseIdealLoop 2
Loop: N0/N0 has_sfpt
Loop: N1924/N1855 limit_check profile_predicated predicated sfpts={ 1777 }
Peel Loop: N2112/N1855 sfpts={ 1777 }
Exceeding node budget: 0 < 141
8. PhaseIdealLoop 3
9. Before PhaseCCP 1
10. PhaseCCP 1
11. Iter GVN 2
Counted Loop: N2288/N1855 counted [1,int),+1 (-1 iters)
Loop: N0/N0 has_sfpt
Loop: N2088/N2085 limit_check profile_predicated predicated sfpts={ 2168 }
Loop: N2287/N2286 limit_check profile_predicated predicated
Loop: N2288/N1855 limit_check profile_predicated predicated counted [1,int),+1 (-1 iters) has_sfpt strip_mined
Predicate RC Loop: N2288/N1855 limit_check profile_predicated predicated counted [1,int),+1 (40920 iters) has_sfpt rce strip_mined
12. PhaseIdealLoop iterations
Loop: N0/N0 has_sfpt
Loop: N2088/N2085 limit_check profile_predicated predicated sfpts={ 2168 }
Loop: N2287/N2286 limit_check profile_predicated predicated sfpts={ 2289 }
Loop: N2288/N1855 limit_check profile_predicated predicated counted [1,int),+1 (40920 iters) rc has_sfpt strip_mined
PreMainPost Loop: N2288/N1855 limit_check profile_predicated predicated counted [1,int),+1 (40920 iters) rc has_sfpt strip_mined
Unroll 2 Loop: N2288/N1855 limit_check counted [int,int),+1 (40920 iters) main rc has_sfpt strip_mined
13. PhaseIdealLoop iterations 2
Loop: N0/N0 has_sfpt
Loop: N2088/N2085 limit_check profile_predicated predicated sfpts={ 2168 }
Loop: N2499/N2498 limit_check profile_predicated predicated counted [1,int),+1 (4 iters) pre rc
Loop: N2287/N2286 limit_check sfpts={ 2289 }
Loop: N2611/N1855 limit_check counted [int,int),+2 (40920 iters) main rc has_sfpt strip_mined
Loop: N2402/N2401 limit_check counted [int,int),+1 (4 iters) post rc
Unroll 4 Loop: N2611/N1855 limit_check counted [int,int),+2 (40920 iters) main rc has_sfpt rce strip_mined
14. PhaseIdealLoop iterations 3
Loop: N0/N0 has_sfpt
Loop: N2088/N2085 limit_check profile_predicated predicated sfpts={ 2168 }
Loop: N2499/N2498 limit_check profile_predicated predicated counted [1,int),+1 (4 iters) pre rc
Loop: N2287/N2286 limit_check sfpts={ 2289 }
Loop: N2741/N1855 limit_check counted [int,int),+4 (40920 iters) main rc has_sfpt strip_mined
Loop: N2402/N2401 limit_check counted [int,int),+1 (4 iters) post rc
Peel Loop: N2875/N1855 has_sfpt rce
Exceeding node budget: 0 < 258
15. PhaseIdealLoop iterations 4
Counted Loop: N3236/N1855 counted [4,int),+4 (-1 iters)
Loop: N0/N0 has_sfpt
Loop: N2088/N2085 limit_check profile_predicated predicated sfpts={ 2168 }
Loop: N2499/N2498 limit_check profile_predicated predicated counted [1,int),+1 (4 iters) pre rc
Loop: N2852/N2849 limit_check sfpts={ 3057 }
Loop: N3235/N3234 limit_check profile_predicated predicated
Loop: N3236/N1855 limit_check profile_predicated predicated counted [4,int),+4 (-1 iters) has_sfpt strip_mined
Loop: N2402/N2401 limit_check counted [int,int),+1 (4 iters) post rc
Predicate RC Loop: N3236/N1855 limit_check profile_predicated predicated counted [4,int),+4 (40920 iters) has_sfpt rce strip_mined
Predicate RC Loop: N3236/N1855 limit_check profile_predicated predicated counted [4,int),+4 (40920 iters) has_sfpt rce strip_mined
Predicate RC Loop: N3236/N1855 limit_check profile_predicated predicated counted [4,int),+4 (40920 iters) has_sfpt rce strip_mined
16. PhaseIdealLoop iterations 5
Loop: N0/N0 has_sfpt
Loop: N2088/N2085 limit_check profile_predicated predicated sfpts={ 2168 }
Loop: N2499/N2498 limit_check profile_predicated predicated counted [1,int),+1 (4 iters) pre rc
Loop: N2852/N2849 limit_check sfpts={ 3057 }
Loop: N3235/N3234 limit_check profile_predicated predicated sfpts={ 3237 }
Loop: N3236/N1855 limit_check profile_predicated predicated counted [4,int),+4 (40920 iters) rc has_sfpt strip_mined
Loop: N2402/N2401 limit_check counted [int,int),+1 (4 iters) post rc
PreMainPost Loop: N3236/N1855 limit_check profile_predicated predicated counted [4,int),+4 (40920 iters) rc has_sfpt strip_mined
Unroll 2 Loop: N3236/N1855 limit_check counted [int,int),+4 (40920 iters) main rc has_sfpt strip_mined
Exceeding node budget: 479 < 569
17. PhaseIdealLoop iterations 6
Loop: N0/N0 has_sfpt
Loop: N2088/N2085 limit_check profile_predicated predicated sfpts={ 2168 }
Loop: N2499/N2498 limit_check profile_predicated predicated counted [1,int),+1 (4 iters) pre rc
Loop: N2852/N2849 limit_check sfpts={ 3057 }
Loop: N3795/N3799 limit_check profile_predicated predicated counted [4,int),+4 (4 iters) pre rc
Loop: N3235/N3234 limit_check sfpts={ 3237 }
Loop: N4050/N1855 limit_check counted [int,int),+8 (40920 iters) main rc has_sfpt strip_mined
Loop: N3562/N3566 limit_check counted [int,int),+4 (4 iters) post rc
Loop: N2402/N2401 limit_check counted [int,int),+1 (4 iters) post rc
Peel Loop: N4281/N1855 has_sfpt rce
Exceeding node budget: 0 < 196
18. PhaseIdealLoop iterations 7
Counted Loop: N4512/N1855 counted [8,int),+8 (-1 iters)
Loop: N0/N0 has_sfpt
Loop: N2088/N2085 limit_check profile_predicated predicated sfpts={ 2168 }
Loop: N2499/N2498 limit_check profile_predicated predicated counted [1,int),+1 (4 iters) pre rc
Loop: N2852/N2849 limit_check sfpts={ 3057 }
Loop: N3795/N3799 limit_check profile_predicated predicated counted [4,int),+4 (4 iters) pre rc
Loop: N4258/N4255 limit_check sfpts={ 4402 }
Loop: N4511/N4510 limit_check profile_predicated predicated
Loop: N4512/N1855 limit_check profile_predicated predicated counted [8,int),+8 (-1 iters) has_sfpt strip_mined
Loop: N3562/N3566 limit_check counted [int,int),+4 (4 iters) post rc
Loop: N2402/N2401 limit_check counted [int,int),+1 (4 iters) post rc
PreMainPost Loop: N4512/N1855 limit_check profile_predicated predicated counted [8,int),+8 (40920 iters) has_sfpt rce strip_mined
RangeCheck Loop: N4512/N1855 counted [int,int),+8 (40920 iters) main has_sfpt rce strip_mined
19. PhaseIdealLoop iterations 8
Loop: N0/N0 has_sfpt
Loop: N2088/N2085 limit_check profile_predicated predicated sfpts={ 2168 }
Loop: N2499/N2498 limit_check profile_predicated predicated counted [1,int),+1 (4 iters) pre rc
Loop: N2852/N2849 limit_check sfpts={ 3057 }
Loop: N3795/N3799 limit_check profile_predicated predicated counted [4,int),+4 (4 iters) pre rc
Loop: N4258/N4255 limit_check sfpts={ 4402 }
Loop: N4731/N4737 limit_check profile_predicated predicated counted [8,int),+8 (4 iters) pre rc
Loop: N4511/N4510 limit_check sfpts={ 4513 }
Loop: N4512/N1855 limit_check counted [int,int),+8 (40920 iters) main rc has_sfpt strip_mined
Loop: N4616/N4622 counted [int,int),+8 (4 iters) post rc
Loop: N3562/N3566 limit_check counted [int,int),+4 (4 iters) post rc
Loop: N2402/N2401 limit_check counted [int,int),+1 (4 iters) post rc
PredicatesOff
20. PhaseIdealLoop iterations 9
Loop: N0/N0 has_sfpt
Loop: N2088/N2085 predicated sfpts={ 2168 }
Loop: N2499/N2498 predicated counted [1,int),+1 (4 iters) pre rc
Loop: N2852/N2849 limit_check sfpts={ 3057 }
Loop: N3795/N3799 predicated counted [4,int),+4 (4 iters) pre rc
Loop: N4258/N4255 limit_check sfpts={ 4402 }
Loop: N4731/N4737 counted [8,int),+8 (4 iters) pre rc
Loop: N4511/N4510 limit_check sfpts={ 4513 }
Loop: N4512/N1855 limit_check counted [int,int),+8 (40920 iters) main rc has_sfpt strip_mined
Loop: N4616/N4622 counted [int,int),+8 (4 iters) post rc
Loop: N3562/N3566 limit_check counted [int,int),+4 (4 iters) post rc
Loop: N2402/N2401 limit_check counted [int,int),+1 (4 iters) post rc
21. After Loop Optimizations
22. After Macro Expansion
23. Barrier expand
24. Optimize finished
25. Before matching
26. After matching
27. Global code motion
28. Register Allocation
29. Final Code
</details>
## Testing
- [ ] [Github Actions](https://github.com/mhaessig/jdk/actions/runs/14972614510)
- [ ] tier1 through tier3 on Oracle supported platforms and OSs plus Oracle internal testing
- [ ] tier1 through tier2 with `-XX:PrintPhaseLevel=4`
-------------
Commit messages:
- Introduce PrintPhaseLevel flag
- Rename IR printing functions
Changes: https://git.openjdk.org/jdk/pull/25183/files
Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=25183&range=00
Issue: https://bugs.openjdk.org/browse/JDK-8355970
Stats: 41 lines in 5 files changed: 33 ins; 0 del; 8 mod
Patch: https://git.openjdk.org/jdk/pull/25183.diff
Fetch: git fetch https://git.openjdk.org/jdk.git pull/25183/head:pull/25183
PR: https://git.openjdk.org/jdk/pull/25183
More information about the hotspot-compiler-dev
mailing list