Crossgen2: Support HVA for ARM64 - #35576

Merged
AntonLapounov merged 2 commits into
dotnet:masterfrom
AntonLapounov:Arm64Hva
May 2, 2020
Merged

Crossgen2: Support HVA for ARM64#35576
AntonLapounov merged 2 commits into
dotnet:masterfrom
AntonLapounov:Arm64Hva

Conversation

@AntonLapounov

@AntonLapounovAntonLapounov commented Apr 28, 2020

Copy link
Copy Markdown
Contributor

Support ARM64 HVAs in Crossgen2.

  • Change FieldLayoutAlgorithm.ComputeValueTypeShapeCharacteristics method to compute the homogeneous aggregate element type and cache it in the existing field. That allows to remove all ComputeHomogeneousFloatAggregateElementType methods.
  • Change MetadataFieldLayoutAlgorithm.ComputeHomogeneousAggregateCharacteristic to compute HVAs in addition to HFAs.
  • Change CorInfoImpl.getHFAType JIT callback to handle HVAs. Note that returning ELEMENT_TYPE_VALUETYPE indicates the TYP_SIMD16 type (see Compiler::GetHfaType).
  • Change TypeFixupSignature.EncodeTypeLayout to handle HVAs.
  • Support HVAs in the ArgIterator class.
  • Fix TransitionBlock.OffsetFromGCRefMapPos for ARM64. R2RDump used to dump incorrect offsets.
  • Use TransitionBlock.OffsetFromGCRefMapPos in GCRefMapBuilder.GetCallRefMap to simplify logic.
  • Remove ARM64 .NET Native-specific code from TransitionBlock.cs and ArgIterator.cs files.

Minor:

  • Remove a redundant GetVectorSize check in MethodTable::GetHFAType.
  • Improve an assertion in Compiler::raUpdateRegStateForArg.
  • Fix comments in JIT code.

Comment on lines -1259 to -1263
vectorSize = pMT->GetVectorSize();
if (vectorSize != 0)
{
return (vectorSize == 8) ? ELEMENT_TYPE_R8 : ELEMENT_TYPE_VALUETYPE;
}

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

