Skip to content

Commit 7989f18

Browse files
authored
[NativeAOT] Inline TLS access for windows/x64 (#89472)
* wip * working model * wip * wip * working * Add helper for tlsIndex * add methods in superpmi * revert some local changes * misc fixes * Stop emitting TLS access code for windows/x64 * fix linux build errors * Do not throw not implemented for windows/x64 * fix the problem where ThreadStaticBase helper was still getting invoked * Revert certain changes from JIT method * Introduce getThreadLocalStaticInfo_ReadyToRun() * Consume getThreadLocalStaticInfo_ReadyToRun() * Remove getTlsRootInfo() and other methods * Revert unneeded changes * missing gtInitCldHnd initialization * save target address * jit format * run thunkgenerator * resolve merge conflicts * fix issues so the TLS is inlined * Rename data structures from *_ReadyToRun to *_NativeAOT * jit format * fix some unit test * fix a bug * fix the weird jump problem * use enclosing type cls handle for VN of static gc/non-gc helper * fix a bug of resetting the flag * useEnclosingTypeOnly from runtime to determine if VN should optimize it * do not use vnf, but only use useEnclosingTypeAsArg0 * Use GT_COMMA to add GCStaticBase call next to TLS call * optimize the cctor call * Remove lazy ctor generation from tls * Update jitinterface to not fetch data for lazy ctor * fix errors after merge * fix test build errors * fix bug in CSE * Use CORINFO_FLG_FIELD_INITCLASS instead of separate flag * Use the INITCLASS flag * Remove useEnclosingTypeOnly * Add NoCtor * Use CORINFO_HELP_READYTORUN_THREADSTATIC_BASE_NOCTOR * Minor cleanup * Renegenrate thunk * Add the SetFalseTarget * fix merge conflict resolution * better handling of GTF_ICON_SECREL_OFFSET better handling of GTF_ICON_SECREL_OFFSET * review feedback * Disable optimization for minopts * Add comments around iiaSecRel * jit format * create emitNewInstrCns() * Expand TLS even if optimization is disabled * Track t_inlinedThreadStaticBase Better tracking `t_inlinedThreadStaticBase` as TYP_REF * jit format
1 parent 5598dac commit 7989f18

37 files changed

+588
-156
lines changed

src/coreclr/inc/corinfo.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -596,6 +596,7 @@ enum CorInfoHelpFunc
596596
CORINFO_HELP_READYTORUN_GCSTATIC_BASE, // static gc field access
597597
CORINFO_HELP_READYTORUN_NONGCSTATIC_BASE, // static non gc field access
598598
CORINFO_HELP_READYTORUN_THREADSTATIC_BASE,
599+
CORINFO_HELP_READYTORUN_THREADSTATIC_BASE_NOCTOR,
599600
CORINFO_HELP_READYTORUN_NONGCTHREADSTATIC_BASE,
600601
CORINFO_HELP_READYTORUN_VIRTUAL_FUNC_PTR,
601602
CORINFO_HELP_READYTORUN_GENERIC_HANDLE,
@@ -1739,6 +1740,17 @@ struct CORINFO_THREAD_STATIC_BLOCKS_INFO
17391740
uint32_t offsetOfGCDataPointer;
17401741
};
17411742

1743+
//----------------------------------------------------------------------------
1744+
// getThreadLocalStaticInfo_NativeAOT and CORINFO_THREAD_STATIC_INFO_NATIVEAOT: The EE instructs the JIT about how to access a thread local field
1745+
1746+
struct CORINFO_THREAD_STATIC_INFO_NATIVEAOT
1747+
{
1748+
uint32_t offsetOfThreadLocalStoragePointer;
1749+
CORINFO_CONST_LOOKUP tlsRootObject;
1750+
CORINFO_CONST_LOOKUP tlsIndexObject;
1751+
CORINFO_CONST_LOOKUP threadStaticBaseSlow;
1752+
};
1753+
17421754
//----------------------------------------------------------------------------
17431755
// Exception handling
17441756

@@ -2832,6 +2844,10 @@ class ICorStaticInfo
28322844
bool isGCType
28332845
) = 0;
28342846

2847+
virtual void getThreadLocalStaticInfo_NativeAOT(
2848+
CORINFO_THREAD_STATIC_INFO_NATIVEAOT* pInfo
2849+
) = 0;
2850+
28352851
// Returns true iff "fldHnd" represents a static field.
28362852
virtual bool isFieldStatic(CORINFO_FIELD_HANDLE fldHnd) = 0;
28372853

