Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.

Fix min-opts spill of tree temp large vectors #22530

Merged
merged 2 commits into from
Feb 13, 2019

Conversation

CarolEidt
Copy link

Even if we're not enregistering local vars, we may have large vectors live across a call that need to be spilled.

Fix #22200

Even if we're not enregistering local vars, we may have large vectors live across a call that need to be spilled.

Fix #22200
@CarolEidt
Copy link
Author

@dotnet-bot test Ubuntu16.04 arm64 Cross Checked jitstress2_jitstressregs8 Build and Test
@dotnet-bot test Ubuntu16.04 arm64 Cross Checked jitstressregs1 Build and Test
@dotnet-bot test Ubuntu16.04 arm64 Cross Checked jitstressregs2 Build and Test
@dotnet-bot test Ubuntu16.04 arm64 Cross Checked jitstressregs3 Build and Test
@dotnet-bot test Ubuntu16.04 arm64 Cross Checked jitstressregs4 Build and Test
@dotnet-bot test Ubuntu16.04 arm64 Cross Checked jitstressregs8 Build and Test
@dotnet-bot test Ubuntu16.04 arm64 Cross Checked jitstressregs0x10 Build and Test
@dotnet-bot test Ubuntu16.04 arm64 Cross Checked jitstressregs0x80 Build and Test
@dotnet-bot test Windows_NT arm64 Cross Checked jitstressregs8 Build and Test

@CarolEidt
Copy link
Author

@dotnet/jit-contrib PTAL

@CarolEidt
Copy link
Author

#22311 Fixed this issue only for the case where we are also enregistering local vars. So, for minopts, or if there are no lclVars, this wasn't kicking in for the tree temps.

@CarolEidt
Copy link
Author

@dotnet/jit-contrib ping
The failures are all this test:

   Loader_NativeLibs._FromNativePaths_FromNativePaths_._FromNativePaths_FromNativePaths_sh

Failing with:

   Unable to find an entry point named 'NativeFunc' in shared library 'FromNativePaths_lib

Copy link

@sandreenko sandreenko left a comment

Choose a reason for hiding this comment

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

It was difficalt for me to understand this change, but it is LSRA so probably it was not expected to be easy.

Do we have a test for this change?

VARSET_TP liveLargeVectors(VarSetOps::MakeEmpty(compiler));
if (!VarSetOps::IsEmpty(compiler, largeVectorVars))
if (enregisterLocalVars && !VarSetOps::IsEmpty(compiler, largeVectorVars))

Choose a reason for hiding this comment

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

Could you please clarify some names, overall we have variables and temps, largeVectorVars refers to variables, enregisterLocalVars also refers to variables, is it correct?
Could we have non-empty largeVectorVars (that doesn't include temps, only vars) when enregisterLocalVars is false? Sound like we can't, then can you move the deleted assert under this condition?

Choose a reason for hiding this comment

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

Looks like this function does two things that needs to be split:

  1. a function that returns the set of lclVars (excluding temps) that are killed by this node;
  2. a function that create special RefPositions for saving the upper half of a set of large vector (including temps).

and the same for buildUpperVectorRestoreRefPositions.

If you do not want to split them now, could you please update their headers to include that they not only create re positions but also save/restore vars.

Copy link
Author

Choose a reason for hiding this comment

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

It would make sense to split out the determination of the live large vector lclVars (including lclVar temps, which are the same as lclVars from the perspective of LSRA) from the building of the RefPositions). I'd prefer to do that as a separate refactor.
Note, though, that this method doesn't actually save or restore anything, it just creates the RefPositions that may cause their upper half to be saved & restored, at allocation time, if they reside in a callee-save register.

Choose a reason for hiding this comment

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

the determination of the live large vector lclVars (including lclVar temps, which are the same as lclVars from the perspective of LSRA)

Do you mean liveLargeVectors that the method returns? We calculate liveLargeVectors only under if (enregisterLocalVars && !VarSetOps::IsEmpty(compiler, largeVectorVars)) as I see. How can it include lclVar temp when we iterate only through vars? Could you please rename liveLargeVectors to liveLargeVectorsVars here as well?

Note that the return value is calculated in the first part of this function and the second part does not affect it at all.

@@ -1376,6 +1375,10 @@ LinearScan::buildUpperVectorSaveRefPositions(GenTree* tree, LsraLocation current
// currentLoc - The location of the current node
// liveLargeVectors - The set of lclVars needing restores (returned by buildUpperVectorSaveRefPositions)

Choose a reason for hiding this comment

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

another question about names, could you please rename it to liveLargeVectorsVars?

{
// Build RefPositions for saving any live large vectors.
// This must be done after the kills, so that we know which large vectors are still live.
VarSetOps::AssignNoCopy(compiler, liveLargeVectors,
buildUpperVectorSaveRefPositions(tree, currentLoc + 1, killMask));
doLargeVectorRestore = true;
if (enregisterLocalVars && !VarSetOps::IsEmpty(compiler, liveLargeVectors))

Choose a reason for hiding this comment

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

The same comment about adding assert(enregisterLocalVars) under if.

Copy link
Author

Choose a reason for hiding this comment

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

Currently the lclVar sets are not initialized if enregisterLocalVars is false, so we can't move the condition to an assert (i.e. we need to check enregisterLocalVars before we test whether the set is empty).

@CarolEidt
Copy link
Author

Do we have a test for this change?

No we don't have a test for this change. It is generally not easy to find tests for LSRA issues, but the GitHub_20657 test has already found more than one.

Copy link

@sandreenko sandreenko left a comment

Choose a reason for hiding this comment

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

LGTM

@CarolEidt
Copy link
Author

@dotnet-bot test Ubuntu16.04 arm64 Cross Checked jitstress2_jitstressregs8 Build and Test
@dotnet-bot test Windows_NT arm64 Cross Checked jitstressregs8 Build and Test

@CarolEidt CarolEidt merged commit fc70d03 into dotnet:master Feb 13, 2019
@CarolEidt CarolEidt deleted the Fix22200 branch February 13, 2019 04:50
picenka21 pushed a commit to picenka21/runtime that referenced this pull request Feb 18, 2022
* Fix min-opts spill of tree temp large vectors

Even if we're not enregistering local vars, we may have large vectors live across a call that need to be spilled.

Fix dotnet/coreclr#22200


Commit migrated from dotnet/coreclr@fc70d03
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants