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

Fix type initialization ordering under R2R #84275

Merged
merged 15 commits into from
Apr 21, 2023
Merged

Conversation

markples
Copy link
Member

@markples markples commented Apr 4, 2023

Expand the fix in #80485 to cover helpers including common ones for R2R as well as some generic helpers for JIT.

This would cause regressions (100ks code size in diffs) if done alone, so it also includes checks on whether a helper may trigger a cctor and whether it is beforefieldinit. The precise ordering of the fix is only required for a non-beforefieldinit ctor. This recovers the (small) losses from #80485 and mitigates this fix.

As before, the primary diff is moving type initialization into (for correctness) or out of (the mitigation optimization) a JIT tree. These leads to secondary effects as values may need to be preserved around the type initialization code.

The end result of the fix+mitigations is very little code size change, but viewing the diffs suggests possible future code improvements. However, the impact of any of these should be established first.

  • A type initializer will never invoke itself
  • When type initialization is removed/CSEed late, it is too late for forward subst/etc., so the loss of the intact tree can still impact code generation
  • A custom calling convention for the static helpers (tuned to the common case of no type initialization needing to occur) could help with the impact of calling it in the middle of a calculation
  • Code can use beforefieldinit in more place

Fixes #84007

@markples
Copy link
Member Author

Some code size measurements:

R2R - ReadyToRun fix
R2R+old - ReadyToRun fix + applying opt to previous fix
undo old - Simply undoing the old fix (seeing its cost)
old - Just applying opt to previous fix
R2R+old 2 - Redoing R2R+old after factoring

Minor variations appear to be due to the repo changing day-to-day, so the takeaway is simply that applying the optimization to the old fix gets that regression back and the new fix+optimization has very little impact. #N/A occurred when the job didn't find the .mch file.

host target opt mch R2R R2R+old undo old old R2R+old 2
x64 linux arm64 min coreclr_tests.run -8 -7200 -7264 -7192 -7200
      libraries_tests.pmi 12 12     12
    full benchmarks.run   -48 -48 -48 -48
      coreclr_tests.run   -728 -732 -664 -672
      libraries.crossgen2 -72 -72     -100
      libraries.pmi   -24 -28 -24 -24
      libraries_tests.pmi 0 -544 -544 -540 -544
  osx arm64 min coreclr_tests.run -8 -7200 -7264 -7192 -7200
      libraries_tests.pmi 12 12     12
    full benchmarks.run   -56 -56 -56 -56
      coreclr_tests.run   -728 -732 -636 -636
      libraries.crossgen2 -140 -140     -140
      libraries.pmi   -28 -32 -28 -28
      libraries_tests.pmi   -536 -536 #N/A -532
  linux x64 min coreclr_tests.run 12 -10456 -10552 -10747 -10735
      libraries_tests.pmi 14 14     14
    full benchmarks.run   -42 -42 -48 -48
      coreclr_tests.run   -1257 -1260 -1254 -1262
      libraries.crossgen2 -159 -159     -195
      libraries.pmi   -45 -48 -44 -44
      libraries_tests.pmi   -395 -395 -390 -402
  win arm64 min coreclr_tests.run -8 -7200 -7264 -7192 -7200
      libraries_tests.pmi 12 12     12
    full benchmarks.run   -48 -48 -48 -48
      coreclr_tests.run   -716 -720 -668 -668
      libraries.crossgen2 -140 -140     -128
      libraries.pmi   -56 -60 -56 -56
      libraries_tests.pmi   -548 -548 -548 -548
  win x64 min aspnet.run   -160 -160 #N/A -160
      coreclr_tests.run 12 -10436 -10532 -10755 -10743
      libraries_tests.pmi 13 13     13
    full aspnet.run   2 2 #N/A 1
      benchmarks.run   -36 -36 -36 -36
      coreclr_tests.run   -1231 -1243 -1221 -1233
      libraries.crossgen2 -252 -252     -252
      libraries.pmi   -112 -115 -108 -108
      libraries_tests.pmi   -470 -470 -454 -452
