Skip to content

Commit 563408a

Browse files
authored
[JIT] Add support to inline the field access of primitive types marked with TLS (#82973)
* Add CORINFO_THREAD_LOCAL_FIELD_INFO and getThreadLocalFieldInfo() * Implementation of getThreadLocalFieldInfo() * Change the field types from CORINFO_CONST_LOOKUP to uint32_t * Introduce CORINFO_FIELD_STATIC_TLS_MANAGED * Introduce GTF_FLD_TLS_MANAGED * Introduce eeGetThreadLocalFieldInfo() * Fix the offsetOfThreadStaticBlocks, hardcode threadStaticBlockIndex for now * Add impThreadLocalFieldAccess() * Switch to GS segment register with a TODO * Add reverse map `g_threadStaticBlockTypeIDMap` for type -> ID * Fix GS segment register encoding * Add comment for g_threadStaticBlockTypeIDMap * Add extra parameter for typeIndex in JIT_GetSharedNonGCThreadStaticBase * Update JIT_GetSharedNonGCThreadStaticBase to add logic for storing typeIndex in t_threadStaticBlocks * Fix encoding of gs:[0x58] * fix some bugs in importer to change size from 4 to 8 * add some printf in jithelpers * To revert * Update the helper to skip making re-entry for staticBlock * Add impThreadLocalFieldWrite() for store * Fix a issue for helper * Use JITDUMP * Just enable the optimization for primitive types * Update the JITEE guid * Fix an assert for volatile variables * Mark helper block as cold block * wip * Fix the size of maxThreadStaticBlock * fix a bug to insert the entry in cache * Add #ifdef for HOST_WINDOWS / TARGET_WINDOWS * Dynamic memory allocation for static block array * Call InitTypeMap only if host == windows * Add CORINFO_HELP_GETSHARED_NONGCTHREADSTATIC_BASE_NOCTOR_OPTIMIZED * Expand the TLS field access in late phase * Move rarely ran block to the end * wip * Fix the bug to access the value from fastPath * Remove code from importer * Cleanup the code * Moved CreateBlockFromTree to fgbasic.cpp * Move fgExpandThreadLocalAccess() to flowgraph.cpp * Add getThreadLocalStaticBlocksInfo() method * Consume getThreadLocalStaticBlocksInfo() method * Updated definition of getThreadLocalFieldInfo() * Rename CORINFO_THREAD_LOCAL_FIELD_INFO to CORINFO_THREAD_STATIC_BLOCKS_INFO * Add TARGET_WINDOWS * Make TARGET_WINDOWS at some definitions * Add dummy definition for unix * jit format * remote unnecessary code from morph * Fix an issue on linux, add assert for tls_index != 0 * Convert from TARGET_WINDOWS to HOST_WINDOWS * jit format * fix the if-check * fix gcc build error * Added MethodHaveTlsFieldAccess() * Handle the case for '_tls_index == 0' * fix a typo * Fix windows/arm64 issue * fix encoding of teb loading for arm64 * Fix the condition in jitinterface to select correct helper * fix the condition for other helper too * fix the windows/x86 case * jit format * Use CORINFO_CONST_LOOKUP for _tls_index * Move typeIdMap to BaseDomain class * Introduce useFatPointerDispatch parameter for GetTypeID() * jit format * Do not pass classID and moduleID to the new helper * fix build for non-windows * fix superpmi methods * review feedback * fix linux build errors * review feedback * fix weight inherit * inline JIT_GetNonGCThreadStaticBase_Helper to fix the contract error * Remove dead code from helper * Add GTF_CALL_M_EXP_TLS_ACCESS to check if we do not revisit the already expanded call node * address feedback * regenerate the files * Introduce fgExpandHelper and fgExpandHelperForBlock and reuse it for various helper expansion * fix the typo * update the assert for runtimelookup * check if we should skip rarely run blocks * review feedback * Remove GTF_IND_INVARIANT from `typeIndex` access because it produces nullptr 1st time and valid value 2nd time onwards
1 parent b68f669 commit 563408a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+1821
-895
lines changed

src/coreclr/inc/corinfo.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,7 @@ enum CorInfoHelpFunc
546546
CORINFO_HELP_GETSHARED_NONGCTHREADSTATIC_BASE_NOCTOR,
547547
CORINFO_HELP_GETSHARED_GCTHREADSTATIC_BASE_DYNAMICCLASS,
548548
CORINFO_HELP_GETSHARED_NONGCTHREADSTATIC_BASE_DYNAMICCLASS,
549+
CORINFO_HELP_GETSHARED_NONGCTHREADSTATIC_BASE_NOCTOR_OPTIMIZED,
549550

550551
/* Debugger */
551552

@@ -1686,6 +1687,7 @@ enum CORINFO_FIELD_ACCESSOR
16861687
CORINFO_FIELD_STATIC_GENERICS_STATIC_HELPER, // static field access using the "generic static" helper (argument is MethodTable *)
16871688
CORINFO_FIELD_STATIC_ADDR_HELPER, // static field accessed using address-of helper (argument is FieldDesc *)
16881689
CORINFO_FIELD_STATIC_TLS, // unmanaged TLS access
1690+
CORINFO_FIELD_STATIC_TLS_MANAGED, // managed TLS access
16891691
CORINFO_FIELD_STATIC_READYTORUN_HELPER, // static field access using a runtime lookup helper
16901692
CORINFO_FIELD_STATIC_RELOCATABLE, // static field access using relocation (used in AOT)
16911693
CORINFO_FIELD_INTRINSIC_ZERO, // intrinsic zero (IntPtr.Zero, UIntPtr.Zero)
@@ -1725,6 +1727,17 @@ struct CORINFO_FIELD_INFO
17251727
CORINFO_CONST_LOOKUP fieldLookup; // Used by Ready-to-Run
17261728
};
17271729

