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

8295166: IGV: dump graph at more locations #16120

Closed
wants to merge 32 commits into from

Conversation

dlunde
Copy link
Member

@dlunde dlunde commented Oct 10, 2023

This changeset

  1. adds a number of new graph dumps for IdealGraphVisualizer (IGV):
    • Before conditional constant propagation
    • After register allocation
    • After block ordering
    • After peephole optimization
    • After post-allocation expansion
    • Before and after
      • loop predication
      • loop peeling
      • pre/main/post loops
      • loop unrolling
      • range check elimination
      • loop unswitching
      • partial peeling
      • split if
      • superword
  2. adds support for enumeration of repeated IGV graph dumps.
  3. adjusts IGV print levels to encompass the new graph dumps. The old levels 4 and 5 are now levels 5 and 6. The new level 4 is for loop optimization dumps.

Example phase list screenshots in IGV (first at level 6, second at level 4)
Screenshot from 2023-12-04 13-55-38 Screenshot from 2023-12-04 13-56-29

Some notes:

  • While discussing the above changes, a separate question was brought up by @chhagedorn:

    On a separate note, I'm wondering how useful it is to always dump all JFR events when calling print_method(). Should this be revisited again in general?

  • The new IGV graph dump enumeration enables a number of cleanups. There is now another RFE for IGV cleanup: JDK-8319599.

Testing

Platforms: windows-x64, linux-x64, linux-aarch64, macosx-x64, macosx-aarch64

  • tier1, tier2, tier3, tier4, tier5.
  • Check that optimized builds (--with-debug-level optimized) still work.

Platforms: linux-x64

  • Tested that thousands of graphs are correctly opened and visualized with IGV.

Progress

  • Change must be properly reviewed (1 review required, with at least 1 Reviewer)
  • Change must not contain extraneous whitespace
  • Commit message must refer to an issue

Issue

  • JDK-8295166: IGV: dump graph at more locations (Enhancement - P4)

Reviewers

Reviewing

Using git

Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/16120/head:pull/16120
$ git checkout pull/16120

Update a local copy of the PR:
$ git checkout pull/16120
$ git pull https://git.openjdk.org/jdk.git pull/16120/head

Using Skara CLI tools

Checkout this PR locally:
$ git pr checkout 16120

View PR using the GUI difftool:
$ git pr show -t 16120

Using diff file

Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/16120.diff

Webrev

Link to Webrev Comment

@bridgekeeper
Copy link

bridgekeeper bot commented Oct 10, 2023

👋 Welcome back dlunde! A progress list of the required criteria for merging this PR into master will be added to the body of your pull request. There are additional pull request commands available for use with this pull request.

@openjdk openjdk bot changed the title 8295166 8295166: IGV: dump graph at more locations Oct 10, 2023
@openjdk
Copy link

openjdk bot commented Oct 10, 2023

@dlunde The following label will be automatically applied to this pull request:

  • hotspot-compiler

When this pull request is ready to be reviewed, an "RFR" email will be sent to the corresponding mailing list. If you would like to change these labels, use the /label pull request command.

@openjdk openjdk bot added the hotspot-compiler hotspot-compiler-dev@openjdk.org label Oct 10, 2023
Copy link
Member

@TobiHartmann TobiHartmann left a comment

Choose a reason for hiding this comment

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

Nice enhancement! Looks good to me overall. Some comments below.

Please add an IGV screenshot of how the new phases look in the phase list.

Could you summarize which of the ideas / proposals from the RFE are not covered? We should file a follow-up RFE for them.

Many of the proposed dump locations are educated guesses. Should we adjust any of them?

They look good to me but let's see what others think.

Are the proposed levels (for PrintIdealGraphLevel) reasonable or should we adjust them? I put the loop optimization dumps at level 4 and adjusted IdealGraphVisualizer/README.md accordingly.

I think that's reasonable.

I put most new calls to print_method/print_method_iter within a NOT_PRODUCT. Is this OK?

Existing calls to print_method are not guarded because the method also commits a JFR event and updates Compile::_latest_stage_start_counter, so I think your new code should behave similar.

And please make sure that you verify that the 'optimized' build (--with-debug-level optimized) still works. It's a level between fastdebug and release where both #ifdef ASSERT and #ifdef PRODUCT are false.

int iter = ++_igv_phase_iter[cpt];
print_method(cpt, level, n, iter);
#else
print_method(cpt, level, n);
Copy link
Member

Choose a reason for hiding this comment

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

This is dead code because all calls are guarded by NOT_PRODUCT, right?

Copy link
Member Author

Choose a reason for hiding this comment

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

