-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Description
#100138 introduced a new representation for ABI information that I am planning on switching the JIT to use in all places that deal with ABI details. It explicitly represents how all parts of all parameters are passed. #100276 and #100526 introduced classifiers for all of our supported targets: win-x86, win-x64, SysV x64, arm64 and arm32.
#100572 is an example PR that is making use of the new ABI representation to rewrite parameter homing.
Before I can proceed with moving the rest of the JIT to the new representation we need implementations of new-style classifiers for LA64 (cc @shushanhf) and RISCV64 (cc @dotnet/samsung). I would greatly appreciate contributions of implementations of these. Otherwise I can try to base it on what happens in lvaInitUserArgs today, but I will not be able to test it.
Once implemented, the following code can be enabled to cross check the new style ABI information against the old one stored in LclVarDsc:
runtime/src/coreclr/jit/lclvars.cpp
Lines 1809 to 1892 in 9b57a26
| #if defined(TARGET_X86) || defined(TARGET_AMD64) || defined(TARGET_ARM64) || defined(TARGET_ARM) | |
| { | |
| PlatformClassifier classifier(cInfo); | |
| lvaClassifyParameterABI(classifier); | |
| } | |
| #endif | |
| #ifdef DEBUG | |
| if (lvaParameterPassingInfo == nullptr) | |
| { | |
| return; | |
| } | |
| for (unsigned lclNum = 0; lclNum < info.compArgsCount; lclNum++) | |
| { | |
| LclVarDsc* dsc = lvaGetDesc(lclNum); | |
| const ABIPassingInformation& abiInfo = lvaParameterPassingInfo[lclNum]; | |
| assert(abiInfo.NumSegments > 0); | |
| if ((dsc->TypeGet() == TYP_STRUCT) && (info.compCallConv == CorInfoCallConvExtension::Swift)) | |
| { | |
| continue; | |
| } | |
| unsigned numSegmentsToCompare = abiInfo.NumSegments; | |
| if (dsc->lvIsHfa()) | |
| { | |
| // LclVarDsc only has one register set for HFAs | |
| numSegmentsToCompare = 1; | |
| } | |
| #ifdef TARGET_ARM | |
| // On arm the old representation only represents the start register for | |
| // struct multireg args. | |
| if (varTypeIsStruct(dsc)) | |
| { | |
| numSegmentsToCompare = 1; | |
| } | |
| // And also for TYP_DOUBLE on soft FP | |
| if (opts.compUseSoftFP && (dsc->TypeGet() == TYP_DOUBLE)) | |
| { | |
| numSegmentsToCompare = 1; | |
| } | |
| #endif | |
| for (unsigned i = 0; i < numSegmentsToCompare; i++) | |
| { | |
| const ABIPassingSegment& expected = abiInfo.Segments[i]; | |
| regNumber reg = REG_NA; | |
| if (i == 0) | |
| { | |
| reg = dsc->GetArgReg(); | |
| } | |
| #if FEATURE_MULTIREG_ARGS | |
| else if (i == 1) | |
| { | |
| reg = dsc->GetOtherArgReg(); | |
| } | |
| #endif | |
| if (expected.IsPassedOnStack()) | |
| { | |
| if (i == 0) | |
| { | |
| assert(reg == REG_STK); | |
| // On x86, varargs methods access stack args off of a base pointer, and the | |
| // first stack arg is not considered to be at offset 0. | |
| // TODO-Cleanup: Unify things so that x86 is consistent with other platforms | |
| // here and change fgMorphExpandStackArgForVarArgs to account for that. | |
| #ifndef TARGET_X86 | |
| assert((unsigned)dsc->GetStackOffset() == expected.GetStackOffset()); | |
| #endif | |
| } | |
| } | |
| else | |
| { | |
| assert(reg == expected.GetRegister()); | |
| } | |
| } | |
| } | |
| #endif // DEBUG |
Eventually the old information will be removed from
LclVarDsc and the new style information will be the only source-of-truth for the ABI information.