1730+
//----------------------------------------------------------------------------
1731+
// getThreadLocalStaticBlocksInfo and CORINFO_THREAD_STATIC_BLOCKS_INFO: The EE instructs the JIT about how to access a thread local field
1732+
1733+
struct CORINFO_THREAD_STATIC_BLOCKS_INFO
1734+
{
1735+
CORINFO_CONST_LOOKUP tlsIndex;
1736+
uint32_t offsetOfThreadLocalStoragePointer;
1737+
uint32_t offsetOfMaxThreadStaticBlocks;
1738+
uint32_t offsetOfThreadStaticBlocks;
1739+
};
1740+
17281741
//----------------------------------------------------------------------------
17291742
// Exception handling
17301743

@@ -2743,6 +2756,12 @@ class ICorStaticInfo
27432756
CORINFO_FIELD_INFO *pResult
27442757
) = 0;
27452758

2759+
virtual uint32_t getThreadLocalFieldInfo (
2760+
CORINFO_FIELD_HANDLE field) = 0;
2761+
2762+
virtual void getThreadLocalStaticBlocksInfo (
2763+
CORINFO_THREAD_STATIC_BLOCKS_INFO* pInfo) = 0;
2764+
27462765
// Returns true iff "fldHnd" represents a static field.
27472766
virtual bool isFieldStatic(CORINFO_FIELD_HANDLE fldHnd) = 0;
27482767

src/coreclr/inc/icorjitinfoimpl_generated.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,12 @@ void getFieldInfo(
414414
CORINFO_ACCESS_FLAGS flags,
415415
CORINFO_FIELD_INFO* pResult) override;
416416

417+
uint32_t getThreadLocalFieldInfo(
418+
CORINFO_FIELD_HANDLE field) override;
419+
420+
void getThreadLocalStaticBlocksInfo(
421+
CORINFO_THREAD_STATIC_BLOCKS_INFO* pInfo) override;
422+
417423
bool isFieldStatic(
418424
CORINFO_FIELD_HANDLE fldHnd) override;
419425

src/coreclr/inc/jiteeversionguid.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,11 @@ typedef const GUID *LPCGUID;
4343
#define GUID_DEFINED
4444
#endif // !GUID_DEFINED
4545