Not quite, there is one unguarded call for PHASE_PHASEIDEALLOOP_ITERATIONS at level 2. This is an existing phase that I converted from print_method to print_method_iter (as suggested by @chhagedorn in the issue corresponding to this PR).

Copy link
Member

@chhagedorn chhagedorn Nov 2, 2023

Choose a reason for hiding this comment

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

The current rule seems to be that we always want to emit a JFR event when dumping a graph - regardless of whether we dump a graph or not. I think we should follow this convention and remove the NOT_PRODUCT from the calls to print_method_iter().

On a separate note, I'm wondering how useful it is to always dump all events when calling print_method(). Should this be revisited again in general?

Copy link
Member Author

Choose a reason for hiding this comment

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

I have now incorporated the functionality of print_method_iter directly into print_method, and also removed all the NOT_PRODUCT wrappers.

I'm resolving this thread now, should we move the discussion regarding JFR event dumping somewhere else?

Copy link
Member

Choose a reason for hiding this comment

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

Maybe we can mention it as a side node in the PR description that it is something we should think about at some point. But it should not block this PR.

Copy link
Member Author

Choose a reason for hiding this comment

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

Sure, I'll add it to the final (non-draft) PR description.

@dlunde
Copy link
Member Author

dlunde commented Oct 13, 2023

Thanks for the review Tobias!

Please add an IGV screenshot of how the new phases look in the phase list.

I've attached two sample screenshots of the phase list (from running one of the tests in hotspot/jtreg/compiler/loopopts/PartialPeelingUnswitch.java). Note the enumeration of the loop optimizations and the attached target loop node indices.

Screenshot from 2023-10-13 12-59-22
Screenshot from 2023-10-13 12-59-53

Could you summarize which of the ideas / proposals from the RFE are not covered? We should file a follow-up RFE for them.

I believe I have covered everything in the RFE.

Existing calls to print_method are not guarded because the method also commits a JFR event and updates Compile::_latest_stage_start_counter, so I think your new code should behave similar.

Ah, I see. Note, however, that the existing call to print_method for PHASE_AFTER_ITER_GVN_STEP (at level 4) is guarded. Also, the bytecode printing (level 5) is guarded (although it does not use Compile::print_method).

And please make sure that you verify that the 'optimized' build (--with-debug-level optimized) still works. It's a level between fastdebug and release where both #ifdef ASSERT and #ifdef PRODUCT are false.

I'll make sure to include this when testing.

Copy link
Contributor

@robcasloz robcasloz left a comment

Choose a reason for hiding this comment

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

Hi Daniel, thanks for working on this! The code changes themselves look good, I have a few comments/suggestions:

  • It might make sense to create a new print level between current 3 and 4 including the new loop transformation dumps but not the individual IGVN step dumps.
  • I see the value in numbering the PHASE_PHASEIDEALLOOP_ITERATIONS dumps, but I am not sure numbering the new loop transformations is worth the additional complexity (_igv_phase_iter array, etc.). Limiting numbering to PHASE_PHASEIDEALLOOP_ITERATIONS dumps would not require any additional state in Compile.
  • In my opinion, it would be clearer to only dump loop transformations if they actually take place. I find it a bit confusing to see e.g. Before/After superword ... graph dumps when vectorization has actually failed and the graph has not changed at all. Dumping only after effective transformations would also match better the output of TraceLoopOpts. Enforcing this invariant would require getting rid of the Before... dumps though, but this is acceptable (and perhaps even preferable) in my opinion.

Copy link
Member

@chhagedorn chhagedorn left a comment

Choose a reason for hiding this comment

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

Thanks for working on this! This is a good addition and helps to better debug with IGV. I left a few comments with some suggestion and improvement ideas. I gave it some more thought to improve some of the places where we dump the phases and how. But this is of course open for discussion.

int iter = ++_igv_phase_iter[cpt];
print_method(cpt, level, n, iter);
#else
print_method(cpt, level, n);
Copy link
Member

@chhagedorn chhagedorn Nov 2, 2023

Choose a reason for hiding this comment

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

The current rule seems to be that we always want to emit a JFR event when dumping a graph - regardless of whether we dump a graph or not. I think we should follow this convention and remove the NOT_PRODUCT from the calls to print_method_iter().

On a separate note, I'm wondering how useful it is to always dump all events when calling print_method(). Should this be revisited again in general?

Comment on lines 5095 to 5121
if (iter > 0) {
ss.print(" %d", iter);
}
Copy link
Member

Choose a reason for hiding this comment

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