@@ -3366,6 +3382,7 @@ class ICorDynamicInfo : public ICorStaticInfo
33663382
// It would be nicer to use existing IMAGE_REL_XXX constants instead of defining our own here...
33673383
#define IMAGE_REL_BASED_REL32 0x10
33683384
#define IMAGE_REL_BASED_THUMB_BRANCH24 0x13
3385+
#define IMAGE_REL_SECREL 0x104
33693386

33703387
// The identifier for ARM32-specific PC-relative address
33713388
// computation corresponds to the following instruction

src/coreclr/inc/icorjitinfoimpl_generated.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,9 @@ void getThreadLocalStaticBlocksInfo(
402402
CORINFO_THREAD_STATIC_BLOCKS_INFO* pInfo,
403403
bool isGCType) override;
404404

405+
void getThreadLocalStaticInfo_NativeAOT(
406+
CORINFO_THREAD_STATIC_INFO_NATIVEAOT* pInfo) override;
407+
405408
bool isFieldStatic(
406409
CORINFO_FIELD_HANDLE fldHnd) override;
407410

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 = { /* 0cb8113f-52e5-444f-b713-dcb749b5d211 */
47-
0x0cb8113f,
48-
0x52e5,
49-
0x444f,
50-
{0xb7, 0x13, 0xdc, 0xb7, 0x49, 0xb5, 0xd2, 0x11}
46+
constexpr GUID JITEEVersionIdentifier = { /* d7bbeb5a-aa7d-43ec-b29e-6f24dd3bca9c */
47+
0xd7bbeb5a,
48+
0xaa7d,
49+
0x43ec,
50+
{0xb2, 0x9e, 0x6f, 0x24, 0xdd, 0x3b, 0xca, 0x9c}
5151
};
5252

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

src/coreclr/inc/jithelpers.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,7 @@
264264
JITHELPER(CORINFO_HELP_READYTORUN_GCSTATIC_BASE, NULL, CORINFO_HELP_SIG_NO_ALIGN_STUB)
265265
JITHELPER(CORINFO_HELP_READYTORUN_NONGCSTATIC_BASE, NULL, CORINFO_HELP_SIG_NO_ALIGN_STUB)
266266
JITHELPER(CORINFO_HELP_READYTORUN_THREADSTATIC_BASE, NULL, CORINFO_HELP_SIG_NO_ALIGN_STUB)
267+
JITHELPER(CORINFO_HELP_READYTORUN_THREADSTATIC_BASE_NOCTOR, NULL, CORINFO_HELP_SIG_NO_ALIGN_STUB)
267268
JITHELPER(CORINFO_HELP_READYTORUN_NONGCTHREADSTATIC_BASE, NULL,CORINFO_HELP_SIG_NO_ALIGN_STUB)
268269
JITHELPER(CORINFO_HELP_READYTORUN_VIRTUAL_FUNC_PTR, NULL, CORINFO_HELP_SIG_NO_ALIGN_STUB)
269270
JITHELPER(CORINFO_HELP_READYTORUN_GENERIC_HANDLE, NULL, CORINFO_HELP_SIG_NO_ALIGN_STUB)

src/coreclr/jit/ICorJitInfo_names_generated.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ DEF_CLR_API(getFieldOffset)
100100
DEF_CLR_API(getFieldInfo)
101101
DEF_CLR_API(getThreadLocalFieldInfo)
102102
DEF_CLR_API(getThreadLocalStaticBlocksInfo)
103+
DEF_CLR_API(getThreadLocalStaticInfo_NativeAOT)
103104
DEF_CLR_API(isFieldStatic)
104105
DEF_CLR_API(getArrayOrStringLength)
105106
DEF_CLR_API(getBoundaries)

src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -950,6 +950,14 @@ void WrapICorJitInfo::getThreadLocalStaticBlocksInfo(
950950
API_LEAVE(getThreadLocalStaticBlocksInfo);
951951
}
952952

953+
void WrapICorJitInfo::getThreadLocalStaticInfo_NativeAOT(
954+
CORINFO_THREAD_STATIC_INFO_NATIVEAOT* pInfo)
955+
{
956+
API_ENTER(getThreadLocalStaticInfo_NativeAOT);
957+
wrapHnd->getThreadLocalStaticInfo_NativeAOT(pInfo);
958+
API_LEAVE(getThreadLocalStaticInfo_NativeAOT);
959+
}
960+
953961
bool WrapICorJitInfo::isFieldStatic(
954962
CORINFO_FIELD_HANDLE fldHnd)
955963
{

src/coreclr/jit/codegenxarch.cpp

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -411,9 +411,17 @@ void CodeGen::instGen_Set_Reg_To_Imm(emitAttr size,
411411
// instruction selection due to different memory placement at runtime.
412412
if (EA_IS_RELOC(origAttr) && genDataIndirAddrCanBeEncodedAsPCRelOffset(imm))
413413
{
414-
// We will use lea so displacement and not immediate will be relocatable
415-
size = EA_SET_FLG(EA_REMOVE_FLG(size, EA_CNS_RELOC_FLG), EA_DSP_RELOC_FLG);
416-
GetEmitter()->emitIns_R_AI(INS_lea, size, reg, imm DEBUGARG(targetHandle) DEBUGARG(gtFlags));
414+
if (!EA_IS_CNS_SEC_RELOC(origAttr))
415+
{
416+
// We will use lea so displacement and not immediate will be relocatable
417+
size = EA_SET_FLG(EA_REMOVE_FLG(size, EA_CNS_RELOC_FLG), EA_DSP_RELOC_FLG);
418+
GetEmitter()->emitIns_R_AI(INS_lea, size, reg, imm DEBUGARG(targetHandle) DEBUGARG(gtFlags));
419+
}
420+
else
421+
{
422+
// For section constant, the immediate will be relocatable
423+
GetEmitter()->emitIns_R_I(INS_mov, size, reg, imm DEBUGARG(targetHandle) DEBUGARG(gtFlags));
424+
}
417425
}
418426
else
419427
{
@@ -616,6 +624,11 @@ void CodeGen::genSetRegToConst(regNumber targetReg, var_types targetType, GenTre
616624
attr = EA_SET_FLG(attr, EA_BYREF_FLG);
617625
}
618626

627+
if (con->IsIconHandle(GTF_ICON_SECREL_OFFSET))
628+
{
629+
attr = EA_SET_FLG(attr, EA_CNS_SEC_RELOC);
630+
}
631+
619632
instGen_Set_Reg_To_Imm(attr, targetReg, cnsVal,
620633
INS_FLAGS_DONT_CARE DEBUGARG(con->gtTargetHandle) DEBUGARG(con->gtFlags));
621634
regSet.verifyRegUsed(targetReg);

src/coreclr/jit/compiler.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5807,6 +5807,7 @@ class Compiler
58075807

58085808
PhaseStatus fgExpandThreadLocalAccess();
58095809
bool fgExpandThreadLocalAccessForCall(BasicBlock** pBlock, Statement* stmt, GenTreeCall* call);
5810+
bool fgExpandThreadLocalAccessForCallNativeAOT(BasicBlock** pBlock, Statement* stmt, GenTreeCall* call);
58105811

58115812
PhaseStatus fgExpandStaticInit();
58125813
bool fgExpandStaticInitForCall(BasicBlock** pBlock, Statement* stmt, GenTreeCall* call);

src/coreclr/jit/compiler.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3941,6 +3941,7 @@ inline bool Compiler::IsSharedStaticHelper(GenTree* tree)
39413941
#ifdef FEATURE_READYTORUN
39423942
helper == CORINFO_HELP_READYTORUN_GENERIC_STATIC_BASE || helper == CORINFO_HELP_READYTORUN_GCSTATIC_BASE ||
39433943
helper == CORINFO_HELP_READYTORUN_NONGCSTATIC_BASE || helper == CORINFO_HELP_READYTORUN_THREADSTATIC_BASE ||
3944+
helper == CORINFO_HELP_READYTORUN_THREADSTATIC_BASE_NOCTOR ||
39443945
helper == CORINFO_HELP_READYTORUN_NONGCTHREADSTATIC_BASE ||
39453946
#endif
39463947
helper == CORINFO_HELP_CLASSINIT_SHARED_DYNAMICCLASS;

src/coreclr/jit/emit.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1021,6 +1021,7 @@ class emitter
10211021
{
10221022
return iiaJmpOffset;
10231023
}
1024+
10241025
#elif defined(TARGET_RISCV64)
10251026
struct
10261027
{
@@ -1039,6 +1040,9 @@ class emitter
10391040
}
10401041
#endif // defined(TARGET_RISCV64)
10411042

1043+
// Used for instrDesc that has relocatable immediate offset
1044+
bool iiaSecRel;
1045+
10421046
} _idAddrUnion;
10431047

10441048
/* Trivial wrappers to return properly typed enums */

src/coreclr/jit/emitxarch.cpp

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5702,7 +5702,15 @@ void emitter::emitIns_R_I(instruction ins,
57025702
break;
57035703
}
57045704

5705-
id = emitNewInstrSC(attr, val);
5705+
if (emitComp->IsTargetAbi(CORINFO_NATIVEAOT_ABI) && EA_IS_CNS_SEC_RELOC(attr))
5706+
{
5707+
id = emitNewInstrCns(attr, val);
5708+
id->idAddr()->iiaSecRel = true;
5709+
}
5710+
else
5711+
{
5712+
id = emitNewInstrSC(attr, val);
5713+
}
57065714
id->idIns(ins);
57075715
id->idInsFmt(fmt);
57085716
id->idReg1(reg);
@@ -15098,7 +15106,16 @@ BYTE* emitter::emitOutputRI(BYTE* dst, instrDesc* id)
1509815106

1509915107
if (id->idIsCnsReloc())
1510015108
{
15101-
emitRecordRelocation((void*)(dst - (unsigned)EA_SIZE(size)), (void*)(size_t)val, IMAGE_REL_BASED_MOFFSET);
15109+
if (emitComp->IsTargetAbi(CORINFO_NATIVEAOT_ABI) && id->idAddr()->iiaSecRel)
15110+
{
15111+
// For section relative, the immediate offset is relocatable and hence need IMAGE_REL_SECREL
15112+
emitRecordRelocation((void*)(dst - (unsigned)EA_SIZE(size)), (void*)(size_t)val, IMAGE_REL_SECREL);
15113+
}
15114+
else
15115+
{
15116+
emitRecordRelocation((void*)(dst - (unsigned)EA_SIZE(size)), (void*)(size_t)val,
15117+
IMAGE_REL_BASED_MOFFSET);
15118+
}
1510215119
}
1510315120

1510415121
goto DONE;

src/coreclr/jit/gentree.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10771,6 +10771,8 @@ const char* GenTree::gtGetHandleKindString(GenTreeFlags flags)
1077110771
return "GTF_ICON_FIELD_SEQ";
1077210772
case GTF_ICON_STATIC_ADDR_PTR:
1077310773
return "GTF_ICON_STATIC_ADDR_PTR";
10774+
case GTF_ICON_SECREL_OFFSET:
10775+
return "GTF_ICON_SECREL_OFFSET";
1077410776
default:
1077510777
return "ILLEGAL!";
1077610778
}
@@ -12000,6 +12002,9 @@ void Compiler::gtDispConst(GenTree* tree)
1200012002
case GTF_ICON_STATIC_ADDR_PTR:
1200112003
printf(" static base addr cell");
1200212004
break;
12005+
case GTF_ICON_SECREL_OFFSET:
12006+
printf(" relative offset in section");
12007+
break;
1200312008
default:
1200412009
printf(" UNKNOWN");
1200512010
break;

src/coreclr/jit/gentree.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,7 @@ enum GenTreeFlags : unsigned int
536536
GTF_ICON_STATIC_BOX_PTR = 0x10000000, // GT_CNS_INT -- constant is an address of the box for a STATIC_IN_HEAP field
537537
GTF_ICON_FIELD_SEQ = 0x11000000, // <--------> -- constant is a FieldSeq* (used only as VNHandle)
538538
GTF_ICON_STATIC_ADDR_PTR = 0x13000000, // GT_CNS_INT -- constant is a pointer to a static base address
539+
GTF_ICON_SECREL_OFFSET = 0x14000000, // GT_CNS_INT -- constant is an offset in a certain section.
539540

540541
// GTF_ICON_REUSE_REG_VAL = 0x00800000 // GT_CNS_INT -- GTF_REUSE_REG_VAL, defined above
541542
GTF_ICON_SIMD_COUNT = 0x00200000, // GT_CNS_INT -- constant is Vector<T>.Count

0 commit comments

Comments
 (0)