From 97125ca7e5e7ef78cad57ca6a90a1b64a0702538 Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Thu, 26 Aug 2021 18:03:29 -0700 Subject: [PATCH 01/15] Move most OS specific handling in JIT to flag checks - Except for ABI specific details... - Notably the FEATURE_ARG_SPLIT for ARM32 and the OSX ARM64 abi differences --- src/coreclr/inc/switches.h | 55 ++++++++++++++++++++++++++ src/coreclr/inc/winwrap.h | 6 +-- src/coreclr/jit/codegenarm64.cpp | 8 +--- src/coreclr/jit/codegencommon.cpp | 23 +++++------ src/coreclr/jit/codegenxarch.cpp | 63 +++++++++++++++-------------- src/coreclr/jit/compiler.cpp | 38 +++++++++++------- src/coreclr/jit/compiler.h | 51 ++++++++++-------------- src/coreclr/jit/compiler.hpp | 8 ++-- src/coreclr/jit/ee_il_dll.cpp | 4 +- src/coreclr/jit/error.h | 2 +- src/coreclr/jit/gentree.h | 10 +++-- src/coreclr/jit/importer.cpp | 15 ++++--- src/coreclr/jit/jit.h | 14 ++++++- src/coreclr/jit/lclvars.cpp | 31 +++++++-------- src/coreclr/jit/lower.cpp | 66 +++++++++++++++++-------------- src/coreclr/jit/lsrabuild.cpp | 10 ++--- src/coreclr/jit/lsraxarch.cpp | 4 +- src/coreclr/jit/morph.cpp | 23 +++++------ src/coreclr/jit/target.h | 9 ++--- src/coreclr/jit/targetamd64.h | 6 +-- src/coreclr/jit/unwind.cpp | 19 +++++---- src/coreclr/jit/unwindarm.cpp | 56 +++++++++++++------------- src/coreclr/jit/unwindarm64.cpp | 32 +++++++-------- src/coreclr/jit/unwindx86.cpp | 4 +- src/coreclr/jit/utils.cpp | 13 ------ 25 files changed, 306 insertions(+), 264 deletions(-) diff --git a/src/coreclr/inc/switches.h b/src/coreclr/inc/switches.h index ab75ce0b7f18ba..789cddd3455e4b 100644 --- a/src/coreclr/inc/switches.h +++ b/src/coreclr/inc/switches.h @@ -175,4 +175,59 @@ #define FEATURE_STACK_SAMPLING #endif // defined (ALLOW_SXS_JIT) +#ifndef TARGET_OS_ARCH_CLASS +#define TARGET_OS_ARCH_CLASS +class TargetOS +{ +public: +#ifdef TARGET_WINDOWS +#define TARGET_WINDOWS_POSSIBLY_SUPPORTED + static const bool IsWindows = true; + static const bool IsUnix = false; +#elif defined(TARGET_UNIX) +#define TARGET_UNIX_POSSIBLY_SUPPORTED + static const bool IsWindows = false; + static const bool IsUnix = true; +#else +#define TARGET_WINDOWS_POSSIBLY_SUPPORTED +#define TARGET_UNIX_POSSIBLY_SUPPORTED +#define TARGET_OS_RUNTIMEDETERMINED + static bool OSSettingConfigured; + static bool IsWindows; + static bool IsUnix; +#endif +}; + +class TargetArchitecture +{ +public: +#ifdef TARGET_ARM + static const bool IsX86 = false; + static const bool IsX64 = false; + static const bool IsArm64 = false; + static const bool IsArm32 = true; + static const bool IsArmArch = true; +#elif defined(TARGET_ARM64) + static const bool IsX86 = false; + static const bool IsX64 = false; + static const bool IsArm64 = true; + static const bool IsArm32 = false; + static const bool IsArmArch = true; +#elif defined(TARGET_AMD64) + static const bool IsX86 = false; + static const bool IsX64 = true; + static const bool IsArm64 = false; + static const bool IsArm32 = false; + static const bool IsArmArch = false; +#elif defined(TARGET_X86) + static const bool IsX86 = true; + static const bool IsX64 = false; + static const bool IsArm64 = false; + static const bool IsArm32 = false; + static const bool IsArmArch = false; +#else +#error Unknown architecture +#endif +}; +#endif // TARGET_OS_ARCH_CLASS diff --git a/src/coreclr/inc/winwrap.h b/src/coreclr/inc/winwrap.h index 570ca5ba19c03d..15c193ee36720d 100644 --- a/src/coreclr/inc/winwrap.h +++ b/src/coreclr/inc/winwrap.h @@ -259,11 +259,11 @@ inline DWORD GetMaxDBCSCharByteSize() #endif // HOST_UNIX } -#ifndef TARGET_UNIX +#ifndef HOST_UNIX BOOL RunningInteractive(); -#else // !TARGET_UNIX +#else // !HOST_UNIX #define RunningInteractive() FALSE -#endif // !TARGET_UNIX +#endif // !HOST_UNIX #ifndef Wsz_mbstowcs #define Wsz_mbstowcs(szOut, szIn, iSize) WszMultiByteToWideChar(CP_ACP, 0, szIn, -1, szOut, iSize) diff --git a/src/coreclr/jit/codegenarm64.cpp b/src/coreclr/jit/codegenarm64.cpp index 33e7ec55a9ce4e..3cbac7895dad3a 100644 --- a/src/coreclr/jit/codegenarm64.cpp +++ b/src/coreclr/jit/codegenarm64.cpp @@ -246,12 +246,10 @@ void CodeGen::genPrologSaveRegPair(regNumber reg1, assert((spOffset % 8) == 0); GetEmitter()->emitIns_R_R_R_I(INS_stp, EA_PTRSIZE, reg1, reg2, REG_SPBASE, spOffset); -#if defined(TARGET_UNIX) - if (compiler->generateCFIUnwindCodes()) + if (TargetOS::IsUnix && compiler->generateCFIUnwindCodes()) { useSaveNextPair = false; } -#endif // TARGET_UNIX if (useSaveNextPair) { @@ -381,12 +379,10 @@ void CodeGen::genEpilogRestoreRegPair(regNumber reg1, { GetEmitter()->emitIns_R_R_R_I(INS_ldp, EA_PTRSIZE, reg1, reg2, REG_SPBASE, spOffset); -#if defined(TARGET_UNIX) - if (compiler->generateCFIUnwindCodes()) + if (TargetOS::IsUnix && compiler->generateCFIUnwindCodes()) { useSaveNextPair = false; } -#endif // TARGET_UNIX if (useSaveNextPair) { diff --git a/src/coreclr/jit/codegencommon.cpp b/src/coreclr/jit/codegencommon.cpp index be04e20b37f7b3..17e5fa5f0ee8ef 100644 --- a/src/coreclr/jit/codegencommon.cpp +++ b/src/coreclr/jit/codegencommon.cpp @@ -2180,11 +2180,14 @@ void CodeGen::genGenerateMachineCode() printf("unknown architecture"); } -#if defined(TARGET_WINDOWS) - printf(" - Windows"); -#elif defined(TARGET_UNIX) - printf(" - Unix"); -#endif + if (TargetOS::IsWindows) + { + printf(" - Windows"); + } + else if (TargetOS::IsUnix) + { + printf(" - Unix"); + } printf("\n"); @@ -3392,11 +3395,9 @@ void CodeGen::genFnPrologCalleeRegArgs(regNumber xtraReg, bool* pXtraRegClobbere // Check if this is an HFA register arg and return the HFA type if (varDsc.lvIsHfaRegArg()) { -#if defined(TARGET_WINDOWS) // Cannot have hfa types on windows arm targets // in vararg methods. - assert(!compiler->info.compIsVarArgs); -#endif // defined(TARGET_WINDOWS) + assert(!TargetOS::IsWindows || !compiler->info.compIsVarArgs); return varDsc.GetHfaType(); } return compiler->mangleVarArgsType(varDsc.lvType); @@ -3463,12 +3464,12 @@ void CodeGen::genFnPrologCalleeRegArgs(regNumber xtraReg, bool* pXtraRegClobbere // Change regType to the HFA type when we have a HFA argument if (varDsc->lvIsHfaRegArg()) { -#if defined(TARGET_WINDOWS) && defined(TARGET_ARM64) - if (compiler->info.compIsVarArgs) +#if defined(TARGET_ARM64) + if (TargetOS::IsWindows && compiler->info.compIsVarArgs) { assert(!"Illegal incoming HFA arg encountered in Vararg method."); } -#endif // defined(TARGET_WINDOWS) && defined(TARGET_ARM64) +#endif // defined(TARGET_ARM64) regType = varDsc->GetHfaType(); } diff --git a/src/coreclr/jit/codegenxarch.cpp b/src/coreclr/jit/codegenxarch.cpp index 071f5c2b23156f..307e6954577f4d 100644 --- a/src/coreclr/jit/codegenxarch.cpp +++ b/src/coreclr/jit/codegenxarch.cpp @@ -1978,29 +1978,32 @@ void CodeGen::genMultiRegStoreToSIMDLocal(GenTreeLclVar* lclNode) inst_RV_RV_IV(INS_shufpd, EA_16BYTE, targetReg, targetReg, 0x01); } genProduceReg(lclNode); -#elif defined(TARGET_X86) && defined(TARGET_WINDOWS) - assert(varTypeIsIntegral(retTypeDesc->GetReturnRegType(0))); - assert(varTypeIsIntegral(retTypeDesc->GetReturnRegType(1))); - assert(lclNode->TypeIs(TYP_SIMD8)); +#elif defined(TARGET_X86) + if (TargetOS::IsWindows) + { + assert(varTypeIsIntegral(retTypeDesc->GetReturnRegType(0))); + assert(varTypeIsIntegral(retTypeDesc->GetReturnRegType(1))); + assert(lclNode->TypeIs(TYP_SIMD8)); - // This is a case where a SIMD8 struct returned as [EAX, EDX] - // and needs to be assembled into a single xmm register, - // note we can't check reg0=EAX, reg1=EDX because they could be already moved. + // This is a case where a SIMD8 struct returned as [EAX, EDX] + // and needs to be assembled into a single xmm register, + // note we can't check reg0=EAX, reg1=EDX because they could be already moved. - inst_Mov(TYP_FLOAT, targetReg, reg0, /* canSkip */ false); - const emitAttr size = emitTypeSize(TYP_SIMD8); - if (compiler->compOpportunisticallyDependsOn(InstructionSet_SSE41)) - { - GetEmitter()->emitIns_SIMD_R_R_R_I(INS_pinsrd, size, targetReg, targetReg, reg1, 1); - } - else - { - regNumber tempXmm = lclNode->GetSingleTempReg(); - inst_Mov(TYP_FLOAT, tempXmm, reg1, /* canSkip */ false); - GetEmitter()->emitIns_SIMD_R_R_R(INS_punpckldq, size, targetReg, targetReg, tempXmm); + inst_Mov(TYP_FLOAT, targetReg, reg0, /* canSkip */ false); + const emitAttr size = emitTypeSize(TYP_SIMD8); + if (compiler->compOpportunisticallyDependsOn(InstructionSet_SSE41)) + { + GetEmitter()->emitIns_SIMD_R_R_R_I(INS_pinsrd, size, targetReg, targetReg, reg1, 1); + } + else + { + regNumber tempXmm = lclNode->GetSingleTempReg(); + inst_Mov(TYP_FLOAT, tempXmm, reg1, /* canSkip */ false); + GetEmitter()->emitIns_SIMD_R_R_R(INS_punpckldq, size, targetReg, targetReg, tempXmm); + } } -#elif defined(TARGET_WINDOWS) && defined(TARGET_AMD64) - assert(!"Multireg store to SIMD reg not supported on Windows x64"); +#elif defined(TARGET_AMD64) + assert(!TargetOS::IsWindows && !"Multireg store to SIMD reg not supported on Windows x64"); #else #error Unsupported or unset target architecture #endif @@ -5100,18 +5103,16 @@ void CodeGen::genCallInstruction(GenTreeCall* call) emitActualTypeSize(TYP_I_IMPL)); } -#if FEATURE_VARARG // In the case of a varargs call, // the ABI dictates that if we have floating point args, // we must pass the enregistered arguments in both the // integer and floating point registers so, let's do that. - if (call->IsVarargs() && varTypeIsFloating(argNode)) + if (GlobalJitOptions::compFeatureVarArg() && call->IsVarargs() && varTypeIsFloating(argNode)) { regNumber srcReg = argNode->GetRegNum(); regNumber targetReg = compiler->getCallArgIntRegister(argNode->GetRegNum()); inst_Mov(TYP_LONG, targetReg, srcReg, /* canSkip */ false, emitActualTypeSize(TYP_I_IMPL)); } -#endif // FEATURE_VARARG } #if defined(TARGET_X86) || defined(UNIX_AMD64_ABI) @@ -5832,12 +5833,12 @@ void CodeGen::genJmpMethod(GenTree* jmp) } } -#if FEATURE_VARARG && defined(TARGET_AMD64) +#if defined(TARGET_AMD64) // In case of a jmp call to a vararg method also pass the float/double arg in the corresponding int arg // register. This is due to the AMD64 ABI which requires floating point values passed to varargs functions to // be passed in both integer and floating point registers. It doesn't apply to x86, which passes floating point // values on the stack. - if (compiler->info.compIsVarArgs) + if (GlobalJitOptions::compFeatureVarArg() && compiler->info.compIsVarArgs) { regNumber intArgReg; var_types loadType = varDsc->lvaArgType(); @@ -5861,10 +5862,10 @@ void CodeGen::genJmpMethod(GenTree* jmp) firstArgVarNum = varNum; } } -#endif // FEATURE_VARARG +#endif // TARGET_AMD64 } -#if FEATURE_VARARG && defined(TARGET_AMD64) +#if defined(TARGET_AMD64) // Jmp call to a vararg method - if the method has fewer than 4 fixed arguments, // load the remaining arg registers (both int and float) from the corresponding // shadow stack slots. This is for the reason that we don't know the number and type @@ -5877,7 +5878,7 @@ void CodeGen::genJmpMethod(GenTree* jmp) // The caller could have passed gc-ref/byref type var args. Since these are var args // the callee no way of knowing their gc-ness. Therefore, mark the region that loads // remaining arg registers from shadow stack slots as non-gc interruptible. - if (fixedIntArgMask != RBM_NONE) + if (GlobalJitOptions::compFeatureVarArg() && fixedIntArgMask != RBM_NONE) { assert(compiler->info.compIsVarArgs); assert(firstArgVarNum != BAD_VAR_NUM); @@ -5906,7 +5907,7 @@ void CodeGen::genJmpMethod(GenTree* jmp) GetEmitter()->emitEnableGC(); } } -#endif // FEATURE_VARARG +#endif // TARGET_AMD64 } // produce code for a GT_LEA subnode @@ -8709,13 +8710,11 @@ void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegZeroed) GetEmitter()->emitIns_R_S(load_ins, emitTypeSize(loadType), argReg, varNum, 0); -#if FEATURE_VARARG - if (compiler->info.compIsVarArgs && varTypeIsFloating(loadType)) + if (GlobalJitOptions::compFeatureVarArg() && compiler->info.compIsVarArgs && varTypeIsFloating(loadType)) { regNumber intArgReg = compiler->getCallArgIntRegister(argReg); inst_Mov(TYP_LONG, intArgReg, argReg, /* canSkip */ false, emitActualTypeSize(loadType)); } -#endif // FEATURE_VARARG } // If initReg is one of RBM_CALLEE_TRASH, then it needs to be zero'ed before using. diff --git a/src/coreclr/jit/compiler.cpp b/src/coreclr/jit/compiler.cpp index 2c35262a5df0db..20fa2d40072ba6 100644 --- a/src/coreclr/jit/compiler.cpp +++ b/src/coreclr/jit/compiler.cpp @@ -615,11 +615,9 @@ var_types Compiler::getPrimitiveTypeForStruct(unsigned structSize, CORINFO_CLASS // Start by determining if we have an HFA/HVA with a single element. if (GlobalJitOptions::compFeatureHfa) { -#if defined(TARGET_WINDOWS) && defined(TARGET_ARM64) // Arm64 Windows VarArg methods arguments will not classify HFA types, they will need to be treated // as if they are not HFA types. - if (!isVarArg) -#endif // defined(TARGET_WINDOWS) && defined(TARGET_ARM64) + if (!(TargetArchitecture::IsArm64 && TargetOS::IsWindows && isVarArg)) { switch (structSize) { @@ -810,13 +808,11 @@ var_types Compiler::getArgTypeForStruct(CORINFO_CLASS_HANDLE clsHnd, // Arm64 Windows VarArg methods arguments will not classify HFA/HVA types, they will need to be treated // as if they are not HFA/HVA types. var_types hfaType; -#if defined(TARGET_WINDOWS) && defined(TARGET_ARM64) - if (isVarArg) + if (TargetArchitecture::IsArm64 && TargetOS::IsWindows && isVarArg) { hfaType = TYP_UNDEF; } else -#endif // defined(TARGET_WINDOWS) && defined(TARGET_ARM64) { hfaType = GetHfaType(clsHnd); } @@ -1028,14 +1024,13 @@ var_types Compiler::getReturnTypeForStruct(CORINFO_CLASS_HANDLE clsHnd, howToReturnStruct = SPK_ByReference; useType = TYP_UNKNOWN; } -#elif defined(TARGET_WINDOWS) && !defined(TARGET_ARM) - if (callConvIsInstanceMethodCallConv(callConv) && !isNativePrimitiveStructType(clsHnd)) +#endif + if (TargetOS::IsWindows && !TargetArchitecture::IsArm32 && callConvIsInstanceMethodCallConv(callConv) && !isNativePrimitiveStructType(clsHnd)) { canReturnInRegister = false; howToReturnStruct = SPK_ByReference; useType = TYP_UNKNOWN; } -#endif // Check for cases where a small struct is returned in a register // via a primitive type. @@ -3183,7 +3178,7 @@ void Compiler::compInitOptions(JitFlags* jitFlags) if (verbose) { printf("****** START compiling %s (MethodHash=%08x)\n", info.compFullName, info.compMethodHash()); - printf("Generating code for %s %s\n", Target::g_tgtPlatformName, Target::g_tgtCPUName); + printf("Generating code for %s %s\n", Target::g_tgtPlatformName(), Target::g_tgtCPUName); printf(""); // in our logic this causes a flush } @@ -5528,11 +5523,14 @@ int Compiler::compCompile(CORINFO_MODULE_HANDLE classPtr, // Match OS for compMatchedVM CORINFO_EE_INFO* eeInfo = eeGetEEInfo(); -#ifdef TARGET_UNIX - info.compMatchedVM = info.compMatchedVM && (eeInfo->osType == CORINFO_UNIX); -#else - info.compMatchedVM = info.compMatchedVM && (eeInfo->osType == CORINFO_WINNT); -#endif + if (TargetOS::IsUnix) + { + info.compMatchedVM = info.compMatchedVM && (eeInfo->osType == CORINFO_UNIX); + } + else if (TargetOS::IsWindows) + { + info.compMatchedVM = info.compMatchedVM && (eeInfo->osType == CORINFO_WINNT); + } // If we are not compiling for a matched VM, then we are getting JIT flags that don't match our target // architecture. The two main examples here are an ARM targeting altjit hosted on x86 and an ARM64 @@ -6091,6 +6089,16 @@ int Compiler::compCompileHelper(CORINFO_MODULE_HANDLE classPtr, { CORINFO_METHOD_HANDLE methodHnd = info.compMethodHnd; +#ifdef TARGET_OS_RUNTIMEDETERMINED + if (!TargetOS::OSSettingConfigured) + { + CORINFO_EE_INFO* eeInfo = eeGetEEInfo(); + TargetOS::IsUnix = eeInfo->osType == CORINFO_UNIX; + TargetOS::IsWindows = eeInfo->osType == CORINFO_WINNT; + TargetOS::OSSettingConfigured = true; + } +#endif + info.compCode = methodInfo->ILCode; info.compILCodeSize = methodInfo->ILCodeSize; info.compILImportSize = 0; diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index beed88b04e8b6a..090555672fd9b3 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -1429,12 +1429,10 @@ struct FuncInfoDsc #elif defined(TARGET_X86) -#if defined(TARGET_UNIX) emitLocation* startLoc; emitLocation* endLoc; emitLocation* coldStartLoc; // locations for the cold section, if there is one. emitLocation* coldEndLoc; -#endif // TARGET_UNIX #elif defined(TARGET_ARMARCH) @@ -1446,18 +1444,16 @@ struct FuncInfoDsc // Note 2: we currently don't support hot/cold splitting in functions // with EH, so uwiCold will be NULL for all funclets. -#if defined(TARGET_UNIX) emitLocation* startLoc; emitLocation* endLoc; emitLocation* coldStartLoc; // locations for the cold section, if there is one. emitLocation* coldEndLoc; -#endif // TARGET_UNIX #endif // TARGET_ARMARCH -#if defined(TARGET_UNIX) +#if defined(FEATURE_CFI_SUPPORT) jitstd::vector* cfiCodes; -#endif // TARGET_UNIX +#endif // FEATURE_CFI_SUPPORT // Eventually we may want to move rsModifiedRegsMask, lvaOutgoingArgSize, and anything else // that isn't shared between the main function body and funclets. @@ -1616,17 +1612,14 @@ struct fgArgTabEntry bool IsVararg() const { -#ifdef FEATURE_VARARG - return _isVararg; -#else - return false; -#endif + return GlobalJitOptions::compFeatureVarArg() && _isVararg; } void SetIsVararg(bool value) { -#ifdef FEATURE_VARARG - _isVararg = value; -#endif // FEATURE_VARARG + if (GlobalJitOptions::compFeatureVarArg()) + { + _isVararg = value; + } } bool IsHfaArg() const @@ -4548,10 +4541,8 @@ class Compiler bool impIsValueType(typeInfo* pTypeInfo); var_types mangleVarArgsType(var_types type); -#if FEATURE_VARARG regNumber getCallArgIntRegister(regNumber floatReg); regNumber getCallArgFloatRegister(regNumber intReg); -#endif // FEATURE_VARARG #if defined(DEBUG) static unsigned jitTotalMethodCompiled; @@ -7903,8 +7894,8 @@ class Compiler bool generateCFIUnwindCodes() { -#if defined(TARGET_UNIX) - return IsTargetAbi(CORINFO_CORERT_ABI); +#if defined(FEATURE_CFI_SUPPORT) + return TargetOS::IsUnix && IsTargetAbi(CORINFO_CORERT_ABI); #else return false; #endif @@ -8347,7 +8338,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX #endif // TARGET_ARM -#if defined(TARGET_UNIX) +#if defined(FEATURE_CFI_SUPPORT) short mapRegNumToDwarfReg(regNumber reg); void createCfiCode(FuncInfoDsc* func, UNATIVE_OFFSET codeOffset, UCHAR opcode, short dwarfReg, INT offset = 0); void unwindPushPopCFI(regNumber reg); @@ -8364,7 +8355,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX const CFI_CODE* const pCfiCode); #endif -#endif // TARGET_UNIX +#endif // FEATURE_CFI_SUPPORT #if !defined(__GNUC__) #pragma endregion // Note: region is NOT under !defined(__GNUC__) @@ -9853,13 +9844,16 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX // 3. Windows ARM64 native instance calling convention requires the address of RetBuff // to be returned in x0. CLANG_FORMAT_COMMENT_ANCHOR; -#if defined(TARGET_WINDOWS) && defined(TARGET_ARM64) - auto callConv = info.compCallConv; - if (callConvIsInstanceMethodCallConv(callConv)) +#if defined(TARGET_ARM64) + if (TargetOS::IsWindows) { - return (info.compRetBuffArg != BAD_VAR_NUM); + auto callConv = info.compCallConv; + if (callConvIsInstanceMethodCallConv(callConv)) + { + return (info.compRetBuffArg != BAD_VAR_NUM); + } } -#endif // TARGET_WINDOWS && TARGET_ARM64 +#endif // TARGET_ARM64 // 4. x86 unmanaged calling conventions require the address of RetBuff to be returned in eax. CLANG_FORMAT_COMMENT_ANCHOR; #if defined(TARGET_X86) @@ -11687,11 +11681,8 @@ const instruction INS_SQRT = INS_vsqrt; #ifdef TARGET_ARM64 const instruction INS_MULADD = INS_madd; -#if defined(TARGET_UNIX) -const instruction INS_BREAKPOINT = INS_brk; -#else -const instruction INS_BREAKPOINT = INS_bkpt; -#endif +inline const instruction INS_BREAKPOINT_osHelper() { return TargetOS::IsUnix ? INS_brk : INS_bkpt; } +#define INS_BREAKPOINT INS_BREAKPOINT_osHelper() const instruction INS_ABS = INS_fabs; const instruction INS_SQRT = INS_fsqrt; diff --git a/src/coreclr/jit/compiler.hpp b/src/coreclr/jit/compiler.hpp index 71bc8760de2532..23757caea1e0e5 100644 --- a/src/coreclr/jit/compiler.hpp +++ b/src/coreclr/jit/compiler.hpp @@ -2303,9 +2303,7 @@ inline var_types Compiler::mangleVarArgsType(var_types type) { #if defined(TARGET_ARMARCH) if (opts.compUseSoftFP -#if defined(TARGET_WINDOWS) - || info.compIsVarArgs -#endif // defined(TARGET_WINDOWS) + || (TargetOS::IsWindows && info.compIsVarArgs) ) { switch (type) @@ -2323,9 +2321,9 @@ inline var_types Compiler::mangleVarArgsType(var_types type) } // For CORECLR there is no vararg on System V systems. -#if FEATURE_VARARG inline regNumber Compiler::getCallArgIntRegister(regNumber floatReg) { + assert(GlobalJitOptions::compFeatureVarArg()); #ifdef TARGET_AMD64 switch (floatReg) { @@ -2349,6 +2347,7 @@ inline regNumber Compiler::getCallArgIntRegister(regNumber floatReg) inline regNumber Compiler::getCallArgFloatRegister(regNumber intReg) { + assert(GlobalJitOptions::compFeatureVarArg()); #ifdef TARGET_AMD64 switch (intReg) { @@ -2369,7 +2368,6 @@ inline regNumber Compiler::getCallArgFloatRegister(regNumber intReg) return REG_NA; #endif // !TARGET_AMD64 } -#endif // FEATURE_VARARG /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX diff --git a/src/coreclr/jit/ee_il_dll.cpp b/src/coreclr/jit/ee_il_dll.cpp index 8904992524f8b5..1a6df3e6495ef5 100644 --- a/src/coreclr/jit/ee_il_dll.cpp +++ b/src/coreclr/jit/ee_il_dll.cpp @@ -418,15 +418,13 @@ unsigned Compiler::eeGetArgSize(CORINFO_ARG_LIST_HANDLE list, CORINFO_SIG_INFO* if (structSize > (2 * TARGET_POINTER_SIZE)) { -#ifndef TARGET_UNIX - if (info.compIsVarArgs) + if (TargetOS::IsWindows && info.compIsVarArgs) { // Arm64 Varargs ABI requires passing in general purpose // registers. Force the decision of whether this is an HFA // to false to correctly pass as if it was not an HFA. isHfa = false; } -#endif // TARGET_UNIX if (!isHfa) { // This struct is passed by reference using a single 'slot' diff --git a/src/coreclr/jit/error.h b/src/coreclr/jit/error.h index a63643c0ee5b8b..126a8665a34e80 100644 --- a/src/coreclr/jit/error.h +++ b/src/coreclr/jit/error.h @@ -213,7 +213,7 @@ extern void notYetImplemented(const char* msg, const char* file, unsigned line); // clang-format on -#if defined(HOST_X86) && !defined(TARGET_UNIX) +#if defined(HOST_X86) && !defined(HOST_UNIX) // While debugging in an Debugger, the "int 3" will cause the program to break // Outside, the exception handler will just filter out the "int 3". diff --git a/src/coreclr/jit/gentree.h b/src/coreclr/jit/gentree.h index b5d45fff36d884..79b8d15336559a 100644 --- a/src/coreclr/jit/gentree.h +++ b/src/coreclr/jit/gentree.h @@ -4463,10 +4463,14 @@ struct GenTreeCall final : public GenTree bool HasFixedRetBufArg() const { -#if defined(TARGET_WINDOWS) && !defined(TARGET_ARM) - return hasFixedRetBuffReg() && HasRetBufArg() && !callConvIsInstanceMethodCallConv(GetUnmanagedCallConv()); + if (!(hasFixedRetBuffReg() && HasRetBufArg())) + { + return false; + } +#if !defined(TARGET_ARM) + return !TargetOS::IsWindows || !callConvIsInstanceMethodCallConv(GetUnmanagedCallConv()); #else - return hasFixedRetBuffReg() && HasRetBufArg(); + return true; #endif } diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 64df19fdf5dd9d..1175743438e8f5 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -1300,9 +1300,9 @@ GenTree* Compiler::impAssignStructPtr(GenTree* destAddr, // Case of call returning a struct via hidden retbuf arg CLANG_FORMAT_COMMENT_ANCHOR; -#if defined(TARGET_WINDOWS) && !defined(TARGET_ARM) +#if !defined(TARGET_ARM) // Unmanaged instance methods on Windows need the retbuf arg after the first (this) parameter - if (srcCall->IsUnmanaged()) + if (TargetOS::IsWindows && srcCall->IsUnmanaged()) { if (callConvIsInstanceMethodCallConv(srcCall->GetUnmanagedCallConv())) { @@ -8717,14 +8717,13 @@ var_types Compiler::impImportCall(OPCODE opcode, CORINFO_CLASS_HANDLE actualMethodRetTypeSigClass; actualMethodRetTypeSigClass = sig->retTypeSigClass; -#if !FEATURE_VARARG /* Check for varargs */ - if ((sig->callConv & CORINFO_CALLCONV_MASK) == CORINFO_CALLCONV_VARARG || - (sig->callConv & CORINFO_CALLCONV_MASK) == CORINFO_CALLCONV_NATIVEVARARG) + if (!GlobalJitOptions::compFeatureVarArg() && + ((sig->callConv & CORINFO_CALLCONV_MASK) == CORINFO_CALLCONV_VARARG || + (sig->callConv & CORINFO_CALLCONV_MASK) == CORINFO_CALLCONV_NATIVEVARARG)) { BADCODE("Varargs not supported."); } -#endif // !FEATURE_VARARG if ((sig->callConv & CORINFO_CALLCONV_MASK) == CORINFO_CALLCONV_VARARG || (sig->callConv & CORINFO_CALLCONV_MASK) == CORINFO_CALLCONV_NATIVEVARARG) @@ -17468,10 +17467,10 @@ bool Compiler::impReturnInstruction(int prefixFlags, OPCODE& opcode) { op1 = gtNewOperNode(GT_RETURN, TYP_BYREF, gtNewLclvNode(info.compRetBuffArg, TYP_BYREF)); } -#if defined(TARGET_WINDOWS) && defined(TARGET_ARM64) +#if defined(TARGET_ARM64) // On ARM64, the native instance calling convention variant // requires the implicit ByRef to be explicitly returned. - else if (callConvIsInstanceMethodCallConv(info.compCallConv)) + else if (TargetOS::IsWindows && callConvIsInstanceMethodCallConv(info.compCallConv)) { op1 = gtNewOperNode(GT_RETURN, TYP_BYREF, gtNewLclvNode(info.compRetBuffArg, TYP_BYREF)); } diff --git a/src/coreclr/jit/jit.h b/src/coreclr/jit/jit.h index fb39fda019c455..d1354bead74235 100644 --- a/src/coreclr/jit/jit.h +++ b/src/coreclr/jit/jit.h @@ -248,11 +248,11 @@ // Arm64 Windows supports FEATURE_ARG_SPLIT, note this is different from // the official Arm64 ABI. // Case: splitting 16 byte struct between x7 and stack -#if (defined(TARGET_ARM) || (defined(TARGET_WINDOWS) && defined(TARGET_ARM64))) +#if (defined(TARGET_ARM) || defined(WINDOWS_ARM64_ABI)) #define FEATURE_ARG_SPLIT 1 #else #define FEATURE_ARG_SPLIT 0 -#endif // (defined(TARGET_ARM) || (defined(TARGET_WINDOWS) && defined(TARGET_ARM64))) +#endif // (defined(TARGET_ARM) || defined(WINDOWS_ARM64_ABI)) // To get rid of warning 4701 : local variable may be used without being initialized #define DUMMY_INIT(x) (x) @@ -360,6 +360,16 @@ class GlobalJitOptions #ifdef FEATURE_HFA #undef FEATURE_HFA #endif + +// Native Varargs are not supported on Unix (all architectures) and Windows ARM +#if defined(TARGET_WINDOWS) && !defined(TARGET_ARM) + static bool compFeatureVarArg() { return true; } +#elif !defined(TARGET_WINDOWS) && !defined(TARGET_UNIX) && !defined(TARGET_ARM) + static bool compFeatureVarArg() { return TargetOS::IsWindows; } +#else + static bool compFeatureVarArg() { return false; } +#endif + }; /*****************************************************************************/ diff --git a/src/coreclr/jit/lclvars.cpp b/src/coreclr/jit/lclvars.cpp index 27771bbb7c18ce..e4af67018ddb7c 100644 --- a/src/coreclr/jit/lclvars.cpp +++ b/src/coreclr/jit/lclvars.cpp @@ -375,8 +375,8 @@ void Compiler::lvaInitArgs(InitVarDscInfo* varDscInfo) unsigned numUserArgsToSkip = 0; unsigned numUserArgs = info.compMethodInfo->args.numArgs; -#if defined(TARGET_WINDOWS) && !defined(TARGET_ARM) - if (callConvIsInstanceMethodCallConv(info.compCallConv)) +#if !defined(TARGET_ARM) + if (TargetOS::IsWindows && callConvIsInstanceMethodCallConv(info.compCallConv)) { // If we are a native instance method, handle the first user arg // (the unmanaged this parameter) and then handle the hidden @@ -685,13 +685,9 @@ void Compiler::lvaInitUserArgs(InitVarDscInfo* varDscInfo, unsigned skipArgs, un bool isHfaArg = false; var_types hfaType = TYP_UNDEF; -#if defined(TARGET_ARM64) && defined(TARGET_UNIX) + // Methods that use VarArg or SoftFP cannot have HFA arguments except // Native varargs on arm64 unix use the regular calling convention. - if (!opts.compUseSoftFP) -#else - // Methods that use VarArg or SoftFP cannot have HFA arguments - if (!info.compIsVarArgs && !opts.compUseSoftFP) -#endif // defined(TARGET_ARM64) && defined(TARGET_UNIX) + if (((TargetOS::IsUnix && TargetArchitecture::IsArm64) || !info.compIsVarArgs) && !opts.compUseSoftFP) { // If the argType is a struct, then check if it is an HFA if (varTypeIsStruct(argType)) @@ -703,14 +699,15 @@ void Compiler::lvaInitUserArgs(InitVarDscInfo* varDscInfo, unsigned skipArgs, un } else if (info.compIsVarArgs) { -#ifdef TARGET_UNIX // Currently native varargs is not implemented on non windows targets. // // Note that some targets like Arm64 Unix should not need much work as // the ABI is the same. While other targets may only need small changes // such as amd64 Unix, which just expects RAX to pass numFPArguments. - NYI("InitUserArgs for Vararg callee is not yet implemented on non Windows targets."); -#endif + if (TargetOS::IsUnix) + { + NYI("InitUserArgs for Vararg callee is not yet implemented on non Windows targets."); + } } if (isHfaArg) @@ -2889,14 +2886,14 @@ void Compiler::makeExtraStructQueries(CORINFO_CLASS_HANDLE structHandle, int lev void Compiler::lvaSetStructUsedAsVarArg(unsigned varNum) { - if (GlobalJitOptions::compFeatureHfa) + if (GlobalJitOptions::compFeatureHfa && TargetOS::IsWindows) { -#if defined(TARGET_WINDOWS) && defined(TARGET_ARM64) +#if defined(TARGET_ARM64) LclVarDsc* varDsc = &lvaTable[varNum]; // For varargs methods incoming and outgoing arguments should not be treated // as HFA. varDsc->SetHfaType(TYP_UNDEF); -#endif // defined(TARGET_WINDOWS) && defined(TARGET_ARM64) +#endif // defined(TARGET_ARM64) } } @@ -5524,19 +5521,19 @@ void Compiler::lvaAssignVirtualFrameOffsetsToArgs() } unsigned userArgsToSkip = 0; -#if defined(TARGET_WINDOWS) && !defined(TARGET_ARM) +#if !defined(TARGET_ARM) // In the native instance method calling convention on Windows, // the this parameter comes before the hidden return buffer parameter. // So, we want to process the native "this" parameter before we process // the native return buffer parameter. - if (callConvIsInstanceMethodCallConv(info.compCallConv)) + if (TargetOS::IsWindows && callConvIsInstanceMethodCallConv(info.compCallConv)) { #ifdef TARGET_X86 if (!lvaTable[lclNum].lvIsRegArg) { argOffs = lvaAssignVirtualFrameOffsetToArg(lclNum, REGSIZE_BYTES, argOffs); } -#else +#elif !defined(UNIX_AMD64_ABI) argOffs = lvaAssignVirtualFrameOffsetToArg(lclNum, REGSIZE_BYTES, argOffs); #endif // TARGET_X86 lclNum++; diff --git a/src/coreclr/jit/lower.cpp b/src/coreclr/jit/lower.cpp index ef0578b2cbff50..9f043ee7b9183d 100644 --- a/src/coreclr/jit/lower.cpp +++ b/src/coreclr/jit/lower.cpp @@ -588,17 +588,18 @@ GenTree* Lowering::LowerSwitch(GenTree* node) bool useJumpSequence = jumpCnt < minSwitchTabJumpCnt; -#if defined(TARGET_UNIX) && defined(TARGET_ARM) - // Force using an inlined jumping instead switch table generation. - // Switch jump table is generated with incorrect values in CoreRT case, - // so any large switch will crash after loading to PC any such value. - // I think this is due to the fact that we use absolute addressing - // instead of relative. But in CoreRT is used as a rule relative - // addressing when we generate an executable. - // See also https://github.com/dotnet/runtime/issues/8683 - // Also https://github.com/dotnet/coreclr/pull/13197 - useJumpSequence = useJumpSequence || comp->IsTargetAbi(CORINFO_CORERT_ABI); -#endif // defined(TARGET_UNIX) && defined(TARGET_ARM) + if (TargetOS::IsUnix && TargetArchitecture::IsArm32) + { + // Force using an inlined jumping instead switch table generation. + // Switch jump table is generated with incorrect values in CoreRT case, + // so any large switch will crash after loading to PC any such value. + // I think this is due to the fact that we use absolute addressing + // instead of relative. But in CoreRT is used as a rule relative + // addressing when we generate an executable. + // See also https://github.com/dotnet/runtime/issues/8683 + // Also https://github.com/dotnet/coreclr/pull/13197 + useJumpSequence = useJumpSequence || comp->IsTargetAbi(CORINFO_CORERT_ABI); + } // If we originally had 2 unique successors, check to see whether there is a unique // non-default case, in which case we can eliminate the switch altogether. @@ -1929,9 +1930,7 @@ void Lowering::LowerFastTailCall(GenTreeCall* call) unsigned int overwrittenStart = put->getArgOffset(); unsigned int overwrittenEnd = overwrittenStart + put->GetStackByteSize(); -#if !(defined(TARGET_WINDOWS) && defined(TARGET_AMD64)) int baseOff = -1; // Stack offset of first arg on stack -#endif for (unsigned callerArgLclNum = 0; callerArgLclNum < comp->info.compArgsCount; callerArgLclNum++) { @@ -1942,27 +1941,34 @@ void Lowering::LowerFastTailCall(GenTreeCall* call) continue; } -#if defined(TARGET_WINDOWS) && defined(TARGET_AMD64) - // On Windows x64, the argument position determines the stack slot uniquely, and even the - // register args take up space in the stack frame (shadow space). - unsigned int argStart = callerArgLclNum * TARGET_POINTER_SIZE; - unsigned int argEnd = argStart + static_cast(callerArgDsc->lvArgStackSize()); -#else - assert(callerArgDsc->GetStackOffset() != BAD_STK_OFFS); - - if (baseOff == -1) + unsigned int argStart; + unsigned int argEnd; +#if defined(TARGET_AMD64) + if (TargetOS::IsWindows) { - baseOff = callerArgDsc->GetStackOffset(); + // On Windows x64, the argument position determines the stack slot uniquely, and even the + // register args take up space in the stack frame (shadow space). + argStart = callerArgLclNum * TARGET_POINTER_SIZE; + argEnd = argStart + static_cast(callerArgDsc->lvArgStackSize()); } + else +#endif // TARGET_AMD64 + { + assert(callerArgDsc->GetStackOffset() != BAD_STK_OFFS); + + if (baseOff == -1) + { + baseOff = callerArgDsc->GetStackOffset(); + } - // On all ABIs where we fast tail call the stack args should come in order. - assert(baseOff <= callerArgDsc->GetStackOffset()); + // On all ABIs where we fast tail call the stack args should come in order. + assert(baseOff <= callerArgDsc->GetStackOffset()); - // Compute offset of this stack argument relative to the first stack arg. - // This will be its offset into the incoming arg space area. - unsigned int argStart = static_cast(callerArgDsc->GetStackOffset() - baseOff); - unsigned int argEnd = argStart + comp->lvaLclSize(callerArgLclNum); -#endif + // Compute offset of this stack argument relative to the first stack arg. + // This will be its offset into the incoming arg space area. + argStart = static_cast(callerArgDsc->GetStackOffset() - baseOff); + argEnd = argStart + comp->lvaLclSize(callerArgLclNum); + } // If ranges do not overlap then this PUTARG_STK will not mess up the arg. if ((overwrittenEnd <= argStart) || (overwrittenStart >= argEnd)) diff --git a/src/coreclr/jit/lsrabuild.cpp b/src/coreclr/jit/lsrabuild.cpp index cf11833a1f356a..5cb853e5c90474 100644 --- a/src/coreclr/jit/lsrabuild.cpp +++ b/src/coreclr/jit/lsrabuild.cpp @@ -3406,8 +3406,8 @@ int LinearScan::BuildStoreLoc(GenTreeLclVarCommon* storeLoc) { BuildUse(op1, RBM_NONE, i); } -#if defined(FEATURE_SIMD) && defined(TARGET_X86) && defined(TARGET_WINDOWS) - if (!compiler->compOpportunisticallyDependsOn(InstructionSet_SSE41)) +#if defined(FEATURE_SIMD) && defined(TARGET_X86) + if (TargetOS::IsWindows && !compiler->compOpportunisticallyDependsOn(InstructionSet_SSE41)) { if (varTypeIsSIMD(storeLoc) && op1->IsCall()) { @@ -3415,7 +3415,7 @@ int LinearScan::BuildStoreLoc(GenTreeLclVarCommon* storeLoc) buildInternalFloatRegisterDefForNode(storeLoc, allSIMDRegs()); } } -#endif // FEATURE_SIMD && TARGET_X86 && TARGET_WINDOWS +#endif // FEATURE_SIMD && TARGET_X86 } else if (op1->isContained() && op1->OperIs(GT_BITCAST)) { @@ -3836,8 +3836,7 @@ int LinearScan::BuildPutArgReg(GenTreeUnOp* node) // (e.g. for the target). void LinearScan::HandleFloatVarArgs(GenTreeCall* call, GenTree* argNode, bool* callHasFloatRegArgs) { -#if FEATURE_VARARG - if (call->IsVarargs() && varTypeIsFloating(argNode)) + if (GlobalJitOptions::compFeatureVarArg() && call->IsVarargs() && varTypeIsFloating(argNode)) { *callHasFloatRegArgs = true; @@ -3847,7 +3846,6 @@ void LinearScan::HandleFloatVarArgs(GenTreeCall* call, GenTree* argNode, bool* c buildInternalIntRegisterDefForNode(call, genRegMask(targetReg)); } -#endif // FEATURE_VARARG } //------------------------------------------------------------------------ diff --git a/src/coreclr/jit/lsraxarch.cpp b/src/coreclr/jit/lsraxarch.cpp index f4401828f8ad21..22056e549305a4 100644 --- a/src/coreclr/jit/lsraxarch.cpp +++ b/src/coreclr/jit/lsraxarch.cpp @@ -1236,17 +1236,15 @@ int LinearScan::BuildCall(GenTreeCall* call) } #endif // TARGET_X86 -#if FEATURE_VARARG // If it is a fast tail call, it is already preferenced to use RAX. // Therefore, no need set src candidates on call tgt again. - if (call->IsVarargs() && callHasFloatRegArgs && !call->IsFastTailCall()) + if (GlobalJitOptions::compFeatureVarArg() && call->IsVarargs() && callHasFloatRegArgs && !call->IsFastTailCall()) { // Don't assign the call target to any of the argument registers because // we will use them to also pass floating point arguments as required // by Amd64 ABI. ctrlExprCandidates = allRegs(TYP_INT) & ~(RBM_ARG_REGS); } -#endif // !FEATURE_VARARG srcCount += BuildOperandUses(ctrlExpr, ctrlExprCandidates); } diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index fb06c52b0942c7..8dd51fc2f2e3a6 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -2542,8 +2542,7 @@ void Compiler::fgInitArgInfo(GenTreeCall* call) // At this point, we should never have gtCallLateArgs, as this needs to be done before those are determined. assert(call->gtCallLateArgs == nullptr); -#ifdef TARGET_UNIX - if (callIsVararg) + if (TargetOS::IsUnix && callIsVararg) { // Currently native varargs is not implemented on non windows targets. // @@ -2552,7 +2551,6 @@ void Compiler::fgInitArgInfo(GenTreeCall* call) // such as amd64 Unix, which just expects RAX to pass numFPArguments. NYI("Morphing Vararg call not yet implemented on non Windows targets."); } -#endif // TARGET_UNIX // Data structure for keeping track of non-standard args. Non-standard args are those that are not passed // following the normal calling convention or in the normal argument registers. We either mark existing @@ -3068,10 +3066,13 @@ void Compiler::fgInitArgInfo(GenTreeCall* call) hfaType = GetHfaType(argx); isHfaArg = varTypeIsValidHfaType(hfaType); -#if defined(TARGET_WINDOWS) && defined(TARGET_ARM64) - // Make sure for vararg methods isHfaArg is not true. - isHfaArg = callIsVararg ? false : isHfaArg; -#endif // defined(TARGET_WINDOWS) && defined(TARGET_ARM64) +#if defined(TARGET_ARM64) + if (TargetOS::IsWindows) + { + // Make sure for vararg methods isHfaArg is not true. + isHfaArg = callIsVararg ? false : isHfaArg; + } +#endif // defined(TARGET_ARM64) if (isHfaArg) { @@ -3388,16 +3389,14 @@ void Compiler::fgInitArgInfo(GenTreeCall* call) // if (!isRegArg && (size > 1)) { -#if defined(TARGET_WINDOWS) // Arm64 windows native varargs allows splitting a 16 byte struct between stack // and the last general purpose register. - if (callIsVararg) + if (TargetOS::IsWindows && callIsVararg) { // Override the decision and force a split. isRegArg = (intArgRegNum + (size - 1)) <= maxRegArgs; } else -#endif // defined(TARGET_WINDOWS) { // We also must update intArgRegNum so that we no longer try to // allocate any new general purpose registers for args @@ -6976,13 +6975,11 @@ bool Compiler::fgCanFastTailCall(GenTreeCall* callee, const char** failReason) // work required to shuffle arguments to the correct locations. CLANG_FORMAT_COMMENT_ANCHOR; -#if (defined(TARGET_WINDOWS) && defined(TARGET_ARM)) || (defined(TARGET_WINDOWS) && defined(TARGET_ARM64)) - if (info.compIsVarArgs || callee->IsVarargs()) + if (TargetOS::IsWindows && TargetArchitecture::IsArmArch && (info.compIsVarArgs || callee->IsVarargs())) { reportFastTailCallDecision("Fast tail calls with varargs not supported on Windows ARM/ARM64"); return false; } -#endif // (defined(TARGET_WINDOWS) && defined(TARGET_ARM)) || defined(TARGET_WINDOWS) && defined(TARGET_ARM64)) if (compLocallocUsed) { diff --git a/src/coreclr/jit/target.h b/src/coreclr/jit/target.h index 3b63cad3f323d3..fa9832f1a1efe0 100644 --- a/src/coreclr/jit/target.h +++ b/src/coreclr/jit/target.h @@ -5,11 +5,8 @@ #ifndef TARGET_H_ #define TARGET_H_ -// Native Varargs are not supported on Unix (all architectures) and Windows ARM -#if defined(TARGET_WINDOWS) && !defined(TARGET_ARM) -#define FEATURE_VARARG 1 -#else -#define FEATURE_VARARG 0 +#ifdef TARGET_UNIX_POSSIBLY_SUPPORTED +#define FEATURE_CFI_SUPPORT #endif /*****************************************************************************/ @@ -268,7 +265,7 @@ class Target { public: static const char* g_tgtCPUName; - static const char* g_tgtPlatformName; + static const char* g_tgtPlatformName() { return TargetOS::IsWindows ? "Windows" : "Unix"; }; enum ArgOrder { diff --git a/src/coreclr/jit/targetamd64.h b/src/coreclr/jit/targetamd64.h index a3d41541e02db1..76d4d903884a72 100644 --- a/src/coreclr/jit/targetamd64.h +++ b/src/coreclr/jit/targetamd64.h @@ -404,10 +404,10 @@ #define REG_STACK_PROBE_HELPER_ARG REG_R11 #define RBM_STACK_PROBE_HELPER_ARG RBM_R11 -#ifdef TARGET_UNIX +#ifdef UNIX_AMD64_ABI #define RBM_STACK_PROBE_HELPER_TRASH RBM_NONE -#else // !TARGET_UNIX +#else // !UNIX_AMD64_ABI #define RBM_STACK_PROBE_HELPER_TRASH RBM_RAX -#endif // !TARGET_UNIX +#endif // !UNIX_AMD64_ABI // clang-format on diff --git a/src/coreclr/jit/unwind.cpp b/src/coreclr/jit/unwind.cpp index f616cba2a2ac3b..d82bb821abafe6 100644 --- a/src/coreclr/jit/unwind.cpp +++ b/src/coreclr/jit/unwind.cpp @@ -117,7 +117,7 @@ void Compiler::unwindGetFuncLocations(FuncInfoDsc* func, #endif // FEATURE_EH_FUNCLETS -#if defined(TARGET_UNIX) +#if defined(FEATURE_CFI_SUPPORT) void Compiler::createCfiCode(FuncInfoDsc* func, UNATIVE_OFFSET codeOffset, UCHAR cfiOpcode, short dwarfReg, INT offset) { @@ -389,7 +389,7 @@ void Compiler::DumpCfiInfo(bool isHotCode, } #endif // DEBUG -#endif // TARGET_UNIX +#endif // FEATURE_CFI_SUPPORT //------------------------------------------------------------------------ // Compiler::unwindGetCurrentOffset: Calculate the current byte offset of the @@ -411,12 +411,15 @@ UNATIVE_OFFSET Compiler::unwindGetCurrentOffset(FuncInfoDsc* func) } else { -#if defined(TARGET_AMD64) || (defined(TARGET_UNIX) && (defined(TARGET_ARMARCH) || defined(TARGET_X86))) - assert(func->startLoc != nullptr); - offset = func->startLoc->GetFuncletPrologOffset(GetEmitter()); -#else - offset = 0; // TODO ??? -#endif + if (TargetArchitecture::IsX64 || (TargetOS::IsUnix && (TargetArchitecture::IsArmArch || TargetArchitecture::IsX86))) + { + assert(func->startLoc != nullptr); + offset = func->startLoc->GetFuncletPrologOffset(GetEmitter()); + } + else + { + offset = 0; // TODO ??? + } } return offset; diff --git a/src/coreclr/jit/unwindarm.cpp b/src/coreclr/jit/unwindarm.cpp index da4219b1d53bd3..2b25ed82942cc5 100644 --- a/src/coreclr/jit/unwindarm.cpp +++ b/src/coreclr/jit/unwindarm.cpp @@ -15,7 +15,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX #pragma hdrstop #endif -#if defined(TARGET_ARM) && defined(TARGET_UNIX) +#if defined(TARGET_ARM) && defined(FEATURE_CFI_SUPPORT) short Compiler::mapRegNumToDwarfReg(regNumber reg) { short dwarfReg = DWARF_REG_ILLEGAL; @@ -124,7 +124,7 @@ short Compiler::mapRegNumToDwarfReg(regNumber reg) return dwarfReg; } -#endif // TARGET_ARM && TARGET_UNIX +#endif // TARGET_ARM && FEATURE_CFI_SUPPORT #ifdef TARGET_ARMARCH @@ -141,13 +141,13 @@ void Compiler::unwindBegProlog() { assert(compGeneratingProlog); -#if defined(TARGET_UNIX) +#if defined(FEATURE_CFI_SUPPORT) if (generateCFIUnwindCodes()) { unwindBegPrologCFI(); return; } -#endif // TARGET_UNIX +#endif // FEATURE_CFI_SUPPORT FuncInfoDsc* func = funCurrentFunc(); @@ -173,12 +173,12 @@ void Compiler::unwindBegEpilog() { assert(compGeneratingEpilog); -#if defined(TARGET_UNIX) +#if defined(FEATURE_CFI_SUPPORT) if (generateCFIUnwindCodes()) { return; } -#endif // TARGET_UNIX +#endif // FEATURE_CFI_SUPPORT funCurrentFunc()->uwi.AddEpilog(); } @@ -319,7 +319,7 @@ void Compiler::unwindPushMaskInt(regMaskTP maskInt) ~(RBM_R0 | RBM_R1 | RBM_R2 | RBM_R3 | RBM_R4 | RBM_R5 | RBM_R6 | RBM_R7 | RBM_R8 | RBM_R9 | RBM_R10 | RBM_R11 | RBM_R12 | RBM_LR)) == 0); -#if defined(TARGET_UNIX) +#if defined(FEATURE_CFI_SUPPORT) if (generateCFIUnwindCodes()) { // If we are pushing LR, we should give unwind codes in terms of caller's PC @@ -330,7 +330,7 @@ void Compiler::unwindPushMaskInt(regMaskTP maskInt) unwindPushPopMaskCFI(maskInt, false); return; } -#endif // TARGET_UNIX +#endif // FEATURE_CFI_SUPPORT bool useOpsize16 = ((maskInt & (RBM_LOW_REGS | RBM_LR)) == maskInt); // Can PUSH use the 16-bit encoding? unwindPushPopMaskInt(maskInt, useOpsize16); @@ -341,25 +341,25 @@ void Compiler::unwindPushMaskFloat(regMaskTP maskFloat) // Only floating point registers should be in maskFloat assert((maskFloat & RBM_ALLFLOAT) == maskFloat); -#if defined(TARGET_UNIX) +#if defined(FEATURE_CFI_SUPPORT) if (generateCFIUnwindCodes()) { unwindPushPopMaskCFI(maskFloat, true); return; } -#endif // TARGET_UNIX +#endif // FEATURE_CFI_SUPPORT unwindPushPopMaskFloat(maskFloat); } void Compiler::unwindPopMaskInt(regMaskTP maskInt) { -#if defined(TARGET_UNIX) +#if defined(FEATURE_CFI_SUPPORT) if (generateCFIUnwindCodes()) { return; } -#endif // TARGET_UNIX +#endif // FEATURE_CFI_SUPPORT // Only r0-r12 and lr and pc are supported (pc is mapped to lr when encoding) assert((maskInt & @@ -382,12 +382,12 @@ void Compiler::unwindPopMaskInt(regMaskTP maskInt) void Compiler::unwindPopMaskFloat(regMaskTP maskFloat) { -#if defined(TARGET_UNIX) +#if defined(FEATURE_CFI_SUPPORT) if (generateCFIUnwindCodes()) { return; } -#endif // TARGET_UNIX +#endif // FEATURE_CFI_SUPPORT // Only floating point registers should be in maskFloat assert((maskFloat & RBM_ALLFLOAT) == maskFloat); @@ -396,7 +396,7 @@ void Compiler::unwindPopMaskFloat(regMaskTP maskFloat) void Compiler::unwindAllocStack(unsigned size) { -#if defined(TARGET_UNIX) +#if defined(FEATURE_CFI_SUPPORT) if (generateCFIUnwindCodes()) { if (compGeneratingProlog) @@ -405,7 +405,7 @@ void Compiler::unwindAllocStack(unsigned size) } return; } -#endif // TARGET_UNIX +#endif // FEATURE_CFI_SUPPORT UnwindInfo* pu = &funCurrentFunc()->uwi; @@ -450,7 +450,7 @@ void Compiler::unwindAllocStack(unsigned size) void Compiler::unwindSetFrameReg(regNumber reg, unsigned offset) { -#if defined(TARGET_UNIX) +#if defined(FEATURE_CFI_SUPPORT) if (generateCFIUnwindCodes()) { if (compGeneratingProlog) @@ -459,7 +459,7 @@ void Compiler::unwindSetFrameReg(regNumber reg, unsigned offset) } return; } -#endif // TARGET_UNIX +#endif // FEATURE_CFI_SUPPORT UnwindInfo* pu = &funCurrentFunc()->uwi; @@ -478,12 +478,12 @@ void Compiler::unwindSaveReg(regNumber reg, unsigned offset) void Compiler::unwindBranch16() { -#if defined(TARGET_UNIX) +#if defined(FEATURE_CFI_SUPPORT) if (generateCFIUnwindCodes()) { return; } -#endif // TARGET_UNIX +#endif // FEATURE_CFI_SUPPORT UnwindInfo* pu = &funCurrentFunc()->uwi; @@ -494,12 +494,12 @@ void Compiler::unwindBranch16() void Compiler::unwindNop(unsigned codeSizeInBytes) // codeSizeInBytes is 2 or 4 bytes for Thumb2 instruction { -#if defined(TARGET_UNIX) +#if defined(FEATURE_CFI_SUPPORT) if (generateCFIUnwindCodes()) { return; } -#endif // TARGET_UNIX +#endif // FEATURE_CFI_SUPPORT UnwindInfo* pu = &funCurrentFunc()->uwi; @@ -535,12 +535,12 @@ void Compiler::unwindNop(unsigned codeSizeInBytes) // codeSizeInBytes is 2 or 4 // for them. void Compiler::unwindPadding() { -#if defined(TARGET_UNIX) +#if defined(FEATURE_CFI_SUPPORT) if (generateCFIUnwindCodes()) { return; } -#endif // TARGET_UNIX +#endif // FEATURE_CFI_SUPPORT UnwindInfo* pu = &funCurrentFunc()->uwi; GetEmitter()->emitUnwindNopPadding(pu->GetCurrentEmitterLocation(), this); @@ -565,7 +565,7 @@ void Compiler::unwindReserveFunc(FuncInfoDsc* func) BOOL isFunclet = (func->funKind == FUNC_ROOT) ? FALSE : TRUE; bool funcHasColdSection = false; -#if defined(TARGET_UNIX) +#if defined(FEATURE_CFI_SUPPORT) if (generateCFIUnwindCodes()) { DWORD unwindCodeBytes = 0; @@ -578,7 +578,7 @@ void Compiler::unwindReserveFunc(FuncInfoDsc* func) return; } -#endif // TARGET_UNIX +#endif // FEATURE_CFI_SUPPORT // If there is cold code, split the unwind data between the hot section and the // cold section. This needs to be done before we split into fragments, as each @@ -638,13 +638,13 @@ void Compiler::unwindEmitFunc(FuncInfoDsc* func, void* pHotCode, void* pColdCode static_assert_no_msg(FUNC_HANDLER == (FuncKind)CORJIT_FUNC_HANDLER); static_assert_no_msg(FUNC_FILTER == (FuncKind)CORJIT_FUNC_FILTER); -#if defined(TARGET_UNIX) +#if defined(FEATURE_CFI_SUPPORT) if (generateCFIUnwindCodes()) { unwindEmitFuncCFI(func, pHotCode, pColdCode); return; } -#endif // TARGET_UNIX +#endif // FEATURE_CFI_SUPPORT func->uwi.Allocate((CorJitFuncKind)func->funKind, pHotCode, pColdCode, true); diff --git a/src/coreclr/jit/unwindarm64.cpp b/src/coreclr/jit/unwindarm64.cpp index 665e0ce9f525ad..f792f74e078eec 100644 --- a/src/coreclr/jit/unwindarm64.cpp +++ b/src/coreclr/jit/unwindarm64.cpp @@ -17,7 +17,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX #if defined(TARGET_ARM64) -#if defined(TARGET_UNIX) +#if defined(FEATURE_CFI_SUPPORT) short Compiler::mapRegNumToDwarfReg(regNumber reg) { short dwarfReg = DWARF_REG_ILLEGAL; @@ -223,7 +223,7 @@ short Compiler::mapRegNumToDwarfReg(regNumber reg) return dwarfReg; } -#endif // TARGET_UNIX +#endif // FEATURE_CFI_SUPPORT void Compiler::unwindPush(regNumber reg) { @@ -232,7 +232,7 @@ void Compiler::unwindPush(regNumber reg) void Compiler::unwindAllocStack(unsigned size) { -#if defined(TARGET_UNIX) +#if defined(FEATURE_CFI_SUPPORT) if (generateCFIUnwindCodes()) { if (compGeneratingProlog) @@ -242,7 +242,7 @@ void Compiler::unwindAllocStack(unsigned size) return; } -#endif // TARGET_UNIX +#endif // FEATURE_CFI_SUPPORT UnwindInfo* pu = &funCurrentFunc()->uwi; @@ -276,7 +276,7 @@ void Compiler::unwindAllocStack(unsigned size) void Compiler::unwindSetFrameReg(regNumber reg, unsigned offset) { -#if defined(TARGET_UNIX) +#if defined(FEATURE_CFI_SUPPORT) if (generateCFIUnwindCodes()) { if (compGeneratingProlog) @@ -286,7 +286,7 @@ void Compiler::unwindSetFrameReg(regNumber reg, unsigned offset) return; } -#endif // TARGET_UNIX +#endif // FEATURE_CFI_SUPPORT UnwindInfo* pu = &funCurrentFunc()->uwi; @@ -348,7 +348,7 @@ void Compiler::unwindSaveRegPair(regNumber reg1, regNumber reg2, int offset) assert(0 <= offset && offset <= 504); assert((offset % 8) == 0); -#if defined(TARGET_UNIX) +#if defined(FEATURE_CFI_SUPPORT) if (generateCFIUnwindCodes()) { if (compGeneratingProlog) @@ -362,7 +362,7 @@ void Compiler::unwindSaveRegPair(regNumber reg1, regNumber reg2, int offset) return; } -#endif // TARGET_UNIX +#endif // FEATURE_CFI_SUPPORT UnwindInfo* pu = &funCurrentFunc()->uwi; @@ -430,7 +430,7 @@ void Compiler::unwindSaveRegPairPreindexed(regNumber reg1, regNumber reg2, int o assert(offset < 0); assert((offset % 8) == 0); -#if defined(TARGET_UNIX) +#if defined(FEATURE_CFI_SUPPORT) if (generateCFIUnwindCodes()) { if (compGeneratingProlog) @@ -445,7 +445,7 @@ void Compiler::unwindSaveRegPairPreindexed(regNumber reg1, regNumber reg2, int o return; } -#endif // TARGET_UNIX +#endif // FEATURE_CFI_SUPPORT UnwindInfo* pu = &funCurrentFunc()->uwi; @@ -519,7 +519,7 @@ void Compiler::unwindSaveReg(regNumber reg, int offset) assert(0 <= offset && offset <= 504); assert((offset % 8) == 0); -#if defined(TARGET_UNIX) +#if defined(FEATURE_CFI_SUPPORT) if (generateCFIUnwindCodes()) { if (compGeneratingProlog) @@ -532,7 +532,7 @@ void Compiler::unwindSaveReg(regNumber reg, int offset) return; } -#endif // TARGET_UNIX +#endif // FEATURE_CFI_SUPPORT int z = offset / 8; assert(0 <= z && z <= 0x3F); @@ -573,7 +573,7 @@ void Compiler::unwindSaveRegPreindexed(regNumber reg, int offset) assert(-256 <= offset && offset < 0); assert((offset % 8) == 0); -#if defined(TARGET_UNIX) +#if defined(FEATURE_CFI_SUPPORT) if (generateCFIUnwindCodes()) { if (compGeneratingProlog) @@ -587,7 +587,7 @@ void Compiler::unwindSaveRegPreindexed(regNumber reg, int offset) return; } -#endif // _TARGET_UNIX_ +#endif // FEATURE_CFI_SUPPORT UnwindInfo* pu = &funCurrentFunc()->uwi; @@ -622,10 +622,10 @@ void Compiler::unwindSaveRegPreindexed(regNumber reg, int offset) void Compiler::unwindSaveNext() { -#if defined(TARGET_UNIX) +#if defined(FEATURE_CFI_SUPPORT) // do not use unwindSaveNext when generating CFI codes as there is no code for this assert(!generateCFIUnwindCodes()); -#endif // TARGET_UNIX +#endif // FEATURE_CFI_SUPPORT UnwindInfo* pu = &funCurrentFunc()->uwi; diff --git a/src/coreclr/jit/unwindx86.cpp b/src/coreclr/jit/unwindx86.cpp index aba58bc93b322d..0cd88fd29ba1e5 100644 --- a/src/coreclr/jit/unwindx86.cpp +++ b/src/coreclr/jit/unwindx86.cpp @@ -19,7 +19,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX #error "This should be included only for x86" #endif // TARGET_X86 -#if defined(TARGET_UNIX) +#if defined(FEATURE_CFI_SUPPORT) short Compiler::mapRegNumToDwarfReg(regNumber reg) { short dwarfReg = DWARF_REG_ILLEGAL; @@ -28,7 +28,7 @@ short Compiler::mapRegNumToDwarfReg(regNumber reg) return dwarfReg; } -#endif // TARGET_UNIX +#endif // FEATURE_CFI_SUPPORT void Compiler::unwindBegProlog() { diff --git a/src/coreclr/jit/utils.cpp b/src/coreclr/jit/utils.cpp index f18c1a6a6709cb..72ef9f4792eb71 100644 --- a/src/coreclr/jit/utils.cpp +++ b/src/coreclr/jit/utils.cpp @@ -23,19 +23,6 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX #include "opcode.h" -/*****************************************************************************/ -// Define the string platform name based on compilation #ifdefs. This is the -// same code for all platforms, hence it is here instead of in the targetXXX.cpp -// files. - -#ifdef TARGET_UNIX -// Should we distinguish Mac? Can we? -// Should we distinguish flavors of Unix? Can we? -const char* Target::g_tgtPlatformName = "Unix"; -#else // !TARGET_UNIX -const char* Target::g_tgtPlatformName = "Windows"; -#endif // !TARGET_UNIX - /*****************************************************************************/ #define DECLARE_DATA From ac4a3e1cc186c2db26a4dabfe416c7eee73ff845 Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Thu, 26 Aug 2021 18:29:22 -0700 Subject: [PATCH 02/15] Implement arg split as flag --- src/coreclr/jit/codegen.h | 8 ++++---- src/coreclr/jit/codegenarmarch.cpp | 14 +++++++------- src/coreclr/jit/codegenlinear.cpp | 12 ++++++------ src/coreclr/jit/compiler.h | 10 +++++----- src/coreclr/jit/compiler.hpp | 4 ++-- src/coreclr/jit/gentree.cpp | 28 ++++++++++++++-------------- src/coreclr/jit/gentree.h | 18 +++++++++--------- src/coreclr/jit/gtlist.h | 4 ++-- src/coreclr/jit/gtstructs.h | 6 +++--- src/coreclr/jit/jit.h | 13 ++++++------- src/coreclr/jit/lclvars.cpp | 29 +++++++++++++++-------------- src/coreclr/jit/lower.cpp | 10 +++++----- src/coreclr/jit/lsra.cpp | 10 +++++----- src/coreclr/jit/lsra.h | 4 ++-- src/coreclr/jit/lsraarm64.cpp | 4 ++-- src/coreclr/jit/lsraarmarch.cpp | 12 ++++++------ src/coreclr/jit/morph.cpp | 14 +++++++------- 17 files changed, 100 insertions(+), 100 deletions(-) diff --git a/src/coreclr/jit/codegen.h b/src/coreclr/jit/codegen.h index 5937e66731e2a4..d5d4441433881f 100644 --- a/src/coreclr/jit/codegen.h +++ b/src/coreclr/jit/codegen.h @@ -941,9 +941,9 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX void genIntrinsic(GenTree* treeNode); void genPutArgStk(GenTreePutArgStk* treeNode); void genPutArgReg(GenTreeOp* tree); -#if FEATURE_ARG_SPLIT +#if FEATURE_ARG_SPLIT_SUPPORTED void genPutArgSplit(GenTreePutArgSplit* treeNode); -#endif // FEATURE_ARG_SPLIT +#endif // FEATURE_ARG_SPLIT_SUPPORTED #if defined(TARGET_XARCH) unsigned getBaseVarForPutArgStk(GenTree* treeNode); @@ -1137,9 +1137,9 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX regNumber srcReg, regNumber sizeReg); #endif // FEATURE_PUT_STRUCT_ARG_STK -#if FEATURE_ARG_SPLIT +#if FEATURE_ARG_SPLIT_SUPPORTED void genConsumeArgSplitStruct(GenTreePutArgSplit* putArgNode); -#endif // FEATURE_ARG_SPLIT +#endif // FEATURE_ARG_SPLIT_SUPPORTED void genConsumeRegs(GenTree* tree); void genConsumeOperands(GenTreeOp* tree); diff --git a/src/coreclr/jit/codegenarmarch.cpp b/src/coreclr/jit/codegenarmarch.cpp index b0a6e8938062c5..ad759274a5ac9c 100644 --- a/src/coreclr/jit/codegenarmarch.cpp +++ b/src/coreclr/jit/codegenarmarch.cpp @@ -398,11 +398,11 @@ void CodeGen::genCodeForTreeNode(GenTree* treeNode) genPutArgReg(treeNode->AsOp()); break; -#if FEATURE_ARG_SPLIT +#if FEATURE_ARG_SPLIT_SUPPORTED case GT_PUTARG_SPLIT: genPutArgSplit(treeNode->AsPutArgSplit()); break; -#endif // FEATURE_ARG_SPLIT +#endif // FEATURE_ARG_SPLIT_SUPPORTED case GT_CALL: genCallInstruction(treeNode->AsCall()); @@ -1136,7 +1136,7 @@ void CodeGen::genPutArgReg(GenTreeOp* tree) genProduceReg(tree); } -#if FEATURE_ARG_SPLIT +#if FEATURE_ARG_SPLIT_SUPPORTED //--------------------------------------------------------------------- // genPutArgSplit - generate code for a GT_PUTARG_SPLIT node // @@ -1357,7 +1357,7 @@ void CodeGen::genPutArgSplit(GenTreePutArgSplit* treeNode) } genProduceReg(treeNode); } -#endif // FEATURE_ARG_SPLIT +#endif // FEATURE_ARG_SPLIT_SUPPORTED #ifdef FEATURE_SIMD //---------------------------------------------------------------------------------- @@ -2307,8 +2307,8 @@ void CodeGen::genCallInstruction(GenTreeCall* call) #endif // TARGET_ARM } } -#if FEATURE_ARG_SPLIT - else if (curArgTabEntry->IsSplit()) +#if FEATURE_ARG_SPLIT_SUPPORTED + else if (GlobalJitOptions::compFeatureArgSplit() && curArgTabEntry->IsSplit()) { assert(curArgTabEntry->numRegs >= 1); genConsumeArgSplitStruct(argNode->AsPutArgSplit()); @@ -2320,7 +2320,7 @@ void CodeGen::genCallInstruction(GenTreeCall* call) emitActualTypeSize(TYP_I_IMPL)); } } -#endif // FEATURE_ARG_SPLIT +#endif // FEATURE_ARG_SPLIT_SUPPORTED else { regNumber argReg = curArgTabEntry->GetRegNum(); diff --git a/src/coreclr/jit/codegenlinear.cpp b/src/coreclr/jit/codegenlinear.cpp index f58a8db0997e3c..be12f2e04e72ca 100644 --- a/src/coreclr/jit/codegenlinear.cpp +++ b/src/coreclr/jit/codegenlinear.cpp @@ -1797,7 +1797,7 @@ void CodeGen::genConsumePutStructArgStk(GenTreePutArgStk* putArgNode, } #endif // FEATURE_PUT_STRUCT_ARG_STK -#if FEATURE_ARG_SPLIT +#if FEATURE_ARG_SPLIT_SUPPORTED //------------------------------------------------------------------------ // genConsumeArgRegSplit: Consume register(s) in Call node to set split struct argument. // Liveness update for the PutArgSplit node is not needed @@ -1820,7 +1820,7 @@ void CodeGen::genConsumeArgSplitStruct(GenTreePutArgSplit* putArgNode) genCheckConsumeNode(putArgNode); } -#endif // FEATURE_ARG_SPLIT +#endif // FEATURE_ARG_SPLIT_SUPPORTED //------------------------------------------------------------------------ // genPutArgStkFieldList: Generate code for a putArgStk whose source is a GT_FIELD_LIST @@ -2136,8 +2136,8 @@ void CodeGen::genProduceReg(GenTree* tree) } } } -#if FEATURE_ARG_SPLIT - else if (tree->OperIsPutArgSplit()) +#if FEATURE_ARG_SPLIT_SUPPORTED + else if (GlobalJitOptions::compFeatureArgSplit() && tree->OperIsPutArgSplit()) { GenTreePutArgSplit* argSplit = tree->AsPutArgSplit(); unsigned regCount = argSplit->gtNumRegs; @@ -2154,7 +2154,7 @@ void CodeGen::genProduceReg(GenTree* tree) } } #ifdef TARGET_ARM - else if (tree->OperIsMultiRegOp()) + else if (GlobalJitOptions::compFeatureArgSplit() && tree->OperIsMultiRegOp()) { GenTreeMultiRegOp* multiReg = tree->AsMultiRegOp(); unsigned regCount = multiReg->GetRegCount(); @@ -2171,7 +2171,7 @@ void CodeGen::genProduceReg(GenTree* tree) } } #endif // TARGET_ARM -#endif // FEATURE_ARG_SPLIT +#endif // FEATURE_ARG_SPLIT_SUPPORTED else { regSet.rsSpillTree(tree->GetRegNum(), tree); diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index 090555672fd9b3..ea1e8bea2a3359 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -1530,9 +1530,9 @@ struct fgArgTabEntry bool isStruct : 1; // True if this is a struct arg bool _isVararg : 1; // True if the argument is in a vararg context. bool passedByRef : 1; // True iff the argument is passed by reference. -#ifdef FEATURE_ARG_SPLIT +#if FEATURE_ARG_SPLIT_SUPPORTED bool _isSplit : 1; // True when this argument is split between the registers and OutArg area -#endif // FEATURE_ARG_SPLIT +#endif // FEATURE_ARG_SPLIT_SUPPORTED #ifdef FEATURE_HFA_FIELDS_PRESENT CorInfoHFAElemType _hfaElemKind : 3; // What kind of an HFA this is (CORINFO_HFA_ELEM_NONE if it is not an HFA). #endif @@ -1597,15 +1597,15 @@ struct fgArgTabEntry bool IsSplit() const { -#ifdef FEATURE_ARG_SPLIT +#if FEATURE_ARG_SPLIT_SUPPORTED return _isSplit; -#else // FEATURE_ARG_SPLIT +#else // FEATURE_ARG_SPLIT_SUPPORTED return false; #endif } void SetSplit(bool value) { -#ifdef FEATURE_ARG_SPLIT +#if FEATURE_ARG_SPLIT_SUPPORTED _isSplit = value; #endif } diff --git a/src/coreclr/jit/compiler.hpp b/src/coreclr/jit/compiler.hpp index 23757caea1e0e5..488222a1362c73 100644 --- a/src/coreclr/jit/compiler.hpp +++ b/src/coreclr/jit/compiler.hpp @@ -4262,9 +4262,9 @@ void GenTree::VisitOperands(TVisitor visitor) case GT_PUTARG_REG: case GT_PUTARG_STK: case GT_PUTARG_TYPE: -#if FEATURE_ARG_SPLIT +#if FEATURE_ARG_SPLIT_SUPPORTED case GT_PUTARG_SPLIT: -#endif // FEATURE_ARG_SPLIT +#endif // FEATURE_ARG_SPLIT_SUPPORTED case GT_RETURNTRAP: case GT_KEEPALIVE: case GT_INC_SATURATE: diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index 18391199a1563e..b9c27a35b077a4 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -279,9 +279,9 @@ void GenTree::InitNodeSize() // TODO-Throughput: This should not need to be a large node. The object info should be // obtained from the child node. GenTree::s_gtNodeSizes[GT_PUTARG_STK] = TREE_NODE_SZ_LARGE; -#if FEATURE_ARG_SPLIT +#if FEATURE_ARG_SPLIT_SUPPORTED GenTree::s_gtNodeSizes[GT_PUTARG_SPLIT] = TREE_NODE_SZ_LARGE; -#endif // FEATURE_ARG_SPLIT +#endif // FEATURE_ARG_SPLIT_SUPPORTED #endif // FEATURE_PUT_STRUCT_ARG_STK assert(GenTree::s_gtNodeSizes[GT_RETURN] == GenTree::s_gtNodeSizes[GT_ASG]); @@ -341,9 +341,9 @@ void GenTree::InitNodeSize() // TODO-Throughput: This should not need to be a large node. The object info should be // obtained from the child node. static_assert_no_msg(sizeof(GenTreePutArgStk) <= TREE_NODE_SZ_LARGE); -#if FEATURE_ARG_SPLIT +#if FEATURE_ARG_SPLIT_SUPPORTED static_assert_no_msg(sizeof(GenTreePutArgSplit) <= TREE_NODE_SZ_LARGE); -#endif // FEATURE_ARG_SPLIT +#endif // FEATURE_ARG_SPLIT_SUPPORTED #endif // FEATURE_PUT_STRUCT_ARG_STK #ifdef FEATURE_SIMD @@ -694,7 +694,7 @@ int GenTree::GetRegisterDstCount(Compiler* compiler) const { return gtGetOp1()->GetRegisterDstCount(compiler); } -#if FEATURE_ARG_SPLIT +#if FEATURE_ARG_SPLIT_SUPPORTED else if (OperIsPutArgSplit()) { return (const_cast(this))->AsPutArgSplit()->gtNumRegs; @@ -769,8 +769,8 @@ regMaskTP GenTree::gtGetRegMask() const } } } -#if FEATURE_ARG_SPLIT - else if (OperIsPutArgSplit()) +#if FEATURE_ARG_SPLIT_SUPPORTED + else if (GlobalJitOptions::compFeatureArgSplit() && OperIsPutArgSplit()) { const GenTreePutArgSplit* splitArg = AsPutArgSplit(); const unsigned regCount = splitArg->gtNumRegs; @@ -783,7 +783,7 @@ regMaskTP GenTree::gtGetRegMask() const resultMask |= genRegMask(reg); } } -#endif // FEATURE_ARG_SPLIT +#endif // FEATURE_ARG_SPLIT_SUPPORTED else { resultMask = genRegMask(GetRegNum()); @@ -5221,7 +5221,7 @@ bool GenTree::TryGetUse(GenTree* def, GenTree*** use) return false; // Variadic nodes -#if FEATURE_ARG_SPLIT +#if FEATURE_ARG_SPLIT_SUPPORTED case GT_PUTARG_SPLIT: if (this->AsUnOp()->gtOp1->gtOper == GT_FIELD_LIST) { @@ -5233,7 +5233,7 @@ bool GenTree::TryGetUse(GenTree* def, GenTree*** use) return true; } return false; -#endif // FEATURE_ARG_SPLIT +#endif // FEATURE_ARG_SPLIT_SUPPORTED #ifdef FEATURE_SIMD case GT_SIMD: @@ -9359,9 +9359,9 @@ GenTreeUseEdgeIterator::GenTreeUseEdgeIterator(GenTree* node) case GT_BSWAP16: case GT_KEEPALIVE: case GT_INC_SATURATE: -#if FEATURE_ARG_SPLIT +#if FEATURE_ARG_SPLIT_SUPPORTED case GT_PUTARG_SPLIT: -#endif // FEATURE_ARG_SPLIT +#endif // FEATURE_ARG_SPLIT_SUPPORTED case GT_RETURNTRAP: m_edge = &m_node->AsUnOp()->gtOp1; assert(*m_edge != nullptr); @@ -11813,7 +11813,7 @@ void Compiler::gtDispTree(GenTree* tree, } } } -#if FEATURE_ARG_SPLIT +#if FEATURE_ARG_SPLIT_SUPPORTED else if (tree->OperGet() == GT_PUTARG_SPLIT) { const GenTreePutArgSplit* putArg = tree->AsPutArgSplit(); @@ -11824,7 +11824,7 @@ void Compiler::gtDispTree(GenTree* tree, putArg->gtNumRegs); #endif } -#endif // FEATURE_ARG_SPLIT +#endif // FEATURE_ARG_SPLIT_SUPPORTED #endif // FEATURE_PUT_STRUCT_ARG_STK if (tree->gtOper == GT_INTRINSIC) diff --git a/src/coreclr/jit/gentree.h b/src/coreclr/jit/gentree.h index 79b8d15336559a..80b8995f1851f1 100644 --- a/src/coreclr/jit/gentree.h +++ b/src/coreclr/jit/gentree.h @@ -1294,9 +1294,9 @@ struct GenTree bool OperIsPutArgSplit() const { -#if FEATURE_ARG_SPLIT +#if FEATURE_ARG_SPLIT_SUPPORTED return gtOper == GT_PUTARG_SPLIT; -#else // !FEATURE_ARG_SPLIT +#else // !FEATURE_ARG_SPLIT_SUPPORTED return false; #endif } @@ -6504,7 +6504,7 @@ struct GenTreePutArgStk : public GenTreeUnOp #endif }; -#if FEATURE_ARG_SPLIT +#if FEATURE_ARG_SPLIT_SUPPORTED // Represent the struct argument: split value in register(s) and stack struct GenTreePutArgSplit : public GenTreePutArgStk { @@ -6665,7 +6665,7 @@ struct GenTreePutArgSplit : public GenTreePutArgStk } #endif }; -#endif // FEATURE_ARG_SPLIT +#endif // FEATURE_ARG_SPLIT_SUPPORTED // Represents GT_COPY or GT_RELOAD node // @@ -7594,7 +7594,7 @@ inline bool GenTree::IsMultiRegNode() const return true; } -#if FEATURE_ARG_SPLIT +#if FEATURE_ARG_SPLIT_SUPPORTED if (OperIsPutArgSplit()) { return true; @@ -7642,7 +7642,7 @@ inline unsigned GenTree::GetMultiRegCount() return AsCall()->GetReturnTypeDesc()->GetReturnRegCount(); } -#if FEATURE_ARG_SPLIT +#if FEATURE_ARG_SPLIT_SUPPORTED if (OperIsPutArgSplit()) { return AsPutArgSplit()->gtNumRegs; @@ -7712,7 +7712,7 @@ inline regNumber GenTree::GetRegByIndex(int regIndex) return AsCall()->GetRegNumByIdx(regIndex); } -#if FEATURE_ARG_SPLIT +#if FEATURE_ARG_SPLIT_SUPPORTED if (OperIsPutArgSplit()) { return AsPutArgSplit()->GetRegNumByIdx(regIndex); @@ -7772,7 +7772,7 @@ inline var_types GenTree::GetRegTypeByIndex(int regIndex) return AsCall()->AsCall()->GetReturnTypeDesc()->GetReturnRegType(regIndex); } -#if FEATURE_ARG_SPLIT +#if FEATURE_ARG_SPLIT_SUPPORTED if (OperIsPutArgSplit()) { return AsPutArgSplit()->GetRegType(regIndex); @@ -7836,7 +7836,7 @@ inline GenTreeFlags GenTree::GetRegSpillFlagByIdx(int regIndex) const return AsCall()->GetRegSpillFlagByIdx(regIndex); } -#if FEATURE_ARG_SPLIT +#if FEATURE_ARG_SPLIT_SUPPORTED if (OperIsPutArgSplit()) { return AsPutArgSplit()->GetRegSpillFlagByIdx(regIndex); diff --git a/src/coreclr/jit/gtlist.h b/src/coreclr/jit/gtlist.h index 248bada7752035..da2ac9bf6006b7 100644 --- a/src/coreclr/jit/gtlist.h +++ b/src/coreclr/jit/gtlist.h @@ -297,9 +297,9 @@ GTNODE(PUTARG_REG , GenTreeOp ,0,GTK_UNOP) #endif GTNODE(PUTARG_TYPE , GenTreeOp ,0,GTK_UNOP|GTK_NOTLIR) // operator that places saves argument type between importation and morph GTNODE(PUTARG_STK , GenTreePutArgStk ,0,GTK_UNOP|GTK_NOVALUE) // operator that places outgoing arg in stack -#if FEATURE_ARG_SPLIT +#if FEATURE_ARG_SPLIT_SUPPORTED GTNODE(PUTARG_SPLIT , GenTreePutArgSplit ,0,GTK_UNOP) // operator that places outgoing arg in registers with stack (split struct in ARM32) -#endif // FEATURE_ARG_SPLIT +#endif // FEATURE_ARG_SPLIT_SUPPORTED GTNODE(RETURNTRAP , GenTreeOp ,0,GTK_UNOP|GTK_NOVALUE) // a conditional call to wait on gc GTNODE(SWAP , GenTreeOp ,0,GTK_BINOP|GTK_NOVALUE) // op1 and op2 swap (registers) GTNODE(IL_OFFSET , Statement ,0,GTK_LEAF|GTK_NOVALUE) // marks an IL offset for debugging purposes diff --git a/src/coreclr/jit/gtstructs.h b/src/coreclr/jit/gtstructs.h index b4bad947fd90f7..db44ef5ae336a6 100644 --- a/src/coreclr/jit/gtstructs.h +++ b/src/coreclr/jit/gtstructs.h @@ -102,12 +102,12 @@ GTSTRUCT_1(PhiArg , GT_PHI_ARG) GTSTRUCT_1(Phi , GT_PHI) GTSTRUCT_1(StoreInd , GT_STOREIND) GTSTRUCT_N(Indir , GT_STOREIND, GT_IND, GT_NULLCHECK, GT_BLK, GT_STORE_BLK, GT_OBJ, GT_STORE_OBJ, GT_DYN_BLK, GT_STORE_DYN_BLK) -#if FEATURE_ARG_SPLIT +#if FEATURE_ARG_SPLIT_SUPPORTED GTSTRUCT_2_SPECIAL(PutArgStk, GT_PUTARG_STK, GT_PUTARG_SPLIT) GTSTRUCT_1(PutArgSplit , GT_PUTARG_SPLIT) -#else // !FEATURE_ARG_SPLIT +#else // !FEATURE_ARG_SPLIT_SUPPORTED GTSTRUCT_1(PutArgStk , GT_PUTARG_STK) -#endif // !FEATURE_ARG_SPLIT +#endif // !FEATURE_ARG_SPLIT_SUPPORTED GTSTRUCT_1(PhysReg , GT_PHYSREG) #ifdef FEATURE_SIMD GTSTRUCT_1(SIMD , GT_SIMD) diff --git a/src/coreclr/jit/jit.h b/src/coreclr/jit/jit.h index d1354bead74235..74a0e73bf05b9a 100644 --- a/src/coreclr/jit/jit.h +++ b/src/coreclr/jit/jit.h @@ -248,11 +248,11 @@ // Arm64 Windows supports FEATURE_ARG_SPLIT, note this is different from // the official Arm64 ABI. // Case: splitting 16 byte struct between x7 and stack -#if (defined(TARGET_ARM) || defined(WINDOWS_ARM64_ABI)) -#define FEATURE_ARG_SPLIT 1 +#if defined(TARGET_ARM) || defined(TARGET_ARM64) +#define FEATURE_ARG_SPLIT_SUPPORTED 1 #else -#define FEATURE_ARG_SPLIT 0 -#endif // (defined(TARGET_ARM) || defined(WINDOWS_ARM64_ABI)) +#define FEATURE_ARG_SPLIT_SUPPORTED 0 +#endif // To get rid of warning 4701 : local variable may be used without being initialized #define DUMMY_INIT(x) (x) @@ -362,14 +362,13 @@ class GlobalJitOptions #endif // Native Varargs are not supported on Unix (all architectures) and Windows ARM -#if defined(TARGET_WINDOWS) && !defined(TARGET_ARM) - static bool compFeatureVarArg() { return true; } -#elif !defined(TARGET_WINDOWS) && !defined(TARGET_UNIX) && !defined(TARGET_ARM) +#if !defined(TARGET_ARM) static bool compFeatureVarArg() { return TargetOS::IsWindows; } #else static bool compFeatureVarArg() { return false; } #endif + static bool compFeatureArgSplit() { return TargetArchitecture::IsArm32 || (TargetOS::IsWindows && TargetArchitecture::IsArm64); } }; /*****************************************************************************/ diff --git a/src/coreclr/jit/lclvars.cpp b/src/coreclr/jit/lclvars.cpp index e4af67018ddb7c..a1a11e3e680bbf 100644 --- a/src/coreclr/jit/lclvars.cpp +++ b/src/coreclr/jit/lclvars.cpp @@ -725,23 +725,26 @@ void Compiler::lvaInitUserArgs(InitVarDscInfo* varDscInfo, unsigned skipArgs, un // it enregistered, as long as we can split the rest onto the stack. unsigned cSlotsToEnregister = cSlots; -#if defined(TARGET_ARM64) && FEATURE_ARG_SPLIT +#if defined(TARGET_ARM64) - // On arm64 Windows we will need to properly handle the case where a >8byte <=16byte - // struct is split between register r7 and virtual stack slot s[0] - // We will only do this for calls to vararg methods on Windows Arm64 - // - // !!This does not affect the normal arm64 calling convention or Unix Arm64!! - if (this->info.compIsVarArgs && argType == TYP_STRUCT) + if (GlobalJitOptions::compFeatureArgSplit()) { - if (varDscInfo->canEnreg(TYP_INT, 1) && // The beginning of the struct can go in a register - !varDscInfo->canEnreg(TYP_INT, cSlots)) // The end of the struct can't fit in a register + // On arm64 Windows we will need to properly handle the case where a >8byte <=16byte + // struct is split between register r7 and virtual stack slot s[0] + // We will only do this for calls to vararg methods on Windows Arm64 + // + // !!This does not affect the normal arm64 calling convention or Unix Arm64!! + if (this->info.compIsVarArgs && argType == TYP_STRUCT) { - cSlotsToEnregister = 1; // Force the split + if (varDscInfo->canEnreg(TYP_INT, 1) && // The beginning of the struct can go in a register + !varDscInfo->canEnreg(TYP_INT, cSlots)) // The end of the struct can't fit in a register + { + cSlotsToEnregister = 1; // Force the split + } } } -#endif // defined(TARGET_ARM64) && FEATURE_ARG_SPLIT +#endif // defined(TARGET_ARM64) #ifdef TARGET_ARM // On ARM we pass the first 4 words of integer arguments and non-HFA structs in registers. @@ -5827,8 +5830,7 @@ int Compiler::lvaAssignVirtualFrameOffsetToArg(unsigned lclNum, #elif defined(TARGET_ARM64) // Register arguments on ARM64 only take stack space when they have a frame home. // Unless on windows and in a vararg method. -#if FEATURE_ARG_SPLIT - if (this->info.compIsVarArgs) + if (GlobalJitOptions::compFeatureArgSplit() && this->info.compIsVarArgs) { if (varDsc->lvType == TYP_STRUCT && varDsc->GetOtherArgReg() >= MAX_REG_ARG && varDsc->GetOtherArgReg() != REG_NA) @@ -5839,7 +5841,6 @@ int Compiler::lvaAssignVirtualFrameOffsetToArg(unsigned lclNum, argOffs += TARGET_POINTER_SIZE; } } -#endif // FEATURE_ARG_SPLIT #elif defined(TARGET_ARM) // On ARM we spill the registers in codeGen->regSet.rsMaskPreSpillRegArg diff --git a/src/coreclr/jit/lower.cpp b/src/coreclr/jit/lower.cpp index 9f043ee7b9183d..5c21f10c4e9497 100644 --- a/src/coreclr/jit/lower.cpp +++ b/src/coreclr/jit/lower.cpp @@ -1039,9 +1039,9 @@ GenTree* Lowering::NewPutArg(GenTreeCall* call, GenTree* arg, fgArgTabEntry* inf } #endif -#if FEATURE_ARG_SPLIT +#if FEATURE_ARG_SPLIT_SUPPORTED // Struct can be split into register(s) and stack on ARM - if (info->IsSplit()) + if (GlobalJitOptions::compFeatureArgSplit() && info->IsSplit()) { assert(arg->OperGet() == GT_OBJ || arg->OperGet() == GT_FIELD_LIST); // TODO: Need to check correctness for FastTailCall @@ -1110,7 +1110,7 @@ GenTree* Lowering::NewPutArg(GenTreeCall* call, GenTree* arg, fgArgTabEntry* inf } } else -#endif // FEATURE_ARG_SPLIT +#endif // FEATURE_ARG_SPLIT_SUPPORTED { if (!isOnStack) { @@ -6451,9 +6451,9 @@ void Lowering::ContainCheckNode(GenTree* node) break; case GT_PUTARG_REG: case GT_PUTARG_STK: -#if FEATURE_ARG_SPLIT +#if FEATURE_ARG_SPLIT_SUPPORTED case GT_PUTARG_SPLIT: -#endif // FEATURE_ARG_SPLIT +#endif // FEATURE_ARG_SPLIT_SUPPORTED // The regNum must have been set by the lowering of the call. assert(node->GetRegNum() != REG_NA); break; diff --git a/src/coreclr/jit/lsra.cpp b/src/coreclr/jit/lsra.cpp index 9491b2c0773578..efceaa9f2d68a1 100644 --- a/src/coreclr/jit/lsra.cpp +++ b/src/coreclr/jit/lsra.cpp @@ -145,13 +145,13 @@ void lsraAssignRegToTree(GenTree* tree, regNumber reg, unsigned regIdx) copy->gtOtherRegs[0] = (regNumberSmall)reg; } #endif // FEATURE_MULTIREG_RET -#if FEATURE_ARG_SPLIT +#if FEATURE_ARG_SPLIT_SUPPORTED else if (tree->OperIsPutArgSplit()) { GenTreePutArgSplit* putArg = tree->AsPutArgSplit(); putArg->SetRegNumByIdx(reg, regIdx); } -#endif // FEATURE_ARG_SPLIT +#endif // FEATURE_ARG_SPLIT_SUPPORTED #if defined(TARGET_XARCH) && defined(FEATURE_HW_INTRINSICS) else if (tree->OperIs(GT_HWINTRINSIC)) { @@ -6887,20 +6887,20 @@ void LinearScan::resolveRegisters() GenTreeCall* call = treeNode->AsCall(); call->SetRegSpillFlagByIdx(GTF_SPILL, currentRefPosition->getMultiRegIdx()); } -#if FEATURE_ARG_SPLIT +#if FEATURE_ARG_SPLIT_SUPPORTED else if (treeNode->OperIsPutArgSplit()) { GenTreePutArgSplit* splitArg = treeNode->AsPutArgSplit(); splitArg->SetRegSpillFlagByIdx(GTF_SPILL, currentRefPosition->getMultiRegIdx()); } #ifdef TARGET_ARM - else if (treeNode->OperIsMultiRegOp()) + else if (GlobalJitOptions::compFeatureArgSplit() && treeNode->OperIsMultiRegOp()) { GenTreeMultiRegOp* multiReg = treeNode->AsMultiRegOp(); multiReg->SetRegSpillFlagByIdx(GTF_SPILL, currentRefPosition->getMultiRegIdx()); } #endif // TARGET_ARM -#endif // FEATURE_ARG_SPLIT +#endif // FEATURE_ARG_SPLIT_SUPPORTED } // If the value is reloaded or moved to a different register, we need to insert diff --git a/src/coreclr/jit/lsra.h b/src/coreclr/jit/lsra.h index b0c17358716952..516080cd3d0b91 100644 --- a/src/coreclr/jit/lsra.h +++ b/src/coreclr/jit/lsra.h @@ -1883,9 +1883,9 @@ class LinearScan : public LinearScanInterface #endif // FEATURE_HW_INTRINSICS int BuildPutArgStk(GenTreePutArgStk* argNode); -#if FEATURE_ARG_SPLIT +#if FEATURE_ARG_SPLIT_SUPPORTED int BuildPutArgSplit(GenTreePutArgSplit* tree); -#endif // FEATURE_ARG_SPLIT +#endif // FEATURE_ARG_SPLIT_SUPPORTED int BuildLclHeap(GenTree* tree); }; diff --git a/src/coreclr/jit/lsraarm64.cpp b/src/coreclr/jit/lsraarm64.cpp index a7a14fdfe54f96..db4f80a0896664 100644 --- a/src/coreclr/jit/lsraarm64.cpp +++ b/src/coreclr/jit/lsraarm64.cpp @@ -479,12 +479,12 @@ int LinearScan::BuildNode(GenTree* tree) } break; -#if FEATURE_ARG_SPLIT +#if FEATURE_ARG_SPLIT_SUPPORTED case GT_PUTARG_SPLIT: srcCount = BuildPutArgSplit(tree->AsPutArgSplit()); dstCount = tree->AsPutArgSplit()->gtNumRegs; break; -#endif // FEATURE _SPLIT_ARG +#endif // FEATURE_ARG_SPLIT_SUPPORTED case GT_PUTARG_STK: srcCount = BuildPutArgStk(tree->AsPutArgStk()); diff --git a/src/coreclr/jit/lsraarmarch.cpp b/src/coreclr/jit/lsraarmarch.cpp index a470e19c94e647..cc95f5f40d5404 100644 --- a/src/coreclr/jit/lsraarmarch.cpp +++ b/src/coreclr/jit/lsraarmarch.cpp @@ -280,7 +280,7 @@ int LinearScan::BuildCall(GenTreeCall* call) srcCount++; } } -#if FEATURE_ARG_SPLIT +#if FEATURE_ARG_SPLIT_SUPPORTED else if (argNode->OperGet() == GT_PUTARG_SPLIT) { unsigned regCount = argNode->AsPutArgSplit()->gtNumRegs; @@ -291,7 +291,7 @@ int LinearScan::BuildCall(GenTreeCall* call) } srcCount += regCount; } -#endif // FEATURE_ARG_SPLIT +#endif // FEATURE_ARG_SPLIT_SUPPORTED else { assert(argNode->OperIs(GT_PUTARG_REG)); @@ -334,11 +334,11 @@ int LinearScan::BuildCall(GenTreeCall* call) { fgArgTabEntry* curArgTabEntry = compiler->gtArgEntryByNode(call, arg); assert(curArgTabEntry != nullptr); -#if FEATURE_ARG_SPLIT +#if FEATURE_ARG_SPLIT_SUPPORTED // PUTARG_SPLIT nodes must be in the gtCallLateArgs list, since they // define registers used by the call. assert(arg->OperGet() != GT_PUTARG_SPLIT); -#endif // FEATURE_ARG_SPLIT +#endif // FEATURE_ARG_SPLIT_SUPPORTED if (arg->gtOper == GT_PUTARG_STK) { assert(curArgTabEntry->GetRegNum() == REG_STK); @@ -474,7 +474,7 @@ int LinearScan::BuildPutArgStk(GenTreePutArgStk* argNode) return srcCount; } -#if FEATURE_ARG_SPLIT +#if FEATURE_ARG_SPLIT_SUPPORTED //------------------------------------------------------------------------ // BuildPutArgSplit: Set the NodeInfo for a GT_PUTARG_SPLIT node // @@ -576,7 +576,7 @@ int LinearScan::BuildPutArgSplit(GenTreePutArgSplit* argNode) BuildDefs(argNode, dstCount, argMask); return srcCount; } -#endif // FEATURE_ARG_SPLIT +#endif // FEATURE_ARG_SPLIT_SUPPORTED //------------------------------------------------------------------------ // BuildBlockStore: Build the RefPositions for a block store node. diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index 8dd51fc2f2e3a6..707b63311560e6 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -1360,13 +1360,13 @@ void fgArgInfo::ArgsComplete() continue; #endif } -#if FEATURE_ARG_SPLIT +#if FEATURE_ARG_SPLIT_SUPPORTED else if (curArgTabEntry->IsSplit()) { hasStructRegArg = true; assert(hasStackArgs == true); } -#endif // FEATURE_ARG_SPLIT +#endif // FEATURE_ARG_SPLIT_SUPPORTED else // we have a register argument, next we look for a struct type. { if (varTypeIsStruct(argx) UNIX_AMD64_ABI_ONLY(|| curArgTabEntry->isStruct)) @@ -1489,12 +1489,12 @@ void fgArgInfo::ArgsComplete() { prevArgTabEntry->needPlace = true; } -#if FEATURE_ARG_SPLIT +#if FEATURE_ARG_SPLIT_SUPPORTED else if (prevArgTabEntry->IsSplit()) { prevArgTabEntry->needPlace = true; } -#endif // TARGET_ARM +#endif // FEATURE_ARG_SPLIT_SUPPORTED #endif } } @@ -3579,9 +3579,9 @@ void Compiler::fgInitArgInfo(GenTreeCall* call) { if (!isNonStandard) { -#if FEATURE_ARG_SPLIT +#if FEATURE_ARG_SPLIT_SUPPORTED // Check for a split (partially enregistered) struct - if (!passUsingFloatRegs && ((intArgRegNum + size) > MAX_REG_ARG)) + if (GlobalJitOptions::compFeatureArgSplit() && !passUsingFloatRegs && ((intArgRegNum + size) > MAX_REG_ARG)) { // This indicates a partial enregistration of a struct type assert((isStructArg) || argx->OperIs(GT_FIELD_LIST) || argx->OperIsCopyBlkOp() || @@ -3590,7 +3590,7 @@ void Compiler::fgInitArgInfo(GenTreeCall* call) assert((unsigned char)numRegsPartial == numRegsPartial); call->fgArgInfo->SplitArg(argIndex, numRegsPartial, size - numRegsPartial); } -#endif // FEATURE_ARG_SPLIT +#endif // FEATURE_ARG_SPLIT_SUPPORTED if (passUsingFloatRegs) { From 2ba216281548867c96d4c06dc8c760914cd79008 Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Thu, 26 Aug 2021 19:08:36 -0700 Subject: [PATCH 03/15] Move OSX Arm64 abi to flags --- .../superpmi-shared/methodcontext.cpp | 4 +- src/coreclr/clrdefinitions.cmake | 3 ++ src/coreclr/gcinfo/gcinfoencoder.cpp | 9 ++-- src/coreclr/inc/corinfo.h | 1 + src/coreclr/inc/switches.h | 7 +++ src/coreclr/jit/codegenarmarch.cpp | 50 +++++++++++-------- src/coreclr/jit/codegenlinear.cpp | 6 +-- src/coreclr/jit/compiler.cpp | 24 +++++---- src/coreclr/jit/compiler.h | 23 +++++---- src/coreclr/jit/ee_il_dll.cpp | 25 ++++++---- src/coreclr/jit/jit.h | 12 +++-- src/coreclr/jit/lclvars.cpp | 22 ++++---- src/coreclr/jit/lower.cpp | 15 ++++-- src/coreclr/jit/lsraarmarch.cpp | 23 +++++---- src/coreclr/jit/morph.cpp | 15 +++--- .../tools/Common/JitInterface/CorInfoImpl.cs | 3 +- .../tools/Common/JitInterface/CorInfoTypes.cs | 1 + src/coreclr/vm/jitinterface.cpp | 4 +- 18 files changed, 146 insertions(+), 101 deletions(-) diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp index 7d4a191c51cf62..7a92af9a04f812 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp @@ -4188,7 +4188,9 @@ void MethodContext::repGetEEInfo(CORINFO_EE_INFO* pEEInfoOut) pEEInfoOut->osPageSize = (size_t)0x1000; pEEInfoOut->maxUncheckedOffsetForNullObject = (size_t)((32 * 1024) - 1); pEEInfoOut->targetAbi = CORINFO_DESKTOP_ABI; -#ifdef TARGET_UNIX +#ifdef TARGET_OSX + pEEInfoOut->osType = CORINFO_MACOS; +#elif defined(TARGET_UNIX) pEEInfoOut->osType = CORINFO_UNIX; #else pEEInfoOut->osType = CORINFO_WINNT; diff --git a/src/coreclr/clrdefinitions.cmake b/src/coreclr/clrdefinitions.cmake index be2335b5910d57..c415448dc09785 100644 --- a/src/coreclr/clrdefinitions.cmake +++ b/src/coreclr/clrdefinitions.cmake @@ -244,6 +244,9 @@ function(set_target_definitions_to_custom_os_and_arch) if ((TARGETDETAILS_ARCH STREQUAL "arm64") AND (TARGETDETAILS_OS STREQUAL "unix_osx")) target_compile_definitions(${TARGETDETAILS_TARGET} PRIVATE OSX_ARM64_ABI) endif() + if (TARGETDETAILS_OS STREQUAL "unix_osx") + target_compile_definitions(${TARGETDETAILS_TARGET} PRIVATE TARGET_OSX) + endif() else() target_compile_definitions(${TARGETDETAILS_TARGET} PRIVATE TARGET_WINDOWS) endif((TARGETDETAILS_OS MATCHES "^unix")) diff --git a/src/coreclr/gcinfo/gcinfoencoder.cpp b/src/coreclr/gcinfo/gcinfoencoder.cpp index 8f56607e22ba5d..b82f0f2335598d 100644 --- a/src/coreclr/gcinfo/gcinfoencoder.cpp +++ b/src/coreclr/gcinfo/gcinfoencoder.cpp @@ -577,10 +577,11 @@ GcSlotId GcInfoEncoder::GetStackSlotId( INT32 spOffset, GcSlotFlags flags, GcSta _ASSERTE( (flags & (GC_SLOT_IS_REGISTER | GC_SLOT_IS_DELETED)) == 0 ); -#if !defined(OSX_ARM64_ABI) - // the spOffset for the stack slot is required to be pointer size aligned - _ASSERTE((spOffset % TARGET_POINTER_SIZE) == 0); -#endif + if (!(TargetOS::IsMacOS && TargetArchitecture::IsArm64)) + { + // the spOffset for the stack slot is required to be pointer size aligned + _ASSERTE((spOffset % TARGET_POINTER_SIZE) == 0); + } m_SlotTable[ m_NumSlots ].Slot.Stack.SpOffset = spOffset; m_SlotTable[ m_NumSlots ].Slot.Stack.Base = spBase; diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h index a0093501b561bc..7981283ac5f0f0 100644 --- a/src/coreclr/inc/corinfo.h +++ b/src/coreclr/inc/corinfo.h @@ -1729,6 +1729,7 @@ enum CORINFO_OS { CORINFO_WINNT, CORINFO_UNIX, + CORINFO_MACOS, }; struct CORINFO_CPU diff --git a/src/coreclr/inc/switches.h b/src/coreclr/inc/switches.h index 789cddd3455e4b..1eab4fc573dc78 100644 --- a/src/coreclr/inc/switches.h +++ b/src/coreclr/inc/switches.h @@ -184,10 +184,16 @@ class TargetOS #define TARGET_WINDOWS_POSSIBLY_SUPPORTED static const bool IsWindows = true; static const bool IsUnix = false; + static const bool IsMacOS = false; #elif defined(TARGET_UNIX) #define TARGET_UNIX_POSSIBLY_SUPPORTED static const bool IsWindows = false; static const bool IsUnix = true; +#if defined(TARGET_OSX) + static const bool IsMacOS = true; +#else + static const bool IsMacOS = false; +#endif #else #define TARGET_WINDOWS_POSSIBLY_SUPPORTED #define TARGET_UNIX_POSSIBLY_SUPPORTED @@ -195,6 +201,7 @@ class TargetOS static bool OSSettingConfigured; static bool IsWindows; static bool IsUnix; + static bool IsMacOS; #endif }; diff --git a/src/coreclr/jit/codegenarmarch.cpp b/src/coreclr/jit/codegenarmarch.cpp index ad759274a5ac9c..e0685c0b8cbe41 100644 --- a/src/coreclr/jit/codegenarmarch.cpp +++ b/src/coreclr/jit/codegenarmarch.cpp @@ -682,11 +682,16 @@ void CodeGen::genPutArgStk(GenTreePutArgStk* treeNode) { assert(treeNode->OperIs(GT_PUTARG_STK)); GenTree* source = treeNode->gtOp1; -#if !defined(OSX_ARM64_ABI) - var_types targetType = genActualType(source->TypeGet()); -#else - var_types targetType = source->TypeGet(); -#endif + var_types targetType; + + if (!GlobalJitOptions::compMacOsArm64Abi()) + { + targetType = genActualType(source->TypeGet()); + } + else + { + targetType = source->TypeGet(); + } emitter* emit = GetEmitter(); // This is the varNum for our store operations, @@ -741,17 +746,17 @@ void CodeGen::genPutArgStk(GenTreePutArgStk* treeNode) regNumber srcReg = genConsumeReg(source); assert((srcReg != REG_NA) && (genIsValidFloatReg(srcReg))); -#if !defined(OSX_ARM64_ABI) - assert(treeNode->GetStackByteSize() % TARGET_POINTER_SIZE == 0); -#else // OSX_ARM64_ABI - if (treeNode->GetStackByteSize() == 12) + assert(GlobalJitOptions::compMacOsArm64Abi() || treeNode->GetStackByteSize() % TARGET_POINTER_SIZE == 0); + +#ifdef TARGET_ARM64 + if (GlobalJitOptions::compMacOsArm64Abi() && (treeNode->GetStackByteSize() == 12)) { regNumber tmpReg = treeNode->GetSingleTempReg(); GetEmitter()->emitStoreSIMD12ToLclOffset(varNumOut, argOffsetOut, srcReg, tmpReg); argOffsetOut += 12; } else -#endif // OSX_ARM64_ABI +#endif // TARGET_ARM64 { emitAttr storeAttr = emitTypeSize(targetType); emit->emitIns_S_R(INS_str, storeAttr, srcReg, varNumOut, argOffsetOut); @@ -761,20 +766,21 @@ void CodeGen::genPutArgStk(GenTreePutArgStk* treeNode) return; } -#if defined(OSX_ARM64_ABI) - switch (treeNode->GetStackByteSize()) + if (GlobalJitOptions::compMacOsArm64Abi()) { - case 1: - targetType = TYP_BYTE; - break; - case 2: - targetType = TYP_SHORT; - break; - default: - assert(treeNode->GetStackByteSize() >= 4); - break; + switch (treeNode->GetStackByteSize()) + { + case 1: + targetType = TYP_BYTE; + break; + case 2: + targetType = TYP_SHORT; + break; + default: + assert(treeNode->GetStackByteSize() >= 4); + break; + } } -#endif instruction storeIns = ins_Store(targetType); emitAttr storeAttr = emitTypeSize(targetType); diff --git a/src/coreclr/jit/codegenlinear.cpp b/src/coreclr/jit/codegenlinear.cpp index be12f2e04e72ca..083e95278010bf 100644 --- a/src/coreclr/jit/codegenlinear.cpp +++ b/src/coreclr/jit/codegenlinear.cpp @@ -1853,16 +1853,16 @@ void CodeGen::genPutArgStkFieldList(GenTreePutArgStk* putArgStk, unsigned outArg // Emit store instructions to store the registers produced by the GT_FIELD_LIST into the outgoing // argument area. -#if defined(FEATURE_SIMD) && defined(OSX_ARM64_ABI) +#if defined(FEATURE_SIMD) && defined(TARGET_ARM64) // storing of TYP_SIMD12 (i.e. Vector3) argument. - if (type == TYP_SIMD12) + if (GlobalJitOptions::compMacOsArm64Abi() && (type == TYP_SIMD12)) { // Need an additional integer register to extract upper 4 bytes from data. regNumber tmpReg = nextArgNode->GetSingleTempReg(); GetEmitter()->emitStoreSIMD12ToLclOffset(outArgVarNum, thisFieldOffset, reg, tmpReg); } else -#endif // FEATURE_SIMD && OSX_ARM64_ABI +#endif // FEATURE_SIMD { emitAttr attr = emitTypeSize(type); GetEmitter()->emitIns_S_R(ins_Store(type), attr, reg, outArgVarNum, thisFieldOffset); diff --git a/src/coreclr/jit/compiler.cpp b/src/coreclr/jit/compiler.cpp index 20fa2d40072ba6..48c0aa7707ee1e 100644 --- a/src/coreclr/jit/compiler.cpp +++ b/src/coreclr/jit/compiler.cpp @@ -5173,13 +5173,14 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl m_pLowering = new (this, CMK_LSRA) Lowering(this, m_pLinearScan); // PHASE_LOWERING m_pLowering->Run(); -#if !defined(OSX_ARM64_ABI) - // Set stack levels; this information is necessary for x86 - // but on other platforms it is used only in asserts. - // TODO: do not run it in release on other platforms, see https://github.com/dotnet/runtime/issues/42673. - StackLevelSetter stackLevelSetter(this); - stackLevelSetter.Run(); -#endif // !OSX_ARM64_ABI + if (!GlobalJitOptions::compMacOsArm64Abi()) + { + // Set stack levels; this information is necessary for x86 + // but on other platforms it is used only in asserts. + // TODO: do not run it in release on other platforms, see https://github.com/dotnet/runtime/issues/42673. + StackLevelSetter stackLevelSetter(this); + stackLevelSetter.Run(); + } // We can not add any new tracked variables after this point. lvaTrackedFixed = true; @@ -5523,7 +5524,11 @@ int Compiler::compCompile(CORINFO_MODULE_HANDLE classPtr, // Match OS for compMatchedVM CORINFO_EE_INFO* eeInfo = eeGetEEInfo(); - if (TargetOS::IsUnix) + if (TargetOS::IsMacOS) + { + info.compMatchedVM = info.compMatchedVM && (eeInfo->osType == CORINFO_MACOS); + } + else if (TargetOS::IsUnix) { info.compMatchedVM = info.compMatchedVM && (eeInfo->osType == CORINFO_UNIX); } @@ -6093,7 +6098,8 @@ int Compiler::compCompileHelper(CORINFO_MODULE_HANDLE classPtr, if (!TargetOS::OSSettingConfigured) { CORINFO_EE_INFO* eeInfo = eeGetEEInfo(); - TargetOS::IsUnix = eeInfo->osType == CORINFO_UNIX; + TargetOS::IsMacOS = eeInfo->osType == CORINFO_MACOS; + TargetOS::IsUnix = (eeInfo->osType == CORINFO_UNIX) || (eeInfo->osType == CORINFO_MACOS); TargetOS::IsWindows = eeInfo->osType == CORINFO_WINNT; TargetOS::OSSettingConfigured = true; } diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index ea1e8bea2a3359..a114573dcebc50 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -1885,20 +1885,23 @@ struct fgArgTabEntry void SetByteSize(unsigned byteSize, bool isStruct, bool isFloatHfa) { -#ifdef OSX_ARM64_ABI unsigned roundedByteSize; - // Only struct types need extension or rounding to pointer size, but HFA does not. - if (isStruct && !isFloatHfa) + if (GlobalJitOptions::compMacOsArm64Abi()) { - roundedByteSize = roundUp(byteSize, TARGET_POINTER_SIZE); + // Only struct types need extension or rounding to pointer size, but HFA does not. + if (isStruct && !isFloatHfa) + { + roundedByteSize = roundUp(byteSize, TARGET_POINTER_SIZE); + } + else + { + roundedByteSize = byteSize; + } } else { - roundedByteSize = byteSize; + roundedByteSize = roundUp(byteSize, TARGET_POINTER_SIZE); } -#else // OSX_ARM64_ABI - unsigned roundedByteSize = roundUp(byteSize, TARGET_POINTER_SIZE); -#endif // OSX_ARM64_ABI #if !defined(TARGET_ARM) // Arm32 could have a struct with 8 byte alignment @@ -3849,8 +3852,8 @@ class Compiler assert(varDsc->lvType == TYP_SIMD12); assert(varDsc->lvExactSize == 12); -#if defined(TARGET_64BIT) && !defined(OSX_ARM64_ABI) - assert(varDsc->lvSize() == 16); +#if defined(TARGET_64BIT) + assert(GlobalJitOptions::compMacOsArm64Abi() || varDsc->lvSize() == 16); #endif // defined(TARGET_64BIT) // We make local variable SIMD12 types 16 bytes instead of just 12. diff --git a/src/coreclr/jit/ee_il_dll.cpp b/src/coreclr/jit/ee_il_dll.cpp index 1a6df3e6495ef5..591496ccd75f2c 100644 --- a/src/coreclr/jit/ee_il_dll.cpp +++ b/src/coreclr/jit/ee_il_dll.cpp @@ -469,22 +469,25 @@ unsigned Compiler::eeGetArgSize(CORINFO_ARG_LIST_HANDLE list, CORINFO_SIG_INFO* // static unsigned Compiler::eeGetArgAlignment(var_types type, bool isFloatHfa) { -#if defined(OSX_ARM64_ABI) - if (isFloatHfa) + if (GlobalJitOptions::compMacOsArm64Abi()) { - assert(varTypeIsStruct(type)); - return sizeof(float); + if (isFloatHfa) + { + assert(varTypeIsStruct(type)); + return sizeof(float); + } + if (varTypeIsStruct(type)) + { + return TARGET_POINTER_SIZE; + } + const unsigned argSize = genTypeSize(type); + assert((0 < argSize) && (argSize <= TARGET_POINTER_SIZE)); + return argSize; } - if (varTypeIsStruct(type)) + else { return TARGET_POINTER_SIZE; } - const unsigned argSize = genTypeSize(type); - assert((0 < argSize) && (argSize <= TARGET_POINTER_SIZE)); - return argSize; -#else - return TARGET_POINTER_SIZE; -#endif } /*****************************************************************************/ diff --git a/src/coreclr/jit/jit.h b/src/coreclr/jit/jit.h index 74a0e73bf05b9a..3ce1db0bb4d8e6 100644 --- a/src/coreclr/jit/jit.h +++ b/src/coreclr/jit/jit.h @@ -206,17 +206,17 @@ #define UNIX_AMD64_ABI_ONLY(x) #endif // defined(UNIX_AMD64_ABI) -#if defined(DEBUG) && !defined(OSX_ARM64_ABI) -// On all platforms except Arm64 OSX arguments on the stack are taking -// register size slots. On these platforms we could check that stack slots count -// matches our new byte size calculations. +#if defined(DEBUG) #define DEBUG_ARG_SLOTS #endif #if defined(DEBUG_ARG_SLOTS) #define DEBUG_ARG_SLOTS_ARG(x) , x #define DEBUG_ARG_SLOTS_ONLY(x) x -#define DEBUG_ARG_SLOTS_ASSERT(x) assert(x) +// On all platforms except Arm64 OSX arguments on the stack are taking +// register size slots. On these platforms we could check that stack slots count +// matches our new byte size calculations. +#define DEBUG_ARG_SLOTS_ASSERT(x) assert(GlobalJitOptions::compMacOsArm64Abi() || x) #else #define DEBUG_ARG_SLOTS_ARG(x) #define DEBUG_ARG_SLOTS_ONLY(x) @@ -369,6 +369,8 @@ class GlobalJitOptions #endif static bool compFeatureArgSplit() { return TargetArchitecture::IsArm32 || (TargetOS::IsWindows && TargetArchitecture::IsArm64); } + + static bool compMacOsArm64Abi() { return TargetArchitecture::IsArm64 && TargetOS::IsUnix && TargetOS::IsMacOS; } }; /*****************************************************************************/ diff --git a/src/coreclr/jit/lclvars.cpp b/src/coreclr/jit/lclvars.cpp index a1a11e3e680bbf..72570e3d2eebbb 100644 --- a/src/coreclr/jit/lclvars.cpp +++ b/src/coreclr/jit/lclvars.cpp @@ -1097,9 +1097,10 @@ void Compiler::lvaInitUserArgs(InitVarDscInfo* varDscInfo, unsigned skipArgs, un #if FEATURE_FASTTAILCALL const unsigned argAlignment = eeGetArgAlignment(origArgType, (hfaType == TYP_FLOAT)); -#if defined(OSX_ARM64_ABI) - varDscInfo->stackArgSize = roundUp(varDscInfo->stackArgSize, argAlignment); -#endif // OSX_ARM64_ABI + if (GlobalJitOptions::compMacOsArm64Abi()) + { + varDscInfo->stackArgSize = roundUp(varDscInfo->stackArgSize, argAlignment); + } assert((argSize % argAlignment) == 0); assert((varDscInfo->stackArgSize % argAlignment) == 0); @@ -5499,9 +5500,7 @@ void Compiler::lvaAssignVirtualFrameOffsetsToArgs() /* Update the argOffs to reflect arguments that are passed in registers */ noway_assert(codeGen->intRegState.rsCalleeRegArgCount <= MAX_REG_ARG); -#if !defined(OSX_ARM64_ABI) - noway_assert(compArgSize >= codeGen->intRegState.rsCalleeRegArgCount * REGSIZE_BYTES); -#endif + noway_assert(GlobalJitOptions::compMacOsArm64Abi() || compArgSize >= codeGen->intRegState.rsCalleeRegArgCount * REGSIZE_BYTES); if (info.compArgOrder == Target::ARG_ORDER_L2R) { @@ -5655,9 +5654,7 @@ void Compiler::lvaAssignVirtualFrameOffsetsToArgs() { unsigned argumentSize = eeGetArgSize(argLst, &info.compMethodInfo->args); -#if !defined(OSX_ARM64_ABI) - assert(argumentSize % TARGET_POINTER_SIZE == 0); -#endif // !defined(OSX_ARM64_ABI) + assert(GlobalJitOptions::compMacOsArm64Abi() || argumentSize % TARGET_POINTER_SIZE == 0); argOffs = lvaAssignVirtualFrameOffsetToArg(lclNum++, argumentSize, argOffs UNIX_AMD64_ABI_ONLY_ARG(&callerArgOffset)); @@ -6037,9 +6034,10 @@ int Compiler::lvaAssignVirtualFrameOffsetToArg(unsigned lclNum, #endif // TARGET_ARM const bool isFloatHfa = (varDsc->lvIsHfa() && (varDsc->GetHfaType() == TYP_FLOAT)); const unsigned argAlignment = eeGetArgAlignment(varDsc->lvType, isFloatHfa); -#if defined(OSX_ARM64_ABI) - argOffs = roundUp(argOffs, argAlignment); -#endif // OSX_ARM64_ABI + if (GlobalJitOptions::compMacOsArm64Abi()) + { + argOffs = roundUp(argOffs, argAlignment); + } assert((argSize % argAlignment) == 0); assert((argOffs % argAlignment) == 0); diff --git a/src/coreclr/jit/lower.cpp b/src/coreclr/jit/lower.cpp index 5c21f10c4e9497..e758e4722055cc 100644 --- a/src/coreclr/jit/lower.cpp +++ b/src/coreclr/jit/lower.cpp @@ -1162,11 +1162,18 @@ GenTree* Lowering::NewPutArg(GenTreeCall* call, GenTree* arg, fgArgTabEntry* inf #if defined(FEATURE_SIMD) && defined(FEATURE_PUT_STRUCT_ARG_STK) if (type == TYP_SIMD12) { -#if !defined(TARGET_64BIT) || defined(OSX_ARM64_ABI) +#if !defined(TARGET_64BIT) assert(info->GetByteSize() == 12); -#else // TARGET_64BIT && !OSX_ARM64_ABI - assert(info->GetByteSize() == 16); -#endif // FEATURE_SIMD && FEATURE_PUT_STRUCT_ARG_STK +#else // TARGET_64BIT + if (GlobalJitOptions::compMacOsArm64Abi()) + { + assert(info->GetByteSize() == 12); + } + else + { + assert(info->GetByteSize() == 16); + } +#endif // TARGET_64BIT } else #endif // defined(FEATURE_SIMD) && defined(FEATURE_PUT_STRUCT_ARG_STK) diff --git a/src/coreclr/jit/lsraarmarch.cpp b/src/coreclr/jit/lsraarmarch.cpp index cc95f5f40d5404..c546f3168efc6d 100644 --- a/src/coreclr/jit/lsraarmarch.cpp +++ b/src/coreclr/jit/lsraarmarch.cpp @@ -411,15 +411,18 @@ int LinearScan::BuildPutArgStk(GenTreePutArgStk* argNode) BuildUse(use.GetNode()); srcCount++; -#if defined(FEATURE_SIMD) && defined(OSX_ARM64_ABI) - if (use.GetType() == TYP_SIMD12) +#if defined(FEATURE_SIMD) + if (GlobalJitOptions::compMacOsArm64Abi()) { - // Vector3 is read/written as two reads/writes: 8 byte and 4 byte. - // To assemble the vector properly we would need an additional int register. - // The other platforms can write it as 16-byte using 1 write. - buildInternalIntRegisterDefForNode(use.GetNode()); + if (use.GetType() == TYP_SIMD12) + { + // Vector3 is read/written as two reads/writes: 8 byte and 4 byte. + // To assemble the vector properly we would need an additional int register. + // The other platforms can write it as 16-byte using 1 write. + buildInternalIntRegisterDefForNode(use.GetNode()); + } } -#endif // FEATURE_SIMD && OSX_ARM64_ABI +#endif // FEATURE_SIMD } } else @@ -460,15 +463,15 @@ int LinearScan::BuildPutArgStk(GenTreePutArgStk* argNode) { assert(!putArgChild->isContained()); srcCount = BuildOperandUses(putArgChild); -#if defined(FEATURE_SIMD) && defined(OSX_ARM64_ABI) - if (argNode->GetStackByteSize() == 12) +#if defined(FEATURE_SIMD) + if (GlobalJitOptions::compMacOsArm64Abi() && argNode->GetStackByteSize() == 12) { // Vector3 is read/written as two reads/writes: 8 byte and 4 byte. // To assemble the vector properly we would need an additional int register. // The other platforms can write it as 16-byte using 1 write. buildInternalIntRegisterDefForNode(argNode); } -#endif // FEATURE_SIMD && OSX_ARM64_ABI +#endif // FEATURE_SIMD } buildInternalRegisterUses(); return srcCount; diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index 707b63311560e6..48e07f8c8386a2 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -3052,9 +3052,7 @@ void Compiler::fgInitArgInfo(GenTreeCall* call) unsigned hfaSlots = 0; bool passUsingFloatRegs; -#if !defined(OSX_ARM64_ABI) unsigned argAlignBytes = TARGET_POINTER_SIZE; -#endif unsigned size = 0; unsigned byteSize = 0; bool isRegArg = false; @@ -3307,12 +3305,13 @@ void Compiler::fgInitArgInfo(GenTreeCall* call) assert(size != 0); assert(byteSize != 0); -#if defined(OSX_ARM64_ABI) - // Arm64 Apple has a special ABI for passing small size arguments on stack, - // bytes are aligned to 1-byte, shorts to 2-byte, int/float to 4-byte, etc. - // It means passing 8 1-byte arguments on stack can take as small as 8 bytes. - unsigned argAlignBytes = eeGetArgAlignment(argType, isFloatHfa); -#endif + if (GlobalJitOptions::compMacOsArm64Abi()) + { + // Arm64 Apple has a special ABI for passing small size arguments on stack, + // bytes are aligned to 1-byte, shorts to 2-byte, int/float to 4-byte, etc. + // It means passing 8 1-byte arguments on stack can take as small as 8 bytes. + argAlignBytes = eeGetArgAlignment(argType, isFloatHfa); + } // // Figure out if the argument will be passed in a register. diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs index 588d026200e0fe..61154e4c6f61d2 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs @@ -2923,7 +2923,8 @@ private void getEEInfo(ref CORINFO_EE_INFO pEEInfoOut) new UIntPtr(32 * 1024 - 1) : new UIntPtr((uint)pEEInfoOut.osPageSize / 2 - 1); pEEInfoOut.targetAbi = TargetABI; - pEEInfoOut.osType = _compilation.NodeFactory.Target.IsWindows ? CORINFO_OS.CORINFO_WINNT : CORINFO_OS.CORINFO_UNIX; + pEEInfoOut.osType = _compilation.NodeFactory.Target.IsWindows ? CORINFO_OS.CORINFO_WINNT : + _compilation.NodeFactory.Target.IsOSX ? CORINFO_OS.CORINFO_MACOS : CORINFO_OS.CORINFO_UNIX; } private char* getJitTimeLogFilename() diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs b/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs index 73f7a5f4eef7c1..d783d49922fb97 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs @@ -837,6 +837,7 @@ public enum CORINFO_OS { CORINFO_WINNT, CORINFO_UNIX, + CORINFO_MACOS, } public enum CORINFO_RUNTIME_ABI diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 36a3f0f54a805b..7c0793ca00abb5 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -9957,7 +9957,9 @@ void CEEInfo::getEEInfo(CORINFO_EE_INFO *pEEInfoOut) pEEInfoOut->maxUncheckedOffsetForNullObject = MAX_UNCHECKED_OFFSET_FOR_NULL_OBJECT; pEEInfoOut->targetAbi = CORINFO_CORECLR_ABI; -#ifdef TARGET_UNIX +#ifdef TARGET_OSX + pEEInfoOut->osType = CORINFO_MACOS; +#elif defined(TARGET_UNIX) pEEInfoOut->osType = CORINFO_UNIX; #else pEEInfoOut->osType = CORINFO_WINNT; From 77824a341c933cf64a5d870baa0248f7a3d0fd27 Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Fri, 27 Aug 2021 10:42:55 -0700 Subject: [PATCH 04/15] All jits build in new configuration --- src/coreclr/clrdefinitions.cmake | 2 +- src/coreclr/gcinfo/CMakeLists.txt | 7 ++----- src/coreclr/inc/jiteeversionguid.h | 10 +++++----- src/coreclr/jit/CMakeLists.txt | 9 +++------ src/coreclr/jit/compiler.cpp | 7 +++++++ 5 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/coreclr/clrdefinitions.cmake b/src/coreclr/clrdefinitions.cmake index c415448dc09785..ffadad35521002 100644 --- a/src/coreclr/clrdefinitions.cmake +++ b/src/coreclr/clrdefinitions.cmake @@ -247,7 +247,7 @@ function(set_target_definitions_to_custom_os_and_arch) if (TARGETDETAILS_OS STREQUAL "unix_osx") target_compile_definitions(${TARGETDETAILS_TARGET} PRIVATE TARGET_OSX) endif() - else() + elseif (TARGETDETAILS_OS STREQUAL "win") target_compile_definitions(${TARGETDETAILS_TARGET} PRIVATE TARGET_WINDOWS) endif((TARGETDETAILS_OS MATCHES "^unix")) diff --git a/src/coreclr/gcinfo/CMakeLists.txt b/src/coreclr/gcinfo/CMakeLists.txt index 96319fd98b4252..78843e5134539d 100644 --- a/src/coreclr/gcinfo/CMakeLists.txt +++ b/src/coreclr/gcinfo/CMakeLists.txt @@ -65,15 +65,12 @@ set(TARGET_OS_NAME win) endif() if (CLR_CMAKE_TARGET_ARCH_ARM64 OR CLR_CMAKE_TARGET_ARCH_AMD64) - create_gcinfo_lib(TARGET gcinfo_unix_arm64 OS unix ARCH arm64) + create_gcinfo_lib(TARGET gcinfo_universal_arm64 OS universal ARCH arm64) create_gcinfo_lib(TARGET gcinfo_unix_x64 OS unix ARCH x64) - create_gcinfo_lib(TARGET gcinfo_win_arm64 OS win ARCH arm64) create_gcinfo_lib(TARGET gcinfo_win_x64 OS win ARCH x64) endif (CLR_CMAKE_TARGET_ARCH_ARM64 OR CLR_CMAKE_TARGET_ARCH_AMD64) -create_gcinfo_lib(TARGET gcinfo_unix_armel OS unix ARCH armel) -create_gcinfo_lib(TARGET gcinfo_unix_arm OS unix ARCH arm) -create_gcinfo_lib(TARGET gcinfo_win_arm OS win ARCH arm) +create_gcinfo_lib(TARGET gcinfo_universal_arm OS universal ARCH arm) create_gcinfo_lib(TARGET gcinfo_win_x86 OS win ARCH x86) if (CLR_CMAKE_TARGET_ARCH_I386 AND CLR_CMAKE_TARGET_UNIX) diff --git a/src/coreclr/inc/jiteeversionguid.h b/src/coreclr/inc/jiteeversionguid.h index f78582151fc69a..8f99d9b4bb8608 100644 --- a/src/coreclr/inc/jiteeversionguid.h +++ b/src/coreclr/inc/jiteeversionguid.h @@ -43,11 +43,11 @@ typedef const GUID *LPCGUID; #define GUID_DEFINED #endif // !GUID_DEFINED -constexpr GUID JITEEVersionIdentifier = { /* 5ed35c58-857b-48dd-a818-7c0136dc9f73 */ - 0x5ed35c58, - 0x857b, - 0x48dd, - {0xa8, 0x18, 0x7c, 0x01, 0x36, 0xdc, 0x9f, 0x73} +constexpr GUID JITEEVersionIdentifier = { /* 017b4b2e-80e1-41eb-afc3-f6f643df6bbc */ + 0x017b4b2e, + 0x80e1, + 0x41eb, + {0xaf, 0xc3, 0xf6, 0xf6, 0x43, 0xdf, 0x6b, 0xbc} }; ////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/coreclr/jit/CMakeLists.txt b/src/coreclr/jit/CMakeLists.txt index 8af142cf63fe9f..036e09062711aa 100644 --- a/src/coreclr/jit/CMakeLists.txt +++ b/src/coreclr/jit/CMakeLists.txt @@ -496,16 +496,13 @@ install_clr(TARGETS clrjit DESTINATIONS . sharedFramework COMPONENT jit) add_pgo(clrjit) if (CLR_CMAKE_TARGET_ARCH_ARM64 OR CLR_CMAKE_TARGET_ARCH_AMD64) - create_standalone_jit(TARGET clrjit_unix_arm64_${ARCH_HOST_NAME} OS unix ARCH arm64 DESTINATIONS .) - create_standalone_jit(TARGET clrjit_unix_osx_arm64_${ARCH_HOST_NAME} OS unix_osx ARCH arm64 DESTINATIONS .) + create_standalone_jit(TARGET clrjit_universal_arm64_${ARCH_HOST_NAME} OS universal ARCH arm64 DESTINATIONS .) create_standalone_jit(TARGET clrjit_unix_x64_${ARCH_HOST_NAME} OS unix ARCH x64 DESTINATIONS .) - create_standalone_jit(TARGET clrjit_win_arm64_${ARCH_HOST_NAME} OS win ARCH arm64 DESTINATIONS .) create_standalone_jit(TARGET clrjit_win_x64_${ARCH_HOST_NAME} OS win ARCH x64 DESTINATIONS .) endif (CLR_CMAKE_TARGET_ARCH_ARM64 OR CLR_CMAKE_TARGET_ARCH_AMD64) -create_standalone_jit(TARGET clrjit_unix_arm_${ARCH_HOST_NAME} OS unix ARCH arm DESTINATIONS .) -target_compile_definitions(clrjit_unix_arm_${ARCH_HOST_NAME} PRIVATE ARM_SOFTFP CONFIGURABLE_ARM_ABI) -create_standalone_jit(TARGET clrjit_win_arm_${ARCH_HOST_NAME} OS win ARCH arm DESTINATIONS .) +create_standalone_jit(TARGET clrjit_universal_arm_${ARCH_HOST_NAME} OS universal ARCH arm DESTINATIONS .) +target_compile_definitions(clrjit_universal_arm_${ARCH_HOST_NAME} PRIVATE ARM_SOFTFP CONFIGURABLE_ARM_ABI) create_standalone_jit(TARGET clrjit_win_x86_${ARCH_HOST_NAME} OS win ARCH x86 DESTINATIONS .) if (CLR_CMAKE_TARGET_ARCH_I386 AND CLR_CMAKE_TARGET_UNIX) diff --git a/src/coreclr/jit/compiler.cpp b/src/coreclr/jit/compiler.cpp index 48c0aa7707ee1e..5fd76defa7fcdf 100644 --- a/src/coreclr/jit/compiler.cpp +++ b/src/coreclr/jit/compiler.cpp @@ -62,6 +62,13 @@ bool GlobalJitOptions::compFeatureHfa = false; LONG GlobalJitOptions::compUseSoftFPConfigured = 0; #endif // CONFIGURABLE_ARM_ABI +#ifdef TARGET_OS_RUNTIMEDETERMINED +bool TargetOS::OSSettingConfigured = false; +bool TargetOS::IsWindows = false; +bool TargetOS::IsUnix = false; +bool TargetOS::IsMacOS = false; +#endif + /***************************************************************************** * * Little helpers to grab the current cycle counter value; this is done From c3b175ac56ed9517740506a1c7f664b0e1a5497f Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Fri, 27 Aug 2021 10:13:45 -0700 Subject: [PATCH 05/15] Builds full clr --- src/coreclr/gcinfo/gcinfoencoder.cpp | 1 + src/coreclr/inc/switches.h | 64 ------------------ src/coreclr/inc/targetosarch.h | 67 +++++++++++++++++++ src/coreclr/jit/jit.h | 2 + .../Common/JitInterface/JitConfigProvider.cs | 4 +- src/coreclr/utilcode/winfix.cpp | 6 +- 6 files changed, 75 insertions(+), 69 deletions(-) create mode 100644 src/coreclr/inc/targetosarch.h diff --git a/src/coreclr/gcinfo/gcinfoencoder.cpp b/src/coreclr/gcinfo/gcinfoencoder.cpp index b82f0f2335598d..8be8b262f1a4a1 100644 --- a/src/coreclr/gcinfo/gcinfoencoder.cpp +++ b/src/coreclr/gcinfo/gcinfoencoder.cpp @@ -10,6 +10,7 @@ #include #include "gcinfoencoder.h" +#include "targetosarch.h" #ifdef _DEBUG #ifndef LOGGING diff --git a/src/coreclr/inc/switches.h b/src/coreclr/inc/switches.h index 1eab4fc573dc78..91947135de94af 100644 --- a/src/coreclr/inc/switches.h +++ b/src/coreclr/inc/switches.h @@ -174,67 +174,3 @@ #if !defined(TARGET_UNIX) #define FEATURE_STACK_SAMPLING #endif // defined (ALLOW_SXS_JIT) - -#ifndef TARGET_OS_ARCH_CLASS -#define TARGET_OS_ARCH_CLASS -class TargetOS -{ -public: -#ifdef TARGET_WINDOWS -#define TARGET_WINDOWS_POSSIBLY_SUPPORTED - static const bool IsWindows = true; - static const bool IsUnix = false; - static const bool IsMacOS = false; -#elif defined(TARGET_UNIX) -#define TARGET_UNIX_POSSIBLY_SUPPORTED - static const bool IsWindows = false; - static const bool IsUnix = true; -#if defined(TARGET_OSX) - static const bool IsMacOS = true; -#else - static const bool IsMacOS = false; -#endif -#else -#define TARGET_WINDOWS_POSSIBLY_SUPPORTED -#define TARGET_UNIX_POSSIBLY_SUPPORTED -#define TARGET_OS_RUNTIMEDETERMINED - static bool OSSettingConfigured; - static bool IsWindows; - static bool IsUnix; - static bool IsMacOS; -#endif -}; - -class TargetArchitecture -{ -public: -#ifdef TARGET_ARM - static const bool IsX86 = false; - static const bool IsX64 = false; - static const bool IsArm64 = false; - static const bool IsArm32 = true; - static const bool IsArmArch = true; -#elif defined(TARGET_ARM64) - static const bool IsX86 = false; - static const bool IsX64 = false; - static const bool IsArm64 = true; - static const bool IsArm32 = false; - static const bool IsArmArch = true; -#elif defined(TARGET_AMD64) - static const bool IsX86 = false; - static const bool IsX64 = true; - static const bool IsArm64 = false; - static const bool IsArm32 = false; - static const bool IsArmArch = false; -#elif defined(TARGET_X86) - static const bool IsX86 = true; - static const bool IsX64 = false; - static const bool IsArm64 = false; - static const bool IsArm32 = false; - static const bool IsArmArch = false; -#else -#error Unknown architecture -#endif -}; -#endif // TARGET_OS_ARCH_CLASS - diff --git a/src/coreclr/inc/targetosarch.h b/src/coreclr/inc/targetosarch.h new file mode 100644 index 00000000000000..b2d1c06a22d669 --- /dev/null +++ b/src/coreclr/inc/targetosarch.h @@ -0,0 +1,67 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#ifndef targetosarch_h +#define targetosarch_h + +class TargetOS +{ +public: +#ifdef TARGET_WINDOWS +#define TARGET_WINDOWS_POSSIBLY_SUPPORTED + static const bool IsWindows = true; + static const bool IsUnix = false; + static const bool IsMacOS = false; +#elif defined(TARGET_UNIX) +#define TARGET_UNIX_POSSIBLY_SUPPORTED + static const bool IsWindows = false; + static const bool IsUnix = true; +#if defined(TARGET_OSX) + static const bool IsMacOS = true; +#else + static const bool IsMacOS = false; +#endif +#else +#define TARGET_WINDOWS_POSSIBLY_SUPPORTED +#define TARGET_UNIX_POSSIBLY_SUPPORTED +#define TARGET_OS_RUNTIMEDETERMINED + static bool OSSettingConfigured; + static bool IsWindows; + static bool IsUnix; + static bool IsMacOS; +#endif +}; + +class TargetArchitecture +{ +public: +#ifdef TARGET_ARM + static const bool IsX86 = false; + static const bool IsX64 = false; + static const bool IsArm64 = false; + static const bool IsArm32 = true; + static const bool IsArmArch = true; +#elif defined(TARGET_ARM64) + static const bool IsX86 = false; + static const bool IsX64 = false; + static const bool IsArm64 = true; + static const bool IsArm32 = false; + static const bool IsArmArch = true; +#elif defined(TARGET_AMD64) + static const bool IsX86 = false; + static const bool IsX64 = true; + static const bool IsArm64 = false; + static const bool IsArm32 = false; + static const bool IsArmArch = false; +#elif defined(TARGET_X86) + static const bool IsX86 = true; + static const bool IsX64 = false; + static const bool IsArm64 = false; + static const bool IsArm32 = false; + static const bool IsArmArch = false; +#else +#error Unknown architecture +#endif +}; + +#endif // targetosarch_h \ No newline at end of file diff --git a/src/coreclr/jit/jit.h b/src/coreclr/jit/jit.h index 3ce1db0bb4d8e6..3f5459278cc1d2 100644 --- a/src/coreclr/jit/jit.h +++ b/src/coreclr/jit/jit.h @@ -6,6 +6,8 @@ #define _JIT_H_ /*****************************************************************************/ +#include "targetosarch.h" + // // clr.sln only defines _DEBUG // The jit uses DEBUG rather than _DEBUG diff --git a/src/coreclr/tools/Common/JitInterface/JitConfigProvider.cs b/src/coreclr/tools/Common/JitInterface/JitConfigProvider.cs index 2dc973c709e8ae..78039b39828590 100644 --- a/src/coreclr/tools/Common/JitInterface/JitConfigProvider.cs +++ b/src/coreclr/tools/Common/JitInterface/JitConfigProvider.cs @@ -141,9 +141,9 @@ private static string GetTargetSpec(TargetDetails target) _ => throw new NotImplementedException(target.Architecture.ToString()) }; - if ((target.Architecture == TargetArchitecture.ARM64) && (target.OperatingSystem == TargetOS.OSX)) + if ((target.Architecture == TargetArchitecture.ARM64) || (target.Architecture == TargetArchitecture.ARM)) { - targetOSComponent = "unix_osx"; + targetOSComponent = "universal"; } return targetOSComponent + '_' + targetArchComponent + "_" + RuntimeInformation.ProcessArchitecture.ToString().ToLowerInvariant(); diff --git a/src/coreclr/utilcode/winfix.cpp b/src/coreclr/utilcode/winfix.cpp index acc91c6d5ba382..d572c8edb26ef6 100644 --- a/src/coreclr/utilcode/winfix.cpp +++ b/src/coreclr/utilcode/winfix.cpp @@ -181,7 +181,7 @@ WszCreateProcess( return fResult; } -#ifndef TARGET_UNIX +#ifndef HOST_UNIX #include "psapi.h" @@ -290,11 +290,11 @@ HRESULT SetThreadName(HANDLE hThread, PCWSTR lpThreadDescription) return g_pfnSetThreadDescription(hThread, lpThreadDescription); } -#else //!TARGET_UNIX +#else //!HOST_UNIX HRESULT SetThreadName(HANDLE hThread, PCWSTR lpThreadDescription) { return SetThreadDescription(hThread, lpThreadDescription); } -#endif //!TARGET_UNIX +#endif //!HOST_UNIX From bd9a51c5aa6f97707a2486717199ce1a621d5136 Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Fri, 27 Aug 2021 10:38:38 -0700 Subject: [PATCH 06/15] Rework checks to be more efficient on debug builds and slightly less wordy --- src/coreclr/jit/codegenarmarch.cpp | 10 +++++----- src/coreclr/jit/codegenlinear.cpp | 6 +++--- src/coreclr/jit/codegenxarch.cpp | 8 ++++---- src/coreclr/jit/compiler.cpp | 2 +- src/coreclr/jit/compiler.h | 8 ++++---- src/coreclr/jit/compiler.hpp | 4 ++-- src/coreclr/jit/ee_il_dll.cpp | 2 +- src/coreclr/jit/gentree.cpp | 2 +- src/coreclr/jit/importer.cpp | 2 +- src/coreclr/jit/jit.h | 13 +------------ src/coreclr/jit/lclvars.cpp | 12 ++++++------ src/coreclr/jit/lower.cpp | 4 ++-- src/coreclr/jit/lsra.cpp | 2 +- src/coreclr/jit/lsraarmarch.cpp | 4 ++-- src/coreclr/jit/lsrabuild.cpp | 2 +- src/coreclr/jit/lsraxarch.cpp | 2 +- src/coreclr/jit/morph.cpp | 4 ++-- src/coreclr/jit/target.h | 5 +++++ 18 files changed, 43 insertions(+), 49 deletions(-) diff --git a/src/coreclr/jit/codegenarmarch.cpp b/src/coreclr/jit/codegenarmarch.cpp index e0685c0b8cbe41..3d4a0b42048223 100644 --- a/src/coreclr/jit/codegenarmarch.cpp +++ b/src/coreclr/jit/codegenarmarch.cpp @@ -684,7 +684,7 @@ void CodeGen::genPutArgStk(GenTreePutArgStk* treeNode) GenTree* source = treeNode->gtOp1; var_types targetType; - if (!GlobalJitOptions::compMacOsArm64Abi()) + if (!compMacOsArm64Abi()) { targetType = genActualType(source->TypeGet()); } @@ -746,10 +746,10 @@ void CodeGen::genPutArgStk(GenTreePutArgStk* treeNode) regNumber srcReg = genConsumeReg(source); assert((srcReg != REG_NA) && (genIsValidFloatReg(srcReg))); - assert(GlobalJitOptions::compMacOsArm64Abi() || treeNode->GetStackByteSize() % TARGET_POINTER_SIZE == 0); + assert(compMacOsArm64Abi() || treeNode->GetStackByteSize() % TARGET_POINTER_SIZE == 0); #ifdef TARGET_ARM64 - if (GlobalJitOptions::compMacOsArm64Abi() && (treeNode->GetStackByteSize() == 12)) + if (compMacOsArm64Abi() && (treeNode->GetStackByteSize() == 12)) { regNumber tmpReg = treeNode->GetSingleTempReg(); GetEmitter()->emitStoreSIMD12ToLclOffset(varNumOut, argOffsetOut, srcReg, tmpReg); @@ -766,7 +766,7 @@ void CodeGen::genPutArgStk(GenTreePutArgStk* treeNode) return; } - if (GlobalJitOptions::compMacOsArm64Abi()) + if (compMacOsArm64Abi()) { switch (treeNode->GetStackByteSize()) { @@ -2314,7 +2314,7 @@ void CodeGen::genCallInstruction(GenTreeCall* call) } } #if FEATURE_ARG_SPLIT_SUPPORTED - else if (GlobalJitOptions::compFeatureArgSplit() && curArgTabEntry->IsSplit()) + else if (compFeatureArgSplit() && curArgTabEntry->IsSplit()) { assert(curArgTabEntry->numRegs >= 1); genConsumeArgSplitStruct(argNode->AsPutArgSplit()); diff --git a/src/coreclr/jit/codegenlinear.cpp b/src/coreclr/jit/codegenlinear.cpp index 083e95278010bf..f4c5058b0121f8 100644 --- a/src/coreclr/jit/codegenlinear.cpp +++ b/src/coreclr/jit/codegenlinear.cpp @@ -1855,7 +1855,7 @@ void CodeGen::genPutArgStkFieldList(GenTreePutArgStk* putArgStk, unsigned outArg #if defined(FEATURE_SIMD) && defined(TARGET_ARM64) // storing of TYP_SIMD12 (i.e. Vector3) argument. - if (GlobalJitOptions::compMacOsArm64Abi() && (type == TYP_SIMD12)) + if (compMacOsArm64Abi() && (type == TYP_SIMD12)) { // Need an additional integer register to extract upper 4 bytes from data. regNumber tmpReg = nextArgNode->GetSingleTempReg(); @@ -2137,7 +2137,7 @@ void CodeGen::genProduceReg(GenTree* tree) } } #if FEATURE_ARG_SPLIT_SUPPORTED - else if (GlobalJitOptions::compFeatureArgSplit() && tree->OperIsPutArgSplit()) + else if (compFeatureArgSplit() && tree->OperIsPutArgSplit()) { GenTreePutArgSplit* argSplit = tree->AsPutArgSplit(); unsigned regCount = argSplit->gtNumRegs; @@ -2154,7 +2154,7 @@ void CodeGen::genProduceReg(GenTree* tree) } } #ifdef TARGET_ARM - else if (GlobalJitOptions::compFeatureArgSplit() && tree->OperIsMultiRegOp()) + else if (compFeatureArgSplit() && tree->OperIsMultiRegOp()) { GenTreeMultiRegOp* multiReg = tree->AsMultiRegOp(); unsigned regCount = multiReg->GetRegCount(); diff --git a/src/coreclr/jit/codegenxarch.cpp b/src/coreclr/jit/codegenxarch.cpp index 307e6954577f4d..83dda69360eb02 100644 --- a/src/coreclr/jit/codegenxarch.cpp +++ b/src/coreclr/jit/codegenxarch.cpp @@ -5107,7 +5107,7 @@ void CodeGen::genCallInstruction(GenTreeCall* call) // the ABI dictates that if we have floating point args, // we must pass the enregistered arguments in both the // integer and floating point registers so, let's do that. - if (GlobalJitOptions::compFeatureVarArg() && call->IsVarargs() && varTypeIsFloating(argNode)) + if (compFeatureVarArg() && call->IsVarargs() && varTypeIsFloating(argNode)) { regNumber srcReg = argNode->GetRegNum(); regNumber targetReg = compiler->getCallArgIntRegister(argNode->GetRegNum()); @@ -5838,7 +5838,7 @@ void CodeGen::genJmpMethod(GenTree* jmp) // register. This is due to the AMD64 ABI which requires floating point values passed to varargs functions to // be passed in both integer and floating point registers. It doesn't apply to x86, which passes floating point // values on the stack. - if (GlobalJitOptions::compFeatureVarArg() && compiler->info.compIsVarArgs) + if (compFeatureVarArg() && compiler->info.compIsVarArgs) { regNumber intArgReg; var_types loadType = varDsc->lvaArgType(); @@ -5878,7 +5878,7 @@ void CodeGen::genJmpMethod(GenTree* jmp) // The caller could have passed gc-ref/byref type var args. Since these are var args // the callee no way of knowing their gc-ness. Therefore, mark the region that loads // remaining arg registers from shadow stack slots as non-gc interruptible. - if (GlobalJitOptions::compFeatureVarArg() && fixedIntArgMask != RBM_NONE) + if (compFeatureVarArg() && fixedIntArgMask != RBM_NONE) { assert(compiler->info.compIsVarArgs); assert(firstArgVarNum != BAD_VAR_NUM); @@ -8710,7 +8710,7 @@ void CodeGen::genProfilingEnterCallback(regNumber initReg, bool* pInitRegZeroed) GetEmitter()->emitIns_R_S(load_ins, emitTypeSize(loadType), argReg, varNum, 0); - if (GlobalJitOptions::compFeatureVarArg() && compiler->info.compIsVarArgs && varTypeIsFloating(loadType)) + if (compFeatureVarArg() && compiler->info.compIsVarArgs && varTypeIsFloating(loadType)) { regNumber intArgReg = compiler->getCallArgIntRegister(argReg); inst_Mov(TYP_LONG, intArgReg, argReg, /* canSkip */ false, emitActualTypeSize(loadType)); diff --git a/src/coreclr/jit/compiler.cpp b/src/coreclr/jit/compiler.cpp index 5fd76defa7fcdf..3bc05b9b848550 100644 --- a/src/coreclr/jit/compiler.cpp +++ b/src/coreclr/jit/compiler.cpp @@ -5180,7 +5180,7 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl m_pLowering = new (this, CMK_LSRA) Lowering(this, m_pLinearScan); // PHASE_LOWERING m_pLowering->Run(); - if (!GlobalJitOptions::compMacOsArm64Abi()) + if (!compMacOsArm64Abi()) { // Set stack levels; this information is necessary for x86 // but on other platforms it is used only in asserts. diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index a114573dcebc50..504957a33f1797 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -1612,11 +1612,11 @@ struct fgArgTabEntry bool IsVararg() const { - return GlobalJitOptions::compFeatureVarArg() && _isVararg; + return compFeatureVarArg() && _isVararg; } void SetIsVararg(bool value) { - if (GlobalJitOptions::compFeatureVarArg()) + if (compFeatureVarArg()) { _isVararg = value; } @@ -1886,7 +1886,7 @@ struct fgArgTabEntry { unsigned roundedByteSize; - if (GlobalJitOptions::compMacOsArm64Abi()) + if (compMacOsArm64Abi()) { // Only struct types need extension or rounding to pointer size, but HFA does not. if (isStruct && !isFloatHfa) @@ -3853,7 +3853,7 @@ class Compiler assert(varDsc->lvExactSize == 12); #if defined(TARGET_64BIT) - assert(GlobalJitOptions::compMacOsArm64Abi() || varDsc->lvSize() == 16); + assert(compMacOsArm64Abi() || varDsc->lvSize() == 16); #endif // defined(TARGET_64BIT) // We make local variable SIMD12 types 16 bytes instead of just 12. diff --git a/src/coreclr/jit/compiler.hpp b/src/coreclr/jit/compiler.hpp index 488222a1362c73..093cccdf6779ba 100644 --- a/src/coreclr/jit/compiler.hpp +++ b/src/coreclr/jit/compiler.hpp @@ -2323,7 +2323,7 @@ inline var_types Compiler::mangleVarArgsType(var_types type) // For CORECLR there is no vararg on System V systems. inline regNumber Compiler::getCallArgIntRegister(regNumber floatReg) { - assert(GlobalJitOptions::compFeatureVarArg()); + assert(compFeatureVarArg()); #ifdef TARGET_AMD64 switch (floatReg) { @@ -2347,7 +2347,7 @@ inline regNumber Compiler::getCallArgIntRegister(regNumber floatReg) inline regNumber Compiler::getCallArgFloatRegister(regNumber intReg) { - assert(GlobalJitOptions::compFeatureVarArg()); + assert(compFeatureVarArg()); #ifdef TARGET_AMD64 switch (intReg) { diff --git a/src/coreclr/jit/ee_il_dll.cpp b/src/coreclr/jit/ee_il_dll.cpp index 591496ccd75f2c..a88f222b6f551b 100644 --- a/src/coreclr/jit/ee_il_dll.cpp +++ b/src/coreclr/jit/ee_il_dll.cpp @@ -469,7 +469,7 @@ unsigned Compiler::eeGetArgSize(CORINFO_ARG_LIST_HANDLE list, CORINFO_SIG_INFO* // static unsigned Compiler::eeGetArgAlignment(var_types type, bool isFloatHfa) { - if (GlobalJitOptions::compMacOsArm64Abi()) + if (compMacOsArm64Abi()) { if (isFloatHfa) { diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index b9c27a35b077a4..6ac6a4be5ce525 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -770,7 +770,7 @@ regMaskTP GenTree::gtGetRegMask() const } } #if FEATURE_ARG_SPLIT_SUPPORTED - else if (GlobalJitOptions::compFeatureArgSplit() && OperIsPutArgSplit()) + else if (compFeatureArgSplit() && OperIsPutArgSplit()) { const GenTreePutArgSplit* splitArg = AsPutArgSplit(); const unsigned regCount = splitArg->gtNumRegs; diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 1175743438e8f5..b17ac92c556e7d 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -8718,7 +8718,7 @@ var_types Compiler::impImportCall(OPCODE opcode, actualMethodRetTypeSigClass = sig->retTypeSigClass; /* Check for varargs */ - if (!GlobalJitOptions::compFeatureVarArg() && + if (!compFeatureVarArg() && ((sig->callConv & CORINFO_CALLCONV_MASK) == CORINFO_CALLCONV_VARARG || (sig->callConv & CORINFO_CALLCONV_MASK) == CORINFO_CALLCONV_NATIVEVARARG)) { diff --git a/src/coreclr/jit/jit.h b/src/coreclr/jit/jit.h index 3f5459278cc1d2..9682efaa062691 100644 --- a/src/coreclr/jit/jit.h +++ b/src/coreclr/jit/jit.h @@ -218,7 +218,7 @@ // On all platforms except Arm64 OSX arguments on the stack are taking // register size slots. On these platforms we could check that stack slots count // matches our new byte size calculations. -#define DEBUG_ARG_SLOTS_ASSERT(x) assert(GlobalJitOptions::compMacOsArm64Abi() || x) +#define DEBUG_ARG_SLOTS_ASSERT(x) assert(compMacOsArm64Abi() || x) #else #define DEBUG_ARG_SLOTS_ARG(x) #define DEBUG_ARG_SLOTS_ONLY(x) @@ -362,17 +362,6 @@ class GlobalJitOptions #ifdef FEATURE_HFA #undef FEATURE_HFA #endif - -// Native Varargs are not supported on Unix (all architectures) and Windows ARM -#if !defined(TARGET_ARM) - static bool compFeatureVarArg() { return TargetOS::IsWindows; } -#else - static bool compFeatureVarArg() { return false; } -#endif - - static bool compFeatureArgSplit() { return TargetArchitecture::IsArm32 || (TargetOS::IsWindows && TargetArchitecture::IsArm64); } - - static bool compMacOsArm64Abi() { return TargetArchitecture::IsArm64 && TargetOS::IsUnix && TargetOS::IsMacOS; } }; /*****************************************************************************/ diff --git a/src/coreclr/jit/lclvars.cpp b/src/coreclr/jit/lclvars.cpp index 72570e3d2eebbb..693aaf28b44857 100644 --- a/src/coreclr/jit/lclvars.cpp +++ b/src/coreclr/jit/lclvars.cpp @@ -727,7 +727,7 @@ void Compiler::lvaInitUserArgs(InitVarDscInfo* varDscInfo, unsigned skipArgs, un #if defined(TARGET_ARM64) - if (GlobalJitOptions::compFeatureArgSplit()) + if (compFeatureArgSplit()) { // On arm64 Windows we will need to properly handle the case where a >8byte <=16byte // struct is split between register r7 and virtual stack slot s[0] @@ -1097,7 +1097,7 @@ void Compiler::lvaInitUserArgs(InitVarDscInfo* varDscInfo, unsigned skipArgs, un #if FEATURE_FASTTAILCALL const unsigned argAlignment = eeGetArgAlignment(origArgType, (hfaType == TYP_FLOAT)); - if (GlobalJitOptions::compMacOsArm64Abi()) + if (compMacOsArm64Abi()) { varDscInfo->stackArgSize = roundUp(varDscInfo->stackArgSize, argAlignment); } @@ -5500,7 +5500,7 @@ void Compiler::lvaAssignVirtualFrameOffsetsToArgs() /* Update the argOffs to reflect arguments that are passed in registers */ noway_assert(codeGen->intRegState.rsCalleeRegArgCount <= MAX_REG_ARG); - noway_assert(GlobalJitOptions::compMacOsArm64Abi() || compArgSize >= codeGen->intRegState.rsCalleeRegArgCount * REGSIZE_BYTES); + noway_assert(compMacOsArm64Abi() || compArgSize >= codeGen->intRegState.rsCalleeRegArgCount * REGSIZE_BYTES); if (info.compArgOrder == Target::ARG_ORDER_L2R) { @@ -5654,7 +5654,7 @@ void Compiler::lvaAssignVirtualFrameOffsetsToArgs() { unsigned argumentSize = eeGetArgSize(argLst, &info.compMethodInfo->args); - assert(GlobalJitOptions::compMacOsArm64Abi() || argumentSize % TARGET_POINTER_SIZE == 0); + assert(compMacOsArm64Abi() || argumentSize % TARGET_POINTER_SIZE == 0); argOffs = lvaAssignVirtualFrameOffsetToArg(lclNum++, argumentSize, argOffs UNIX_AMD64_ABI_ONLY_ARG(&callerArgOffset)); @@ -5827,7 +5827,7 @@ int Compiler::lvaAssignVirtualFrameOffsetToArg(unsigned lclNum, #elif defined(TARGET_ARM64) // Register arguments on ARM64 only take stack space when they have a frame home. // Unless on windows and in a vararg method. - if (GlobalJitOptions::compFeatureArgSplit() && this->info.compIsVarArgs) + if (compFeatureArgSplit() && this->info.compIsVarArgs) { if (varDsc->lvType == TYP_STRUCT && varDsc->GetOtherArgReg() >= MAX_REG_ARG && varDsc->GetOtherArgReg() != REG_NA) @@ -6034,7 +6034,7 @@ int Compiler::lvaAssignVirtualFrameOffsetToArg(unsigned lclNum, #endif // TARGET_ARM const bool isFloatHfa = (varDsc->lvIsHfa() && (varDsc->GetHfaType() == TYP_FLOAT)); const unsigned argAlignment = eeGetArgAlignment(varDsc->lvType, isFloatHfa); - if (GlobalJitOptions::compMacOsArm64Abi()) + if (compMacOsArm64Abi()) { argOffs = roundUp(argOffs, argAlignment); } diff --git a/src/coreclr/jit/lower.cpp b/src/coreclr/jit/lower.cpp index e758e4722055cc..a4f9c10107ee2e 100644 --- a/src/coreclr/jit/lower.cpp +++ b/src/coreclr/jit/lower.cpp @@ -1041,7 +1041,7 @@ GenTree* Lowering::NewPutArg(GenTreeCall* call, GenTree* arg, fgArgTabEntry* inf #if FEATURE_ARG_SPLIT_SUPPORTED // Struct can be split into register(s) and stack on ARM - if (GlobalJitOptions::compFeatureArgSplit() && info->IsSplit()) + if (compFeatureArgSplit() && info->IsSplit()) { assert(arg->OperGet() == GT_OBJ || arg->OperGet() == GT_FIELD_LIST); // TODO: Need to check correctness for FastTailCall @@ -1165,7 +1165,7 @@ GenTree* Lowering::NewPutArg(GenTreeCall* call, GenTree* arg, fgArgTabEntry* inf #if !defined(TARGET_64BIT) assert(info->GetByteSize() == 12); #else // TARGET_64BIT - if (GlobalJitOptions::compMacOsArm64Abi()) + if (compMacOsArm64Abi()) { assert(info->GetByteSize() == 12); } diff --git a/src/coreclr/jit/lsra.cpp b/src/coreclr/jit/lsra.cpp index efceaa9f2d68a1..6223e4a0994f22 100644 --- a/src/coreclr/jit/lsra.cpp +++ b/src/coreclr/jit/lsra.cpp @@ -6894,7 +6894,7 @@ void LinearScan::resolveRegisters() splitArg->SetRegSpillFlagByIdx(GTF_SPILL, currentRefPosition->getMultiRegIdx()); } #ifdef TARGET_ARM - else if (GlobalJitOptions::compFeatureArgSplit() && treeNode->OperIsMultiRegOp()) + else if (compFeatureArgSplit() && treeNode->OperIsMultiRegOp()) { GenTreeMultiRegOp* multiReg = treeNode->AsMultiRegOp(); multiReg->SetRegSpillFlagByIdx(GTF_SPILL, currentRefPosition->getMultiRegIdx()); diff --git a/src/coreclr/jit/lsraarmarch.cpp b/src/coreclr/jit/lsraarmarch.cpp index c546f3168efc6d..abdfabb3fdcc7e 100644 --- a/src/coreclr/jit/lsraarmarch.cpp +++ b/src/coreclr/jit/lsraarmarch.cpp @@ -412,7 +412,7 @@ int LinearScan::BuildPutArgStk(GenTreePutArgStk* argNode) srcCount++; #if defined(FEATURE_SIMD) - if (GlobalJitOptions::compMacOsArm64Abi()) + if (compMacOsArm64Abi()) { if (use.GetType() == TYP_SIMD12) { @@ -464,7 +464,7 @@ int LinearScan::BuildPutArgStk(GenTreePutArgStk* argNode) assert(!putArgChild->isContained()); srcCount = BuildOperandUses(putArgChild); #if defined(FEATURE_SIMD) - if (GlobalJitOptions::compMacOsArm64Abi() && argNode->GetStackByteSize() == 12) + if (compMacOsArm64Abi() && argNode->GetStackByteSize() == 12) { // Vector3 is read/written as two reads/writes: 8 byte and 4 byte. // To assemble the vector properly we would need an additional int register. diff --git a/src/coreclr/jit/lsrabuild.cpp b/src/coreclr/jit/lsrabuild.cpp index 5cb853e5c90474..f95c37abc82916 100644 --- a/src/coreclr/jit/lsrabuild.cpp +++ b/src/coreclr/jit/lsrabuild.cpp @@ -3836,7 +3836,7 @@ int LinearScan::BuildPutArgReg(GenTreeUnOp* node) // (e.g. for the target). void LinearScan::HandleFloatVarArgs(GenTreeCall* call, GenTree* argNode, bool* callHasFloatRegArgs) { - if (GlobalJitOptions::compFeatureVarArg() && call->IsVarargs() && varTypeIsFloating(argNode)) + if (compFeatureVarArg() && call->IsVarargs() && varTypeIsFloating(argNode)) { *callHasFloatRegArgs = true; diff --git a/src/coreclr/jit/lsraxarch.cpp b/src/coreclr/jit/lsraxarch.cpp index 22056e549305a4..c8986052e1d000 100644 --- a/src/coreclr/jit/lsraxarch.cpp +++ b/src/coreclr/jit/lsraxarch.cpp @@ -1238,7 +1238,7 @@ int LinearScan::BuildCall(GenTreeCall* call) // If it is a fast tail call, it is already preferenced to use RAX. // Therefore, no need set src candidates on call tgt again. - if (GlobalJitOptions::compFeatureVarArg() && call->IsVarargs() && callHasFloatRegArgs && !call->IsFastTailCall()) + if (compFeatureVarArg() && call->IsVarargs() && callHasFloatRegArgs && !call->IsFastTailCall()) { // Don't assign the call target to any of the argument registers because // we will use them to also pass floating point arguments as required diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index 48e07f8c8386a2..26d896f07df2fd 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -3305,7 +3305,7 @@ void Compiler::fgInitArgInfo(GenTreeCall* call) assert(size != 0); assert(byteSize != 0); - if (GlobalJitOptions::compMacOsArm64Abi()) + if (compMacOsArm64Abi()) { // Arm64 Apple has a special ABI for passing small size arguments on stack, // bytes are aligned to 1-byte, shorts to 2-byte, int/float to 4-byte, etc. @@ -3580,7 +3580,7 @@ void Compiler::fgInitArgInfo(GenTreeCall* call) { #if FEATURE_ARG_SPLIT_SUPPORTED // Check for a split (partially enregistered) struct - if (GlobalJitOptions::compFeatureArgSplit() && !passUsingFloatRegs && ((intArgRegNum + size) > MAX_REG_ARG)) + if (compFeatureArgSplit() && !passUsingFloatRegs && ((intArgRegNum + size) > MAX_REG_ARG)) { // This indicates a partial enregistration of a struct type assert((isStructArg) || argx->OperIs(GT_FIELD_LIST) || argx->OperIsCopyBlkOp() || diff --git a/src/coreclr/jit/target.h b/src/coreclr/jit/target.h index fa9832f1a1efe0..0aa0f4085c4484 100644 --- a/src/coreclr/jit/target.h +++ b/src/coreclr/jit/target.h @@ -9,6 +9,11 @@ #define FEATURE_CFI_SUPPORT #endif +// Native Varargs are not supported on Unix (all architectures) and Windows ARM +#define compFeatureVarArg() (TargetOS::IsWindows && !TargetArchitecture::IsArm32) +#define compMacOsArm64Abi() (TargetArchitecture::IsArm64 && TargetOS::IsMacOS) +#define compFeatureArgSplit() ( TargetArchitecture::IsArm32 || (TargetOS::IsWindows && TargetArchitecture::IsArm64) ) + /*****************************************************************************/ // The following are human readable names for the target architectures #if defined(TARGET_X86) From 3f4a439d30a792c7f78fe518b92458796e353ffd Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Fri, 27 Aug 2021 10:53:45 -0700 Subject: [PATCH 07/15] add compFeatureArgSplit checks --- src/coreclr/jit/compiler.h | 2 +- src/coreclr/jit/gentree.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index 504957a33f1797..88c961c8f259c1 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -1598,7 +1598,7 @@ struct fgArgTabEntry bool IsSplit() const { #if FEATURE_ARG_SPLIT_SUPPORTED - return _isSplit; + return compFeatureArgSplit() && _isSplit; #else // FEATURE_ARG_SPLIT_SUPPORTED return false; #endif diff --git a/src/coreclr/jit/gentree.h b/src/coreclr/jit/gentree.h index 80b8995f1851f1..55d3bcae8878b2 100644 --- a/src/coreclr/jit/gentree.h +++ b/src/coreclr/jit/gentree.h @@ -1295,7 +1295,7 @@ struct GenTree bool OperIsPutArgSplit() const { #if FEATURE_ARG_SPLIT_SUPPORTED - return gtOper == GT_PUTARG_SPLIT; + return compFeatureArgSplit() && (gtOper == GT_PUTARG_SPLIT); #else // !FEATURE_ARG_SPLIT_SUPPORTED return false; #endif From 05cea7a8cf578042c6f730960ad66448918eeb0f Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Sun, 29 Aug 2021 13:20:36 -0700 Subject: [PATCH 08/15] - Fixup pack production - Don't special case Windows handling of clrjit.dll, just use the crossgen2 targetted one - Fix cross compilation targets - Build the universal cross clrjit targets, but they don't need to be part of the runtimepack - Fixup setting of compMatchedVM for macOS X64 in crossgen2 --- src/coreclr/crosscomponents.cmake | 24 +++++++------- src/coreclr/gcinfo/CMakeLists.txt | 5 +++ src/coreclr/jit/CMakeLists.txt | 9 ++--- src/coreclr/jit/compiler.cpp | 33 ++++++++++++------- .../tools/aot/crossgen2/crossgen2.props | 11 ------- .../Microsoft.NETCore.App.Crossgen2.sfxproj | 7 ++-- 6 files changed, 45 insertions(+), 44 deletions(-) diff --git a/src/coreclr/crosscomponents.cmake b/src/coreclr/crosscomponents.cmake index 864bdf9e722184..f095d9ba5d34c7 100644 --- a/src/coreclr/crosscomponents.cmake +++ b/src/coreclr/crosscomponents.cmake @@ -2,27 +2,27 @@ if (CLR_CMAKE_HOST_OS STREQUAL CLR_CMAKE_TARGET_OS) install_clr (TARGETS - clrjit - DESTINATIONS . sharedFramework - COMPONENT crosscomponents - ) - install_clr (TARGETS - clrjit jitinterface_${ARCH_HOST_NAME} DESTINATIONS . COMPONENT crosscomponents ) - if(CLR_CMAKE_TARGET_OSX AND ARCH_TARGET_NAME STREQUAL arm64) + if (CLR_CMAKE_TARGET_OSX AND ARCH_TARGET_NAME STREQUAL arm64) + install_clr (TARGETS + clrjit_universal_${ARCH_TARGET_NAME}_${ARCH_HOST_NAME} + DESTINATIONS . + COMPONENT crosscomponents + ) + elseif (CLR_CMAKE_TARGET_ARCH_ARM OR CLR_CMAKE_TARGET_ARCH_ARM64) install_clr (TARGETS - clrjit_unix_osx_${ARCH_TARGET_NAME}_${ARCH_HOST_NAME} - DESTINATIONS . sharedFramework + clrjit_universal_${ARCH_TARGET_NAME}_${ARCH_HOST_NAME} + DESTINATIONS . COMPONENT crosscomponents ) - elseif (CLR_CMAKE_TARGET_UNIX) + else () install_clr (TARGETS - clrjit_unix_${ARCH_TARGET_NAME}_${ARCH_HOST_NAME} - DESTINATIONS . sharedFramework + clrjit_${TARGET_OS_NAME}_${ARCH_TARGET_NAME}_${ARCH_HOST_NAME} + DESTINATIONS . COMPONENT crosscomponents ) endif() diff --git a/src/coreclr/gcinfo/CMakeLists.txt b/src/coreclr/gcinfo/CMakeLists.txt index 78843e5134539d..8c966bb3403b5e 100644 --- a/src/coreclr/gcinfo/CMakeLists.txt +++ b/src/coreclr/gcinfo/CMakeLists.txt @@ -64,6 +64,11 @@ else() set(TARGET_OS_NAME win) endif() +# For clrjit we need to build an exact targetted gcinfo instead of the universal one +if (CLR_CMAKE_TARGET_ARCH_ARM64 OR CLR_CMAKE_TARGET_ARCH_ARM) + create_gcinfo_lib(TARGET gcinfo_${TARGET_OS_NAME}_${ARCH_TARGET_NAME} OS ${TARGET_OS_NAME} ARCH ${ARCH_TARGET_NAME}) +endif() + if (CLR_CMAKE_TARGET_ARCH_ARM64 OR CLR_CMAKE_TARGET_ARCH_AMD64) create_gcinfo_lib(TARGET gcinfo_universal_arm64 OS universal ARCH arm64) create_gcinfo_lib(TARGET gcinfo_unix_x64 OS unix ARCH x64) diff --git a/src/coreclr/jit/CMakeLists.txt b/src/coreclr/jit/CMakeLists.txt index 036e09062711aa..b9ee414cd456d5 100644 --- a/src/coreclr/jit/CMakeLists.txt +++ b/src/coreclr/jit/CMakeLists.txt @@ -511,11 +511,12 @@ endif (CLR_CMAKE_TARGET_ARCH_I386 AND CLR_CMAKE_TARGET_UNIX) if (CLR_CMAKE_TARGET_UNIX) if (NOT ARCH_TARGET_NAME STREQUAL s390x) - install_clr(TARGETS clrjit_unix_${ARCH_TARGET_NAME}_${ARCH_HOST_NAME} DESTINATIONS . COMPONENT jit) + if(CLR_CMAKE_TARGET_ARCH_ARM OR CLR_CMAKE_TARGET_ARCH_ARM64) + install_clr(TARGETS clrjit_universal_${ARCH_TARGET_NAME}_${ARCH_HOST_NAME} DESTINATIONS . COMPONENT jit) + else() + install_clr(TARGETS clrjit_unix_${ARCH_TARGET_NAME}_${ARCH_HOST_NAME} DESTINATIONS . COMPONENT jit) + endif() endif(NOT ARCH_TARGET_NAME STREQUAL s390x) - if (ARCH_TARGET_NAME STREQUAL arm) - target_compile_definitions(clrjit_unix_arm_${ARCH_HOST_NAME} PRIVATE ARM_SOFTFP CONFIGURABLE_ARM_ABI) - endif (ARCH_TARGET_NAME STREQUAL arm) endif() if (CLR_CMAKE_TARGET_WIN32 AND CLR_CMAKE_PGO_INSTRUMENT) diff --git a/src/coreclr/jit/compiler.cpp b/src/coreclr/jit/compiler.cpp index 3bc05b9b848550..4b17e2136e161e 100644 --- a/src/coreclr/jit/compiler.cpp +++ b/src/coreclr/jit/compiler.cpp @@ -5531,13 +5531,33 @@ int Compiler::compCompile(CORINFO_MODULE_HANDLE classPtr, // Match OS for compMatchedVM CORINFO_EE_INFO* eeInfo = eeGetEEInfo(); + +#ifdef TARGET_OS_RUNTIMEDETERMINED + if (!TargetOS::OSSettingConfigured) + { + CORINFO_EE_INFO* eeInfo = eeGetEEInfo(); + TargetOS::IsMacOS = eeInfo->osType == CORINFO_MACOS; + TargetOS::IsUnix = (eeInfo->osType == CORINFO_UNIX) || (eeInfo->osType == CORINFO_MACOS); + TargetOS::IsWindows = eeInfo->osType == CORINFO_WINNT; + TargetOS::OSSettingConfigured = true; + } +#endif + if (TargetOS::IsMacOS) { info.compMatchedVM = info.compMatchedVM && (eeInfo->osType == CORINFO_MACOS); } else if (TargetOS::IsUnix) { - info.compMatchedVM = info.compMatchedVM && (eeInfo->osType == CORINFO_UNIX); + if (TargetArchitecture::IsX64) + { + // MacOS x64 uses the Unix jit variant in crossgen2, not a special jit + info.compMatchedVM = info.compMatchedVM && ((eeInfo->osType == CORINFO_UNIX) || (eeInfo->osType == CORINFO_MACOS)); + } + else + { + info.compMatchedVM = info.compMatchedVM && (eeInfo->osType == CORINFO_UNIX); + } } else if (TargetOS::IsWindows) { @@ -6101,17 +6121,6 @@ int Compiler::compCompileHelper(CORINFO_MODULE_HANDLE classPtr, { CORINFO_METHOD_HANDLE methodHnd = info.compMethodHnd; -#ifdef TARGET_OS_RUNTIMEDETERMINED - if (!TargetOS::OSSettingConfigured) - { - CORINFO_EE_INFO* eeInfo = eeGetEEInfo(); - TargetOS::IsMacOS = eeInfo->osType == CORINFO_MACOS; - TargetOS::IsUnix = (eeInfo->osType == CORINFO_UNIX) || (eeInfo->osType == CORINFO_MACOS); - TargetOS::IsWindows = eeInfo->osType == CORINFO_WINNT; - TargetOS::OSSettingConfigured = true; - } -#endif - info.compCode = methodInfo->ILCode; info.compILCodeSize = methodInfo->ILCodeSize; info.compILImportSize = 0; diff --git a/src/coreclr/tools/aot/crossgen2/crossgen2.props b/src/coreclr/tools/aot/crossgen2/crossgen2.props index 7f38cdc728a750..e69b66ceecb3e2 100644 --- a/src/coreclr/tools/aot/crossgen2/crossgen2.props +++ b/src/coreclr/tools/aot/crossgen2/crossgen2.props @@ -82,17 +82,6 @@ /> - - - - - - - - + - - - + From adfc7b3b37be36194979854a0bb13a1f535d581f Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Mon, 30 Aug 2021 10:43:40 -0700 Subject: [PATCH 09/15] - Fix Windows X86 cross target build - Adjust superpmi setup to know about the new dll names - Adjust DEBUG_ARG_SLOTS handling to work with osx arm64 abi. (By disabling anything meaningful) --- src/coreclr/crosscomponents.cmake | 10 ++++-- src/coreclr/jit/compiler.h | 2 +- src/coreclr/jit/gentree.cpp | 22 ++++++++++--- src/coreclr/jit/morph.cpp | 47 +++++++++++++++++++-------- src/coreclr/scripts/superpmi_setup.py | 6 ++++ 5 files changed, 67 insertions(+), 20 deletions(-) diff --git a/src/coreclr/crosscomponents.cmake b/src/coreclr/crosscomponents.cmake index f095d9ba5d34c7..ceb5b5384e5a74 100644 --- a/src/coreclr/crosscomponents.cmake +++ b/src/coreclr/crosscomponents.cmake @@ -19,9 +19,15 @@ if (CLR_CMAKE_HOST_OS STREQUAL CLR_CMAKE_TARGET_OS) DESTINATIONS . COMPONENT crosscomponents ) - else () + elseif (CLR_CMAKE_TARGET_UNIX) install_clr (TARGETS - clrjit_${TARGET_OS_NAME}_${ARCH_TARGET_NAME}_${ARCH_HOST_NAME} + clrjit_unix_${ARCH_TARGET_NAME}_${ARCH_HOST_NAME} + DESTINATIONS . + COMPONENT crosscomponents + ) + else() + install_clr (TARGETS + clrjit_win_${ARCH_TARGET_NAME}_${ARCH_HOST_NAME} DESTINATIONS . COMPONENT crosscomponents ) diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index 88c961c8f259c1..303a7bea1d44de 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -1911,7 +1911,7 @@ struct fgArgTabEntry #endif // TARGET_ARM #if defined(DEBUG_ARG_SLOTS) - if (!isStruct) + if (!compMacOsArm64Abi() && !isStruct) { assert(roundedByteSize == getSlotCount() * TARGET_POINTER_SIZE); } diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index 6ac6a4be5ce525..18114460179af6 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -11789,8 +11789,15 @@ void Compiler::gtDispTree(GenTree* tree, #if !defined(DEBUG_ARG_SLOTS) printf(" (%d stackByteSize), (%d byteOffset)", putArg->GetStackByteSize(), putArg->getArgOffset()); #else - printf(" (%d slots), (%d stackByteSize), (%d slot), (%d byteOffset)", putArg->gtNumSlots, - putArg->GetStackByteSize(), putArg->gtSlotNum, putArg->getArgOffset()); + if (compMacOsArm64Abi()) + { + printf(" (%d stackByteSize), (%d byteOffset)", putArg->GetStackByteSize(), putArg->getArgOffset()); + } + else + { + printf(" (%d slots), (%d stackByteSize), (%d slot), (%d byteOffset)", putArg->gtNumSlots, + putArg->GetStackByteSize(), putArg->gtSlotNum, putArg->getArgOffset()); + } #endif if (putArg->gtPutArgStkKind != GenTreePutArgStk::Kind::Invalid) { @@ -11820,8 +11827,15 @@ void Compiler::gtDispTree(GenTree* tree, #if !defined(DEBUG_ARG_SLOTS) printf(" (%d stackByteSize), (%d numRegs)", putArg->GetStackByteSize(), putArg->gtNumRegs); #else - printf(" (%d slots), (%d stackByteSize), (%d numRegs)", putArg->gtNumSlots, putArg->GetStackByteSize(), - putArg->gtNumRegs); + if (compMacOsArm64Abi()) + { + printf(" (%d stackByteSize), (%d numRegs)", putArg->GetStackByteSize(), putArg->gtNumRegs); + } + else + { + printf(" (%d slots), (%d stackByteSize), (%d numRegs)", putArg->gtNumSlots, putArg->GetStackByteSize(), + putArg->gtNumRegs); + } #endif } #endif // FEATURE_ARG_SPLIT_SUPPORTED diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index 26d896f07df2fd..f67a5c0db4ddad 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -1172,7 +1172,10 @@ fgArgTabEntry* fgArgInfo::AddStkArg(unsigned argNum, fgArgTabEntry* curArgTabEntry = new (compiler, CMK_fgArgInfo) fgArgTabEntry; #if defined(DEBUG_ARG_SLOTS) - nextSlotNum = roundUp(nextSlotNum, byteAlignment / TARGET_POINTER_SIZE); + if (!compMacOsArm64Abi()) + { + nextSlotNum = roundUp(nextSlotNum, byteAlignment / TARGET_POINTER_SIZE); + } #endif nextStackByteOffset = roundUp(nextStackByteOffset, byteAlignment); @@ -1271,9 +1274,12 @@ void fgArgInfo::UpdateStkArg(fgArgTabEntry* curArgTabEntry, GenTree* node, bool assert((curArgTabEntry->GetRegNum() == REG_STK) || curArgTabEntry->IsSplit()); assert(curArgTabEntry->use->GetNode() == node); #if defined(DEBUG_ARG_SLOTS) - nextSlotNum = roundUp(nextSlotNum, curArgTabEntry->GetByteAlignment() / TARGET_POINTER_SIZE); - assert(curArgTabEntry->slotNum == nextSlotNum); - nextSlotNum += curArgTabEntry->numSlots; + if (!compMacOsArm64Abi()) + { + nextSlotNum = roundUp(nextSlotNum, curArgTabEntry->GetByteAlignment() / TARGET_POINTER_SIZE); + assert(curArgTabEntry->slotNum == nextSlotNum); + nextSlotNum += curArgTabEntry->numSlots; + } #endif nextStackByteOffset = roundUp(nextStackByteOffset, curArgTabEntry->GetByteAlignment()); @@ -3782,11 +3788,14 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* call) CORINFO_CLASS_HANDLE copyBlkClass = NO_CLASS_HANDLE; #if defined(DEBUG_ARG_SLOTS) - if (argEntry->GetByteAlignment() == 2 * TARGET_POINTER_SIZE) + if (!compMacOsArm64Abi()) { - if (argSlots % 2 == 1) + if (argEntry->GetByteAlignment() == 2 * TARGET_POINTER_SIZE) { - argSlots++; + if (argSlots % 2 == 1) + { + argSlots++; + } } } #endif // DEBUG @@ -4238,8 +4247,12 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* call) const unsigned outgoingArgSpaceSize = GetOutgoingArgByteSize(call->fgArgInfo->GetNextSlotByteOffset()); #if defined(DEBUG_ARG_SLOTS) - unsigned preallocatedArgCount = call->fgArgInfo->GetNextSlotNum(); - assert(outgoingArgSpaceSize == preallocatedArgCount * REGSIZE_BYTES); + unsigned preallocatedArgCount = 0; + if (!compMacOsArm64Abi()) + { + preallocatedArgCount = call->fgArgInfo->GetNextSlotNum(); + assert(outgoingArgSpaceSize == preallocatedArgCount * REGSIZE_BYTES); + } #endif call->fgArgInfo->SetOutArgSize(max(outgoingArgSpaceSize, MIN_ARG_AREA_FOR_CALL)); @@ -4248,10 +4261,18 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* call) { const fgArgInfo* argInfo = call->fgArgInfo; #if defined(DEBUG_ARG_SLOTS) - printf("argSlots=%d, preallocatedArgCount=%d, nextSlotNum=%d, nextSlotByteOffset=%d, " - "outgoingArgSpaceSize=%d\n", - argSlots, preallocatedArgCount, argInfo->GetNextSlotNum(), argInfo->GetNextSlotByteOffset(), - outgoingArgSpaceSize); + if (!compMacOsArm64Abi()) + { + printf("argSlots=%d, preallocatedArgCount=%d, nextSlotNum=%d, nextSlotByteOffset=%d, " + "outgoingArgSpaceSize=%d\n", + argSlots, preallocatedArgCount, argInfo->GetNextSlotNum(), argInfo->GetNextSlotByteOffset(), + outgoingArgSpaceSize); + } + else + { + printf("nextSlotByteOffset=%d, outgoingArgSpaceSize=%d\n", argInfo->GetNextSlotByteOffset(), + outgoingArgSpaceSize); + } #else printf("nextSlotByteOffset=%d, outgoingArgSpaceSize=%d\n", argInfo->GetNextSlotByteOffset(), outgoingArgSpaceSize); diff --git a/src/coreclr/scripts/superpmi_setup.py b/src/coreclr/scripts/superpmi_setup.py index 0d0bc0bb341232..6702ffc140231a 100644 --- a/src/coreclr/scripts/superpmi_setup.py +++ b/src/coreclr/scripts/superpmi_setup.py @@ -128,6 +128,12 @@ "clrjit_win_x86_arm64.dll", "clrjit_win_x86_x64.dll", "clrjit_win_x86_x86.dll", + "clrjit_universal_arm_arm.dll", + "clrjit_universal_arm_arm64.dll", + "clrjit_universal_arm_x64.dll", + "clrjit_universal_arm_x86.dll", + "clrjit_universal_arm64_arm64.dll", + "clrjit_universal_arm64_x64.dll", "coreclr.dll", "CoreConsole.exe", "coredistools.dll", From c90c3cd80ea6fed1238101e1f74d144ef874d895 Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Tue, 14 Sep 2021 17:17:30 -0700 Subject: [PATCH 10/15] Address code review feedback - Undef all TARGET_ OS macros within the JIT so that they can't be used there - Convert the feature macros to inline functions. Should have equivalent perf on release/chk builds as macro approach, and is less problematic in general. --- src/coreclr/jit/target.h | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/coreclr/jit/target.h b/src/coreclr/jit/target.h index 92063f96ef0532..278ffbb2b3fe4e 100644 --- a/src/coreclr/jit/target.h +++ b/src/coreclr/jit/target.h @@ -9,10 +9,25 @@ #define FEATURE_CFI_SUPPORT #endif +// Undefine all of the target OS macros +// Within the JIT codebase we use the TargetOS features +#ifdef TARGET_UNIX +#undef TARGET_UNIX +#endif + +#ifdef TARGET_OSX +#undef TARGET_OSX +#endif + +#ifdef TARGET_WINDOWS +#undef TARGET_WINDOWS +#endif + + // Native Varargs are not supported on Unix (all architectures) and Windows ARM -#define compFeatureVarArg() (TargetOS::IsWindows && !TargetArchitecture::IsArm32) -#define compMacOsArm64Abi() (TargetArchitecture::IsArm64 && TargetOS::IsMacOS) -#define compFeatureArgSplit() ( TargetArchitecture::IsArm32 || (TargetOS::IsWindows && TargetArchitecture::IsArm64) ) +inline bool compFeatureVarArg() { return TargetOS::IsWindows && !TargetArchitecture::IsArm32; } +inline bool compMacOsArm64Abi() { return TargetArchitecture::IsArm64 && TargetOS::IsMacOS; } +inline bool compFeatureArgSplit() { return TargetArchitecture::IsArm32 || (TargetOS::IsWindows && TargetArchitecture::IsArm64); } /*****************************************************************************/ // The following are human readable names for the target architectures From efc7e202a064725d37d25d8a7d90ac8a58be9661 Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Thu, 16 Sep 2021 11:58:58 -0700 Subject: [PATCH 11/15] First set of Bruce's feedback --- src/coreclr/jit/codegen.h | 8 ++++---- src/coreclr/jit/codegenarmarch.cpp | 9 ++------- src/coreclr/jit/codegenlinear.cpp | 11 ++++++----- src/coreclr/jit/codegenxarch.cpp | 2 +- src/coreclr/jit/compiler.h | 10 +++++----- src/coreclr/jit/compiler.hpp | 4 ++-- src/coreclr/jit/gentree.cpp | 26 +++++++++++++------------- src/coreclr/jit/gentree.h | 21 +++++++++++---------- src/coreclr/jit/gtlist.h | 4 ++-- src/coreclr/jit/gtstructs.h | 6 +++--- src/coreclr/jit/jit.h | 6 +++--- src/coreclr/jit/lower.cpp | 8 ++++---- src/coreclr/jit/lsra.cpp | 8 ++++---- src/coreclr/jit/lsra.h | 4 ++-- src/coreclr/jit/lsraarm64.cpp | 4 ++-- src/coreclr/jit/lsraarmarch.cpp | 6 ------ src/coreclr/jit/morph.cpp | 12 ++++++------ src/coreclr/scripts/superpmi-replay.py | 1 + 18 files changed, 71 insertions(+), 79 deletions(-) diff --git a/src/coreclr/jit/codegen.h b/src/coreclr/jit/codegen.h index acf742df35d1c8..e88fcb59ca440f 100644 --- a/src/coreclr/jit/codegen.h +++ b/src/coreclr/jit/codegen.h @@ -941,9 +941,9 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX void genIntrinsic(GenTree* treeNode); void genPutArgStk(GenTreePutArgStk* treeNode); void genPutArgReg(GenTreeOp* tree); -#if FEATURE_ARG_SPLIT_SUPPORTED +#if FEATURE_ARG_SPLIT void genPutArgSplit(GenTreePutArgSplit* treeNode); -#endif // FEATURE_ARG_SPLIT_SUPPORTED +#endif // FEATURE_ARG_SPLIT #if defined(TARGET_XARCH) unsigned getBaseVarForPutArgStk(GenTree* treeNode); @@ -1137,9 +1137,9 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX regNumber srcReg, regNumber sizeReg); #endif // FEATURE_PUT_STRUCT_ARG_STK -#if FEATURE_ARG_SPLIT_SUPPORTED +#if FEATURE_ARG_SPLIT void genConsumeArgSplitStruct(GenTreePutArgSplit* putArgNode); -#endif // FEATURE_ARG_SPLIT_SUPPORTED +#endif // FEATURE_ARG_SPLIT void genConsumeRegs(GenTree* tree); void genConsumeOperands(GenTreeOp* tree); diff --git a/src/coreclr/jit/codegenarmarch.cpp b/src/coreclr/jit/codegenarmarch.cpp index 2f9e34c8080496..9203383acc2f6f 100644 --- a/src/coreclr/jit/codegenarmarch.cpp +++ b/src/coreclr/jit/codegenarmarch.cpp @@ -398,11 +398,9 @@ void CodeGen::genCodeForTreeNode(GenTree* treeNode) genPutArgReg(treeNode->AsOp()); break; -#if FEATURE_ARG_SPLIT_SUPPORTED case GT_PUTARG_SPLIT: genPutArgSplit(treeNode->AsPutArgSplit()); break; -#endif // FEATURE_ARG_SPLIT_SUPPORTED case GT_CALL: genCallInstruction(treeNode->AsCall()); @@ -1142,7 +1140,6 @@ void CodeGen::genPutArgReg(GenTreeOp* tree) genProduceReg(tree); } -#if FEATURE_ARG_SPLIT_SUPPORTED //--------------------------------------------------------------------- // genPutArgSplit - generate code for a GT_PUTARG_SPLIT node // @@ -1363,7 +1360,6 @@ void CodeGen::genPutArgSplit(GenTreePutArgSplit* treeNode) } genProduceReg(treeNode); } -#endif // FEATURE_ARG_SPLIT_SUPPORTED #ifdef FEATURE_SIMD //---------------------------------------------------------------------------------- @@ -2313,9 +2309,9 @@ void CodeGen::genCallInstruction(GenTreeCall* call) #endif // TARGET_ARM } } -#if FEATURE_ARG_SPLIT_SUPPORTED - else if (compFeatureArgSplit() && curArgTabEntry->IsSplit()) + else if (curArgTabEntry->IsSplit()) { + assert(compFeatureArgSplit()); assert(curArgTabEntry->numRegs >= 1); genConsumeArgSplitStruct(argNode->AsPutArgSplit()); for (unsigned idx = 0; idx < curArgTabEntry->numRegs; idx++) @@ -2326,7 +2322,6 @@ void CodeGen::genCallInstruction(GenTreeCall* call) emitActualTypeSize(TYP_I_IMPL)); } } -#endif // FEATURE_ARG_SPLIT_SUPPORTED else { regNumber argReg = curArgTabEntry->GetRegNum(); diff --git a/src/coreclr/jit/codegenlinear.cpp b/src/coreclr/jit/codegenlinear.cpp index 0063dc0965b328..17ba8858b8b9f7 100644 --- a/src/coreclr/jit/codegenlinear.cpp +++ b/src/coreclr/jit/codegenlinear.cpp @@ -1794,7 +1794,7 @@ void CodeGen::genConsumePutStructArgStk(GenTreePutArgStk* putArgNode, } #endif // FEATURE_PUT_STRUCT_ARG_STK -#if FEATURE_ARG_SPLIT_SUPPORTED +#if FEATURE_ARG_SPLIT //------------------------------------------------------------------------ // genConsumeArgRegSplit: Consume register(s) in Call node to set split struct argument. // Liveness update for the PutArgSplit node is not needed @@ -1817,7 +1817,7 @@ void CodeGen::genConsumeArgSplitStruct(GenTreePutArgSplit* putArgNode) genCheckConsumeNode(putArgNode); } -#endif // FEATURE_ARG_SPLIT_SUPPORTED +#endif // FEATURE_ARG_SPLIT //------------------------------------------------------------------------ // genPutArgStkFieldList: Generate code for a putArgStk whose source is a GT_FIELD_LIST @@ -2133,9 +2133,10 @@ void CodeGen::genProduceReg(GenTree* tree) } } } -#if FEATURE_ARG_SPLIT_SUPPORTED - else if (compFeatureArgSplit() && tree->OperIsPutArgSplit()) +#if FEATURE_ARG_SPLIT + else if (tree->OperIsPutArgSplit()) { + assert(compFeatureArgSplit()); GenTreePutArgSplit* argSplit = tree->AsPutArgSplit(); unsigned regCount = argSplit->gtNumRegs; @@ -2168,7 +2169,7 @@ void CodeGen::genProduceReg(GenTree* tree) } } #endif // TARGET_ARM -#endif // FEATURE_ARG_SPLIT_SUPPORTED +#endif // FEATURE_ARG_SPLIT else { regSet.rsSpillTree(tree->GetRegNum(), tree); diff --git a/src/coreclr/jit/codegenxarch.cpp b/src/coreclr/jit/codegenxarch.cpp index cc35272218dd60..b992b1f3fad573 100644 --- a/src/coreclr/jit/codegenxarch.cpp +++ b/src/coreclr/jit/codegenxarch.cpp @@ -2004,7 +2004,7 @@ void CodeGen::genMultiRegStoreToSIMDLocal(GenTreeLclVar* lclNode) } } #elif defined(TARGET_AMD64) - assert(!TargetOS::IsWindows && !"Multireg store to SIMD reg not supported on Windows x64"); + assert(!TargetOS::IsWindows || !"Multireg store to SIMD reg not supported on Windows x64"); #else #error Unsupported or unset target architecture #endif diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index 6df9b142aa3fa0..ef9bdeba0422d8 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -1621,9 +1621,9 @@ struct fgArgTabEntry bool isStruct : 1; // True if this is a struct arg bool _isVararg : 1; // True if the argument is in a vararg context. bool passedByRef : 1; // True iff the argument is passed by reference. -#if FEATURE_ARG_SPLIT_SUPPORTED +#if FEATURE_ARG_SPLIT bool _isSplit : 1; // True when this argument is split between the registers and OutArg area -#endif // FEATURE_ARG_SPLIT_SUPPORTED +#endif // FEATURE_ARG_SPLIT #ifdef FEATURE_HFA_FIELDS_PRESENT CorInfoHFAElemType _hfaElemKind : 3; // What kind of an HFA this is (CORINFO_HFA_ELEM_NONE if it is not an HFA). #endif @@ -1716,15 +1716,15 @@ struct fgArgTabEntry bool IsSplit() const { -#if FEATURE_ARG_SPLIT_SUPPORTED +#if FEATURE_ARG_SPLIT return compFeatureArgSplit() && _isSplit; -#else // FEATURE_ARG_SPLIT_SUPPORTED +#else // FEATURE_ARG_SPLIT return false; #endif } void SetSplit(bool value) { -#if FEATURE_ARG_SPLIT_SUPPORTED +#if FEATURE_ARG_SPLIT _isSplit = value; #endif } diff --git a/src/coreclr/jit/compiler.hpp b/src/coreclr/jit/compiler.hpp index cedb8df8a5ed0a..18cb2cbd216294 100644 --- a/src/coreclr/jit/compiler.hpp +++ b/src/coreclr/jit/compiler.hpp @@ -4308,9 +4308,9 @@ void GenTree::VisitOperands(TVisitor visitor) case GT_PUTARG_REG: case GT_PUTARG_STK: case GT_PUTARG_TYPE: -#if FEATURE_ARG_SPLIT_SUPPORTED +#if FEATURE_ARG_SPLIT case GT_PUTARG_SPLIT: -#endif // FEATURE_ARG_SPLIT_SUPPORTED +#endif // FEATURE_ARG_SPLIT case GT_RETURNTRAP: case GT_KEEPALIVE: case GT_INC_SATURATE: diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index b8999e466ac01b..dd55f6f2b79a6b 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -279,9 +279,9 @@ void GenTree::InitNodeSize() // TODO-Throughput: This should not need to be a large node. The object info should be // obtained from the child node. GenTree::s_gtNodeSizes[GT_PUTARG_STK] = TREE_NODE_SZ_LARGE; -#if FEATURE_ARG_SPLIT_SUPPORTED +#if FEATURE_ARG_SPLIT GenTree::s_gtNodeSizes[GT_PUTARG_SPLIT] = TREE_NODE_SZ_LARGE; -#endif // FEATURE_ARG_SPLIT_SUPPORTED +#endif // FEATURE_ARG_SPLIT #endif // FEATURE_PUT_STRUCT_ARG_STK assert(GenTree::s_gtNodeSizes[GT_RETURN] == GenTree::s_gtNodeSizes[GT_ASG]); @@ -341,9 +341,9 @@ void GenTree::InitNodeSize() // TODO-Throughput: This should not need to be a large node. The object info should be // obtained from the child node. static_assert_no_msg(sizeof(GenTreePutArgStk) <= TREE_NODE_SZ_LARGE); -#if FEATURE_ARG_SPLIT_SUPPORTED +#if FEATURE_ARG_SPLIT static_assert_no_msg(sizeof(GenTreePutArgSplit) <= TREE_NODE_SZ_LARGE); -#endif // FEATURE_ARG_SPLIT_SUPPORTED +#endif // FEATURE_ARG_SPLIT #endif // FEATURE_PUT_STRUCT_ARG_STK #ifdef FEATURE_SIMD @@ -694,7 +694,7 @@ int GenTree::GetRegisterDstCount(Compiler* compiler) const { return gtGetOp1()->GetRegisterDstCount(compiler); } -#if FEATURE_ARG_SPLIT_SUPPORTED +#if FEATURE_ARG_SPLIT else if (OperIsPutArgSplit()) { return (const_cast(this))->AsPutArgSplit()->gtNumRegs; @@ -769,7 +769,7 @@ regMaskTP GenTree::gtGetRegMask() const } } } -#if FEATURE_ARG_SPLIT_SUPPORTED +#if FEATURE_ARG_SPLIT else if (compFeatureArgSplit() && OperIsPutArgSplit()) { const GenTreePutArgSplit* splitArg = AsPutArgSplit(); @@ -783,7 +783,7 @@ regMaskTP GenTree::gtGetRegMask() const resultMask |= genRegMask(reg); } } -#endif // FEATURE_ARG_SPLIT_SUPPORTED +#endif // FEATURE_ARG_SPLIT else { resultMask = genRegMask(GetRegNum()); @@ -5234,7 +5234,7 @@ bool GenTree::TryGetUse(GenTree* def, GenTree*** use) return false; // Variadic nodes -#if FEATURE_ARG_SPLIT_SUPPORTED +#if FEATURE_ARG_SPLIT case GT_PUTARG_SPLIT: if (this->AsUnOp()->gtOp1->gtOper == GT_FIELD_LIST) { @@ -5246,7 +5246,7 @@ bool GenTree::TryGetUse(GenTree* def, GenTree*** use) return true; } return false; -#endif // FEATURE_ARG_SPLIT_SUPPORTED +#endif // FEATURE_ARG_SPLIT #ifdef FEATURE_SIMD case GT_SIMD: @@ -9372,9 +9372,9 @@ GenTreeUseEdgeIterator::GenTreeUseEdgeIterator(GenTree* node) case GT_BSWAP16: case GT_KEEPALIVE: case GT_INC_SATURATE: -#if FEATURE_ARG_SPLIT_SUPPORTED +#if FEATURE_ARG_SPLIT case GT_PUTARG_SPLIT: -#endif // FEATURE_ARG_SPLIT_SUPPORTED +#endif // FEATURE_ARG_SPLIT case GT_RETURNTRAP: m_edge = &m_node->AsUnOp()->gtOp1; assert(*m_edge != nullptr); @@ -11833,7 +11833,7 @@ void Compiler::gtDispTree(GenTree* tree, } } } -#if FEATURE_ARG_SPLIT_SUPPORTED +#if FEATURE_ARG_SPLIT else if (tree->OperGet() == GT_PUTARG_SPLIT) { const GenTreePutArgSplit* putArg = tree->AsPutArgSplit(); @@ -11851,7 +11851,7 @@ void Compiler::gtDispTree(GenTree* tree, } #endif } -#endif // FEATURE_ARG_SPLIT_SUPPORTED +#endif // FEATURE_ARG_SPLIT #endif // FEATURE_PUT_STRUCT_ARG_STK if (tree->gtOper == GT_INTRINSIC) diff --git a/src/coreclr/jit/gentree.h b/src/coreclr/jit/gentree.h index 091afe294ae361..bc24ffcae240f1 100644 --- a/src/coreclr/jit/gentree.h +++ b/src/coreclr/jit/gentree.h @@ -1292,9 +1292,10 @@ struct GenTree bool OperIsPutArgSplit() const { -#if FEATURE_ARG_SPLIT_SUPPORTED - return compFeatureArgSplit() && (gtOper == GT_PUTARG_SPLIT); -#else // !FEATURE_ARG_SPLIT_SUPPORTED +#if FEATURE_ARG_SPLIT + assert((gtOper != GT_PUTARG_SPLIT) || compFeatureArgSplit()); + return gtOper == GT_PUTARG_SPLIT; +#else // !FEATURE_ARG_SPLIT return false; #endif } @@ -6530,7 +6531,7 @@ struct GenTreePutArgStk : public GenTreeUnOp #endif }; -#if FEATURE_ARG_SPLIT_SUPPORTED +#if FEATURE_ARG_SPLIT // Represent the struct argument: split value in register(s) and stack struct GenTreePutArgSplit : public GenTreePutArgStk { @@ -6691,7 +6692,7 @@ struct GenTreePutArgSplit : public GenTreePutArgStk } #endif }; -#endif // FEATURE_ARG_SPLIT_SUPPORTED +#endif // FEATURE_ARG_SPLIT // Represents GT_COPY or GT_RELOAD node // @@ -7620,7 +7621,7 @@ inline bool GenTree::IsMultiRegNode() const return true; } -#if FEATURE_ARG_SPLIT_SUPPORTED +#if FEATURE_ARG_SPLIT if (OperIsPutArgSplit()) { return true; @@ -7668,7 +7669,7 @@ inline unsigned GenTree::GetMultiRegCount() return AsCall()->GetReturnTypeDesc()->GetReturnRegCount(); } -#if FEATURE_ARG_SPLIT_SUPPORTED +#if FEATURE_ARG_SPLIT if (OperIsPutArgSplit()) { return AsPutArgSplit()->gtNumRegs; @@ -7738,7 +7739,7 @@ inline regNumber GenTree::GetRegByIndex(int regIndex) return AsCall()->GetRegNumByIdx(regIndex); } -#if FEATURE_ARG_SPLIT_SUPPORTED +#if FEATURE_ARG_SPLIT if (OperIsPutArgSplit()) { return AsPutArgSplit()->GetRegNumByIdx(regIndex); @@ -7798,7 +7799,7 @@ inline var_types GenTree::GetRegTypeByIndex(int regIndex) return AsCall()->AsCall()->GetReturnTypeDesc()->GetReturnRegType(regIndex); } -#if FEATURE_ARG_SPLIT_SUPPORTED +#if FEATURE_ARG_SPLIT if (OperIsPutArgSplit()) { return AsPutArgSplit()->GetRegType(regIndex); @@ -7862,7 +7863,7 @@ inline GenTreeFlags GenTree::GetRegSpillFlagByIdx(int regIndex) const return AsCall()->GetRegSpillFlagByIdx(regIndex); } -#if FEATURE_ARG_SPLIT_SUPPORTED +#if FEATURE_ARG_SPLIT if (OperIsPutArgSplit()) { return AsPutArgSplit()->GetRegSpillFlagByIdx(regIndex); diff --git a/src/coreclr/jit/gtlist.h b/src/coreclr/jit/gtlist.h index da2ac9bf6006b7..248bada7752035 100644 --- a/src/coreclr/jit/gtlist.h +++ b/src/coreclr/jit/gtlist.h @@ -297,9 +297,9 @@ GTNODE(PUTARG_REG , GenTreeOp ,0,GTK_UNOP) #endif GTNODE(PUTARG_TYPE , GenTreeOp ,0,GTK_UNOP|GTK_NOTLIR) // operator that places saves argument type between importation and morph GTNODE(PUTARG_STK , GenTreePutArgStk ,0,GTK_UNOP|GTK_NOVALUE) // operator that places outgoing arg in stack -#if FEATURE_ARG_SPLIT_SUPPORTED +#if FEATURE_ARG_SPLIT GTNODE(PUTARG_SPLIT , GenTreePutArgSplit ,0,GTK_UNOP) // operator that places outgoing arg in registers with stack (split struct in ARM32) -#endif // FEATURE_ARG_SPLIT_SUPPORTED +#endif // FEATURE_ARG_SPLIT GTNODE(RETURNTRAP , GenTreeOp ,0,GTK_UNOP|GTK_NOVALUE) // a conditional call to wait on gc GTNODE(SWAP , GenTreeOp ,0,GTK_BINOP|GTK_NOVALUE) // op1 and op2 swap (registers) GTNODE(IL_OFFSET , Statement ,0,GTK_LEAF|GTK_NOVALUE) // marks an IL offset for debugging purposes diff --git a/src/coreclr/jit/gtstructs.h b/src/coreclr/jit/gtstructs.h index db44ef5ae336a6..b4bad947fd90f7 100644 --- a/src/coreclr/jit/gtstructs.h +++ b/src/coreclr/jit/gtstructs.h @@ -102,12 +102,12 @@ GTSTRUCT_1(PhiArg , GT_PHI_ARG) GTSTRUCT_1(Phi , GT_PHI) GTSTRUCT_1(StoreInd , GT_STOREIND) GTSTRUCT_N(Indir , GT_STOREIND, GT_IND, GT_NULLCHECK, GT_BLK, GT_STORE_BLK, GT_OBJ, GT_STORE_OBJ, GT_DYN_BLK, GT_STORE_DYN_BLK) -#if FEATURE_ARG_SPLIT_SUPPORTED +#if FEATURE_ARG_SPLIT GTSTRUCT_2_SPECIAL(PutArgStk, GT_PUTARG_STK, GT_PUTARG_SPLIT) GTSTRUCT_1(PutArgSplit , GT_PUTARG_SPLIT) -#else // !FEATURE_ARG_SPLIT_SUPPORTED +#else // !FEATURE_ARG_SPLIT GTSTRUCT_1(PutArgStk , GT_PUTARG_STK) -#endif // !FEATURE_ARG_SPLIT_SUPPORTED +#endif // !FEATURE_ARG_SPLIT GTSTRUCT_1(PhysReg , GT_PHYSREG) #ifdef FEATURE_SIMD GTSTRUCT_1(SIMD , GT_SIMD) diff --git a/src/coreclr/jit/jit.h b/src/coreclr/jit/jit.h index 7ab722fdd90bf8..72a18b88a70ba1 100644 --- a/src/coreclr/jit/jit.h +++ b/src/coreclr/jit/jit.h @@ -218,7 +218,7 @@ // On all platforms except Arm64 OSX arguments on the stack are taking // register size slots. On these platforms we could check that stack slots count // matches our new byte size calculations. -#define DEBUG_ARG_SLOTS_ASSERT(x) assert(compMacOsArm64Abi() || x) +#define DEBUG_ARG_SLOTS_ASSERT(x) assert(compMacOsArm64Abi() || (x)) #else #define DEBUG_ARG_SLOTS_ARG(x) #define DEBUG_ARG_SLOTS_ONLY(x) @@ -251,9 +251,9 @@ // the official Arm64 ABI. // Case: splitting 16 byte struct between x7 and stack #if defined(TARGET_ARM) || defined(TARGET_ARM64) -#define FEATURE_ARG_SPLIT_SUPPORTED 1 +#define FEATURE_ARG_SPLIT 1 #else -#define FEATURE_ARG_SPLIT_SUPPORTED 0 +#define FEATURE_ARG_SPLIT 0 #endif // To get rid of warning 4701 : local variable may be used without being initialized diff --git a/src/coreclr/jit/lower.cpp b/src/coreclr/jit/lower.cpp index d27eb28f0eb05e..329b5d48e1d4ef 100644 --- a/src/coreclr/jit/lower.cpp +++ b/src/coreclr/jit/lower.cpp @@ -1044,7 +1044,7 @@ GenTree* Lowering::NewPutArg(GenTreeCall* call, GenTree* arg, fgArgTabEntry* inf } #endif -#if FEATURE_ARG_SPLIT_SUPPORTED +#if FEATURE_ARG_SPLIT // Struct can be split into register(s) and stack on ARM if (compFeatureArgSplit() && info->IsSplit()) { @@ -1115,7 +1115,7 @@ GenTree* Lowering::NewPutArg(GenTreeCall* call, GenTree* arg, fgArgTabEntry* inf } } else -#endif // FEATURE_ARG_SPLIT_SUPPORTED +#endif // FEATURE_ARG_SPLIT { if (!isOnStack) { @@ -6497,9 +6497,9 @@ void Lowering::ContainCheckNode(GenTree* node) break; case GT_PUTARG_REG: case GT_PUTARG_STK: -#if FEATURE_ARG_SPLIT_SUPPORTED +#if FEATURE_ARG_SPLIT case GT_PUTARG_SPLIT: -#endif // FEATURE_ARG_SPLIT_SUPPORTED +#endif // FEATURE_ARG_SPLIT // The regNum must have been set by the lowering of the call. assert(node->GetRegNum() != REG_NA); break; diff --git a/src/coreclr/jit/lsra.cpp b/src/coreclr/jit/lsra.cpp index 3dbdffa7585166..9989fe363e710c 100644 --- a/src/coreclr/jit/lsra.cpp +++ b/src/coreclr/jit/lsra.cpp @@ -145,13 +145,13 @@ void lsraAssignRegToTree(GenTree* tree, regNumber reg, unsigned regIdx) copy->gtOtherRegs[0] = (regNumberSmall)reg; } #endif // FEATURE_MULTIREG_RET -#if FEATURE_ARG_SPLIT_SUPPORTED +#if FEATURE_ARG_SPLIT else if (tree->OperIsPutArgSplit()) { GenTreePutArgSplit* putArg = tree->AsPutArgSplit(); putArg->SetRegNumByIdx(reg, regIdx); } -#endif // FEATURE_ARG_SPLIT_SUPPORTED +#endif // FEATURE_ARG_SPLIT #if defined(TARGET_XARCH) && defined(FEATURE_HW_INTRINSICS) else if (tree->OperIs(GT_HWINTRINSIC)) { @@ -6910,7 +6910,7 @@ void LinearScan::resolveRegisters() GenTreeCall* call = treeNode->AsCall(); call->SetRegSpillFlagByIdx(GTF_SPILL, currentRefPosition->getMultiRegIdx()); } -#if FEATURE_ARG_SPLIT_SUPPORTED +#if FEATURE_ARG_SPLIT else if (treeNode->OperIsPutArgSplit()) { GenTreePutArgSplit* splitArg = treeNode->AsPutArgSplit(); @@ -6923,7 +6923,7 @@ void LinearScan::resolveRegisters() multiReg->SetRegSpillFlagByIdx(GTF_SPILL, currentRefPosition->getMultiRegIdx()); } #endif // TARGET_ARM -#endif // FEATURE_ARG_SPLIT_SUPPORTED +#endif // FEATURE_ARG_SPLIT } // If the value is reloaded or moved to a different register, we need to insert diff --git a/src/coreclr/jit/lsra.h b/src/coreclr/jit/lsra.h index 59b7dbe08e840e..ce94501a396712 100644 --- a/src/coreclr/jit/lsra.h +++ b/src/coreclr/jit/lsra.h @@ -1883,9 +1883,9 @@ class LinearScan : public LinearScanInterface #endif // FEATURE_HW_INTRINSICS int BuildPutArgStk(GenTreePutArgStk* argNode); -#if FEATURE_ARG_SPLIT_SUPPORTED +#if FEATURE_ARG_SPLIT int BuildPutArgSplit(GenTreePutArgSplit* tree); -#endif // FEATURE_ARG_SPLIT_SUPPORTED +#endif // FEATURE_ARG_SPLIT int BuildLclHeap(GenTree* tree); }; diff --git a/src/coreclr/jit/lsraarm64.cpp b/src/coreclr/jit/lsraarm64.cpp index 1243f2d19b250c..4e3fc015ae98a7 100644 --- a/src/coreclr/jit/lsraarm64.cpp +++ b/src/coreclr/jit/lsraarm64.cpp @@ -479,12 +479,12 @@ int LinearScan::BuildNode(GenTree* tree) } break; -#if FEATURE_ARG_SPLIT_SUPPORTED +#if FEATURE_ARG_SPLIT case GT_PUTARG_SPLIT: srcCount = BuildPutArgSplit(tree->AsPutArgSplit()); dstCount = tree->AsPutArgSplit()->gtNumRegs; break; -#endif // FEATURE_ARG_SPLIT_SUPPORTED +#endif // FEATURE_ARG_SPLIT case GT_PUTARG_STK: srcCount = BuildPutArgStk(tree->AsPutArgStk()); diff --git a/src/coreclr/jit/lsraarmarch.cpp b/src/coreclr/jit/lsraarmarch.cpp index abdfabb3fdcc7e..51ee28a1453070 100644 --- a/src/coreclr/jit/lsraarmarch.cpp +++ b/src/coreclr/jit/lsraarmarch.cpp @@ -280,7 +280,6 @@ int LinearScan::BuildCall(GenTreeCall* call) srcCount++; } } -#if FEATURE_ARG_SPLIT_SUPPORTED else if (argNode->OperGet() == GT_PUTARG_SPLIT) { unsigned regCount = argNode->AsPutArgSplit()->gtNumRegs; @@ -291,7 +290,6 @@ int LinearScan::BuildCall(GenTreeCall* call) } srcCount += regCount; } -#endif // FEATURE_ARG_SPLIT_SUPPORTED else { assert(argNode->OperIs(GT_PUTARG_REG)); @@ -334,11 +332,9 @@ int LinearScan::BuildCall(GenTreeCall* call) { fgArgTabEntry* curArgTabEntry = compiler->gtArgEntryByNode(call, arg); assert(curArgTabEntry != nullptr); -#if FEATURE_ARG_SPLIT_SUPPORTED // PUTARG_SPLIT nodes must be in the gtCallLateArgs list, since they // define registers used by the call. assert(arg->OperGet() != GT_PUTARG_SPLIT); -#endif // FEATURE_ARG_SPLIT_SUPPORTED if (arg->gtOper == GT_PUTARG_STK) { assert(curArgTabEntry->GetRegNum() == REG_STK); @@ -477,7 +473,6 @@ int LinearScan::BuildPutArgStk(GenTreePutArgStk* argNode) return srcCount; } -#if FEATURE_ARG_SPLIT_SUPPORTED //------------------------------------------------------------------------ // BuildPutArgSplit: Set the NodeInfo for a GT_PUTARG_SPLIT node // @@ -579,7 +574,6 @@ int LinearScan::BuildPutArgSplit(GenTreePutArgSplit* argNode) BuildDefs(argNode, dstCount, argMask); return srcCount; } -#endif // FEATURE_ARG_SPLIT_SUPPORTED //------------------------------------------------------------------------ // BuildBlockStore: Build the RefPositions for a block store node. diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index 68771e4e26d0cb..1cc926f148a123 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -1392,13 +1392,13 @@ void fgArgInfo::ArgsComplete() continue; #endif } -#if FEATURE_ARG_SPLIT_SUPPORTED +#if FEATURE_ARG_SPLIT else if (curArgTabEntry->IsSplit()) { hasStructRegArg = true; assert(hasStackArgs == true); } -#endif // FEATURE_ARG_SPLIT_SUPPORTED +#endif // FEATURE_ARG_SPLIT else // we have a register argument, next we look for a struct type. { if (varTypeIsStruct(argx) UNIX_AMD64_ABI_ONLY(|| curArgTabEntry->isStruct)) @@ -1521,12 +1521,12 @@ void fgArgInfo::ArgsComplete() { prevArgTabEntry->needPlace = true; } -#if FEATURE_ARG_SPLIT_SUPPORTED +#if FEATURE_ARG_SPLIT else if (prevArgTabEntry->IsSplit()) { prevArgTabEntry->needPlace = true; } -#endif // FEATURE_ARG_SPLIT_SUPPORTED +#endif // FEATURE_ARG_SPLIT #endif } } @@ -3612,7 +3612,7 @@ void Compiler::fgInitArgInfo(GenTreeCall* call) { if (!isNonStandard) { -#if FEATURE_ARG_SPLIT_SUPPORTED +#if FEATURE_ARG_SPLIT // Check for a split (partially enregistered) struct if (compFeatureArgSplit() && !passUsingFloatRegs && ((intArgRegNum + size) > MAX_REG_ARG)) { @@ -3623,7 +3623,7 @@ void Compiler::fgInitArgInfo(GenTreeCall* call) assert((unsigned char)numRegsPartial == numRegsPartial); call->fgArgInfo->SplitArg(argIndex, numRegsPartial, size - numRegsPartial); } -#endif // FEATURE_ARG_SPLIT_SUPPORTED +#endif // FEATURE_ARG_SPLIT if (passUsingFloatRegs) { diff --git a/src/coreclr/scripts/superpmi-replay.py b/src/coreclr/scripts/superpmi-replay.py index 5b10e569de8510..158c50162340c9 100644 --- a/src/coreclr/scripts/superpmi-replay.py +++ b/src/coreclr/scripts/superpmi-replay.py @@ -92,6 +92,7 @@ def main(main_args): os_name = "win" if platform_name.lower() == "windows" else "unix" arch_name = coreclr_args.arch host_arch_name = "x64" if arch_name.endswith("64") else "x86" + os_name = "universal" if arch_name.startswith("arm") else os_name jit_path = path.join(coreclr_args.jit_directory, 'clrjit_{}_{}_{}.dll'.format(os_name, arch_name, host_arch_name)) print("Running superpmi.py download") From a1b893f557f5690e1847d14282b4a14995d897a0 Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Thu, 16 Sep 2021 16:28:13 -0700 Subject: [PATCH 12/15] Address SuperPMI and initialization feedback --- .../ToolBox/superpmi/mcs/removedup.cpp | 6 +++-- .../ToolBox/superpmi/mcs/verbdumpmap.cpp | 8 +++--- .../ToolBox/superpmi/mcs/verbildump.cpp | 3 ++- .../superpmi/superpmi-shared/agnostic.h | 1 + .../superpmi/superpmi-shared/asmdumper.cpp | 3 ++- .../superpmi-shared/icorjitcompilerimpl.h | 2 ++ .../superpmi-shared/methodcontext.cpp | 25 +++++++++++++------ .../superpmi/superpmi-shared/methodcontext.h | 4 +-- .../icorjitcompiler.cpp | 10 +++++++- .../superpmi-shim-counter/icorjitcompiler.cpp | 5 ++++ .../superpmi-shim-simple/icorjitcompiler.cpp | 5 ++++ .../ToolBox/superpmi/superpmi/jitinstance.cpp | 8 +++--- .../superpmi/superpmi/methodstatsemitter.cpp | 3 ++- .../ToolBox/superpmi/superpmi/neardiffer.cpp | 6 +++-- src/coreclr/inc/corjit.h | 5 ++++ src/coreclr/jit/compiler.cpp | 16 +----------- src/coreclr/jit/ee_il_dll.cpp | 17 +++++++++++++ src/coreclr/jit/ee_il_dll.hpp | 2 ++ .../tools/Common/JitInterface/CorInfoImpl.cs | 15 ++++++++--- .../Common/JitInterface/JitConfigProvider.cs | 2 +- .../tools/aot/jitinterface/jitwrapper.cpp | 5 ++++ src/coreclr/vm/codeman.cpp | 5 ++++ src/coreclr/vm/jitinterface.cpp | 20 +++++++++------ 23 files changed, 125 insertions(+), 51 deletions(-) diff --git a/src/coreclr/ToolBox/superpmi/mcs/removedup.cpp b/src/coreclr/ToolBox/superpmi/mcs/removedup.cpp index fb00c860860ad2..98cd16fc027774 100644 --- a/src/coreclr/ToolBox/superpmi/mcs/removedup.cpp +++ b/src/coreclr/ToolBox/superpmi/mcs/removedup.cpp @@ -61,7 +61,8 @@ bool RemoveDup::unique(MethodContext* mc) CORINFO_METHOD_INFO newInfo; unsigned newFlags = 0; - mc->repCompileMethod(&newInfo, &newFlags); + CORINFO_OS newOs = CORINFO_WINNT; + mc->repCompileMethod(&newInfo, &newFlags, &newOs); // Assume that there are lots of duplicates, so don't allocate a new buffer for the MD5 hash data // until we know we're going to add it to the map. @@ -95,7 +96,8 @@ bool RemoveDup::uniqueLegacy(MethodContext* mc) CORINFO_METHOD_INFO newInfo; unsigned newFlags = 0; - mc->repCompileMethod(&newInfo, &newFlags); + CORINFO_OS newOs = CORINFO_WINNT; + mc->repCompileMethod(&newInfo, &newFlags, &newOs); if (m_inFileLegacy->GetIndex(newInfo.ILCodeSize) == -1) m_inFileLegacy->Add(newInfo.ILCodeSize, new DenseLightWeightMap()); diff --git a/src/coreclr/ToolBox/superpmi/mcs/verbdumpmap.cpp b/src/coreclr/ToolBox/superpmi/mcs/verbdumpmap.cpp index a86b85be14ff43..c612b13f80de6e 100644 --- a/src/coreclr/ToolBox/superpmi/mcs/verbdumpmap.cpp +++ b/src/coreclr/ToolBox/superpmi/mcs/verbdumpmap.cpp @@ -17,15 +17,17 @@ void DumpMapHeader() // printf("process name,"); printf("method name,"); printf("full signature,"); - printf("jit flags\n"); + printf("jit flags,"); + printf("os\n"); } void DumpMap(int index, MethodContext* mc) { CORINFO_METHOD_INFO cmi; unsigned int flags = 0; + CORINFO_OS os; - mc->repCompileMethod(&cmi, &flags); + mc->repCompileMethod(&cmi, &flags, &os); const char* moduleName = nullptr; const char* methodName = mc->repGetMethodName(cmi.ftn, &moduleName); @@ -121,7 +123,7 @@ void DumpMap(int index, MethodContext* mc) } } - printf(", %s\n", SpmiDumpHelper::DumpJitFlags(rawFlags).c_str()); + printf(", %s, %d\n", SpmiDumpHelper::DumpJitFlags(rawFlags).c_str(), (int)os); } int verbDumpMap::DoWork(const char* nameOfInput) diff --git a/src/coreclr/ToolBox/superpmi/mcs/verbildump.cpp b/src/coreclr/ToolBox/superpmi/mcs/verbildump.cpp index fef9292d99dcf1..506d14e587f992 100644 --- a/src/coreclr/ToolBox/superpmi/mcs/verbildump.cpp +++ b/src/coreclr/ToolBox/superpmi/mcs/verbildump.cpp @@ -927,8 +927,9 @@ void DumpIL(MethodContext* mc) { CORINFO_METHOD_INFO cmi; unsigned int flags = 0; + CORINFO_OS os = CORINFO_WINNT; - mc->repCompileMethod(&cmi, &flags); + mc->repCompileMethod(&cmi, &flags, &os); const char* moduleName = nullptr; const char* methodName = mc->repGetMethodName(cmi.ftn, &moduleName); diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/agnostic.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/agnostic.h index e51eb3ef6d049b..fd2a35093c7dec 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/agnostic.h +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/agnostic.h @@ -48,6 +48,7 @@ struct Agnostic_CompileMethod { Agnostic_CORINFO_METHOD_INFO info; DWORD flags; + DWORD os; }; struct Agnostic_InitClass diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/asmdumper.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/asmdumper.cpp index 1a88589e7e55ff..0e22c494559101 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/asmdumper.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/asmdumper.cpp @@ -8,7 +8,8 @@ void ASMDumper::DumpToFile(HANDLE hFile, MethodContext* mc, CompileResult* cr) { CORINFO_METHOD_INFO info; unsigned flags = 0; - mc->repCompileMethod(&info, &flags); + CORINFO_OS os = CORINFO_WINNT; + mc->repCompileMethod(&info, &flags, &os); #define bufflen 4096 DWORD bytesWritten; diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/icorjitcompilerimpl.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/icorjitcompilerimpl.h index 6b7ed4fd8e73d3..a59c55cba06acf 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/icorjitcompilerimpl.h +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/icorjitcompilerimpl.h @@ -47,4 +47,6 @@ void getVersionIdentifier(GUID* versionIdentifier /* OUT */ // intrinsics, so the EE should use the default size (i.e. the size of the IL implementation). unsigned getMaxIntrinsicSIMDVectorLength(CORJIT_FLAGS cpuCompileFlags); /* { return 0; } */ +// Used to specify which OS a JIT should be compiled for. Currently expected to only be called once pre process +void setJitOs(CORINFO_OS os); #endif diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp index 7a92af9a04f812..999ad17a870546 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp @@ -384,11 +384,13 @@ bool MethodContext::Equal(MethodContext* other) // Compare MethodInfo's first. CORINFO_METHOD_INFO otherInfo; unsigned otherFlags = 0; - other->repCompileMethod(&otherInfo, &otherFlags); + CORINFO_OS otherOs = CORINFO_WINNT; + other->repCompileMethod(&otherInfo, &otherFlags, &otherOs); CORINFO_METHOD_INFO ourInfo; unsigned ourFlags = 0; - repCompileMethod(&ourInfo, &ourFlags); + CORINFO_OS ourOs = CORINFO_WINNT; + repCompileMethod(&ourInfo, &ourFlags, &ourOs); if (otherInfo.ILCodeSize != ourInfo.ILCodeSize) return false; @@ -419,6 +421,8 @@ bool MethodContext::Equal(MethodContext* other) return false; if (otherFlags != ourFlags) return false; + if (otherOs != ourOs) + return false; // Now compare the other maps to "estimate" equality. @@ -643,7 +647,7 @@ unsigned int toCorInfoSize(CorInfoType cit) return -1; } -void MethodContext::recCompileMethod(CORINFO_METHOD_INFO* info, unsigned flags) +void MethodContext::recCompileMethod(CORINFO_METHOD_INFO* info, unsigned flags, CORINFO_OS os) { if (CompileMethod == nullptr) CompileMethod = new LightWeightMap(); @@ -662,6 +666,8 @@ void MethodContext::recCompileMethod(CORINFO_METHOD_INFO* info, unsigned flags) value.info.args = SpmiRecordsHelper::StoreAgnostic_CORINFO_SIG_INFO(info->args, CompileMethod, SigInstHandleMap); value.info.locals = SpmiRecordsHelper::StoreAgnostic_CORINFO_SIG_INFO(info->locals, CompileMethod, SigInstHandleMap); + value.os = (DWORD)os; + value.flags = (DWORD)flags; CompileMethod->Add(0, value); @@ -669,14 +675,14 @@ void MethodContext::recCompileMethod(CORINFO_METHOD_INFO* info, unsigned flags) } void MethodContext::dmpCompileMethod(DWORD key, const Agnostic_CompileMethod& value) { - printf("CompileMethod key %u, value ftn-%016llX scp-%016llX ilo-%u ils-%u ms-%u ehc-%u opt-%u rk-%u args-%s locals-%s flg-%08X", + printf("CompileMethod key %u, value ftn-%016llX scp-%016llX ilo-%u ils-%u ms-%u ehc-%u opt-%u rk-%u args-%s locals-%s flg-%08X os-%u", key, value.info.ftn, value.info.scope, value.info.ILCode_offset, value.info.ILCodeSize, value.info.maxStack, value.info.EHcount, value.info.options, value.info.regionKind, SpmiDumpHelper::DumpAgnostic_CORINFO_SIG_INFO(value.info.args, CompileMethod, SigInstHandleMap).c_str(), SpmiDumpHelper::DumpAgnostic_CORINFO_SIG_INFO(value.info.locals, CompileMethod, SigInstHandleMap).c_str(), - value.flags); + value.flags, value.os); } -void MethodContext::repCompileMethod(CORINFO_METHOD_INFO* info, unsigned* flags) +void MethodContext::repCompileMethod(CORINFO_METHOD_INFO* info, unsigned* flags, CORINFO_OS* os) { AssertMapAndKeyExistNoMessage(CompileMethod, 0); @@ -699,6 +705,7 @@ void MethodContext::repCompileMethod(CORINFO_METHOD_INFO* info, unsigned* flags) info->locals = SpmiRecordsHelper::Restore_CORINFO_SIG_INFO(value.info.locals, CompileMethod, SigInstHandleMap); *flags = (unsigned)value.flags; + *os = (CORINFO_OS)value.os; } void MethodContext::recGetMethodClass(CORINFO_METHOD_HANDLE methodHandle, CORINFO_CLASS_HANDLE classHandle) @@ -6850,7 +6857,8 @@ int MethodContext::dumpMethodIdentityInfoToBuffer(char* buff, int len, bool igno } else { - repCompileMethod(&info, &flags); + CORINFO_OS os; + repCompileMethod(&info, &flags, &os); pInfo = &info; } @@ -6984,7 +6992,8 @@ bool MethodContext::hasPgoData(bool& hasEdgeProfile, bool& hasClassProfile, bool // Obtain the Method Info structure for this method CORINFO_METHOD_INFO info; unsigned flags = 0; - repCompileMethod(&info, &flags); + CORINFO_OS os; + repCompileMethod(&info, &flags, &os); if ((GetPgoInstrumentationResults != nullptr) && (GetPgoInstrumentationResults->GetIndex(CastHandle(info.ftn)) != -1)) diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.h index 4abbef3faf135d..f209a4b5d0ad71 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.h +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.h @@ -109,9 +109,9 @@ class MethodContext void dmpEnvironment(DWORD key, const Agnostic_Environment& value); - void recCompileMethod(CORINFO_METHOD_INFO* info, unsigned flags); + void recCompileMethod(CORINFO_METHOD_INFO* info, unsigned flags, CORINFO_OS os); void dmpCompileMethod(DWORD key, const Agnostic_CompileMethod& value); - void repCompileMethod(CORINFO_METHOD_INFO* info, unsigned* flags); + void repCompileMethod(CORINFO_METHOD_INFO* info, unsigned* flags, CORINFO_OS* os); void recGetMethodClass(CORINFO_METHOD_HANDLE methodHandle, CORINFO_CLASS_HANDLE classHandle); void dmpGetMethodClass(DWORDLONG key, DWORDLONG value); diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitcompiler.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitcompiler.cpp index da110199d8621a..bc8756757f1796 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitcompiler.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitcompiler.cpp @@ -10,6 +10,14 @@ #define fatMC // this is nice to have on so ildump works... +CORINFO_OS g_currentOs = CORINFO_WINNT; + +void interceptor_ICJC::setJitOs(CORINFO_OS os) +{ + g_currentOs = os; + original_ICorJitCompiler->setJitOs(os); +} + CorJitResult interceptor_ICJC::compileMethod(ICorJitInfo* comp, /* IN */ struct CORINFO_METHOD_INFO* info, /* IN */ unsigned /* code:CorJitFlag */ flags, /* IN */ @@ -24,7 +32,7 @@ CorJitResult interceptor_ICJC::compileMethod(ICorJitInfo* comp, our_ICorJitInfo.mc = mc; our_ICorJitInfo.mc->cr->recProcessName(GetCommandLineA()); - our_ICorJitInfo.mc->recCompileMethod(info, flags); + our_ICorJitInfo.mc->recCompileMethod(info, flags, g_currentOs); // force some extra data into our tables.. // data probably not needed with RyuJIT, but needed in 4.5 and 4.5.1 to help with catching cached values diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitcompiler.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitcompiler.cpp index 36f262611d9d63..927ba60cb0dbc5 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitcompiler.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitcompiler.cpp @@ -5,6 +5,11 @@ #include "icorjitcompiler.h" #include "icorjitinfo.h" +void interceptor_ICJC::setJitOs(CORINFO_OS os) +{ + original_ICorJitCompiler->setJitOs(os); +} + CorJitResult interceptor_ICJC::compileMethod(ICorJitInfo* comp, /* IN */ struct CORINFO_METHOD_INFO* info, /* IN */ unsigned /* code:CorJitFlag */ flags, /* IN */ diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitcompiler.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitcompiler.cpp index c634843e442896..27e5eb63c45f82 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitcompiler.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitcompiler.cpp @@ -5,6 +5,11 @@ #include "icorjitcompiler.h" #include "icorjitinfo.h" +void interceptor_ICJC::setJitOs(CORINFO_OS os) +{ + original_ICorJitCompiler->setJitOs(os); +} + CorJitResult interceptor_ICJC::compileMethod(ICorJitInfo* comp, /* IN */ struct CORINFO_METHOD_INFO* info, /* IN */ unsigned /* code:CorJitFlag */ flags, /* IN */ diff --git a/src/coreclr/ToolBox/superpmi/superpmi/jitinstance.cpp b/src/coreclr/ToolBox/superpmi/superpmi/jitinstance.cpp index c1264b6c6cf492..9a5c7eea15b97f 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi/jitinstance.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi/jitinstance.cpp @@ -303,14 +303,16 @@ JitInstance::Result JitInstance::CompileMethod(MethodContext* MethodToCompile, i PAL_TRY(Param*, pParam, ¶m) { - uint8_t* NEntryBlock = nullptr; - uint32_t NCodeSizeBlock = 0; + uint8_t* NEntryBlock = nullptr; + uint32_t NCodeSizeBlock = 0; + CORINFO_OS os = CORINFO_WINNT; - pParam->pThis->mc->repCompileMethod(&pParam->info, &pParam->flags); + pParam->pThis->mc->repCompileMethod(&pParam->info, &pParam->flags, &os); if (pParam->collectThroughput) { pParam->pThis->lt.Start(); } + pParam->pThis->pJitInstance->setJitOs(os); CorJitResult jitResult = pParam->pThis->pJitInstance->compileMethod(pParam->pThis->icji, &pParam->info, pParam->flags, &NEntryBlock, &NCodeSizeBlock); if (pParam->collectThroughput) diff --git a/src/coreclr/ToolBox/superpmi/superpmi/methodstatsemitter.cpp b/src/coreclr/ToolBox/superpmi/superpmi/methodstatsemitter.cpp index 51bf5b1fddb8c1..51ecfab64fb464 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi/methodstatsemitter.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi/methodstatsemitter.cpp @@ -60,7 +60,8 @@ void MethodStatsEmitter::Emit(int methodNumber, MethodContext* mc, ULONGLONG fir // Obtain the IL code size for this method CORINFO_METHOD_INFO info; unsigned flags = 0; - mc->repCompileMethod(&info, &flags); + CORINFO_OS os = CORINFO_WINNT; + mc->repCompileMethod(&info, &flags, &os); charCount += sprintf_s(rowData + charCount, _countof(rowData) - charCount, "%d,", info.ILCodeSize); } diff --git a/src/coreclr/ToolBox/superpmi/superpmi/neardiffer.cpp b/src/coreclr/ToolBox/superpmi/superpmi/neardiffer.cpp index cc11b287419d81..b9921e189de285 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi/neardiffer.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi/neardiffer.cpp @@ -930,7 +930,8 @@ bool NearDiffer::compareVars(MethodContext* mc, CompileResult* cr1, CompileResul CORINFO_METHOD_INFO info; unsigned flags = 0; - mc->repCompileMethod(&info, &flags); + CORINFO_OS os = CORINFO_WINNT; + mc->repCompileMethod(&info, &flags, &os); bool set1 = cr1->repSetVars(&ftn_1, &cVars_1, &vars_1); bool set2 = cr2->repSetVars(&ftn_2, &cVars_2, &vars_2); @@ -1003,7 +1004,8 @@ bool NearDiffer::compareBoundaries(MethodContext* mc, CompileResult* cr1, Compil CORINFO_METHOD_INFO info; unsigned flags = 0; - mc->repCompileMethod(&info, &flags); + CORINFO_OS os = CORINFO_WINNT; + mc->repCompileMethod(&info, &flags, &os); bool set1 = cr1->repSetBoundaries(&ftn_1, &cMap_1, &map_1); bool set2 = cr2->repSetBoundaries(&ftn_2, &cMap_2, &map_2); diff --git a/src/coreclr/inc/corjit.h b/src/coreclr/inc/corjit.h index d679c99ce90270..af9d44330f3d79 100644 --- a/src/coreclr/inc/corjit.h +++ b/src/coreclr/inc/corjit.h @@ -211,6 +211,11 @@ class ICorJitCompiler // SIMD vector it supports as an intrinsic type. Zero means that the JIT does not support SIMD // intrinsics, so the EE should use the default size (i.e. the size of the IL implementation). virtual unsigned getMaxIntrinsicSIMDVectorLength(CORJIT_FLAGS cpuCompileFlags) { return 0; } + + // Some JIT's may support multiple OSs. This api provides a means to specify to the JIT what OS it should + // be trying to compile. This api does not produce any errors, any errors are to be generated by the + // the compileMethod call, which will call back into the VM to ensure bits are correctly setup. + virtual void setJitOs(CORINFO_OS os) = 0; }; //------------------------------------------------------------------------------------------ diff --git a/src/coreclr/jit/compiler.cpp b/src/coreclr/jit/compiler.cpp index debc315d209d7a..505a9a319fbd47 100644 --- a/src/coreclr/jit/compiler.cpp +++ b/src/coreclr/jit/compiler.cpp @@ -62,13 +62,6 @@ bool GlobalJitOptions::compFeatureHfa = false; LONG GlobalJitOptions::compUseSoftFPConfigured = 0; #endif // CONFIGURABLE_ARM_ABI -#ifdef TARGET_OS_RUNTIMEDETERMINED -bool TargetOS::OSSettingConfigured = false; -bool TargetOS::IsWindows = false; -bool TargetOS::IsUnix = false; -bool TargetOS::IsMacOS = false; -#endif - /***************************************************************************** * * Little helpers to grab the current cycle counter value; this is done @@ -5523,14 +5516,7 @@ int Compiler::compCompile(CORINFO_MODULE_HANDLE classPtr, CORINFO_EE_INFO* eeInfo = eeGetEEInfo(); #ifdef TARGET_OS_RUNTIMEDETERMINED - if (!TargetOS::OSSettingConfigured) - { - CORINFO_EE_INFO* eeInfo = eeGetEEInfo(); - TargetOS::IsMacOS = eeInfo->osType == CORINFO_MACOS; - TargetOS::IsUnix = (eeInfo->osType == CORINFO_UNIX) || (eeInfo->osType == CORINFO_MACOS); - TargetOS::IsWindows = eeInfo->osType == CORINFO_WINNT; - TargetOS::OSSettingConfigured = true; - } + noway_assert(TargetOS::OSSettingConfigured); #endif if (TargetOS::IsMacOS) diff --git a/src/coreclr/jit/ee_il_dll.cpp b/src/coreclr/jit/ee_il_dll.cpp index a88f222b6f551b..f5b0f40d5ea634 100644 --- a/src/coreclr/jit/ee_il_dll.cpp +++ b/src/coreclr/jit/ee_il_dll.cpp @@ -300,6 +300,23 @@ void CILJit::getVersionIdentifier(GUID* versionIdentifier) memcpy(versionIdentifier, &JITEEVersionIdentifier, sizeof(GUID)); } +#ifdef TARGET_OS_RUNTIMEDETERMINED +bool TargetOS::OSSettingConfigured = false; +bool TargetOS::IsWindows = false; +bool TargetOS::IsUnix = false; +bool TargetOS::IsMacOS = false; +#endif + +void CILJit::setJitOs(CORINFO_OS os) +{ +#ifdef TARGET_OS_RUNTIMEDETERMINED + TargetOS::IsMacOS = os == CORINFO_MACOS; + TargetOS::IsUnix = (os == CORINFO_UNIX) || (os == CORINFO_MACOS); + TargetOS::IsWindows = os == CORINFO_WINNT; + TargetOS::OSSettingConfigured = true; +#endif +} + /***************************************************************************** * Determine the maximum length of SIMD vector supported by this JIT. */ diff --git a/src/coreclr/jit/ee_il_dll.hpp b/src/coreclr/jit/ee_il_dll.hpp index e9dd74e96db833..6965b24e40ecf7 100644 --- a/src/coreclr/jit/ee_il_dll.hpp +++ b/src/coreclr/jit/ee_il_dll.hpp @@ -18,6 +18,8 @@ class CILJit : public ICorJitCompiler ); unsigned getMaxIntrinsicSIMDVectorLength(CORJIT_FLAGS cpuCompileFlags); + + void setJitOs(CORINFO_OS os); }; /***************************************************************************** diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs index 61154e4c6f61d2..835dc7f0f03f85 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs @@ -128,6 +128,9 @@ private extern static CorJitResult JitCompileMethod(out IntPtr exception, [DllImport(JitSupportLibrary)] private extern static IntPtr AllocException([MarshalAs(UnmanagedType.LPWStr)]string message, int messageLength); + [DllImport(JitSupportLibrary)] + private extern static void JitSetOs(IntPtr jit, CORINFO_OS os); + private IntPtr AllocException(Exception ex) { _lastException = ExceptionDispatchInfo.Capture(ex); @@ -148,9 +151,10 @@ private IntPtr AllocException(Exception ex) [DllImport(JitSupportLibrary)] private extern static char* GetExceptionMessage(IntPtr obj); - public static void Startup() + public static void Startup(CORINFO_OS os) { jitStartup(GetJitHost(JitConfigProvider.Instance.UnmanagedInstance)); + JitSetOs(JitPointerAccessor.Get(), os); } public CorInfoImpl() @@ -2897,6 +2901,12 @@ private void ThrowExceptionForJitResult(HRESULT result) private void ThrowExceptionForHelper(ref CORINFO_HELPER_DESC throwHelper) { throw new NotImplementedException("ThrowExceptionForHelper"); } + public static CORINFO_OS TargetToOs(TargetDetails target) + { + return target.IsWindows ? CORINFO_OS.CORINFO_WINNT : + target.IsOSX ? CORINFO_OS.CORINFO_MACOS : CORINFO_OS.CORINFO_UNIX; + } + private void getEEInfo(ref CORINFO_EE_INFO pEEInfoOut) { pEEInfoOut = new CORINFO_EE_INFO(); @@ -2923,8 +2933,7 @@ private void getEEInfo(ref CORINFO_EE_INFO pEEInfoOut) new UIntPtr(32 * 1024 - 1) : new UIntPtr((uint)pEEInfoOut.osPageSize / 2 - 1); pEEInfoOut.targetAbi = TargetABI; - pEEInfoOut.osType = _compilation.NodeFactory.Target.IsWindows ? CORINFO_OS.CORINFO_WINNT : - _compilation.NodeFactory.Target.IsOSX ? CORINFO_OS.CORINFO_MACOS : CORINFO_OS.CORINFO_UNIX; + pEEInfoOut.osType = TargetToOs(_compilation.NodeFactory.Target); } private char* getJitTimeLogFilename() diff --git a/src/coreclr/tools/Common/JitInterface/JitConfigProvider.cs b/src/coreclr/tools/Common/JitInterface/JitConfigProvider.cs index 78039b39828590..0fad745ec6701e 100644 --- a/src/coreclr/tools/Common/JitInterface/JitConfigProvider.cs +++ b/src/coreclr/tools/Common/JitInterface/JitConfigProvider.cs @@ -62,7 +62,7 @@ public static void Initialize( return libHandle; }); - CorInfoImpl.Startup(); + CorInfoImpl.Startup(CorInfoImpl.TargetToOs(target)); } public IntPtr UnmanagedInstance diff --git a/src/coreclr/tools/aot/jitinterface/jitwrapper.cpp b/src/coreclr/tools/aot/jitinterface/jitwrapper.cpp index 5f611ccc705a91..4951bcfa3a2c89 100644 --- a/src/coreclr/tools/aot/jitinterface/jitwrapper.cpp +++ b/src/coreclr/tools/aot/jitinterface/jitwrapper.cpp @@ -43,6 +43,11 @@ DLL_EXPORT int JitCompileMethod( return 1; } +DLL_EXPORT void JitSetOs(ICorJitCompiler* pJit, CORINFO_OS os) +{ + pJit->setJitOs(os); +} + DLL_EXPORT void JitProcessShutdownWork(ICorJitCompiler * pJit) { return pJit->ProcessShutdownWork(nullptr); diff --git a/src/coreclr/vm/codeman.cpp b/src/coreclr/vm/codeman.cpp index 4e8117c7b7c6f6..c52e3094c30c7a 100644 --- a/src/coreclr/vm/codeman.cpp +++ b/src/coreclr/vm/codeman.cpp @@ -1566,6 +1566,8 @@ static bool ValidateJitName(LPCWSTR pwzJitName) return true; } +CORINFO_OS getClrVmOs(); + // LoadAndInitializeJIT: load the JIT dll into the process, and initialize it (call the UtilCode initialization function, // check the JIT-EE interface GUID, etc.) // @@ -1673,6 +1675,9 @@ static void LoadAndInitializeJIT(LPCWSTR pwzJitName, OUT HINSTANCE* phJit, OUT I { pJitLoadData->jld_status = JIT_LOAD_STATUS_DONE_VERSION_CHECK; + // Specify to the JIT that it is working with the OS that we are compiled against + pICorJitCompiler->setJitOs(getClrVmOs()); + // The JIT has loaded and passed the version identifier test, so publish the JIT interface to the caller. *ppICorJitCompiler = pICorJitCompiler; diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 7c0793ca00abb5..ec5c987bdb6a9c 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -9911,6 +9911,17 @@ void InlinedCallFrame::GetEEInfo(CORINFO_EE_INFO::InlinedCallFrameInfo *pInfo) #endif // TARGET_ARM } +CORINFO_OS getClrVmOs() +{ +#ifdef TARGET_OSX + return CORINFO_MACOS; +#elif defined(TARGET_UNIX) + return CORINFO_UNIX; +#else + return CORINFO_WINNT; +#endif +} + /*********************************************************************/ // Return details about EE internal data structures void CEEInfo::getEEInfo(CORINFO_EE_INFO *pEEInfoOut) @@ -9956,14 +9967,7 @@ void CEEInfo::getEEInfo(CORINFO_EE_INFO *pEEInfoOut) pEEInfoOut->osPageSize = GetOsPageSize(); pEEInfoOut->maxUncheckedOffsetForNullObject = MAX_UNCHECKED_OFFSET_FOR_NULL_OBJECT; pEEInfoOut->targetAbi = CORINFO_CORECLR_ABI; - -#ifdef TARGET_OSX - pEEInfoOut->osType = CORINFO_MACOS; -#elif defined(TARGET_UNIX) - pEEInfoOut->osType = CORINFO_UNIX; -#else - pEEInfoOut->osType = CORINFO_WINNT; -#endif + pEEInfoOut->osType = getClrVmOs(); EE_TO_JIT_TRANSITION(); } From 255c1f856795089fbd71460ed950aff702926be5 Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Tue, 21 Sep 2021 17:32:37 -0700 Subject: [PATCH 13/15] Code review details from Bruce and Kunal --- .../superpmi/superpmi-shared/icorjitcompilerimpl.h | 10 +++++++--- .../superpmi-shim-collector/icorjitcompiler.cpp | 10 ++++------ .../superpmi/superpmi-shim-collector/icorjitcompiler.h | 1 + .../superpmi-shim-collector.cpp | 10 ++++++++++ .../superpmi/superpmi-shim-counter/icorjitcompiler.cpp | 4 ++-- .../superpmi/superpmi-shim-simple/icorjitcompiler.cpp | 4 ++-- src/coreclr/ToolBox/superpmi/superpmi/jitinstance.cpp | 2 +- src/coreclr/inc/corjit.h | 5 ++++- src/coreclr/jit/codegencommon.cpp | 4 ++++ src/coreclr/jit/ee_il_dll.cpp | 6 +++++- src/coreclr/jit/ee_il_dll.hpp | 2 +- src/coreclr/jit/jit.h | 3 +-- src/coreclr/scripts/jitrollingbuild.py | 4 ++-- src/coreclr/scripts/superpmi.py | 2 +- src/coreclr/scripts/superpmi_replay_setup.py | 2 +- src/coreclr/tools/aot/jitinterface/jitwrapper.cpp | 2 +- src/coreclr/vm/codeman.cpp | 2 +- 17 files changed, 48 insertions(+), 25 deletions(-) diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/icorjitcompilerimpl.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/icorjitcompilerimpl.h index a59c55cba06acf..49cfb3b7a1482f 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/icorjitcompilerimpl.h +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/icorjitcompilerimpl.h @@ -24,7 +24,7 @@ // * In the 32 bit jit this is implemented by code:CILJit.compileMethod // * For the 64 bit jit this is implemented by code:PreJit.compileMethod // -// Note: Obfuscators that are hacking the JIT depend on this method having __stdcall calling convention +// Note: setTargetOS must be called before this api is used. CorJitResult compileMethod(ICorJitInfo* comp, /* IN */ struct CORINFO_METHOD_INFO* info, /* IN */ unsigned /* code:CorJitFlag */ flags, /* IN */ @@ -47,6 +47,10 @@ void getVersionIdentifier(GUID* versionIdentifier /* OUT */ // intrinsics, so the EE should use the default size (i.e. the size of the IL implementation). unsigned getMaxIntrinsicSIMDVectorLength(CORJIT_FLAGS cpuCompileFlags); /* { return 0; } */ -// Used to specify which OS a JIT should be compiled for. Currently expected to only be called once pre process -void setJitOs(CORINFO_OS os); +// Some JIT's may support multiple OSs. This api provides a means to specify to the JIT what OS it should +// be trying to compile. This api does not produce any errors, any errors are to be generated by the +// the compileMethod call, which will call back into the VM to ensure bits are correctly setup. +// +// Note: this api MUST be called before the compileMethod is called for the first time in the process. +void setTargetOS(CORINFO_OS os); #endif diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitcompiler.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitcompiler.cpp index bc8756757f1796..0b0a22476c3bde 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitcompiler.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitcompiler.cpp @@ -10,12 +10,10 @@ #define fatMC // this is nice to have on so ildump works... -CORINFO_OS g_currentOs = CORINFO_WINNT; - -void interceptor_ICJC::setJitOs(CORINFO_OS os) +void interceptor_ICJC::setTargetOS(CORINFO_OS os) { - g_currentOs = os; - original_ICorJitCompiler->setJitOs(os); + currentOs = os; + original_ICorJitCompiler->setTargetOS(os); } CorJitResult interceptor_ICJC::compileMethod(ICorJitInfo* comp, /* IN */ @@ -32,7 +30,7 @@ CorJitResult interceptor_ICJC::compileMethod(ICorJitInfo* comp, our_ICorJitInfo.mc = mc; our_ICorJitInfo.mc->cr->recProcessName(GetCommandLineA()); - our_ICorJitInfo.mc->recCompileMethod(info, flags, g_currentOs); + our_ICorJitInfo.mc->recCompileMethod(info, flags, currentOs); // force some extra data into our tables.. // data probably not needed with RyuJIT, but needed in 4.5 and 4.5.1 to help with catching cached values diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitcompiler.h b/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitcompiler.h index 687f75a2f2d31a..3a711bd0765951 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitcompiler.h +++ b/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/icorjitcompiler.h @@ -15,6 +15,7 @@ class interceptor_ICJC : public ICorJitCompiler // Added to help us track the original icjc and be able to easily indirect to it. ICorJitCompiler* original_ICorJitCompiler; HANDLE hFile; + CORINFO_OS currentOs; }; #endif diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/superpmi-shim-collector.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/superpmi-shim-collector.cpp index 9cd22007107534..70bbb071229769 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/superpmi-shim-collector.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shim-collector/superpmi-shim-collector.cpp @@ -193,6 +193,16 @@ extern "C" DLLEXPORT ICorJitCompiler* getJit() pJitInstance = new interceptor_ICJC(); pJitInstance->original_ICorJitCompiler = tICJI; +#ifdef TARGET_WINDOWS + pJitInstance->currentOs = CORINFO_WINNT; +#elif defined(TARGET_OSX) + pJitInstance->currentOs = CORINFO_MACOS; +#elif defined(TARGET_UNIX) + pJitInstance->currentOs = CORINFO_UNIX; +#else +#error No target os defined +#endif + // create our datafile pJitInstance->hFile = CreateFileW(g_dataFileName, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitcompiler.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitcompiler.cpp index 927ba60cb0dbc5..1f1f1d210ef6e1 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitcompiler.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shim-counter/icorjitcompiler.cpp @@ -5,9 +5,9 @@ #include "icorjitcompiler.h" #include "icorjitinfo.h" -void interceptor_ICJC::setJitOs(CORINFO_OS os) +void interceptor_ICJC::setTargetOS(CORINFO_OS os) { - original_ICorJitCompiler->setJitOs(os); + original_ICorJitCompiler->setTargetOS(os); } CorJitResult interceptor_ICJC::compileMethod(ICorJitInfo* comp, /* IN */ diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitcompiler.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitcompiler.cpp index 27e5eb63c45f82..53442ced042e17 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitcompiler.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shim-simple/icorjitcompiler.cpp @@ -5,9 +5,9 @@ #include "icorjitcompiler.h" #include "icorjitinfo.h" -void interceptor_ICJC::setJitOs(CORINFO_OS os) +void interceptor_ICJC::setTargetOS(CORINFO_OS os) { - original_ICorJitCompiler->setJitOs(os); + original_ICorJitCompiler->setTargetOS(os); } CorJitResult interceptor_ICJC::compileMethod(ICorJitInfo* comp, /* IN */ diff --git a/src/coreclr/ToolBox/superpmi/superpmi/jitinstance.cpp b/src/coreclr/ToolBox/superpmi/superpmi/jitinstance.cpp index 9a5c7eea15b97f..fafc367669d47c 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi/jitinstance.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi/jitinstance.cpp @@ -312,7 +312,7 @@ JitInstance::Result JitInstance::CompileMethod(MethodContext* MethodToCompile, i { pParam->pThis->lt.Start(); } - pParam->pThis->pJitInstance->setJitOs(os); + pParam->pThis->pJitInstance->setTargetOS(os); CorJitResult jitResult = pParam->pThis->pJitInstance->compileMethod(pParam->pThis->icji, &pParam->info, pParam->flags, &NEntryBlock, &NCodeSizeBlock); if (pParam->collectThroughput) diff --git a/src/coreclr/inc/corjit.h b/src/coreclr/inc/corjit.h index af9d44330f3d79..122fcd0d7b0ba2 100644 --- a/src/coreclr/inc/corjit.h +++ b/src/coreclr/inc/corjit.h @@ -188,6 +188,7 @@ class ICorJitCompiler // // * In the 32 bit jit this is implemented by code:CILJit.compileMethod // * For the 64 bit jit this is implemented by code:PreJit.compileMethod + // Note: setTargetOS must be called before this api is used. virtual CorJitResult compileMethod ( ICorJitInfo *comp, /* IN */ struct CORINFO_METHOD_INFO *info, /* IN */ @@ -215,7 +216,9 @@ class ICorJitCompiler // Some JIT's may support multiple OSs. This api provides a means to specify to the JIT what OS it should // be trying to compile. This api does not produce any errors, any errors are to be generated by the // the compileMethod call, which will call back into the VM to ensure bits are correctly setup. - virtual void setJitOs(CORINFO_OS os) = 0; + // + // Note: this api MUST be called before the compileMethod is called for the first time in the process. + virtual void setTargetOS(CORINFO_OS os) = 0; }; //------------------------------------------------------------------------------------------ diff --git a/src/coreclr/jit/codegencommon.cpp b/src/coreclr/jit/codegencommon.cpp index 789642d95df988..83a3ac8f2ffbeb 100644 --- a/src/coreclr/jit/codegencommon.cpp +++ b/src/coreclr/jit/codegencommon.cpp @@ -2185,6 +2185,10 @@ void CodeGen::genGenerateMachineCode() { printf(" - Windows"); } + else if (TargetOS::IsMacOS) + { + printf(" - MacOS"); + } else if (TargetOS::IsUnix) { printf(" - Unix"); diff --git a/src/coreclr/jit/ee_il_dll.cpp b/src/coreclr/jit/ee_il_dll.cpp index f5b0f40d5ea634..097d20debbbb95 100644 --- a/src/coreclr/jit/ee_il_dll.cpp +++ b/src/coreclr/jit/ee_il_dll.cpp @@ -307,7 +307,11 @@ bool TargetOS::IsUnix = false; bool TargetOS::IsMacOS = false; #endif -void CILJit::setJitOs(CORINFO_OS os) +/***************************************************************************** + * Set the OS that this JIT should be generating code for. The contract with the VM + * is that this must be called before compileMethod is called. + */ +void CILJit::setTargetOS(CORINFO_OS os) { #ifdef TARGET_OS_RUNTIMEDETERMINED TargetOS::IsMacOS = os == CORINFO_MACOS; diff --git a/src/coreclr/jit/ee_il_dll.hpp b/src/coreclr/jit/ee_il_dll.hpp index 6965b24e40ecf7..bc6503bc4f8bbb 100644 --- a/src/coreclr/jit/ee_il_dll.hpp +++ b/src/coreclr/jit/ee_il_dll.hpp @@ -19,7 +19,7 @@ class CILJit : public ICorJitCompiler unsigned getMaxIntrinsicSIMDVectorLength(CORJIT_FLAGS cpuCompileFlags); - void setJitOs(CORINFO_OS os); + void setTargetOS(CORINFO_OS os); }; /***************************************************************************** diff --git a/src/coreclr/jit/jit.h b/src/coreclr/jit/jit.h index 72a18b88a70ba1..ab7924240de129 100644 --- a/src/coreclr/jit/jit.h +++ b/src/coreclr/jit/jit.h @@ -6,8 +6,6 @@ #define _JIT_H_ /*****************************************************************************/ -#include "targetosarch.h" - // // clr.sln only defines _DEBUG // The jit uses DEBUG rather than _DEBUG @@ -185,6 +183,7 @@ #include "utilcode.h" // this defines assert as _ASSERTE #include "host.h" // this redefines assert for the JIT to use assertAbort #include "utils.h" +#include "targetosarch.h" #ifdef DEBUG #define INDEBUG(x) x diff --git a/src/coreclr/scripts/jitrollingbuild.py b/src/coreclr/scripts/jitrollingbuild.py index c5bf6d065b590e..0003805b49960d 100644 --- a/src/coreclr/scripts/jitrollingbuild.py +++ b/src/coreclr/scripts/jitrollingbuild.py @@ -309,8 +309,8 @@ def upload_blob(file, blob_name): # Next, look for any and all cross-compilation JITs. These are named, e.g.: # clrjit_unix_x64_x64.dll - # clrjit_win_arm_x64.dll - # clrjit_win_arm64_x64.dll + # clrjit_universal_arm_x64.dll + # clrjit_universal_arm64_x64.dll # and so on, and live in the same product directory as the primary JIT. # # Note that the expression below explicitly filters out the primary JIT since we added that above. diff --git a/src/coreclr/scripts/superpmi.py b/src/coreclr/scripts/superpmi.py index c43592897e7a06..dd69e1cd7c75e3 100755 --- a/src/coreclr/scripts/superpmi.py +++ b/src/coreclr/scripts/superpmi.py @@ -254,7 +254,7 @@ superpmi_common_parser.add_argument("--skip_cleanup", action="store_true", help=skip_cleanup_help) superpmi_common_parser.add_argument("--sequential", action="store_true", help="Run SuperPMI in sequential mode. Default is to run in parallel for faster runs.") superpmi_common_parser.add_argument("-spmi_log_file", help=spmi_log_file_help) -superpmi_common_parser.add_argument("-jit_name", help="Specify the filename of the jit to use, e.g., 'clrjit_win_arm64_x64.dll'. Default is clrjit.dll/libclrjit.so") +superpmi_common_parser.add_argument("-jit_name", help="Specify the filename of the jit to use, e.g., 'clrjit_universal_arm64_x64.dll'. Default is clrjit.dll/libclrjit.so") superpmi_common_parser.add_argument("--altjit", action="store_true", help="Set the altjit variables on replay.") superpmi_common_parser.add_argument("-error_limit", help=error_limit_help) diff --git a/src/coreclr/scripts/superpmi_replay_setup.py b/src/coreclr/scripts/superpmi_replay_setup.py index 34cc8301fc5fd4..c6c6fcb507f892 100644 --- a/src/coreclr/scripts/superpmi_replay_setup.py +++ b/src/coreclr/scripts/superpmi_replay_setup.py @@ -94,7 +94,7 @@ def match_correlation_files(full_path): file_name = os.path.basename(full_path) if file_name.startswith("clrjit_") and file_name.endswith(".dll") and file_name.find( - "osx") == -1 and file_name.find("armel") == -1: + "osx") == -1: return True if file_name == "superpmi.exe" or file_name == "mcs.exe": diff --git a/src/coreclr/tools/aot/jitinterface/jitwrapper.cpp b/src/coreclr/tools/aot/jitinterface/jitwrapper.cpp index 4951bcfa3a2c89..cbacd3c190d5ed 100644 --- a/src/coreclr/tools/aot/jitinterface/jitwrapper.cpp +++ b/src/coreclr/tools/aot/jitinterface/jitwrapper.cpp @@ -45,7 +45,7 @@ DLL_EXPORT int JitCompileMethod( DLL_EXPORT void JitSetOs(ICorJitCompiler* pJit, CORINFO_OS os) { - pJit->setJitOs(os); + pJit->setTargetOS(os); } DLL_EXPORT void JitProcessShutdownWork(ICorJitCompiler * pJit) diff --git a/src/coreclr/vm/codeman.cpp b/src/coreclr/vm/codeman.cpp index c52e3094c30c7a..f95419134084bc 100644 --- a/src/coreclr/vm/codeman.cpp +++ b/src/coreclr/vm/codeman.cpp @@ -1676,7 +1676,7 @@ static void LoadAndInitializeJIT(LPCWSTR pwzJitName, OUT HINSTANCE* phJit, OUT I pJitLoadData->jld_status = JIT_LOAD_STATUS_DONE_VERSION_CHECK; // Specify to the JIT that it is working with the OS that we are compiled against - pICorJitCompiler->setJitOs(getClrVmOs()); + pICorJitCompiler->setTargetOS(getClrVmOs()); // The JIT has loaded and passed the version identifier test, so publish the JIT interface to the caller. *ppICorJitCompiler = pICorJitCompiler; From 5bfd6ca59dda3a39d6ee0f7dfed415023db5f3c5 Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Wed, 22 Sep 2021 11:49:25 -0700 Subject: [PATCH 14/15] Update formatting --- src/coreclr/jit/codegenarmarch.cpp | 4 ++-- src/coreclr/jit/compiler.cpp | 8 +++++--- src/coreclr/jit/compiler.h | 7 +++++-- src/coreclr/jit/compiler.hpp | 4 +--- src/coreclr/jit/gentree.cpp | 4 ++-- src/coreclr/jit/importer.cpp | 5 ++--- src/coreclr/jit/lclvars.cpp | 8 ++++---- src/coreclr/jit/lower.cpp | 6 +++--- src/coreclr/jit/morph.cpp | 12 ++++++------ src/coreclr/jit/target.h | 21 ++++++++++++++++----- src/coreclr/jit/unwind.cpp | 3 ++- src/coreclr/jit/utils.cpp | 4 ++-- 12 files changed, 50 insertions(+), 36 deletions(-) diff --git a/src/coreclr/jit/codegenarmarch.cpp b/src/coreclr/jit/codegenarmarch.cpp index 9203383acc2f6f..3a833623b7b78b 100644 --- a/src/coreclr/jit/codegenarmarch.cpp +++ b/src/coreclr/jit/codegenarmarch.cpp @@ -679,9 +679,9 @@ void CodeGen::genIntrinsic(GenTree* treeNode) void CodeGen::genPutArgStk(GenTreePutArgStk* treeNode) { assert(treeNode->OperIs(GT_PUTARG_STK)); - GenTree* source = treeNode->gtOp1; + GenTree* source = treeNode->gtOp1; var_types targetType; - + if (!compMacOsArm64Abi()) { targetType = genActualType(source->TypeGet()); diff --git a/src/coreclr/jit/compiler.cpp b/src/coreclr/jit/compiler.cpp index 505a9a319fbd47..2c59a46836ed59 100644 --- a/src/coreclr/jit/compiler.cpp +++ b/src/coreclr/jit/compiler.cpp @@ -1025,7 +1025,8 @@ var_types Compiler::getReturnTypeForStruct(CORINFO_CLASS_HANDLE clsHnd, useType = TYP_UNKNOWN; } #endif - if (TargetOS::IsWindows && !TargetArchitecture::IsArm32 && callConvIsInstanceMethodCallConv(callConv) && !isNativePrimitiveStructType(clsHnd)) + if (TargetOS::IsWindows && !TargetArchitecture::IsArm32 && callConvIsInstanceMethodCallConv(callConv) && + !isNativePrimitiveStructType(clsHnd)) { canReturnInRegister = false; howToReturnStruct = SPK_ByReference; @@ -5528,7 +5529,8 @@ int Compiler::compCompile(CORINFO_MODULE_HANDLE classPtr, if (TargetArchitecture::IsX64) { // MacOS x64 uses the Unix jit variant in crossgen2, not a special jit - info.compMatchedVM = info.compMatchedVM && ((eeInfo->osType == CORINFO_UNIX) || (eeInfo->osType == CORINFO_MACOS)); + info.compMatchedVM = + info.compMatchedVM && ((eeInfo->osType == CORINFO_UNIX) || (eeInfo->osType == CORINFO_MACOS)); } else { @@ -5537,7 +5539,7 @@ int Compiler::compCompile(CORINFO_MODULE_HANDLE classPtr, } else if (TargetOS::IsWindows) { - info.compMatchedVM = info.compMatchedVM && (eeInfo->osType == CORINFO_WINNT); + info.compMatchedVM = info.compMatchedVM && (eeInfo->osType == CORINFO_WINNT); } // If we are not compiling for a matched VM, then we are getting JIT flags that don't match our target diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index ef9bdeba0422d8..3f339e65c1700f 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -11821,8 +11821,11 @@ const instruction INS_SQRT = INS_vsqrt; #ifdef TARGET_ARM64 -const instruction INS_MULADD = INS_madd; -inline const instruction INS_BREAKPOINT_osHelper() { return TargetOS::IsUnix ? INS_brk : INS_bkpt; } +const instruction INS_MULADD = INS_madd; +inline const instruction INS_BREAKPOINT_osHelper() +{ + return TargetOS::IsUnix ? INS_brk : INS_bkpt; +} #define INS_BREAKPOINT INS_BREAKPOINT_osHelper() const instruction INS_ABS = INS_fabs; diff --git a/src/coreclr/jit/compiler.hpp b/src/coreclr/jit/compiler.hpp index 18cb2cbd216294..f2a6f255dec447 100644 --- a/src/coreclr/jit/compiler.hpp +++ b/src/coreclr/jit/compiler.hpp @@ -2362,9 +2362,7 @@ inline unsigned Compiler::compMapILargNum(unsigned ILargNum) inline var_types Compiler::mangleVarArgsType(var_types type) { #if defined(TARGET_ARMARCH) - if (opts.compUseSoftFP - || (TargetOS::IsWindows && info.compIsVarArgs) - ) + if (opts.compUseSoftFP || (TargetOS::IsWindows && info.compIsVarArgs)) { switch (type) { diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index dd55f6f2b79a6b..08a4768d3051d5 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -11809,7 +11809,7 @@ void Compiler::gtDispTree(GenTree* tree, else { printf(" (%d slots), (%d stackByteSize), (%d slot), (%d byteOffset)", putArg->gtNumSlots, - putArg->GetStackByteSize(), putArg->gtSlotNum, putArg->getArgOffset()); + putArg->GetStackByteSize(), putArg->gtSlotNum, putArg->getArgOffset()); } #endif if (putArg->gtPutArgStkKind != GenTreePutArgStk::Kind::Invalid) @@ -11847,7 +11847,7 @@ void Compiler::gtDispTree(GenTree* tree, else { printf(" (%d slots), (%d stackByteSize), (%d numRegs)", putArg->gtNumSlots, putArg->GetStackByteSize(), - putArg->gtNumRegs); + putArg->gtNumRegs); } #endif } diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 1ea613eb762e79..abe8834ac9410d 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -8770,9 +8770,8 @@ var_types Compiler::impImportCall(OPCODE opcode, actualMethodRetTypeSigClass = sig->retTypeSigClass; /* Check for varargs */ - if (!compFeatureVarArg() && - ((sig->callConv & CORINFO_CALLCONV_MASK) == CORINFO_CALLCONV_VARARG || - (sig->callConv & CORINFO_CALLCONV_MASK) == CORINFO_CALLCONV_NATIVEVARARG)) + if (!compFeatureVarArg() && ((sig->callConv & CORINFO_CALLCONV_MASK) == CORINFO_CALLCONV_VARARG || + (sig->callConv & CORINFO_CALLCONV_MASK) == CORINFO_CALLCONV_NATIVEVARARG)) { BADCODE("Varargs not supported."); } diff --git a/src/coreclr/jit/lclvars.cpp b/src/coreclr/jit/lclvars.cpp index 6d6c645bfb06ff..cfc46d35e74755 100644 --- a/src/coreclr/jit/lclvars.cpp +++ b/src/coreclr/jit/lclvars.cpp @@ -5630,7 +5630,7 @@ void Compiler::lvaAssignVirtualFrameOffsetsToArgs() } lclNum += argLcls; -#else // !TARGET_ARM +#else // !TARGET_ARM for (unsigned i = 0; i < argSigLen; i++) { unsigned argumentSize = eeGetArgSize(argLst, &info.compMethodInfo->args); @@ -5806,8 +5806,8 @@ int Compiler::lvaAssignVirtualFrameOffsetToArg(unsigned lclNum, varDsc->SetStackOffset(argOffs); argOffs += TARGET_POINTER_SIZE; #elif defined(TARGET_ARM64) -// Register arguments on ARM64 only take stack space when they have a frame home. -// Unless on windows and in a vararg method. + // Register arguments on ARM64 only take stack space when they have a frame home. + // Unless on windows and in a vararg method. if (compFeatureArgSplit() && this->info.compIsVarArgs) { if (varDsc->lvType == TYP_STRUCT && varDsc->GetOtherArgReg() >= MAX_REG_ARG && @@ -6017,7 +6017,7 @@ int Compiler::lvaAssignVirtualFrameOffsetToArg(unsigned lclNum, const unsigned argAlignment = eeGetArgAlignment(varDsc->lvType, isFloatHfa); if (compMacOsArm64Abi()) { - argOffs = roundUp(argOffs, argAlignment); + argOffs = roundUp(argOffs, argAlignment); } assert((argSize % argAlignment) == 0); diff --git a/src/coreclr/jit/lower.cpp b/src/coreclr/jit/lower.cpp index 329b5d48e1d4ef..ed9ee4f7284052 100644 --- a/src/coreclr/jit/lower.cpp +++ b/src/coreclr/jit/lower.cpp @@ -1942,7 +1942,7 @@ void Lowering::LowerFastTailCall(GenTreeCall* call) unsigned int overwrittenStart = put->getArgOffset(); unsigned int overwrittenEnd = overwrittenStart + put->GetStackByteSize(); - int baseOff = -1; // Stack offset of first arg on stack + int baseOff = -1; // Stack offset of first arg on stack for (unsigned callerArgLclNum = 0; callerArgLclNum < comp->info.compArgsCount; callerArgLclNum++) { @@ -2555,8 +2555,8 @@ GenTree* Lowering::OptimizeConstCompare(GenTree* cmp) op2->SetIconValue(0xff); op2->gtType = castOp->gtType; #else - castOp->gtType = castToType; - op2->gtType = castToType; + castOp->gtType = castToType; + op2->gtType = castToType; #endif // If we have any contained memory ops on castOp, they must now not be contained. if (castOp->OperIsLogical()) diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index 1cc926f148a123..ddd9dbfb698665 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -3086,7 +3086,7 @@ void Compiler::fgInitArgInfo(GenTreeCall* call) var_types hfaType = TYP_UNDEF; unsigned hfaSlots = 0; - bool passUsingFloatRegs; + bool passUsingFloatRegs; unsigned argAlignBytes = TARGET_POINTER_SIZE; unsigned size = 0; unsigned byteSize = 0; @@ -3439,7 +3439,7 @@ void Compiler::fgInitArgInfo(GenTreeCall* call) } } } -#else // not TARGET_ARM or TARGET_ARM64 +#else // not TARGET_ARM or TARGET_ARM64 #if defined(UNIX_AMD64_ABI) @@ -4294,14 +4294,14 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* call) if (!compMacOsArm64Abi()) { printf("argSlots=%d, preallocatedArgCount=%d, nextSlotNum=%d, nextSlotByteOffset=%d, " - "outgoingArgSpaceSize=%d\n", - argSlots, preallocatedArgCount, argInfo->GetNextSlotNum(), argInfo->GetNextSlotByteOffset(), - outgoingArgSpaceSize); + "outgoingArgSpaceSize=%d\n", + argSlots, preallocatedArgCount, argInfo->GetNextSlotNum(), argInfo->GetNextSlotByteOffset(), + outgoingArgSpaceSize); } else { printf("nextSlotByteOffset=%d, outgoingArgSpaceSize=%d\n", argInfo->GetNextSlotByteOffset(), - outgoingArgSpaceSize); + outgoingArgSpaceSize); } #else printf("nextSlotByteOffset=%d, outgoingArgSpaceSize=%d\n", argInfo->GetNextSlotByteOffset(), diff --git a/src/coreclr/jit/target.h b/src/coreclr/jit/target.h index 278ffbb2b3fe4e..7e823f7f4bd7d2 100644 --- a/src/coreclr/jit/target.h +++ b/src/coreclr/jit/target.h @@ -23,11 +23,19 @@ #undef TARGET_WINDOWS #endif - // Native Varargs are not supported on Unix (all architectures) and Windows ARM -inline bool compFeatureVarArg() { return TargetOS::IsWindows && !TargetArchitecture::IsArm32; } -inline bool compMacOsArm64Abi() { return TargetArchitecture::IsArm64 && TargetOS::IsMacOS; } -inline bool compFeatureArgSplit() { return TargetArchitecture::IsArm32 || (TargetOS::IsWindows && TargetArchitecture::IsArm64); } +inline bool compFeatureVarArg() +{ + return TargetOS::IsWindows && !TargetArchitecture::IsArm32; +} +inline bool compMacOsArm64Abi() +{ + return TargetArchitecture::IsArm64 && TargetOS::IsMacOS; +} +inline bool compFeatureArgSplit() +{ + return TargetArchitecture::IsArm32 || (TargetOS::IsWindows && TargetArchitecture::IsArm64); +} /*****************************************************************************/ // The following are human readable names for the target architectures @@ -285,7 +293,10 @@ class Target { public: static const char* g_tgtCPUName; - static const char* g_tgtPlatformName() { return TargetOS::IsWindows ? "Windows" : "Unix"; }; + static const char* g_tgtPlatformName() + { + return TargetOS::IsWindows ? "Windows" : "Unix"; + }; enum ArgOrder { diff --git a/src/coreclr/jit/unwind.cpp b/src/coreclr/jit/unwind.cpp index d82bb821abafe6..8d5efd0051906d 100644 --- a/src/coreclr/jit/unwind.cpp +++ b/src/coreclr/jit/unwind.cpp @@ -411,7 +411,8 @@ UNATIVE_OFFSET Compiler::unwindGetCurrentOffset(FuncInfoDsc* func) } else { - if (TargetArchitecture::IsX64 || (TargetOS::IsUnix && (TargetArchitecture::IsArmArch || TargetArchitecture::IsX86))) + if (TargetArchitecture::IsX64 || + (TargetOS::IsUnix && (TargetArchitecture::IsArmArch || TargetArchitecture::IsX86))) { assert(func->startLoc != nullptr); offset = func->startLoc->GetFuncletPrologOffset(GetEmitter()); diff --git a/src/coreclr/jit/utils.cpp b/src/coreclr/jit/utils.cpp index b7df83b0e14744..673ee0c8c4176a 100644 --- a/src/coreclr/jit/utils.cpp +++ b/src/coreclr/jit/utils.cpp @@ -1914,7 +1914,7 @@ double FloatingPointUtils::convertUInt64ToDouble(unsigned __int64 uIntVal) uint64_t adjHex = 0x43F0000000000000UL; d = (double)s64 + *(double*)&adjHex; #else - d = (double)uIntVal; + d = (double)uIntVal; #endif } else @@ -1962,7 +1962,7 @@ unsigned __int64 FloatingPointUtils::convertDoubleToUInt64(double d) u64 = UINT64(INT64(d)); #else - u64 = UINT64(d); + u64 = UINT64(d); #endif // TARGET_XARCH return u64; From 94c30f5e0fdbc4a4aca552adbc22d8a290e9f8cb Mon Sep 17 00:00:00 2001 From: David Wrighton Date: Wed, 22 Sep 2021 12:04:00 -0700 Subject: [PATCH 15/15] Add compUnixX86Abi function as needed in merge --- src/coreclr/jit/target.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/coreclr/jit/target.h b/src/coreclr/jit/target.h index 7e823f7f4bd7d2..4c339fb3b80f3e 100644 --- a/src/coreclr/jit/target.h +++ b/src/coreclr/jit/target.h @@ -36,6 +36,10 @@ inline bool compFeatureArgSplit() { return TargetArchitecture::IsArm32 || (TargetOS::IsWindows && TargetArchitecture::IsArm64); } +inline bool compUnixX86Abi() +{ + return TargetArchitecture::IsX86 && TargetOS::IsUnix; +} /*****************************************************************************/ // The following are human readable names for the target architectures