46-
constexpr GUID JITEEVersionIdentifier = { /* 3054e9ba-bcfe-417c-9043-92ccc8738b80 */
47-
0x3054e9ba,
48-
0xbcfe,
49-
0x417c,
50-
{0x90, 0x43, 0x92, 0xcc, 0xc8, 0x73, 0x8b, 0x80}
46+
constexpr GUID JITEEVersionIdentifier = { /* 236d7997-3d71-45f9-b7d7-5241ad89a56f */
47+
0x236d7997,
48+
0x3d71,
49+
0x45f9,
50+
{ 0xb7, 0xd7, 0x52, 0x41, 0xad, 0x89, 0xa5, 0x6f }
5151
};
5252

5353
//////////////////////////////////////////////////////////////////////////////////////////////////////////

src/coreclr/inc/jithelpers.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@
203203
JITHELPER(CORINFO_HELP_GETSHARED_NONGCTHREADSTATIC_BASE_NOCTOR, JIT_GetSharedNonGCThreadStaticBase, CORINFO_HELP_SIG_REG_ONLY)
204204
JITHELPER(CORINFO_HELP_GETSHARED_GCTHREADSTATIC_BASE_DYNAMICCLASS, JIT_GetSharedGCThreadStaticBaseDynamicClass, CORINFO_HELP_SIG_REG_ONLY)
205205
JITHELPER(CORINFO_HELP_GETSHARED_NONGCTHREADSTATIC_BASE_DYNAMICCLASS, JIT_GetSharedNonGCThreadStaticBaseDynamicClass, CORINFO_HELP_SIG_REG_ONLY)
206+
JITHELPER(CORINFO_HELP_GETSHARED_NONGCTHREADSTATIC_BASE_NOCTOR_OPTIMIZED, JIT_GetSharedNonGCThreadStaticBaseOptimized, CORINFO_HELP_SIG_REG_ONLY)
206207

207208
// Debugger
208209
JITHELPER(CORINFO_HELP_DBG_IS_JUST_MY_CODE, JIT_DbgIsJustMyCode,CORINFO_HELP_SIG_REG_ONLY)

src/coreclr/jit/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ set( JIT_SOURCES
129129
hwintrinsic.cpp
130130
hostallocator.cpp
131131
ifconversion.cpp
132-
runtimelookup.cpp
132+
helperexpansion.cpp
133133
indirectcalltransformer.cpp
134134
importercalls.cpp
135135
importer.cpp

src/coreclr/jit/ICorJitInfo_names_generated.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ DEF_CLR_API(getFieldClass)
103103
DEF_CLR_API(getFieldType)
104104
DEF_CLR_API(getFieldOffset)
105105
DEF_CLR_API(getFieldInfo)
106+
DEF_CLR_API(getThreadLocalFieldInfo)
107+
DEF_CLR_API(getThreadLocalStaticBlocksInfo)
106108
DEF_CLR_API(isFieldStatic)
107109
DEF_CLR_API(getArrayOrStringLength)
108110
DEF_CLR_API(getBoundaries)

src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -981,6 +981,23 @@ void WrapICorJitInfo::getFieldInfo(
981981
API_LEAVE(getFieldInfo);
982982
}
983983

984+
uint32_t WrapICorJitInfo::getThreadLocalFieldInfo(
985+
CORINFO_FIELD_HANDLE field)
986+
{
987+
API_ENTER(getThreadLocalFieldInfo);
988+
uint32_t temp = wrapHnd->getThreadLocalFieldInfo(field);
989+
API_LEAVE(getThreadLocalFieldInfo);
990+
return temp;
991+
}
992+
993+
void WrapICorJitInfo::getThreadLocalStaticBlocksInfo(
994+
CORINFO_THREAD_STATIC_BLOCKS_INFO* pInfo)
995+
{
996+
API_ENTER(getThreadLocalStaticBlocksInfo);
997+
wrapHnd->getThreadLocalStaticBlocksInfo(pInfo);
998+
API_LEAVE(getThreadLocalStaticBlocksInfo);
999+
}
1000+
9841001
bool WrapICorJitInfo::isFieldStatic(
9851002
CORINFO_FIELD_HANDLE fldHnd)
9861003
{

src/coreclr/jit/codegenxarch.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5420,8 +5420,13 @@ void CodeGen::genCodeForIndir(GenTreeIndir* tree)
54205420
if (addr->IsIconHandle(GTF_ICON_TLS_HDL))
54215421
{
54225422
noway_assert(EA_ATTR(genTypeSize(targetType)) == EA_PTRSIZE);
5423+
#if TARGET_64BIT
5424+
emit->emitIns_R_C(ins_Load(TYP_I_IMPL), EA_PTRSIZE, tree->GetRegNum(), FLD_GLOBAL_GS,
5425+
(int)addr->AsIntCon()->gtIconVal);
5426+
#else
54235427
emit->emitIns_R_C(ins_Load(TYP_I_IMPL), EA_PTRSIZE, tree->GetRegNum(), FLD_GLOBAL_FS,
54245428
(int)addr->AsIntCon()->gtIconVal);
5429+
#endif
54255430
}
54265431
else
54275432
{

src/coreclr/jit/compiler.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5044,6 +5044,12 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
50445044
// Partially inline static initializations
50455045
DoPhase(this, PHASE_EXPAND_STATIC_INIT, &Compiler::fgExpandStaticInit);
50465046

5047+
if (TargetOS::IsWindows)
5048+
{
5049+
// Currently this is only applicable for Windows
5050+
DoPhase(this, PHASE_EXPAND_TLS, &Compiler::fgExpandThreadLocalAccess);
5051+
}
5052+
50475053
// Insert GC Polls
50485054
DoPhase(this, PHASE_INSERT_GC_POLLS, &Compiler::fgInsertGCPolls);
50495055

src/coreclr/jit/compiler.h

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4834,7 +4834,7 @@ class Compiler
48344834

48354835
GenTree* fgInitThisClass();
48364836

4837-
GenTreeCall* fgGetStaticsCCtorHelper(CORINFO_CLASS_HANDLE cls, CorInfoHelpFunc helper);
4837+
GenTreeCall* fgGetStaticsCCtorHelper(CORINFO_CLASS_HANDLE cls, CorInfoHelpFunc helper, uint32_t typeIndex = 0);
48384838

48394839
GenTreeCall* fgGetSharedCCtor(CORINFO_CLASS_HANDLE cls);
48404840

@@ -5287,11 +5287,21 @@ class Compiler
52875287
PhaseStatus StressSplitTree();
52885288
void SplitTreesRandomly();
52895289
void SplitTreesRemoveCommas();
5290+
5291+
template <bool (Compiler::*ExpansionFunction)(BasicBlock*, Statement*, GenTreeCall*)>
5292+
PhaseStatus fgExpandHelper(bool skipRarelyRunBlocks);
5293+
5294+
template <bool (Compiler::*ExpansionFunction)(BasicBlock*, Statement*, GenTreeCall*)>
5295+
bool fgExpandHelperForBlock(BasicBlock* block);
5296+
52905297
PhaseStatus fgExpandRuntimeLookups();
5298+
bool fgExpandRuntimeLookupsForCall(BasicBlock* block, Statement* stmt, GenTreeCall* call);
5299+
5300+
PhaseStatus fgExpandThreadLocalAccess();
5301+
bool fgExpandThreadLocalAccessForCall(BasicBlock* block, Statement* stmt, GenTreeCall* call);
52915302

5292-
bool fgExpandStaticInitForBlock(BasicBlock* block);
5293-
bool fgExpandStaticInitForCall(BasicBlock* block, Statement* stmt, GenTreeCall* call);
52945303
PhaseStatus fgExpandStaticInit();
5304+
bool fgExpandStaticInitForCall(BasicBlock* block, Statement* stmt, GenTreeCall* call);
52955305

52965306
PhaseStatus fgInsertGCPolls();
52975307
BasicBlock* fgCreateGCPoll(GCPollType pollType, BasicBlock* block);
@@ -7018,6 +7028,7 @@ class Compiler
70187028
#define OMF_HAS_MDNEWARRAY 0x00002000 // Method contains 'new' of an MD array
70197029
#define OMF_HAS_MDARRAYREF 0x00004000 // Method contains multi-dimensional intrinsic array element loads or stores.
70207030
#define OMF_HAS_STATIC_INIT 0x00008000 // Method has static initializations we might want to partially inline
7031+
#define OMF_HAS_TLS_FIELD 0x00010000 // Method contains TLS field access
70217032

70227033
// clang-format on
70237034

@@ -7068,6 +7079,16 @@ class Compiler
70687079
optMethodFlags |= OMF_HAS_GUARDEDDEVIRT;
70697080
}
70707081

7082+
bool doesMethodHasTlsFieldAccess()
7083+
{
7084+
return (optMethodFlags & OMF_HAS_TLS_FIELD) != 0;
7085+
}
7086+
7087+
void setMethodHasTlsFieldAccess()
7088+
{
7089+
optMethodFlags |= OMF_HAS_TLS_FIELD;
7090+
}
7091+
70717092
void pickGDV(GenTreeCall* call,
70727093
IL_OFFSET ilOffset,
70737094
bool isInterface,
@@ -7769,6 +7790,7 @@ class Compiler
77697790
void eeGetFieldInfo(CORINFO_RESOLVED_TOKEN* pResolvedToken,
77707791
CORINFO_ACCESS_FLAGS flags,
77717792
CORINFO_FIELD_INFO* pResult);
7793+
uint32_t eeGetThreadLocalFieldInfo(CORINFO_FIELD_HANDLE field);
77727794

77737795
// Get the flags
77747796

0 commit comments

Comments
 (0)