x86 linux arm min coreclr_tests.run -6 -5346 -5344 -5340 -5346
      libraries_tests.pmi 6 6     6
    full benchmarks.run   24 24 10 10
      coreclr_tests.run   -236 -238 -232 -236
      libraries.crossgen2 -170 -170     -62
      libraries.pmi   188 196 182 182
      libraries_tests.pmi   -120 -120 -126 -126
  win x86 min coreclr_tests.run 2 -8533 -8582 -8535 -8533
      libraries_tests.pmi 9 9     9
    full benchmarks.run   -52 -52 -62 -62
      coreclr_tests.run   -1623 -1631 -1627 -1630
      libraries.crossgen2 -194 -194     -172
      libraries.pmi   -99 -101 -102 -102
      libraries_tests.pmi   -225 -225 -201 -201

@markples
Copy link
Member Author

/azp run runtime-coreclr outerloop, runtime-extra-platforms

@dotnet dotnet deleted a comment from azure-pipelines bot Apr 12, 2023
@azure-pipelines
Copy link

Azure Pipelines successfully started running 2 pipeline(s).

@markples markples marked this pull request as ready for review April 12, 2023 21:55
@markples markples closed this Apr 13, 2023
@markples markples reopened this Apr 13, 2023
@markples markples added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Apr 13, 2023
@ghost
Copy link

ghost commented Apr 13, 2023

Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch, @kunalspathak
See info in area-owners.md if you want to be subscribed.

Issue Details

Expand the fix in #80485 to cover helpers including common ones for R2R as well as some generic helpers for JIT.

This would cause regressions (100ks code size in diffs) if done alone, so it also includes checks on whether a helper may trigger a cctor and whether it is beforefieldinit. The precise ordering of the fix is only required for a non-beforefieldinit ctor. This recovers the (small) losses from #80485 and mitigates this fix.

As before, the primary diff is moving type initialization into (for correctness) or out of (the mitigation optimization) a JIT tree. These leads to secondary effects as values may need to be preserved around the type initialization code.

The end result of the fix+mitigations is very little code size change, but viewing the diffs suggests possible future code improvements. However, the impact of any of these should be established first.

  • A type initializer will never invoke itself
  • When type initialization is removed/CSEed late, it is too late for forward subst/etc., so the loss of the intact tree can still impact code generation
  • A custom calling convention for the static helpers (tuned to the common case of no type initialization needing to occur) could help with the impact of calling it in the middle of a calculation
  • Code can use beforefieldinit in more place

Fixes #84007

Author: markples
Assignees: markples
Labels:

area-CodeGen-coreclr, area-crossgen2-coreclr

Milestone: -

@markples
Copy link
Member Author

/azp run runtime-coreclr outerloop, runtime-extra-platforms

@azure-pipelines
Copy link

Azure Pipelines successfully started running 2 pipeline(s).

@markples
Copy link
Member Author

markples commented Apr 14, 2023

test results:

runtime

outerloop

extra-platforms has tons of failures. It's very hard to tell what's going on, but other jobs that I've looked at seem to have similar failures.

@markples
Copy link
Member Author

/azp run runtime-coreclr outerloop

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@markples
Copy link
Member Author

@AndyAyersMS Could you please review this one?

Copy link
Member

@AndyAyersMS AndyAyersMS left a comment

Choose a reason for hiding this comment

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

LGTM with one commenting nit.

@@ -4097,7 +4097,8 @@ GenTree* Compiler::impImportCnsTreeFromBuffer(uint8_t* buffer, var_types valueTy
GenTree* Compiler::impImportStaticFieldAccess(CORINFO_RESOLVED_TOKEN* pResolvedToken,
CORINFO_ACCESS_FLAGS access,
CORINFO_FIELD_INFO* pFieldInfo,
var_types lclTyp)
var_types lclTyp,
/* OUT */ bool* pIsHoistable)
Copy link
Member

Choose a reason for hiding this comment

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

Add a header comment? I know we still have many without these comments but I try to add one for the methods I'm changing.

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 attempted one.. learning a bit about those types in the process.

(the merge conflict was between code that I moved and main removed)

@markples markples merged commit fa60eb7 into dotnet:main Apr 21, 2023
@trylek trylek mentioned this pull request May 4, 2023
46 tasks
@ghost ghost locked as resolved and limited conversation to collaborators May 22, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI area-crossgen2-coreclr
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Test failure Loader\\classloader\\TypeInitialization\\CctorsWithSideEffects\\CctorForWrite\\CctorForWrite.cmd
2 participants