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