I'm not so sure about having an extra method print_method_iter() where the user need to keep track if a method is possibly repeated or not. I therefore suggest to only keep print_method() with its original signature and do the increment here like this:

  int iter = ++_igv_phase_iter[cpt];
  if (iter > 1) {
    ss.print(" %d", iter);
  }

Doing it this way we only add a number for the second time a phase is dumped again. I guess that's fine. But I'm open for other opinions about that.

Copy link
Member Author

Choose a reason for hiding this comment

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

I agree with just having a print_method. I initially hesitated to modify print_method in the way you suggest, as it would then add iteration numbering to all phases with no exceptions. But, it seems this is a feature we want then?

Copy link
Member

Choose a reason for hiding this comment

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

I think it could be useful for any repeated phase, if others also agree with that. And we would still keep the same name for phases that are only printed once and only add a number for the repeated dumps.

Copy link
Member Author

Choose a reason for hiding this comment

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

I've changed it for now. If anyone does not agree, please let us know.

@dlunde dlunde force-pushed the 8295166-igv branch 6 times, most recently from 2e763a2 to b80215f Compare November 7, 2023 16:15
@openjdk openjdk bot removed ready Pull request is ready to be integrated rfr Pull request is ready for review labels Dec 7, 2023
@openjdk openjdk bot added ready Pull request is ready to be integrated rfr Pull request is ready for review labels Dec 7, 2023
Copy link
Member

@chhagedorn chhagedorn left a comment

Choose a reason for hiding this comment

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

Otherwise, it looks good to me! Thanks for addressing all the comments and suggestions.

dlunde and others added 3 commits December 7, 2023 14:58
Co-authored-by: Christian Hagedorn <christian.hagedorn@oracle.com>
Co-authored-by: Christian Hagedorn <christian.hagedorn@oracle.com>
Co-authored-by: Christian Hagedorn <christian.hagedorn@oracle.com>
Copy link
Contributor

@robcasloz robcasloz left a comment

Choose a reason for hiding this comment

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

Thanks for addressing all the comments and thanks for this nice contribution! The additional dumps, in combination with the CFG view in IGV, make C2 loop optimizations much more approachable.

@dlunde
Copy link
Member Author

dlunde commented Dec 8, 2023

Thanks for the comments and reviews! The tests are now finished, integrating (and I need a sponsor).

/integrate

@openjdk openjdk bot added the sponsor Pull request is ready to be sponsored label Dec 8, 2023
@openjdk
Copy link

openjdk bot commented Dec 8, 2023

@dlunde
Your change (at version 61be342) is now ready to be sponsored by a Committer.

@robcasloz
Copy link
Contributor

/sponsor

@openjdk
Copy link

openjdk bot commented Dec 8, 2023

Going to push as commit 701bc3b.
Since your change was applied there have been 81 commits pushed to the master branch:

  • 9e48b90: 8310524: C2: record parser-generated LoadN nodes for IGVN
  • bad5edf: 8320959: jdk/jfr/event/runtime/TestShutdownEvent.java crash with CONF=fastdebug -Xcomp
  • f577385: 8316738: java/net/httpclient/HttpClientLocalAddrTest.java failed in timeout
  • 86623aa: 8320786: Remove ThreadGroup.stop
  • af5c492: 8320532: Remove Thread/ThreadGroup suspend/resume
  • cb7e3d2: 8321560: [BACKOUT] 8299426: Heap dump does not contain virtual Thread stack references
  • 25dc476: 8286827: BogusColorSpace methods return wrong array
  • 11e4a92: 8320597: RSA signature verification fails on signed data that does not encode params correctly
  • 354ea4c: 8299426: Heap dump does not contain virtual Thread stack references
  • 959a443: 8288712: Typo in javadoc in javax.imageio.ImageReader.java
  • ... and 71 more: https://git.openjdk.org/jdk/compare/1cf7ef520b73321c9fe7856b2f55ca6ecb555126...master

Your commit was automatically rebased without conflicts.

@openjdk openjdk bot added the integrated Pull request has been integrated label Dec 8, 2023
@openjdk openjdk bot closed this Dec 8, 2023
@openjdk openjdk bot removed ready Pull request is ready to be integrated rfr Pull request is ready for review sponsor Pull request is ready to be sponsored labels Dec 8, 2023
@openjdk
Copy link

openjdk bot commented Dec 8, 2023

@robcasloz @dlunde Pushed as commit 701bc3b.

💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored.

@dlunde dlunde deleted the 8295166-igv branch December 8, 2023 15:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
hotspot-compiler hotspot-compiler-dev@openjdk.org integrated Pull request has been integrated
Development

Successfully merging this pull request may close these issues.

4 participants