-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Armel support in crossgen2 #43706
Armel support in crossgen2 #43706
Conversation
@t-mustafin These are my changes to enable armel targetting from crossgen2. As I have no armel hardware or test environments, I have not tested the behavior of this. @dotnet/jit-contrib This modifies the jit to be dynamically configurable for the ARM_SOFTFP and FEATURE_HFA ifdefs. I'd like some opinions on this approach, as I plan to make similar changes for the arm64 on OSX work that is ongoing, as well as possibly an attempt to compile a single arm and arm64 jit which targets both unix and Windows platforms. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm intrigued by the ability to build a single binary to target multiple ABIs but still enable compile time specific code to avoid runtime overhead in some cases. I'm much more skeptical about something grander, such as arm/arm64 unification, compared to arm softfp, which is relatively small.
#ifdef UNIX_AMD64_ABI | ||
if (true) | ||
#else // !UNIX_AMD64_ABI | ||
if (GlobalJitOptions::compFeatureHfa) | ||
#endif // UNIX_AMD64_ABI |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Couldn't this just be:
#if !defined(UNIX_AMD64_ABI)
if (GlobalJitOptions::compFeatureHfa)
#endif // !UNIX_AMD64_ABI
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
src/coreclr/src/jit/compiler.cpp
Outdated
opts.compUseSoftFP = !!JitConfig.JitSoftFP(); | ||
if (opts.compUseSoftFP) | ||
{ | ||
GlobalJitOptions::compFeatureHfa = !opts.compUseSoftFP; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure we want this as a static global. It seems like it needs to be a member of the Compiler
object. What if we want to allow compiling both for arm and armel in the same process? Or if multiple threads try to initialize this concurrently?
Also, I don't think the config variable JitSoftFP should be the way this ABI is communicated to the JIT; it should come in via the jit flags, as a CorJitFlag.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem with compFeatureHfa is that it needs to be useable from the code in the code in LclVarDsc and fgArgTabEntry structures which don't have access to a Compiler object to query. Of course, I could pass the Compiler* as a parameter to these functions, but that didn't seem like a good approach. Given that the current model for usage of this is to only support one target architecture per process, I just went with a static. An alternative approach would be to use a threadstatic, which would allow for different compilations in the same process to have different values.
In reply to: 510494195 [](ancestors = 510494195)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We already stash Compiler*
in a thread static: JitTls::GetCompiler()
, but I'm not sure it's used in non-DEBUG code.
src/coreclr/src/jit/compiler.cpp
Outdated
@@ -469,49 +474,6 @@ var_types Compiler::getJitGCType(BYTE gcType) | |||
return result; | |||
} | |||
|
|||
#ifdef ARM_SOFTFP |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess this appeared to be statically dead code?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this was only callable when FEATURE_HFA was true, except that ARM_SOFTFP also disables FEATURE_HFA.
In reply to: 510494655 [](ancestors = 510494655)
src/coreclr/src/jit/compiler.h
Outdated
#else | ||
return false; | ||
#endif | ||
NYI("GetLvHfaElemKind"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These NYI
should be NOWAY
, since they're never going to be implemented, it not that they are "not yet implemented".
src/coreclr/src/jit/lower.cpp
Outdated
@@ -3231,38 +3231,39 @@ void Lowering::LowerStoreLocCommon(GenTreeLclVarCommon* lclStore) | |||
// | |||
void Lowering::LowerRetStruct(GenTreeUnOp* ret) | |||
{ | |||
#if defined(FEATURE_HFA) && defined(TARGET_ARM64) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why remove the #if defined(TARGET_ARM64)
? You've enabled this code for arm32. Is that correct? Maybe you can get away with it because we don't support SIMD on arm32.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did not intend to make this change. Thank you for catching it.
In reply to: 510499387 [](ancestors = 510499387)
src/coreclr/src/jit/lower.cpp
Outdated
// `call->HasMultiRegRetVal()` count double registers. | ||
assert(comp->GetHfaCount(call) <= 2); | ||
#else // !TARGET_ARM64 && !TARGET_ARM | ||
NYI("Unknown architecture"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why change this from unreached()
to NYI
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It turns out that part of the #if statement was never reached because of the #if which used to wrap it, and unreached() causes a compiler error now as the followon statements start producing errors. I'll change it to NOWAY from NYI per your other comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Upon reflection, this should actually probably remain as an NYI.
In reply to: 511061420 [](ancestors = 511061420)
@@ -42,6 +42,10 @@ public enum TargetAbi | |||
/// </summary> | |||
CoreRT, | |||
/// <summary> | |||
/// model for armel execution model | |||
/// </summary> | |||
CoreRTArmel, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you consider making this a TargetArchitecture
instead? A separate TargetArchitecture is how we had it until it got deleted because there was no use for it at that point.
We could put a helper on TargetDetails
to help normalize those two into one for places that don't care about the distinction.
My thinking is that while hard
/softfp
distinction is only about the ABI, if we ever add support for soft
- that's not just ABI anymore. I would just treat it as a very similar, but still a bit different CPU.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(I don't have strong opinion either way, it's just we still keep TargetAbi.Jit
and if we ever resurrect that and have to add JitArmel for parity, it feels a bit confusing.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is all very confusing, and I agree its this isn't a very stable model within the compiler. The problem is that we tend to check for architecture with a simple equality check, and there are quite a few checks (and it would be really easy to get this wrong as we don't actively test this.).
With the abi, as this change is actually specific to the abi, and we don't have many abi checks in the product, this seemed safer and less risky going forward.
What I meant by single arm and arm64 jits is that we would produce and arm targetting jit that handled all the various ABIs, Windows, Linux, Linux with Armel abi, and that we will generate a single arm64 jit, which targets Windows, Linux, and MacOS. I agree, merging the different architectures is a lost cause. Also, merging the X64 jit is a lot more work than the Arm one, as there are many more differences between Windows and Unix. In reply to: 515161729 [](ancestors = 515161729) |
src/coreclr/src/jit/lclvars.cpp
Outdated
@@ -2821,14 +2823,15 @@ void Compiler::makeExtraStructQueries(CORINFO_CLASS_HANDLE structHandle, int lev | |||
|
|||
void Compiler::lvaSetStructUsedAsVarArg(unsigned varNum) | |||
{ | |||
#ifdef FEATURE_HFA | |||
if (GlobalJitOptions::compFeatureHfa) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this if can be removed. The existing #ifdef for FEATURE_HFA was imo redundant.
b2c7f1e
to
f911918
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Sorry for a long answering. Results on master_0e402bc + cherry-picked 1st_commit and 2nd_commit: Results on master_0e402bc for reference: Unfortunatelly patched.tar.gz is not a full log, cause I do not got it yet. I will restart testing with all patches from the PR and more recent master. |
Ah, ok, from the logs it appears that the way you are using crossgen2, you are not using the --targetarch switch to pass armel to crossgen2. And, unlike all of the other architectures, when run locally, armel isn't autodetected (as there is no platform api that will provide that bit of information.). Fortunately, I believe that is pretty simple to fix. I'll fix that, as well as the build break you noticed. |
@t-mustafin Actually, I've just fixed the build break. I don't believe I fully understand the means by which you are running crossgen2, and the environment. As of the last PR you submitted, I believe that crossgen2 should be failing while trying to load libjitinterface_arm.so when you actually are building libjitinterface_armel.so. Did you do something like add a new enum value to the Architecture enum in System.InteropServices.RuntimeInformation that is Armel? In any case, you should be passing the |
Two tests starts to fail:
One test starts to pass, looking at another runs seems it is unstable:
Results on master_7d15ecf + cherry picked commits 1 2 3 4 5 6 Also I would like to run tests after cross compiling on x64 to armel, but not done it yet. |
Results with cross generated ni files on x64. Libs failed to cross-generate, that generates on native-run:
Tests was failed to cross-generate, that native-generated successfully:
Tests was failed after cross-generate, that pass after native-generate:
Roughly it looks good: 11 tests fails + 13 crossgen fails compared with 112 fails on master branch. Does native-generated and cross-generated ni files should be equal? I got different hashes for it.
Cross:
cc @alpencolt |
src/coreclr/src/jit/jit.h
Outdated
@@ -514,7 +535,7 @@ typedef ptrdiff_t ssize_t; | |||
|
|||
#if DUMP_GC_TABLES | |||
#pragma message("NOTE: this non-debug build has GC ptr table dumping always enabled!") | |||
const bool dspGCtbls = true; | |||
const bool dspGCtbls = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you did not mean to insert those spaces.
// Auto-generated message 69e114c which was merged 12/7 removed the intermediate src/coreclr/src/ folder. This PR needs to be updated as it touches files in that directory which causes conflicts. To update your commits you can use this bash script: https://gist.github.com/ViktorHofer/6d24f62abdcddb518b4966ead5ef3783. Feel free to use the comment section of the gist to improve the script for others. |
@davidwrighton @t-mustafin assume we should still merge these changes? Is there anything blocking other than resolving conflicts since its a been a few months since this was opened? |
Yes, we need this changes. I have already appreved it, let it merge please. |
since this has been dormant for a few months, the conflicts need some manual resolving. @davidwrighton if you think they should be straightforward I can have someone shepherd this through. |
@davidwrighton Could you look into #49347 ? |
…armhf and armel calling conventions Crossgen2 managed code changes to support Armel abi - Adjust handling for armel target architecture command line handling to capture that armel is the abi - Tweak field layout to disable computation of hfa status for valuetypes - Inform JIT that armel abi is to be used - Add armel abi value to TargetAbi enum Checkin requested changes Fix build on Unix platforms Make the JIT built for crossgen2 be dynamically configurable between armhf and armel calling conventions Crossgen2 managed code changes to support Armel abi - Adjust handling for armel target architecture command line handling to capture that armel is the abi - Tweak field layout to disable computation of hfa status for valuetypes - Inform JIT that armel abi is to be used - Add armel abi value to TargetAbi enum Checkin requested changes Fix build on Unix platforms Reformat the code Fix build break Fix Windows build Code review - Use static variable, but protect from misuse with NO_WAY - Pass info to jit via jitflag, not via jit config tweak variable type Address jit format issue Fix build break
4221196
to
e92b859
Compare
This change adds support for armel target compilation in crossgen2
To use the feature compile an application using the --targetos Linux and --targetarch armel flags.
Summary of changes
With this change it becomes possible to run crossgen2 on a Windows or Linux machine and target a Linux Armel target.