The next loop iteration performs this check anyway, so this one is redundant.

}
else
{
assert(!regState->rsIsFloat);

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

We could miss this check due to the break below, then fail later in an unexpected way.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

cc: @dotnet/jit-contrib

@MichalStrehovsky

Copy link
Copy Markdown
Member

We have xUnit test coverage for these aspects in the CoreRT repo: https://github.com/dotnet/corert/blob/923eeee2fb70497fe07b74d56bc51bee029c108b/src/ILCompiler.TypeSystem/tests/ValueTypeShapeCharacteristicsTests.cs

Issue #200 tracks porting these xUnit tests to the runtime repo, but for now they only compile and run in the experimental CoreRT repo (they will run if you just build.cmd from the root of the repo). I don't know if porting them is on anyone's radar soon (it would be about figuring out how to run xUnit as part of the coreclr managed tools build). Cc @dotnet/crossgen-contrib on that.

We haven't made significant type system changes in the runtime repo yet, so there's no process for this.

I sync the type system and compiler back to the CoreRT repo on weekends when I have time. Truth to be told, when I port this over and tests stop working, I'm just going to delete the tests because I don't have that much time.

If it's not too much hassle, could you do this change in the CoreRT repo too, and adjust/add test coverage as needed? Type system bugs tend to be subtle and that's why we try to unit test as much of it as possible.

You should be able to just xcopy src\coreclr\src\tools\Common\TypeSystem to src\Common\src\TypeSystem and src\coreclr\src\tools\Common\JitInterface to src\JitInterface\src. There's about two weeks worth of diffs because I didn't sync in 2 weeks, but it should be manageable to just undo irrelevant changes.

@davidwrightondavidwrighton left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'd like to see some effect on GCStress numbers. @janvorli has run GCStress for crossgen2 images on X64, and I imagine he has some instructions for doing so that you could adapt to Arm64.

{
int ofs;

if (_target.Architecture == TargetArchitecture.X86)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I realize that we don't yet support Crossgen2 for x86, but is removing this special case correct? Should it instead be moved to the OffsetFromGCRefMapPos function?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

This special case is already in OffsetFromGCRefMapPos overload for x86:

publicoverrideintOffsetFromGCRefMapPos(intpos)
{
if(pos<NumArgumentRegisters)
{
returnOffsetOfArgumentRegisters+SizeOfArgumentRegisters-(pos+1)*PointerSize;
}
else
{
returnOffsetOfArgs+(pos-NumArgumentRegisters)*PointerSize;
}
}

@janvorli

Copy link
Copy Markdown
Member

@janvorli has run GCStress for crossgen2 images on X64, and I imagine he has some instructions for doing so that you could adapt to Arm64.

Running with GC stress enabled is as easy as passing --gcstress argument to r2rtest tool (e.g. --gcstress 3). Or, if you are using runtest.cmd, then passing in gcstresslevel argument (and runcrossgen2tests to use crossgen2).

@janvorlijanvorli left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM, thank you!

@MichalStrehovsky

Copy link
Copy Markdown
Member

I sync the type system and compiler back to the CoreRT repo on weekends when I have time

Since we had a public holiday in Slovakia, managed to sync the compiler a bit earlier. dotnet/corert#8122.

@AntonLapounov

Copy link
Copy Markdown
ContributorAuthor

@davidwrighton Below are results of --gcstress 3 for pri-0 tests after the changes. Before the changes the framework could not be compiled with crossgen2.

CompilationCrossgenCPAOT
PASS39873998
FAIL143
Total40014001
ExecutionCrossgenCPAOT
PASS27652754
EXIT_CODE818
CRASHED00
TIMED_OUT66
BUILD_FAILED23
Total27812781

@AntonLapounov

AntonLapounov commented May 1, 2020

Copy link
Copy Markdown
ContributorAuthor

@echesakovMSFT This PR includes minor changes under jit and vm. It would be good to add an assert that if JIT recognizes some type as SIMD (see types in Compiler::getBaseTypeAndSizeOfSIMDType), then the GetHFAType callback returns a valid HFA/HVA type. Otherwise, JIT fails later in the prolog codegen phase or the register allocation phase.

@AntonLapounov

Copy link
Copy Markdown
ContributorAuthor

@CarolEidt Implementation of HFA/HVA property calculation in this PR is free of issues documented in #35144. We need them to be fixed so that Crossgen2 compiler and VM agree on the calling convention. One possible way of fixing that is to introduce a new enumeration for fundamental data types of homogeneous aggregates, like I did in this PR: https://github.com/dotnet/runtime/pull/35576/files#diff-e553d696b7062596f5653d5bba53d278, and use it as the return type of the getHFAType callback. I also suggested adding an assertion for its returned value: #35576 (comment).

@CarolEidt

Copy link
Copy Markdown
Contributor

It would be good to add an assert that if JIT recognizes some type as SIMD (see types in Compiler::getBaseTypeAndSizeOfSIMDType), then the GetHFAType callback returns a valid HFA/HVA type.

Did you want to add that to this PR, or perhaps file an issue for the JIT to do that?

@AntonLapounov - I was previously thinking that fixing #35144 would require a change to the JIT/EE interface, but I believe it's the case that from a JIT perspective it doesn't really need to distinguish between an HFA of double and an HVA of SIMD8. So I think the fix just needs to be made on the vm side of the JIT/EE interface, as you've done here.

@CarolEidtCarolEidt left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The JIT changes LGTM

@AntonLapounov

Copy link
Copy Markdown
ContributorAuthor

Did you want to add that to this PR, or perhaps file an issue for the JIT to do that?

@CarolEidt I would prefer someone with more JIT knowledge to do that. You are right that technically we do not have to change the getHFA API; however, I find using ELEMENT_TYPE_VALUETYPE to actually mean HfaElemKind.HFA_ELEM_SIMD16 (apparently JIT already has this enumeration) less than perfect.

@AntonLapounov
AntonLapounov merged commit 5893741 into dotnet:masterMay 2, 2020
@AntonLapounov
AntonLapounov deleted the Arm64Hva branch May 2, 2020 02:56
@janvorli

Copy link
Copy Markdown
Member

@AntonLapounov as for the timed out tests, can you please try to bump the execution timeout using the --execution-timeout-minutes r2rtest option to see if the timeouts are just taking more time or they represent hangs? You can try to bump it to e.g. 60 minutes to give it enough space.

@ghostghost locked as resolved and limited conversation to collaborators Dec 9, 2020
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@AntonLapounov@MichalStrehovsky@janvorli@CarolEidt@davidwrighton@Dotnet-GitSync-Bot
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Crossgen2: Support HVA for ARM64 - #35576

Merged
AntonLapounov merged 2 commits into
dotnet:masterfrom
AntonLapounov:Arm64Hva
May 2, 2020
Merged

Crossgen2: Support HVA for ARM64#35576
AntonLapounov merged 2 commits into
dotnet:masterfrom
AntonLapounov:Arm64Hva

Conversation

@AntonLapounov

@AntonLapounovAntonLapounov commented Apr 28, 2020

Copy link
Copy Markdown
Contributor

Support ARM64 HVAs in Crossgen2.

  • Change FieldLayoutAlgorithm.ComputeValueTypeShapeCharacteristics method to compute the homogeneous aggregate element type and cache it in the existing field. That allows to remove all ComputeHomogeneousFloatAggregateElementType methods.
  • Change MetadataFieldLayoutAlgorithm.ComputeHomogeneousAggregateCharacteristic to compute HVAs in addition to HFAs.
  • Change CorInfoImpl.getHFAType JIT callback to handle HVAs. Note that returning ELEMENT_TYPE_VALUETYPE indicates the TYP_SIMD16 type (see Compiler::GetHfaType).
  • Change TypeFixupSignature.EncodeTypeLayout to handle HVAs.
  • Support HVAs in the ArgIterator class.
  • Fix TransitionBlock.OffsetFromGCRefMapPos for ARM64. R2RDump used to dump incorrect offsets.
  • Use TransitionBlock.OffsetFromGCRefMapPos in GCRefMapBuilder.GetCallRefMap to simplify logic.
  • Remove ARM64 .NET Native-specific code from TransitionBlock.cs and ArgIterator.cs files.

Minor:

  • Remove a redundant GetVectorSize check in MethodTable::GetHFAType.
  • Improve an assertion in Compiler::raUpdateRegStateForArg.
  • Fix comments in JIT code.

Comment on lines -1259 to -1263
vectorSize = pMT->GetVectorSize();
if (vectorSize != 0)
{
return (vectorSize == 8) ? ELEMENT_TYPE_R8 : ELEMENT_TYPE_VALUETYPE;
}

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

The next loop iteration performs this check anyway, so this one is redundant.

}
else
{
assert(!regState->rsIsFloat);

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

We could miss this check due to the break below, then fail later in an unexpected way.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

cc: @dotnet/jit-contrib

@MichalStrehovsky

Copy link
Copy Markdown
Member

We have xUnit test coverage for these aspects in the CoreRT repo: https://github.com/dotnet/corert/blob/923eeee2fb70497fe07b74d56bc51bee029c108b/src/ILCompiler.TypeSystem/tests/ValueTypeShapeCharacteristicsTests.cs

Issue #200 tracks porting these xUnit tests to the runtime repo, but for now they only compile and run in the experimental CoreRT repo (they will run if you just build.cmd from the root of the repo). I don't know if porting them is on anyone's radar soon (it would be about figuring out how to run xUnit as part of the coreclr managed tools build). Cc @dotnet/crossgen-contrib on that.

We haven't made significant type system changes in the runtime repo yet, so there's no process for this.

I sync the type system and compiler back to the CoreRT repo on weekends when I have time. Truth to be told, when I port this over and tests stop working, I'm just going to delete the tests because I don't have that much time.

If it's not too much hassle, could you do this change in the CoreRT repo too, and adjust/add test coverage as needed? Type system bugs tend to be subtle and that's why we try to unit test as much of it as possible.

You should be able to just xcopy src\coreclr\src\tools\Common\TypeSystem to src\Common\src\TypeSystem and src\coreclr\src\tools\Common\JitInterface to src\JitInterface\src. There's about two weeks worth of diffs because I didn't sync in 2 weeks, but it should be manageable to just undo irrelevant changes.

@davidwrightondavidwrighton left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'd like to see some effect on GCStress numbers. @janvorli has run GCStress for crossgen2 images on X64, and I imagine he has some instructions for doing so that you could adapt to Arm64.

{
int ofs;

if (_target.Architecture == TargetArchitecture.X86)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I realize that we don't yet support Crossgen2 for x86, but is removing this special case correct? Should it instead be moved to the OffsetFromGCRefMapPos function?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

This special case is already in OffsetFromGCRefMapPos overload for x86:

publicoverrideintOffsetFromGCRefMapPos(intpos)
{
if(pos<NumArgumentRegisters)
{
returnOffsetOfArgumentRegisters+SizeOfArgumentRegisters-(pos+1)*PointerSize;
}
else
{
returnOffsetOfArgs+(pos-NumArgumentRegisters)*PointerSize;
}
}

@janvorli

Copy link
Copy Markdown
Member

@janvorli has run GCStress for crossgen2 images on X64, and I imagine he has some instructions for doing so that you could adapt to Arm64.

Running with GC stress enabled is as easy as passing --gcstress argument to r2rtest tool (e.g. --gcstress 3). Or, if you are using runtest.cmd, then passing in gcstresslevel argument (and runcrossgen2tests to use crossgen2).

@janvorlijanvorli left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM, thank you!

@MichalStrehovsky

Copy link
Copy Markdown
Member

I sync the type system and compiler back to the CoreRT repo on weekends when I have time

Since we had a public holiday in Slovakia, managed to sync the compiler a bit earlier. dotnet/corert#8122.

@AntonLapounov

Copy link
Copy Markdown
ContributorAuthor

@davidwrighton Below are results of --gcstress 3 for pri-0 tests after the changes. Before the changes the framework could not be compiled with crossgen2.

CompilationCrossgenCPAOT
PASS39873998
FAIL143
Total40014001
ExecutionCrossgenCPAOT
PASS27652754
EXIT_CODE818
CRASHED00
TIMED_OUT66
BUILD_FAILED23
Total27812781

@AntonLapounov

AntonLapounov commented May 1, 2020

Copy link
Copy Markdown
ContributorAuthor

@echesakovMSFT This PR includes minor changes under jit and vm. It would be good to add an assert that if JIT recognizes some type as SIMD (see types in Compiler::getBaseTypeAndSizeOfSIMDType), then the GetHFAType callback returns a valid HFA/HVA type. Otherwise, JIT fails later in the prolog codegen phase or the register allocation phase.

@AntonLapounov

Copy link
Copy Markdown
ContributorAuthor

@CarolEidt Implementation of HFA/HVA property calculation in this PR is free of issues documented in #35144. We need them to be fixed so that Crossgen2 compiler and VM agree on the calling convention. One possible way of fixing that is to introduce a new enumeration for fundamental data types of homogeneous aggregates, like I did in this PR: https://github.com/dotnet/runtime/pull/35576/files#diff-e553d696b7062596f5653d5bba53d278, and use it as the return type of the getHFAType callback. I also suggested adding an assertion for its returned value: #35576 (comment).

@CarolEidt

Copy link
Copy Markdown
Contributor

It would be good to add an assert that if JIT recognizes some type as SIMD (see types in Compiler::getBaseTypeAndSizeOfSIMDType), then the GetHFAType callback returns a valid HFA/HVA type.

Did you want to add that to this PR, or perhaps file an issue for the JIT to do that?

@AntonLapounov - I was previously thinking that fixing #35144 would require a change to the JIT/EE interface, but I believe it's the case that from a JIT perspective it doesn't really need to distinguish between an HFA of double and an HVA of SIMD8. So I think the fix just needs to be made on the vm side of the JIT/EE interface, as you've done here.

@CarolEidtCarolEidt left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The JIT changes LGTM

@AntonLapounov

Copy link
Copy Markdown
ContributorAuthor

Did you want to add that to this PR, or perhaps file an issue for the JIT to do that?

@CarolEidt I would prefer someone with more JIT knowledge to do that. You are right that technically we do not have to change the getHFA API; however, I find using ELEMENT_TYPE_VALUETYPE to actually mean HfaElemKind.HFA_ELEM_SIMD16 (apparently JIT already has this enumeration) less than perfect.

@AntonLapounov
AntonLapounov merged commit 5893741 into dotnet:masterMay 2, 2020
@AntonLapounov
AntonLapounov deleted the Arm64Hva branch May 2, 2020 02:56
@janvorli

Copy link
Copy Markdown
Member

@AntonLapounov as for the timed out tests, can you please try to bump the execution timeout using the --execution-timeout-minutes r2rtest option to see if the timeouts are just taking more time or they represent hangs? You can try to bump it to e.g. 60 minutes to give it enough space.

@ghostghost locked as resolved and limited conversation to collaborators Dec 9, 2020
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@AntonLapounov@MichalStrehovsky@janvorli@CarolEidt@davidwrighton@Dotnet-GitSync-Bot
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Crossgen2: Support HVA for ARM64 - #35576

Merged
AntonLapounov merged 2 commits into
dotnet:masterfrom
AntonLapounov:Arm64Hva
May 2, 2020
Merged

Crossgen2: Support HVA for ARM64#35576
AntonLapounov merged 2 commits into
dotnet:masterfrom
AntonLapounov:Arm64Hva

Conversation

@AntonLapounov

@AntonLapounovAntonLapounov commented Apr 28, 2020

Copy link
Copy Markdown
Contributor

Support ARM64 HVAs in Crossgen2.

  • Change FieldLayoutAlgorithm.ComputeValueTypeShapeCharacteristics method to compute the homogeneous aggregate element type and cache it in the existing field. That allows to remove all ComputeHomogeneousFloatAggregateElementType methods.
  • Change MetadataFieldLayoutAlgorithm.ComputeHomogeneousAggregateCharacteristic to compute HVAs in addition to HFAs.
  • Change CorInfoImpl.getHFAType JIT callback to handle HVAs. Note that returning ELEMENT_TYPE_VALUETYPE indicates the TYP_SIMD16 type (see Compiler::GetHfaType).
  • Change TypeFixupSignature.EncodeTypeLayout to handle HVAs.
  • Support HVAs in the ArgIterator class.
  • Fix TransitionBlock.OffsetFromGCRefMapPos for ARM64. R2RDump used to dump incorrect offsets.
  • Use TransitionBlock.OffsetFromGCRefMapPos in GCRefMapBuilder.GetCallRefMap to simplify logic.
  • Remove ARM64 .NET Native-specific code from TransitionBlock.cs and ArgIterator.cs files.

Minor:

  • Remove a redundant GetVectorSize check in MethodTable::GetHFAType.
  • Improve an assertion in Compiler::raUpdateRegStateForArg.
  • Fix comments in JIT code.

Comment on lines -1259 to -1263
vectorSize = pMT->GetVectorSize();
if (vectorSize != 0)
{
return (vectorSize == 8) ? ELEMENT_TYPE_R8 : ELEMENT_TYPE_VALUETYPE;
}

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

The next loop iteration performs this check anyway, so this one is redundant.

}
else
{
assert(!regState->rsIsFloat);

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

We could miss this check due to the break below, then fail later in an unexpected way.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

cc: @dotnet/jit-contrib

@MichalStrehovsky

Copy link
Copy Markdown
Member

We have xUnit test coverage for these aspects in the CoreRT repo: https://github.com/dotnet/corert/blob/923eeee2fb70497fe07b74d56bc51bee029c108b/src/ILCompiler.TypeSystem/tests/ValueTypeShapeCharacteristicsTests.cs

Issue #200 tracks porting these xUnit tests to the runtime repo, but for now they only compile and run in the experimental CoreRT repo (they will run if you just build.cmd from the root of the repo). I don't know if porting them is on anyone's radar soon (it would be about figuring out how to run xUnit as part of the coreclr managed tools build). Cc @dotnet/crossgen-contrib on that.

We haven't made significant type system changes in the runtime repo yet, so there's no process for this.

I sync the type system and compiler back to the CoreRT repo on weekends when I have time. Truth to be told, when I port this over and tests stop working, I'm just going to delete the tests because I don't have that much time.

If it's not too much hassle, could you do this change in the CoreRT repo too, and adjust/add test coverage as needed? Type system bugs tend to be subtle and that's why we try to unit test as much of it as possible.

You should be able to just xcopy src\coreclr\src\tools\Common\TypeSystem to src\Common\src\TypeSystem and src\coreclr\src\tools\Common\JitInterface to src\JitInterface\src. There's about two weeks worth of diffs because I didn't sync in 2 weeks, but it should be manageable to just undo irrelevant changes.

@davidwrightondavidwrighton left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'd like to see some effect on GCStress numbers. @janvorli has run GCStress for crossgen2 images on X64, and I imagine he has some instructions for doing so that you could adapt to Arm64.

{
int ofs;

if (_target.Architecture == TargetArchitecture.X86)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I realize that we don't yet support Crossgen2 for x86, but is removing this special case correct? Should it instead be moved to the OffsetFromGCRefMapPos function?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

This special case is already in OffsetFromGCRefMapPos overload for x86:

publicoverrideintOffsetFromGCRefMapPos(intpos)
{
if(pos<NumArgumentRegisters)
{
returnOffsetOfArgumentRegisters+SizeOfArgumentRegisters-(pos+1)*PointerSize;
}
else
{
returnOffsetOfArgs+(pos-NumArgumentRegisters)*PointerSize;
}
}

@janvorli

Copy link
Copy Markdown
Member

@janvorli has run GCStress for crossgen2 images on X64, and I imagine he has some instructions for doing so that you could adapt to Arm64.

Running with GC stress enabled is as easy as passing --gcstress argument to r2rtest tool (e.g. --gcstress 3). Or, if you are using runtest.cmd, then passing in gcstresslevel argument (and runcrossgen2tests to use crossgen2).

@janvorlijanvorli left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM, thank you!

@MichalStrehovsky

Copy link
Copy Markdown
Member

I sync the type system and compiler back to the CoreRT repo on weekends when I have time

Since we had a public holiday in Slovakia, managed to sync the compiler a bit earlier. dotnet/corert#8122.

@AntonLapounov

Copy link
Copy Markdown
ContributorAuthor

@davidwrighton Below are results of --gcstress 3 for pri-0 tests after the changes. Before the changes the framework could not be compiled with crossgen2.

CompilationCrossgenCPAOT
PASS39873998
FAIL143
Total40014001
ExecutionCrossgenCPAOT
PASS27652754
EXIT_CODE818
CRASHED00
TIMED_OUT66
BUILD_FAILED23
Total27812781

@AntonLapounov

AntonLapounov commented May 1, 2020

Copy link
Copy Markdown
ContributorAuthor

@echesakovMSFT This PR includes minor changes under jit and vm. It would be good to add an assert that if JIT recognizes some type as SIMD (see types in Compiler::getBaseTypeAndSizeOfSIMDType), then the GetHFAType callback returns a valid HFA/HVA type. Otherwise, JIT fails later in the prolog codegen phase or the register allocation phase.

@AntonLapounov

Copy link
Copy Markdown
ContributorAuthor

@CarolEidt Implementation of HFA/HVA property calculation in this PR is free of issues documented in #35144. We need them to be fixed so that Crossgen2 compiler and VM agree on the calling convention. One possible way of fixing that is to introduce a new enumeration for fundamental data types of homogeneous aggregates, like I did in this PR: https://github.com/dotnet/runtime/pull/35576/files#diff-e553d696b7062596f5653d5bba53d278, and use it as the return type of the getHFAType callback. I also suggested adding an assertion for its returned value: #35576 (comment).

@CarolEidt

Copy link
Copy Markdown
Contributor

It would be good to add an assert that if JIT recognizes some type as SIMD (see types in Compiler::getBaseTypeAndSizeOfSIMDType), then the GetHFAType callback returns a valid HFA/HVA type.

Did you want to add that to this PR, or perhaps file an issue for the JIT to do that?

@AntonLapounov - I was previously thinking that fixing #35144 would require a change to the JIT/EE interface, but I believe it's the case that from a JIT perspective it doesn't really need to distinguish between an HFA of double and an HVA of SIMD8. So I think the fix just needs to be made on the vm side of the JIT/EE interface, as you've done here.

@CarolEidtCarolEidt left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The JIT changes LGTM

@AntonLapounov

Copy link
Copy Markdown
ContributorAuthor

Did you want to add that to this PR, or perhaps file an issue for the JIT to do that?

@CarolEidt I would prefer someone with more JIT knowledge to do that. You are right that technically we do not have to change the getHFA API; however, I find using ELEMENT_TYPE_VALUETYPE to actually mean HfaElemKind.HFA_ELEM_SIMD16 (apparently JIT already has this enumeration) less than perfect.

@AntonLapounov
AntonLapounov merged commit 5893741 into dotnet:masterMay 2, 2020
@AntonLapounov
AntonLapounov deleted the Arm64Hva branch May 2, 2020 02:56
@janvorli

Copy link
Copy Markdown
Member

@AntonLapounov as for the timed out tests, can you please try to bump the execution timeout using the --execution-timeout-minutes r2rtest option to see if the timeouts are just taking more time or they represent hangs? You can try to bump it to e.g. 60 minutes to give it enough space.

@ghostghost locked as resolved and limited conversation to collaborators Dec 9, 2020
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@AntonLapounov@MichalStrehovsky@janvorli@CarolEidt@davidwrighton@Dotnet-GitSync-Bot
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Crossgen2: Support HVA for ARM64 - #35576

Merged
AntonLapounov merged 2 commits into
dotnet:masterfrom
AntonLapounov:Arm64Hva
May 2, 2020
Merged

Crossgen2: Support HVA for ARM64#35576
AntonLapounov merged 2 commits into
dotnet:masterfrom
AntonLapounov:Arm64Hva

Conversation

@AntonLapounov

@AntonLapounovAntonLapounov commented Apr 28, 2020

Copy link
Copy Markdown
Contributor

Support ARM64 HVAs in Crossgen2.

  • Change FieldLayoutAlgorithm.ComputeValueTypeShapeCharacteristics method to compute the homogeneous aggregate element type and cache it in the existing field. That allows to remove all ComputeHomogeneousFloatAggregateElementType methods.
  • Change MetadataFieldLayoutAlgorithm.ComputeHomogeneousAggregateCharacteristic to compute HVAs in addition to HFAs.
  • Change CorInfoImpl.getHFAType JIT callback to handle HVAs. Note that returning ELEMENT_TYPE_VALUETYPE indicates the TYP_SIMD16 type (see Compiler::GetHfaType).
  • Change TypeFixupSignature.EncodeTypeLayout to handle HVAs.
  • Support HVAs in the ArgIterator class.
  • Fix TransitionBlock.OffsetFromGCRefMapPos for ARM64. R2RDump used to dump incorrect offsets.
  • Use TransitionBlock.OffsetFromGCRefMapPos in GCRefMapBuilder.GetCallRefMap to simplify logic.
  • Remove ARM64 .NET Native-specific code from TransitionBlock.cs and ArgIterator.cs files.

Minor:

  • Remove a redundant GetVectorSize check in MethodTable::GetHFAType.
  • Improve an assertion in Compiler::raUpdateRegStateForArg.
  • Fix comments in JIT code.

Comment on lines -1259 to -1263
vectorSize = pMT->GetVectorSize();
if (vectorSize != 0)
{
return (vectorSize == 8) ? ELEMENT_TYPE_R8 : ELEMENT_TYPE_VALUETYPE;
}

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

The next loop iteration performs this check anyway, so this one is redundant.

}
else
{
assert(!regState->rsIsFloat);

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

We could miss this check due to the break below, then fail later in an unexpected way.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

cc: @dotnet/jit-contrib

@MichalStrehovsky

Copy link
Copy Markdown
Member

We have xUnit test coverage for these aspects in the CoreRT repo: https://github.com/dotnet/corert/blob/923eeee2fb70497fe07b74d56bc51bee029c108b/src/ILCompiler.TypeSystem/tests/ValueTypeShapeCharacteristicsTests.cs

Issue #200 tracks porting these xUnit tests to the runtime repo, but for now they only compile and run in the experimental CoreRT repo (they will run if you just build.cmd from the root of the repo). I don't know if porting them is on anyone's radar soon (it would be about figuring out how to run xUnit as part of the coreclr managed tools build). Cc @dotnet/crossgen-contrib on that.

We haven't made significant type system changes in the runtime repo yet, so there's no process for this.

I sync the type system and compiler back to the CoreRT repo on weekends when I have time. Truth to be told, when I port this over and tests stop working, I'm just going to delete the tests because I don't have that much time.

If it's not too much hassle, could you do this change in the CoreRT repo too, and adjust/add test coverage as needed? Type system bugs tend to be subtle and that's why we try to unit test as much of it as possible.

You should be able to just xcopy src\coreclr\src\tools\Common\TypeSystem to src\Common\src\TypeSystem and src\coreclr\src\tools\Common\JitInterface to src\JitInterface\src. There's about two weeks worth of diffs because I didn't sync in 2 weeks, but it should be manageable to just undo irrelevant changes.

@davidwrightondavidwrighton left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'd like to see some effect on GCStress numbers. @janvorli has run GCStress for crossgen2 images on X64, and I imagine he has some instructions for doing so that you could adapt to Arm64.

{
int ofs;

if (_target.Architecture == TargetArchitecture.X86)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I realize that we don't yet support Crossgen2 for x86, but is removing this special case correct? Should it instead be moved to the OffsetFromGCRefMapPos function?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

This special case is already in OffsetFromGCRefMapPos overload for x86:

publicoverrideintOffsetFromGCRefMapPos(intpos)
{
if(pos<NumArgumentRegisters)
{
returnOffsetOfArgumentRegisters+SizeOfArgumentRegisters-(pos+1)*PointerSize;
}
else
{
returnOffsetOfArgs+(pos-NumArgumentRegisters)*PointerSize;
}
}

@janvorli

Copy link
Copy Markdown
Member

@janvorli has run GCStress for crossgen2 images on X64, and I imagine he has some instructions for doing so that you could adapt to Arm64.

Running with GC stress enabled is as easy as passing --gcstress argument to r2rtest tool (e.g. --gcstress 3). Or, if you are using runtest.cmd, then passing in gcstresslevel argument (and runcrossgen2tests to use crossgen2).

@janvorlijanvorli left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM, thank you!

@MichalStrehovsky

Copy link
Copy Markdown
Member

I sync the type system and compiler back to the CoreRT repo on weekends when I have time

Since we had a public holiday in Slovakia, managed to sync the compiler a bit earlier. dotnet/corert#8122.

@AntonLapounov

Copy link
Copy Markdown
ContributorAuthor

@davidwrighton Below are results of --gcstress 3 for pri-0 tests after the changes. Before the changes the framework could not be compiled with crossgen2.

CompilationCrossgenCPAOT
PASS39873998
FAIL143
Total40014001
ExecutionCrossgenCPAOT
PASS27652754
EXIT_CODE818
CRASHED00
TIMED_OUT66
BUILD_FAILED23
Total27812781

@AntonLapounov

AntonLapounov commented May 1, 2020

Copy link
Copy Markdown
ContributorAuthor

@echesakovMSFT This PR includes minor changes under jit and vm. It would be good to add an assert that if JIT recognizes some type as SIMD (see types in Compiler::getBaseTypeAndSizeOfSIMDType), then the GetHFAType callback returns a valid HFA/HVA type. Otherwise, JIT fails later in the prolog codegen phase or the register allocation phase.

@AntonLapounov

Copy link
Copy Markdown
ContributorAuthor

@CarolEidt Implementation of HFA/HVA property calculation in this PR is free of issues documented in #35144. We need them to be fixed so that Crossgen2 compiler and VM agree on the calling convention. One possible way of fixing that is to introduce a new enumeration for fundamental data types of homogeneous aggregates, like I did in this PR: https://github.com/dotnet/runtime/pull/35576/files#diff-e553d696b7062596f5653d5bba53d278, and use it as the return type of the getHFAType callback. I also suggested adding an assertion for its returned value: #35576 (comment).

@CarolEidt

Copy link
Copy Markdown
Contributor

It would be good to add an assert that if JIT recognizes some type as SIMD (see types in Compiler::getBaseTypeAndSizeOfSIMDType), then the GetHFAType callback returns a valid HFA/HVA type.

Did you want to add that to this PR, or perhaps file an issue for the JIT to do that?

@AntonLapounov - I was previously thinking that fixing #35144 would require a change to the JIT/EE interface, but I believe it's the case that from a JIT perspective it doesn't really need to distinguish between an HFA of double and an HVA of SIMD8. So I think the fix just needs to be made on the vm side of the JIT/EE interface, as you've done here.

@CarolEidtCarolEidt left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The JIT changes LGTM

@AntonLapounov

Copy link
Copy Markdown
ContributorAuthor

Did you want to add that to this PR, or perhaps file an issue for the JIT to do that?

@CarolEidt I would prefer someone with more JIT knowledge to do that. You are right that technically we do not have to change the getHFA API; however, I find using ELEMENT_TYPE_VALUETYPE to actually mean HfaElemKind.HFA_ELEM_SIMD16 (apparently JIT already has this enumeration) less than perfect.

@AntonLapounov
AntonLapounov merged commit 5893741 into dotnet:masterMay 2, 2020
@AntonLapounov
AntonLapounov deleted the Arm64Hva branch May 2, 2020 02:56
@janvorli

Copy link
Copy Markdown
Member

@AntonLapounov as for the timed out tests, can you please try to bump the execution timeout using the --execution-timeout-minutes r2rtest option to see if the timeouts are just taking more time or they represent hangs? You can try to bump it to e.g. 60 minutes to give it enough space.

@ghostghost locked as resolved and limited conversation to collaborators Dec 9, 2020
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@AntonLapounov@MichalStrehovsky@janvorli@CarolEidt@davidwrighton@Dotnet-GitSync-Bot
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Crossgen2: Support HVA for ARM64 - #35576

Merged
AntonLapounov merged 2 commits into
dotnet:masterfrom
AntonLapounov:Arm64Hva
May 2, 2020
Merged

Crossgen2: Support HVA for ARM64#35576
AntonLapounov merged 2 commits into
dotnet:masterfrom
AntonLapounov:Arm64Hva

Conversation

@AntonLapounov

@AntonLapounovAntonLapounov commented Apr 28, 2020

Copy link
Copy Markdown
Contributor

Support ARM64 HVAs in Crossgen2.

  • Change FieldLayoutAlgorithm.ComputeValueTypeShapeCharacteristics method to compute the homogeneous aggregate element type and cache it in the existing field. That allows to remove all ComputeHomogeneousFloatAggregateElementType methods.
  • Change MetadataFieldLayoutAlgorithm.ComputeHomogeneousAggregateCharacteristic to compute HVAs in addition to HFAs.
  • Change CorInfoImpl.getHFAType JIT callback to handle HVAs. Note that returning ELEMENT_TYPE_VALUETYPE indicates the TYP_SIMD16 type (see Compiler::GetHfaType).
  • Change TypeFixupSignature.EncodeTypeLayout to handle HVAs.
  • Support HVAs in the ArgIterator class.
  • Fix TransitionBlock.OffsetFromGCRefMapPos for ARM64. R2RDump used to dump incorrect offsets.
  • Use TransitionBlock.OffsetFromGCRefMapPos in GCRefMapBuilder.GetCallRefMap to simplify logic.
  • Remove ARM64 .NET Native-specific code from TransitionBlock.cs and ArgIterator.cs files.

Minor:

  • Remove a redundant GetVectorSize check in MethodTable::GetHFAType.
  • Improve an assertion in Compiler::raUpdateRegStateForArg.
  • Fix comments in JIT code.

Comment on lines -1259 to -1263
vectorSize = pMT->GetVectorSize();
if (vectorSize != 0)
{
return (vectorSize == 8) ? ELEMENT_TYPE_R8 : ELEMENT_TYPE_VALUETYPE;
}

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

The next loop iteration performs this check anyway, so this one is redundant.

}
else
{
assert(!regState->rsIsFloat);

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

We could miss this check due to the break below, then fail later in an unexpected way.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

cc: @dotnet/jit-contrib

@MichalStrehovsky

Copy link
Copy Markdown
Member

We have xUnit test coverage for these aspects in the CoreRT repo: https://github.com/dotnet/corert/blob/923eeee2fb70497fe07b74d56bc51bee029c108b/src/ILCompiler.TypeSystem/tests/ValueTypeShapeCharacteristicsTests.cs

Issue #200 tracks porting these xUnit tests to the runtime repo, but for now they only compile and run in the experimental CoreRT repo (they will run if you just build.cmd from the root of the repo). I don't know if porting them is on anyone's radar soon (it would be about figuring out how to run xUnit as part of the coreclr managed tools build). Cc @dotnet/crossgen-contrib on that.

We haven't made significant type system changes in the runtime repo yet, so there's no process for this.

I sync the type system and compiler back to the CoreRT repo on weekends when I have time. Truth to be told, when I port this over and tests stop working, I'm just going to delete the tests because I don't have that much time.

If it's not too much hassle, could you do this change in the CoreRT repo too, and adjust/add test coverage as needed? Type system bugs tend to be subtle and that's why we try to unit test as much of it as possible.

You should be able to just xcopy src\coreclr\src\tools\Common\TypeSystem to src\Common\src\TypeSystem and src\coreclr\src\tools\Common\JitInterface to src\JitInterface\src. There's about two weeks worth of diffs because I didn't sync in 2 weeks, but it should be manageable to just undo irrelevant changes.

@davidwrightondavidwrighton left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'd like to see some effect on GCStress numbers. @janvorli has run GCStress for crossgen2 images on X64, and I imagine he has some instructions for doing so that you could adapt to Arm64.

{
int ofs;

if (_target.Architecture == TargetArchitecture.X86)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I realize that we don't yet support Crossgen2 for x86, but is removing this special case correct? Should it instead be moved to the OffsetFromGCRefMapPos function?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

This special case is already in OffsetFromGCRefMapPos overload for x86:

publicoverrideintOffsetFromGCRefMapPos(intpos)
{
if(pos<NumArgumentRegisters)
{
returnOffsetOfArgumentRegisters+SizeOfArgumentRegisters-(pos+1)*PointerSize;
}
else
{
returnOffsetOfArgs+(pos-NumArgumentRegisters)*PointerSize;
}
}

@janvorli

Copy link
Copy Markdown
Member

@janvorli has run GCStress for crossgen2 images on X64, and I imagine he has some instructions for doing so that you could adapt to Arm64.

Running with GC stress enabled is as easy as passing --gcstress argument to r2rtest tool (e.g. --gcstress 3). Or, if you are using runtest.cmd, then passing in gcstresslevel argument (and runcrossgen2tests to use crossgen2).

@janvorlijanvorli left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM, thank you!

@MichalStrehovsky

Copy link
Copy Markdown
Member

I sync the type system and compiler back to the CoreRT repo on weekends when I have time

Since we had a public holiday in Slovakia, managed to sync the compiler a bit earlier. dotnet/corert#8122.

@AntonLapounov

Copy link
Copy Markdown
ContributorAuthor

@davidwrighton Below are results of --gcstress 3 for pri-0 tests after the changes. Before the changes the framework could not be compiled with crossgen2.

CompilationCrossgenCPAOT
PASS39873998
FAIL143
Total40014001
ExecutionCrossgenCPAOT
PASS27652754
EXIT_CODE818
CRASHED00
TIMED_OUT66
BUILD_FAILED23
Total27812781

@AntonLapounov

AntonLapounov commented May 1, 2020

Copy link
Copy Markdown
ContributorAuthor

@echesakovMSFT This PR includes minor changes under jit and vm. It would be good to add an assert that if JIT recognizes some type as SIMD (see types in Compiler::getBaseTypeAndSizeOfSIMDType), then the GetHFAType callback returns a valid HFA/HVA type. Otherwise, JIT fails later in the prolog codegen phase or the register allocation phase.

@AntonLapounov

Copy link
Copy Markdown
ContributorAuthor

@CarolEidt Implementation of HFA/HVA property calculation in this PR is free of issues documented in #35144. We need them to be fixed so that Crossgen2 compiler and VM agree on the calling convention. One possible way of fixing that is to introduce a new enumeration for fundamental data types of homogeneous aggregates, like I did in this PR: https://github.com/dotnet/runtime/pull/35576/files#diff-e553d696b7062596f5653d5bba53d278, and use it as the return type of the getHFAType callback. I also suggested adding an assertion for its returned value: #35576 (comment).

@CarolEidt

Copy link
Copy Markdown
Contributor

It would be good to add an assert that if JIT recognizes some type as SIMD (see types in Compiler::getBaseTypeAndSizeOfSIMDType), then the GetHFAType callback returns a valid HFA/HVA type.

Did you want to add that to this PR, or perhaps file an issue for the JIT to do that?

@AntonLapounov - I was previously thinking that fixing #35144 would require a change to the JIT/EE interface, but I believe it's the case that from a JIT perspective it doesn't really need to distinguish between an HFA of double and an HVA of SIMD8. So I think the fix just needs to be made on the vm side of the JIT/EE interface, as you've done here.

@CarolEidtCarolEidt left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The JIT changes LGTM

@AntonLapounov

Copy link
Copy Markdown
ContributorAuthor

Did you want to add that to this PR, or perhaps file an issue for the JIT to do that?

@CarolEidt I would prefer someone with more JIT knowledge to do that. You are right that technically we do not have to change the getHFA API; however, I find using ELEMENT_TYPE_VALUETYPE to actually mean HfaElemKind.HFA_ELEM_SIMD16 (apparently JIT already has this enumeration) less than perfect.

@AntonLapounov
AntonLapounov merged commit 5893741 into dotnet:masterMay 2, 2020
@AntonLapounov
AntonLapounov deleted the Arm64Hva branch May 2, 2020 02:56
@janvorli

Copy link
Copy Markdown
Member

@AntonLapounov as for the timed out tests, can you please try to bump the execution timeout using the --execution-timeout-minutes r2rtest option to see if the timeouts are just taking more time or they represent hangs? You can try to bump it to e.g. 60 minutes to give it enough space.

@ghostghost locked as resolved and limited conversation to collaborators Dec 9, 2020
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@AntonLapounov@MichalStrehovsky@janvorli@CarolEidt@davidwrighton@Dotnet-GitSync-Bot
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Crossgen2: Support HVA for ARM64 - #35576

Merged
AntonLapounov merged 2 commits into
dotnet:masterfrom
AntonLapounov:Arm64Hva
May 2, 2020
Merged

Crossgen2: Support HVA for ARM64#35576
AntonLapounov merged 2 commits into
dotnet:masterfrom
AntonLapounov:Arm64Hva

Conversation

@AntonLapounov

@AntonLapounovAntonLapounov commented Apr 28, 2020

Copy link
Copy Markdown
Contributor

Support ARM64 HVAs in Crossgen2.

  • Change FieldLayoutAlgorithm.ComputeValueTypeShapeCharacteristics method to compute the homogeneous aggregate element type and cache it in the existing field. That allows to remove all ComputeHomogeneousFloatAggregateElementType methods.
  • Change MetadataFieldLayoutAlgorithm.ComputeHomogeneousAggregateCharacteristic to compute HVAs in addition to HFAs.
  • Change CorInfoImpl.getHFAType JIT callback to handle HVAs. Note that returning ELEMENT_TYPE_VALUETYPE indicates the TYP_SIMD16 type (see Compiler::GetHfaType).
  • Change TypeFixupSignature.EncodeTypeLayout to handle HVAs.
  • Support HVAs in the ArgIterator class.
  • Fix TransitionBlock.OffsetFromGCRefMapPos for ARM64. R2RDump used to dump incorrect offsets.
  • Use TransitionBlock.OffsetFromGCRefMapPos in GCRefMapBuilder.GetCallRefMap to simplify logic.
  • Remove ARM64 .NET Native-specific code from TransitionBlock.cs and ArgIterator.cs files.

Minor:

  • Remove a redundant GetVectorSize check in MethodTable::GetHFAType.
  • Improve an assertion in Compiler::raUpdateRegStateForArg.
  • Fix comments in JIT code.

Comment on lines -1259 to -1263
vectorSize = pMT->GetVectorSize();
if (vectorSize != 0)
{
return (vectorSize == 8) ? ELEMENT_TYPE_R8 : ELEMENT_TYPE_VALUETYPE;
}

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

The next loop iteration performs this check anyway, so this one is redundant.

}
else
{
assert(!regState->rsIsFloat);

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

We could miss this check due to the break below, then fail later in an unexpected way.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

cc: @dotnet/jit-contrib

@MichalStrehovsky

Copy link
Copy Markdown
Member

We have xUnit test coverage for these aspects in the CoreRT repo: https://github.com/dotnet/corert/blob/923eeee2fb70497fe07b74d56bc51bee029c108b/src/ILCompiler.TypeSystem/tests/ValueTypeShapeCharacteristicsTests.cs

Issue #200 tracks porting these xUnit tests to the runtime repo, but for now they only compile and run in the experimental CoreRT repo (they will run if you just build.cmd from the root of the repo). I don't know if porting them is on anyone's radar soon (it would be about figuring out how to run xUnit as part of the coreclr managed tools build). Cc @dotnet/crossgen-contrib on that.

We haven't made significant type system changes in the runtime repo yet, so there's no process for this.

I sync the type system and compiler back to the CoreRT repo on weekends when I have time. Truth to be told, when I port this over and tests stop working, I'm just going to delete the tests because I don't have that much time.

If it's not too much hassle, could you do this change in the CoreRT repo too, and adjust/add test coverage as needed? Type system bugs tend to be subtle and that's why we try to unit test as much of it as possible.

You should be able to just xcopy src\coreclr\src\tools\Common\TypeSystem to src\Common\src\TypeSystem and src\coreclr\src\tools\Common\JitInterface to src\JitInterface\src. There's about two weeks worth of diffs because I didn't sync in 2 weeks, but it should be manageable to just undo irrelevant changes.

@davidwrightondavidwrighton left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'd like to see some effect on GCStress numbers. @janvorli has run GCStress for crossgen2 images on X64, and I imagine he has some instructions for doing so that you could adapt to Arm64.

{
int ofs;

if (_target.Architecture == TargetArchitecture.X86)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I realize that we don't yet support Crossgen2 for x86, but is removing this special case correct? Should it instead be moved to the OffsetFromGCRefMapPos function?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

This special case is already in OffsetFromGCRefMapPos overload for x86:

publicoverrideintOffsetFromGCRefMapPos(intpos)
{
if(pos<NumArgumentRegisters)
{
returnOffsetOfArgumentRegisters+SizeOfArgumentRegisters-(pos+1)*PointerSize;
}
else
{
returnOffsetOfArgs+(pos-NumArgumentRegisters)*PointerSize;
}
}

@janvorli

Copy link
Copy Markdown
Member

@janvorli has run GCStress for crossgen2 images on X64, and I imagine he has some instructions for doing so that you could adapt to Arm64.

Running with GC stress enabled is as easy as passing --gcstress argument to r2rtest tool (e.g. --gcstress 3). Or, if you are using runtest.cmd, then passing in gcstresslevel argument (and runcrossgen2tests to use crossgen2).

@janvorlijanvorli left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM, thank you!

@MichalStrehovsky

Copy link
Copy Markdown
Member

I sync the type system and compiler back to the CoreRT repo on weekends when I have time

Since we had a public holiday in Slovakia, managed to sync the compiler a bit earlier. dotnet/corert#8122.

@AntonLapounov

Copy link
Copy Markdown
ContributorAuthor

@davidwrighton Below are results of --gcstress 3 for pri-0 tests after the changes. Before the changes the framework could not be compiled with crossgen2.

CompilationCrossgenCPAOT
PASS39873998
FAIL143
Total40014001
ExecutionCrossgenCPAOT
PASS27652754
EXIT_CODE818
CRASHED00
TIMED_OUT66
BUILD_FAILED23
Total27812781

@AntonLapounov

AntonLapounov commented May 1, 2020

Copy link
Copy Markdown
ContributorAuthor

@echesakovMSFT This PR includes minor changes under jit and vm. It would be good to add an assert that if JIT recognizes some type as SIMD (see types in Compiler::getBaseTypeAndSizeOfSIMDType), then the GetHFAType callback returns a valid HFA/HVA type. Otherwise, JIT fails later in the prolog codegen phase or the register allocation phase.

@AntonLapounov

Copy link
Copy Markdown
ContributorAuthor

@CarolEidt Implementation of HFA/HVA property calculation in this PR is free of issues documented in #35144. We need them to be fixed so that Crossgen2 compiler and VM agree on the calling convention. One possible way of fixing that is to introduce a new enumeration for fundamental data types of homogeneous aggregates, like I did in this PR: https://github.com/dotnet/runtime/pull/35576/files#diff-e553d696b7062596f5653d5bba53d278, and use it as the return type of the getHFAType callback. I also suggested adding an assertion for its returned value: #35576 (comment).

@CarolEidt

Copy link
Copy Markdown
Contributor

It would be good to add an assert that if JIT recognizes some type as SIMD (see types in Compiler::getBaseTypeAndSizeOfSIMDType), then the GetHFAType callback returns a valid HFA/HVA type.

Did you want to add that to this PR, or perhaps file an issue for the JIT to do that?

@AntonLapounov - I was previously thinking that fixing #35144 would require a change to the JIT/EE interface, but I believe it's the case that from a JIT perspective it doesn't really need to distinguish between an HFA of double and an HVA of SIMD8. So I think the fix just needs to be made on the vm side of the JIT/EE interface, as you've done here.

@CarolEidtCarolEidt left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The JIT changes LGTM

@AntonLapounov

Copy link
Copy Markdown
ContributorAuthor

Did you want to add that to this PR, or perhaps file an issue for the JIT to do that?

@CarolEidt I would prefer someone with more JIT knowledge to do that. You are right that technically we do not have to change the getHFA API; however, I find using ELEMENT_TYPE_VALUETYPE to actually mean HfaElemKind.HFA_ELEM_SIMD16 (apparently JIT already has this enumeration) less than perfect.

@AntonLapounov
AntonLapounov merged commit 5893741 into dotnet:masterMay 2, 2020
@AntonLapounov
AntonLapounov deleted the Arm64Hva branch May 2, 2020 02:56
@janvorli

Copy link
Copy Markdown
Member

@AntonLapounov as for the timed out tests, can you please try to bump the execution timeout using the --execution-timeout-minutes r2rtest option to see if the timeouts are just taking more time or they represent hangs? You can try to bump it to e.g. 60 minutes to give it enough space.

@ghostghost locked as resolved and limited conversation to collaborators Dec 9, 2020
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@AntonLapounov@MichalStrehovsky@janvorli@CarolEidt@davidwrighton@Dotnet-GitSync-Bot
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Crossgen2: Support HVA for ARM64 - #35576

Merged
AntonLapounov merged 2 commits into
dotnet:masterfrom
AntonLapounov:Arm64Hva
May 2, 2020
Merged

Crossgen2: Support HVA for ARM64#35576
AntonLapounov merged 2 commits into
dotnet:masterfrom
AntonLapounov:Arm64Hva

Conversation

@AntonLapounov

@AntonLapounovAntonLapounov commented Apr 28, 2020

Copy link
Copy Markdown
Contributor

Support ARM64 HVAs in Crossgen2.

  • Change FieldLayoutAlgorithm.ComputeValueTypeShapeCharacteristics method to compute the homogeneous aggregate element type and cache it in the existing field. That allows to remove all ComputeHomogeneousFloatAggregateElementType methods.
  • Change MetadataFieldLayoutAlgorithm.ComputeHomogeneousAggregateCharacteristic to compute HVAs in addition to HFAs.
  • Change CorInfoImpl.getHFAType JIT callback to handle HVAs. Note that returning ELEMENT_TYPE_VALUETYPE indicates the TYP_SIMD16 type (see Compiler::GetHfaType).
  • Change TypeFixupSignature.EncodeTypeLayout to handle HVAs.
  • Support HVAs in the ArgIterator class.
  • Fix TransitionBlock.OffsetFromGCRefMapPos for ARM64. R2RDump used to dump incorrect offsets.
  • Use TransitionBlock.OffsetFromGCRefMapPos in GCRefMapBuilder.GetCallRefMap to simplify logic.
  • Remove ARM64 .NET Native-specific code from TransitionBlock.cs and ArgIterator.cs files.

Minor:

  • Remove a redundant GetVectorSize check in MethodTable::GetHFAType.
  • Improve an assertion in Compiler::raUpdateRegStateForArg.
  • Fix comments in JIT code.

Comment on lines -1259 to -1263
vectorSize = pMT->GetVectorSize();
if (vectorSize != 0)
{
return (vectorSize == 8) ? ELEMENT_TYPE_R8 : ELEMENT_TYPE_VALUETYPE;
}

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

The next loop iteration performs this check anyway, so this one is redundant.

}
else
{
assert(!regState->rsIsFloat);

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

We could miss this check due to the break below, then fail later in an unexpected way.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

cc: @dotnet/jit-contrib

@MichalStrehovsky

Copy link
Copy Markdown
Member

We have xUnit test coverage for these aspects in the CoreRT repo: https://github.com/dotnet/corert/blob/923eeee2fb70497fe07b74d56bc51bee029c108b/src/ILCompiler.TypeSystem/tests/ValueTypeShapeCharacteristicsTests.cs

Issue #200 tracks porting these xUnit tests to the runtime repo, but for now they only compile and run in the experimental CoreRT repo (they will run if you just build.cmd from the root of the repo). I don't know if porting them is on anyone's radar soon (it would be about figuring out how to run xUnit as part of the coreclr managed tools build). Cc @dotnet/crossgen-contrib on that.

We haven't made significant type system changes in the runtime repo yet, so there's no process for this.

I sync the type system and compiler back to the CoreRT repo on weekends when I have time. Truth to be told, when I port this over and tests stop working, I'm just going to delete the tests because I don't have that much time.

If it's not too much hassle, could you do this change in the CoreRT repo too, and adjust/add test coverage as needed? Type system bugs tend to be subtle and that's why we try to unit test as much of it as possible.

You should be able to just xcopy src\coreclr\src\tools\Common\TypeSystem to src\Common\src\TypeSystem and src\coreclr\src\tools\Common\JitInterface to src\JitInterface\src. There's about two weeks worth of diffs because I didn't sync in 2 weeks, but it should be manageable to just undo irrelevant changes.

@davidwrightondavidwrighton left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'd like to see some effect on GCStress numbers. @janvorli has run GCStress for crossgen2 images on X64, and I imagine he has some instructions for doing so that you could adapt to Arm64.

{
int ofs;

if (_target.Architecture == TargetArchitecture.X86)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I realize that we don't yet support Crossgen2 for x86, but is removing this special case correct? Should it instead be moved to the OffsetFromGCRefMapPos function?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

This special case is already in OffsetFromGCRefMapPos overload for x86:

publicoverrideintOffsetFromGCRefMapPos(intpos)
{
if(pos<NumArgumentRegisters)
{
returnOffsetOfArgumentRegisters+SizeOfArgumentRegisters-(pos+1)*PointerSize;
}
else
{
returnOffsetOfArgs+(pos-NumArgumentRegisters)*PointerSize;
}
}

@janvorli

Copy link
Copy Markdown
Member

@janvorli has run GCStress for crossgen2 images on X64, and I imagine he has some instructions for doing so that you could adapt to Arm64.

Running with GC stress enabled is as easy as passing --gcstress argument to r2rtest tool (e.g. --gcstress 3). Or, if you are using runtest.cmd, then passing in gcstresslevel argument (and runcrossgen2tests to use crossgen2).

@janvorlijanvorli left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM, thank you!

@MichalStrehovsky

Copy link
Copy Markdown
Member

I sync the type system and compiler back to the CoreRT repo on weekends when I have time

Since we had a public holiday in Slovakia, managed to sync the compiler a bit earlier. dotnet/corert#8122.

@AntonLapounov

Copy link
Copy Markdown
ContributorAuthor

@davidwrighton Below are results of --gcstress 3 for pri-0 tests after the changes. Before the changes the framework could not be compiled with crossgen2.

CompilationCrossgenCPAOT
PASS39873998
FAIL143
Total40014001
ExecutionCrossgenCPAOT
PASS27652754
EXIT_CODE818
CRASHED00
TIMED_OUT66
BUILD_FAILED23
Total27812781

@AntonLapounov

AntonLapounov commented May 1, 2020

Copy link
Copy Markdown
ContributorAuthor

@echesakovMSFT This PR includes minor changes under jit and vm. It would be good to add an assert that if JIT recognizes some type as SIMD (see types in Compiler::getBaseTypeAndSizeOfSIMDType), then the GetHFAType callback returns a valid HFA/HVA type. Otherwise, JIT fails later in the prolog codegen phase or the register allocation phase.

@AntonLapounov

Copy link
Copy Markdown
ContributorAuthor

@CarolEidt Implementation of HFA/HVA property calculation in this PR is free of issues documented in #35144. We need them to be fixed so that Crossgen2 compiler and VM agree on the calling convention. One possible way of fixing that is to introduce a new enumeration for fundamental data types of homogeneous aggregates, like I did in this PR: https://github.com/dotnet/runtime/pull/35576/files#diff-e553d696b7062596f5653d5bba53d278, and use it as the return type of the getHFAType callback. I also suggested adding an assertion for its returned value: #35576 (comment).

@CarolEidt

Copy link
Copy Markdown
Contributor

It would be good to add an assert that if JIT recognizes some type as SIMD (see types in Compiler::getBaseTypeAndSizeOfSIMDType), then the GetHFAType callback returns a valid HFA/HVA type.

Did you want to add that to this PR, or perhaps file an issue for the JIT to do that?

@AntonLapounov - I was previously thinking that fixing #35144 would require a change to the JIT/EE interface, but I believe it's the case that from a JIT perspective it doesn't really need to distinguish between an HFA of double and an HVA of SIMD8. So I think the fix just needs to be made on the vm side of the JIT/EE interface, as you've done here.

@CarolEidtCarolEidt left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The JIT changes LGTM

@AntonLapounov

Copy link
Copy Markdown
ContributorAuthor

Did you want to add that to this PR, or perhaps file an issue for the JIT to do that?

@CarolEidt I would prefer someone with more JIT knowledge to do that. You are right that technically we do not have to change the getHFA API; however, I find using ELEMENT_TYPE_VALUETYPE to actually mean HfaElemKind.HFA_ELEM_SIMD16 (apparently JIT already has this enumeration) less than perfect.

@AntonLapounov
AntonLapounov merged commit 5893741 into dotnet:masterMay 2, 2020
@AntonLapounov
AntonLapounov deleted the Arm64Hva branch May 2, 2020 02:56
@janvorli

Copy link
Copy Markdown
Member

@AntonLapounov as for the timed out tests, can you please try to bump the execution timeout using the --execution-timeout-minutes r2rtest option to see if the timeouts are just taking more time or they represent hangs? You can try to bump it to e.g. 60 minutes to give it enough space.

@ghostghost locked as resolved and limited conversation to collaborators Dec 9, 2020
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@AntonLapounov@MichalStrehovsky@janvorli@CarolEidt@davidwrighton@Dotnet-GitSync-Bot
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Crossgen2: Support HVA for ARM64 - #35576

Merged
AntonLapounov merged 2 commits into
dotnet:masterfrom
AntonLapounov:Arm64Hva
May 2, 2020
Merged

Crossgen2: Support HVA for ARM64#35576
AntonLapounov merged 2 commits into
dotnet:masterfrom
AntonLapounov:Arm64Hva

Conversation

@AntonLapounov

@AntonLapounovAntonLapounov commented Apr 28, 2020

Copy link
Copy Markdown
Contributor

Support ARM64 HVAs in Crossgen2.

  • Change FieldLayoutAlgorithm.ComputeValueTypeShapeCharacteristics method to compute the homogeneous aggregate element type and cache it in the existing field. That allows to remove all ComputeHomogeneousFloatAggregateElementType methods.
  • Change MetadataFieldLayoutAlgorithm.ComputeHomogeneousAggregateCharacteristic to compute HVAs in addition to HFAs.
  • Change CorInfoImpl.getHFAType JIT callback to handle HVAs. Note that returning ELEMENT_TYPE_VALUETYPE indicates the TYP_SIMD16 type (see Compiler::GetHfaType).
  • Change TypeFixupSignature.EncodeTypeLayout to handle HVAs.
  • Support HVAs in the ArgIterator class.
  • Fix TransitionBlock.OffsetFromGCRefMapPos for ARM64. R2RDump used to dump incorrect offsets.
  • Use TransitionBlock.OffsetFromGCRefMapPos in GCRefMapBuilder.GetCallRefMap to simplify logic.
  • Remove ARM64 .NET Native-specific code from TransitionBlock.cs and ArgIterator.cs files.

Minor:

  • Remove a redundant GetVectorSize check in MethodTable::GetHFAType.
  • Improve an assertion in Compiler::raUpdateRegStateForArg.
  • Fix comments in JIT code.

Comment on lines -1259 to -1263
vectorSize = pMT->GetVectorSize();
if (vectorSize != 0)
{
return (vectorSize == 8) ? ELEMENT_TYPE_R8 : ELEMENT_TYPE_VALUETYPE;
}

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

The next loop iteration performs this check anyway, so this one is redundant.

}
else
{
assert(!regState->rsIsFloat);

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

We could miss this check due to the break below, then fail later in an unexpected way.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

cc: @dotnet/jit-contrib

@MichalStrehovsky

Copy link
Copy Markdown
Member

We have xUnit test coverage for these aspects in the CoreRT repo: https://github.com/dotnet/corert/blob/923eeee2fb70497fe07b74d56bc51bee029c108b/src/ILCompiler.TypeSystem/tests/ValueTypeShapeCharacteristicsTests.cs

Issue #200 tracks porting these xUnit tests to the runtime repo, but for now they only compile and run in the experimental CoreRT repo (they will run if you just build.cmd from the root of the repo). I don't know if porting them is on anyone's radar soon (it would be about figuring out how to run xUnit as part of the coreclr managed tools build). Cc @dotnet/crossgen-contrib on that.

We haven't made significant type system changes in the runtime repo yet, so there's no process for this.

I sync the type system and compiler back to the CoreRT repo on weekends when I have time. Truth to be told, when I port this over and tests stop working, I'm just going to delete the tests because I don't have that much time.

If it's not too much hassle, could you do this change in the CoreRT repo too, and adjust/add test coverage as needed? Type system bugs tend to be subtle and that's why we try to unit test as much of it as possible.

You should be able to just xcopy src\coreclr\src\tools\Common\TypeSystem to src\Common\src\TypeSystem and src\coreclr\src\tools\Common\JitInterface to src\JitInterface\src. There's about two weeks worth of diffs because I didn't sync in 2 weeks, but it should be manageable to just undo irrelevant changes.

@davidwrightondavidwrighton left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'd like to see some effect on GCStress numbers. @janvorli has run GCStress for crossgen2 images on X64, and I imagine he has some instructions for doing so that you could adapt to Arm64.

{
int ofs;

if (_target.Architecture == TargetArchitecture.X86)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I realize that we don't yet support Crossgen2 for x86, but is removing this special case correct? Should it instead be moved to the OffsetFromGCRefMapPos function?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

This special case is already in OffsetFromGCRefMapPos overload for x86:

publicoverrideintOffsetFromGCRefMapPos(intpos)
{
if(pos<NumArgumentRegisters)
{
returnOffsetOfArgumentRegisters+SizeOfArgumentRegisters-(pos+1)*PointerSize;
}
else
{
returnOffsetOfArgs+(pos-NumArgumentRegisters)*PointerSize;
}
}

@janvorli

Copy link
Copy Markdown
Member

@janvorli has run GCStress for crossgen2 images on X64, and I imagine he has some instructions for doing so that you could adapt to Arm64.

Running with GC stress enabled is as easy as passing --gcstress argument to r2rtest tool (e.g. --gcstress 3). Or, if you are using runtest.cmd, then passing in gcstresslevel argument (and runcrossgen2tests to use crossgen2).

@janvorlijanvorli left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM, thank you!

@MichalStrehovsky

Copy link
Copy Markdown
Member

I sync the type system and compiler back to the CoreRT repo on weekends when I have time

Since we had a public holiday in Slovakia, managed to sync the compiler a bit earlier. dotnet/corert#8122.

@AntonLapounov

Copy link
Copy Markdown
ContributorAuthor

@davidwrighton Below are results of --gcstress 3 for pri-0 tests after the changes. Before the changes the framework could not be compiled with crossgen2.

CompilationCrossgenCPAOT
PASS39873998
FAIL143
Total40014001
ExecutionCrossgenCPAOT
PASS27652754
EXIT_CODE818
CRASHED00
TIMED_OUT66
BUILD_FAILED23
Total27812781

@AntonLapounov

AntonLapounov commented May 1, 2020

Copy link
Copy Markdown
ContributorAuthor

@echesakovMSFT This PR includes minor changes under jit and vm. It would be good to add an assert that if JIT recognizes some type as SIMD (see types in Compiler::getBaseTypeAndSizeOfSIMDType), then the GetHFAType callback returns a valid HFA/HVA type. Otherwise, JIT fails later in the prolog codegen phase or the register allocation phase.

@AntonLapounov

Copy link
Copy Markdown
ContributorAuthor

@CarolEidt Implementation of HFA/HVA property calculation in this PR is free of issues documented in #35144. We need them to be fixed so that Crossgen2 compiler and VM agree on the calling convention. One possible way of fixing that is to introduce a new enumeration for fundamental data types of homogeneous aggregates, like I did in this PR: https://github.com/dotnet/runtime/pull/35576/files#diff-e553d696b7062596f5653d5bba53d278, and use it as the return type of the getHFAType callback. I also suggested adding an assertion for its returned value: #35576 (comment).

@CarolEidt

Copy link
Copy Markdown
Contributor

It would be good to add an assert that if JIT recognizes some type as SIMD (see types in Compiler::getBaseTypeAndSizeOfSIMDType), then the GetHFAType callback returns a valid HFA/HVA type.

Did you want to add that to this PR, or perhaps file an issue for the JIT to do that?

@AntonLapounov - I was previously thinking that fixing #35144 would require a change to the JIT/EE interface, but I believe it's the case that from a JIT perspective it doesn't really need to distinguish between an HFA of double and an HVA of SIMD8. So I think the fix just needs to be made on the vm side of the JIT/EE interface, as you've done here.

@CarolEidtCarolEidt left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The JIT changes LGTM

@AntonLapounov

Copy link
Copy Markdown
ContributorAuthor

Did you want to add that to this PR, or perhaps file an issue for the JIT to do that?

@CarolEidt I would prefer someone with more JIT knowledge to do that. You are right that technically we do not have to change the getHFA API; however, I find using ELEMENT_TYPE_VALUETYPE to actually mean HfaElemKind.HFA_ELEM_SIMD16 (apparently JIT already has this enumeration) less than perfect.

@AntonLapounov
AntonLapounov merged commit 5893741 into dotnet:masterMay 2, 2020
@AntonLapounov
AntonLapounov deleted the Arm64Hva branch May 2, 2020 02:56
@janvorli

Copy link
Copy Markdown
Member

@AntonLapounov as for the timed out tests, can you please try to bump the execution timeout using the --execution-timeout-minutes r2rtest option to see if the timeouts are just taking more time or they represent hangs? You can try to bump it to e.g. 60 minutes to give it enough space.

@ghostghost locked as resolved and limited conversation to collaborators Dec 9, 2020
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@AntonLapounov@MichalStrehovsky@janvorli@CarolEidt@davidwrighton@Dotnet-GitSync-Bot