From fa769cb1e06d69d23095ea28a680fa0fb7af92f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomek=20Sowi=C5=84ski?= Date: Thu, 27 Jul 2023 08:29:26 +0200 Subject: [PATCH] [RISC-V] Enable TLS field access optimization --- src/coreclr/jit/codegenriscv64.cpp | 12 +++++++++++- src/coreclr/jit/helperexpansion.cpp | 10 +++++++--- src/coreclr/vm/jitinterface.cpp | 14 ++++++-------- src/coreclr/vm/riscv64/asmhelpers.S | 9 +++++++++ 4 files changed, 33 insertions(+), 12 deletions(-) diff --git a/src/coreclr/jit/codegenriscv64.cpp b/src/coreclr/jit/codegenriscv64.cpp index 015a33f82c2c32..30648fb2adb13b 100644 --- a/src/coreclr/jit/codegenriscv64.cpp +++ b/src/coreclr/jit/codegenriscv64.cpp @@ -1607,7 +1607,17 @@ void CodeGen::genCodeForStoreLclVar(GenTreeLclVar* lclNode) } else // store into register (i.e move into register) { - inst_Mov(targetType, targetReg, dataReg, true); + if (data->IsIconHandle(GTF_ICON_TLS_HDL)) + { + assert(data->AsIntCon()->IconValue() == 0); + emitAttr attr = emitActualTypeSize(targetType); + // need to load the address from thread pointer reg + emit->emitIns_R_R(INS_mov, attr, targetReg, REG_TP); + } + else + { + inst_Mov(targetType, targetReg, dataReg, true); + } genProduceReg(lclNode); } } diff --git a/src/coreclr/jit/helperexpansion.cpp b/src/coreclr/jit/helperexpansion.cpp index 271030a9e2dd9c..5295e9e19244b1 100644 --- a/src/coreclr/jit/helperexpansion.cpp +++ b/src/coreclr/jit/helperexpansion.cpp @@ -652,17 +652,21 @@ bool Compiler::fgExpandThreadLocalAccessForCall(BasicBlock** pBlock, Statement* #ifdef UNIX_X86_ABI tlsRefCall->gtFlags &= ~GTF_CALL_POP_ARGS; #endif // UNIX_X86_ABI -#elif defined(TARGET_ARM64) +#elif defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64) // Code sequence to access thread local variable on linux/arm64: // // mrs xt, tpidr_elf0 // mov xd, [xt+cns] - tlsValue = gtNewIconHandleNode(0, GTF_ICON_TLS_HDL); -#elif defined(TARGET_LOONGARCH64) + // // Code sequence to access thread local variable on linux/loongarch64: // // ori, targetReg, $tp, 0 // load rd, targetReg, cns + // + // Code sequence to access thread local variable on linux/riscv64: + // + // mov targetReg, $tp, 0 + // ld rd, targetReg(cns) tlsValue = gtNewIconHandleNode(0, GTF_ICON_TLS_HDL); #else assert(!"Unsupported scenario of optimizing TLS access on Linux Arm32/x86"); diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index b7dcf9eacd88ef..22188a33bef363 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -1414,11 +1414,11 @@ static void* GetTlsIndexObjectAddress() return GetThreadStaticDescriptor(p); } -#elif defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) +#elif defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64) extern "C" size_t GetThreadStaticsVariableOffset(); -#endif // TARGET_ARM64 || TARGET_LOONGARCH64 +#endif // TARGET_ARM64 || TARGET_LOONGARCH64 || TARGET_RISCV64 #endif // TARGET_WINDOWS @@ -1452,9 +1452,9 @@ void CEEInfo::getThreadLocalStaticBlocksInfo (CORINFO_THREAD_STATIC_BLOCKS_INFO* pInfo->tlsGetAddrFtnPtr = reinterpret_cast(&__tls_get_addr); pInfo->tlsIndexObject = GetTlsIndexObjectAddress(); -#elif defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) +#elif defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64) - // For Linux arm64/loongarch64, just get the offset of thread static variable, and during execution, + // For Linux arm64/loongarch64/riscv64, just get the offset of thread static variable, and during execution, // this offset, arm64 taken from trpid_elp0 system register gives back the thread variable address. // this offset, loongarch64 taken from $tp register gives back the thread variable address. threadStaticBaseOffset = GetThreadStaticsVariableOffset(); @@ -1588,8 +1588,6 @@ void CEEInfo::getFieldInfo (CORINFO_RESOLVED_TOKEN * pResolvedToken, // Optimization is disabled for linux/x86 #elif defined(TARGET_LINUX_MUSL) && defined(TARGET_ARM64) // Optimization is disabled for linux musl arm64 -#elif defined(TARGET_RISCV64) - // Optimization is disabled for riscv64 #else bool optimizeThreadStaticAccess = true; #if !defined(TARGET_OSX) && defined(TARGET_UNIX) && defined(TARGET_AMD64) @@ -1597,11 +1595,11 @@ void CEEInfo::getFieldInfo (CORINFO_RESOLVED_TOKEN * pResolvedToken, // For single file, the `tls_index` might not be accurate. // Do not perform this optimization in such case. optimizeThreadStaticAccess = GetTlsIndexObjectAddress() != nullptr; -#endif // TARGET_UNIX && TARGET_AMD64 +#endif // !TARGET_OSX && TARGET_UNIX && TARGET_AMD64 if (optimizeThreadStaticAccess) { - // For windows x64/x86/arm64, linux x64/arm64/loongarch64: + // For windows x64/x86/arm64, linux x64/arm64/loongarch64/riscv64: // We convert the TLS access to the optimized helper where we will store // the static blocks in TLS directly and access them via inline code. if ((pResult->helper == CORINFO_HELP_GETSHARED_NONGCTHREADSTATIC_BASE_NOCTOR) || diff --git a/src/coreclr/vm/riscv64/asmhelpers.S b/src/coreclr/vm/riscv64/asmhelpers.S index f3ec25babc3054..8908130634de87 100644 --- a/src/coreclr/vm/riscv64/asmhelpers.S +++ b/src/coreclr/vm/riscv64/asmhelpers.S @@ -954,3 +954,12 @@ NESTED_ENTRY OnCallCountThresholdReachedStub, _TEXT, NoHandler NESTED_END OnCallCountThresholdReachedStub, _TEXT #endif // FEATURE_TIERED_COMPILATION + +// ------------------------------------------------------------------ +// size_t GetThreadStaticsVariableOffset() + +// Load offset of native thread local variable `t_ThreadStatics` in TCB and return it in `a0` register. +LEAF_ENTRY GetThreadStaticsVariableOffset, _TEXT + la.tls.ie a0, t_ThreadStatics + EPILOG_RETURN +LEAF_END GetThreadStaticsVariableOffset, _TEXT