From 936faffb753f929fc69e7a7079c6f7c798713a1b Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Wed, 31 Jan 2024 14:42:17 -0800 Subject: [PATCH 01/22] wip --- src/coreclr/inc/corinfo.h | 10 ++ src/coreclr/jit/codegenarm64.cpp | 9 ++ src/coreclr/jit/codegencommon.cpp | 1 + src/coreclr/jit/emitarm64.cpp | 35 ++++- src/coreclr/jit/helperexpansion.cpp | 127 ++++++++++++++---- .../Compiler/DependencyAnalysis/Relocation.cs | 4 +- .../tools/Common/JitInterface/CorInfoImpl.cs | 6 + .../JitInterface/CorInfoImpl.RyuJit.cs | 3 +- 8 files changed, 163 insertions(+), 32 deletions(-) diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h index d7c31c2623eae6..32163416fd870f 100644 --- a/src/coreclr/inc/corinfo.h +++ b/src/coreclr/inc/corinfo.h @@ -3371,8 +3371,18 @@ class ICorDynamicInfo : public ICorStaticInfo #define IMAGE_REL_BASED_REL32 0x10 #define IMAGE_REL_BASED_THUMB_BRANCH24 0x13 #define IMAGE_REL_SECREL 0x104 + +// Linux x64 +// GD model #define IMAGE_REL_TLSGD 0x105 +// Linux arm64 +// TLSDESC (dynamic) +#define IMAGE_REL_AARCH64_TLSDESC_ADR_PAGE21 0x107 +#define IMAGE_REL_AARCH64_TLSDESC_LD64_LO12 0x108 +#define IMAGE_REL_AARCH64_TLSDESC_ADD_LO12 0x109 +#define IMAGE_REL_AARCH64_TLSDESC_CALL 0x10A + // The identifier for ARM32-specific PC-relative address // computation corresponds to the following instruction // sequence: diff --git a/src/coreclr/jit/codegenarm64.cpp b/src/coreclr/jit/codegenarm64.cpp index dc0fe90c1e2fe1..f52eb6866d79fb 100644 --- a/src/coreclr/jit/codegenarm64.cpp +++ b/src/coreclr/jit/codegenarm64.cpp @@ -2333,6 +2333,15 @@ void CodeGen::genSetRegToConst(regNumber targetReg, var_types targetType, GenTre if (con->ImmedValNeedsReloc(compiler)) { attr = EA_SET_FLG(attr, EA_CNS_RELOC_FLG); + if (tree->IsIconHandle(GTF_ICON_TLS_HDL)) + { + GetEmitter()->emitIns_R(INS_mrs_tpid0, attr, targetReg); + break; + } + else if (tree->IsIconHandle(GTF_ICON_TLSGD_OFFSET)) + { + attr = EA_SET_FLG(attr, EA_CNS_TLSGD_RELOC); + } } if (targetType == TYP_BYREF) diff --git a/src/coreclr/jit/codegencommon.cpp b/src/coreclr/jit/codegencommon.cpp index 66901eab857383..639024bafb5f24 100644 --- a/src/coreclr/jit/codegencommon.cpp +++ b/src/coreclr/jit/codegencommon.cpp @@ -1695,6 +1695,7 @@ void CodeGen::genGenerateCode(void** codePtr, uint32_t* nativeSizeOfCode) this->codePtr = codePtr; this->nativeSizeOfCode = nativeSizeOfCode; + compiler->opts.dspCode = compiler->opts.disAsm; DoPhase(this, PHASE_GENERATE_CODE, &CodeGen::genGenerateMachineCode); DoPhase(this, PHASE_EMIT_CODE, &CodeGen::genEmitMachineCode); DoPhase(this, PHASE_EMIT_GCEH, &CodeGen::genEmitUnwindDebugGCandEH); diff --git a/src/coreclr/jit/emitarm64.cpp b/src/coreclr/jit/emitarm64.cpp index 2c4dd9f640fe46..0a5b6bfa386325 100644 --- a/src/coreclr/jit/emitarm64.cpp +++ b/src/coreclr/jit/emitarm64.cpp @@ -8466,7 +8466,10 @@ void emitter::emitIns_R_R_I( id->idReg1(reg1); id->idReg2(reg2); - + if (EA_IS_CNS_TLSGD_RELOC(attr)) + { + id->idSetTlsGD(); + } dispIns(id); appendToCurIG(id); } @@ -12699,6 +12702,10 @@ void emitter::emitIns_R_AI(instruction ins, id->idAddr()->iiaAddr = (BYTE*)addr; id->idReg1(ireg); id->idSetIsDspReloc(); + if (EA_IS_CNS_TLSGD_RELOC(attr)) + { + id->idSetTlsGD(); + } #ifdef DEBUG id->idDebugOnlyInfo()->idMemCookie = targetHandle; id->idDebugOnlyInfo()->idFlags = gtFlags; @@ -12722,6 +12729,10 @@ void emitter::emitIns_R_AI(instruction ins, id->idAddr()->iiaAddr = (BYTE*)addr; id->idReg1(ireg); id->idReg2(ireg); + if (EA_IS_CNS_TLSGD_RELOC(attr)) + { + id->idSetTlsGD(); + } dispIns(id); appendToCurIG(id); @@ -16406,7 +16417,14 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) code = emitInsCode(ins, fmt); code |= insEncodeReg_Rd(id->idReg1()); // ddddd dst += emitOutput_Instr(dst, code); - emitRecordRelocation(odst, id->idAddr()->iiaAddr, IMAGE_REL_ARM64_PAGEBASE_REL21); + if (id->idIsTlsGD()) + { + emitRecordRelocation(odst, id->idAddr()->iiaAddr, IMAGE_REL_AARCH64_TLSDESC_ADR_PAGE21); + } + else + { + emitRecordRelocation(odst, id->idAddr()->iiaAddr, IMAGE_REL_ARM64_PAGEBASE_REL21); + } } else { @@ -16449,7 +16467,14 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) { assert(sz == sizeof(instrDesc)); assert(id->idAddr()->iiaAddr != nullptr); - emitRecordRelocation(odst, id->idAddr()->iiaAddr, IMAGE_REL_ARM64_PAGEOFFSET_12A); + if (id->idIsTlsGD()) + { + emitRecordRelocation(odst, id->idAddr()->iiaAddr, IMAGE_REL_AARCH64_TLSDESC_ADD_LO12); + } + else + { + emitRecordRelocation(odst, id->idAddr()->iiaAddr, IMAGE_REL_ARM64_PAGEOFFSET_12A); + } } break; @@ -21021,6 +21046,10 @@ void emitter::emitInsLoadStoreOp(instruction ins, emitAttr attr, regNumber dataR } #endif // DEBUG + if (addr->gtFlags & GTF_ICON_TLSGD_OFFSET) + { + attr = EA_SET_FLG(attr, EA_CNS_TLSGD_RELOC); + } // Then load/store dataReg from/to [addrReg] emitIns_R_R(ins, attr, dataReg, addr->GetRegNum()); } diff --git a/src/coreclr/jit/helperexpansion.cpp b/src/coreclr/jit/helperexpansion.cpp index 8a1d6e38b0d1a2..4d678631a5270c 100644 --- a/src/coreclr/jit/helperexpansion.cpp +++ b/src/coreclr/jit/helperexpansion.cpp @@ -591,8 +591,8 @@ bool Compiler::fgExpandThreadLocalAccessForCallNativeAOT(BasicBlock** pBlock, St // use(tlsRoot); // ... - GenTree* tlsRootAddr = nullptr; - CORINFO_CONST_LOOKUP tlsRootObject = threadStaticInfo.tlsRootObject; + GenTree* tlsRootAddr = nullptr; + CORINFO_GENERIC_HANDLE tlsRootObject = threadStaticInfo.tlsRootObject.handle; if (TargetOS::IsWindows) { @@ -613,7 +613,7 @@ bool Compiler::fgExpandThreadLocalAccessForCallNativeAOT(BasicBlock** pBlock, St tlsValue = gtNewIndir(TYP_I_IMPL, tlsValue, GTF_IND_NONFAULTING | GTF_IND_INVARIANT); // This resolves to an offset which is TYP_INT - GenTree* tlsRootOffset = gtNewIconNode((size_t)tlsRootObject.handle, TYP_INT); + GenTree* tlsRootOffset = gtNewIconNode((size_t)tlsRootObject, TYP_INT); tlsRootOffset->gtFlags |= GTF_ICON_SECREL_OFFSET; // Add the tlsValue and tlsRootOffset to produce tlsRootAddr. @@ -621,34 +621,107 @@ bool Compiler::fgExpandThreadLocalAccessForCallNativeAOT(BasicBlock** pBlock, St } else if (TargetOS::IsUnix) { - // Code sequence to access thread local variable on linux/x64: - // data16 - // lea rdi, 0x7FE5C418CD28 ; tlsRootObject - // data16 data16 - // call _tls_get_addr - // - // This sequence along with `data16` prefix is expected by the linker so it - // will patch these with TLS access. - GenTree* tls_get_addr_val = - gtNewIconHandleNode((size_t)threadStaticInfo.tlsGetAddrFtnPtr.handle, GTF_ICON_FTN_ADDR); - tls_get_addr_val->SetContained(); + if (TargetArchitecture::IsX64) + { + // Code sequence to access thread local variable on linux/x64: + // data16 + // lea rdi, 0x7FE5C418CD28 ; tlsRootObject + // data16 data16 + // call _tls_get_addr + // + // This sequence along with `data16` prefix is expected by the linker so it + // will patch these with TLS access. + GenTree* tls_get_addr_val = + gtNewIconHandleNode((size_t)threadStaticInfo.tlsGetAddrFtnPtr.handle, GTF_ICON_FTN_ADDR); + tls_get_addr_val->SetContained(); + + GenTreeCall* tlsRefCall = gtNewIndCallNode(tls_get_addr_val, TYP_I_IMPL); + tlsRefCall->gtFlags |= GTF_TLS_GET_ADDR; + + // This is an indirect call which takes an argument. + // Populate and set the ABI appropriately. + assert(tlsRootObject != 0); + GenTree* tlsArg = gtNewIconNode((size_t)tlsRootObject, TYP_I_IMPL); + tlsArg->gtFlags |= GTF_ICON_TLSGD_OFFSET; + tlsRefCall->gtArgs.PushBack(this, NewCallArg::Primitive(tlsArg)); + + fgMorphArgs(tlsRefCall); + + tlsRefCall->gtFlags |= GTF_EXCEPT | (tls_get_addr_val->gtFlags & GTF_GLOB_EFFECT); + tlsRootAddr = tlsRefCall; + } + else if (TargetArchitecture::IsArm64) + { + /* + x0 = adrp :tlsdesc:tlsRoot ; 1st parameter + x0 += tlsdesc_lo12:tlsRoot ; update 1st parameter - // GenTreeCall* tlsRefCall = gtNewCallNode(CT_ tls_get_addr_val, TYP_I_IMPL); - GenTreeCall* tlsRefCall = gtNewIndCallNode(tls_get_addr_val, TYP_I_IMPL); - tlsRefCall->gtFlags |= GTF_TLS_GET_ADDR; - // // + x1 = tpidr_el0 ; 2nd parameter - // This is an indirect call which takes an argument. - // Populate and set the ABI appropriately. - assert(tlsRootObject.handle != 0); - GenTree* tlsArg = gtNewIconNode((size_t)tlsRootObject.handle, TYP_I_IMPL); - tlsArg->gtFlags |= GTF_ICON_TLSGD_OFFSET; - tlsRefCall->gtArgs.PushBack(this, NewCallArg::Primitive(tlsArg)); + x2 = [x0] ; call + blr x2 - fgMorphArgs(tlsRefCall); + */ - tlsRefCall->gtFlags |= GTF_EXCEPT | (tls_get_addr_val->gtFlags & GTF_GLOB_EFFECT); - tlsRootAddr = tlsRefCall; + unsigned tlsLclNum = lvaGrabTemp(true DEBUGARG("TLS access")); + lvaTable[tlsLclNum].lvType = TYP_I_IMPL; + GenTree* tlsRootOffset = gtNewIconHandleNode((size_t)tlsRootObject, GTF_ICON_TLS_HDL); // [000016] + GenTree* tlsValueDef = gtNewStoreLclVarNode(tlsLclNum, tlsRootOffset); // [000017] + //tlsValueDef->gtFlags + GenTree* tlsValueUse = gtNewLclVarNode(tlsLclNum); // [000018] + + + //tlsRootOffset->gtFlags |= GTF_ICON_SECREL_OFFSET; + + // param1 + // + GenTree* tlsCallParam1 = gtCloneExpr(tlsRootOffset); // TODO: IMAGE_REL_AARCH64_TLSDESC_ADR_PAGE21 + tlsCallParam1->gtFlags &= ~GTF_ICON_TLS_HDL; // [000017] + tlsCallParam1->gtFlags |= GTF_ICON_TLSGD_OFFSET; // [000017] + + //tlsCallParam2->SetContained(); + + //unsigned tlsRootAddrLclNum = lvaGrabTemp(true DEBUGARG("TlsRootAddr access")); + //lvaTable[tlsRootAddrLclNum].lvType = TYP_I_IMPL; + //GenTree* tlsRootAddrDef = gtNewStoreLclVarNode(tlsRootAddrLclNum, tlsRootOffset); + //GenTree* tlsRootAddrUse = gtNewLclVarNode(tlsRootAddrLclNum); + + //GenTree* cnsOffset = gtNewIconNode(0, TYP_INT); + //cnsOffset->gtFlags |= GTF_ICON_TLSGD_OFFSET; + + //GenTree* tlsCallOffset = + // gtNewOperNode(GT_ADD, TYP_I_IMPL, gtClone(tlsCallParam1), cnsOffset); + + + // [000020] + GenTree* tlsCall1 = gtCloneExpr(tlsCallParam1); + //tlsCall1->SetContained(); + GenTree* tlsCallAddr = + gtNewIndir(TYP_I_IMPL, tlsCall1, + GTF_IND_NONFAULTING | GTF_IND_INVARIANT); // IMAGE_REL_AARCH64_TLSDESC_LD64_LO12 + + //// param1 + //// + //GenTree* tlsCallParam1 = gtNewOperNode(GT_ADD, TYP_I_IMPL, gtClone(tlsRootAddrUse), + // gtNewIconNode(0, TYP_INT)); // IMAGE_REL_AARCH64_TLSDESC_ADD_LO12 + + + + // [000021] + GenTreeCall* tlsRefCall = gtNewIndCallNode(tlsCallAddr, TYP_I_IMPL); + tlsRefCall->gtFlags |= GTF_TLS_GET_ADDR; + tlsRefCall->gtArgs.PushBack(this, NewCallArg::Primitive(tlsCallParam1)); + tlsRefCall->gtArgs.PushBack(this, NewCallArg::Primitive(gtNewIconHandleNode(0, GTF_ICON_TLS_HDL))); + + fgMorphArgs(tlsRefCall); + + tlsRefCall->gtFlags |= GTF_EXCEPT | (tlsCallAddr->gtFlags & GTF_GLOB_EFFECT); + tlsRootAddr = tlsRefCall; + } + else + { + unreached(); + } } else { diff --git a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Relocation.cs b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Relocation.cs index 337811103e35f7..1ad30f4309dafc 100644 --- a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Relocation.cs +++ b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Relocation.cs @@ -475,7 +475,9 @@ public static unsafe void WriteValue(RelocType relocType, void* location, long v case RelocType.IMAGE_REL_TPOFF: case RelocType.IMAGE_REL_SYMBOL_SIZE: case RelocType.IMAGE_REL_FILE_ABSOLUTE: - *(int*)location = (int)value; + case RelocType.IMAGE_REL_AARCH64_TLSDESC_ADR_PAGE21: + case RelocType.IMAGE_REL_AARCH64_TLSDESC_ADD_LO12: + * (int*)location = (int)value; break; case RelocType.IMAGE_REL_BASED_DIR64: *(long*)location = value; diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs index d26463264e9ebc..c26c1a6f9005d3 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs @@ -3875,6 +3875,8 @@ private static RelocType GetRelocType(TargetArchitecture targetArchitecture, ush const ushort IMAGE_REL_ARM64_BRANCH26 = 3; const ushort IMAGE_REL_ARM64_PAGEBASE_REL21 = 4; const ushort IMAGE_REL_ARM64_PAGEOFFSET_12A = 6; + const ushort IMAGE_REL_ARM64_TLSDESC_ADR_PAGE21 = 0x107; + const ushort IMAGE_REL_ARM64_TLSDESC_ADD_LO12 = 0x109; switch (fRelocType) { @@ -3884,6 +3886,10 @@ private static RelocType GetRelocType(TargetArchitecture targetArchitecture, ush return RelocType.IMAGE_REL_BASED_ARM64_PAGEBASE_REL21; case IMAGE_REL_ARM64_PAGEOFFSET_12A: return RelocType.IMAGE_REL_BASED_ARM64_PAGEOFFSET_12A; + case IMAGE_REL_ARM64_TLSDESC_ADR_PAGE21: + return RelocType.IMAGE_REL_AARCH64_TLSDESC_ADR_PAGE21; + case IMAGE_REL_ARM64_TLSDESC_ADD_LO12: + return RelocType.IMAGE_REL_AARCH64_TLSDESC_ADD_LO12; default: Debug.Fail("Invalid RelocType: " + fRelocType); return 0; diff --git a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs index 39a03aafa7e28b..c4cbd4b0ffc09f 100644 --- a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs +++ b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs @@ -2157,7 +2157,8 @@ private void getFieldInfo(ref CORINFO_RESOLVED_TOKEN pResolvedToken, CORINFO_MET } else if (field.IsThreadStatic) { - if ((MethodBeingCompiled.Context.Target.IsWindows || MethodBeingCompiled.Context.Target.OperatingSystem == TargetOS.Linux) && MethodBeingCompiled.Context.Target.Architecture == TargetArchitecture.X64) + if ((MethodBeingCompiled.Context.Target.IsWindows && MethodBeingCompiled.Context.Target.Architecture == TargetArchitecture.X64) || + (MethodBeingCompiled.Context.Target.OperatingSystem == TargetOS.Linux)) { ISortableSymbolNode index = _compilation.NodeFactory.TypeThreadStaticIndex((MetadataType)field.OwningType); if (index is TypeThreadStaticIndexNode ti) From 531ec41eb41ffc39d5b7a30c95a10711f8497150 Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Wed, 31 Jan 2024 20:09:03 -0800 Subject: [PATCH 02/22] hacky version --- src/coreclr/jit/helperexpansion.cpp | 21 ++++++++++++++++++++- src/coreclr/jit/lsraarm64.cpp | 8 +++++++- src/coreclr/jit/lsrabuild.cpp | 8 ++++++++ 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/coreclr/jit/helperexpansion.cpp b/src/coreclr/jit/helperexpansion.cpp index 4d678631a5270c..023896078774fc 100644 --- a/src/coreclr/jit/helperexpansion.cpp +++ b/src/coreclr/jit/helperexpansion.cpp @@ -669,6 +669,16 @@ bool Compiler::fgExpandThreadLocalAccessForCallNativeAOT(BasicBlock** pBlock, St GenTree* tlsValueDef = gtNewStoreLclVarNode(tlsLclNum, tlsRootOffset); // [000017] //tlsValueDef->gtFlags GenTree* tlsValueUse = gtNewLclVarNode(tlsLclNum); // [000018] + GenTree* tlsDefUse = gtNewOperNode(GT_COMMA, TYP_I_IMPL, tlsValueDef, tlsValueUse); + + //fgInsertStmtAtBeg(block, fgNewStmtFromTree(tlsValueDef)); + + /*BasicBlock* oldBb = block; + BasicBlock* newBlock = fgNewBBFromTreeAfter(BBJ_ALWAYS, prevBb, tlsValueDef, debugInfo); + newBlock->SetTarget(block); + fgAddRefPred(block, newBlock);*/ + + //tlsRootOffset->gtFlags |= GTF_ICON_SECREL_OFFSET; @@ -695,6 +705,12 @@ bool Compiler::fgExpandThreadLocalAccessForCallNativeAOT(BasicBlock** pBlock, St // [000020] GenTree* tlsCall1 = gtCloneExpr(tlsCallParam1); + tlsCall1->gtFlags &= ~GTF_ICON_TLSGD_OFFSET; + tlsCall1->gtFlags |= GTF_ICON_SECREL_OFFSET; + //gtNewOperNode(GT_COMMA, TYP_I_IMPL, tlsValueDef, + // gtCloneExpr( + // tlsCallParam1)); // TODO: + // // IMAGE_REL_AARCH64_TLSDESC_ADR_PAGE21gtCloneExpr(tlsValueUse); //tlsCall1->SetContained(); GenTree* tlsCallAddr = gtNewIndir(TYP_I_IMPL, tlsCall1, @@ -789,7 +805,10 @@ bool Compiler::fgExpandThreadLocalAccessForCallNativeAOT(BasicBlock** pBlock, St // fallback will just execute first time fallbackBb->bbSetRunRarely(); - fgRemoveRefPred(block, prevBb); + //if (!(TargetOS::IsUnix && TargetArchitecture::IsArm64)) + { + fgRemoveRefPred(block, prevBb); + } fgAddRefPred(tlsRootNullCondBB, prevBb); prevBb->SetTarget(tlsRootNullCondBB); diff --git a/src/coreclr/jit/lsraarm64.cpp b/src/coreclr/jit/lsraarm64.cpp index ea3bc9d7fb37e0..c3b654b46c87e2 100644 --- a/src/coreclr/jit/lsraarm64.cpp +++ b/src/coreclr/jit/lsraarm64.cpp @@ -698,7 +698,13 @@ int LinearScan::BuildNode(GenTree* tree) { srcCount = 0; assert(dstCount == 1); - RefPosition* def = BuildDef(tree); + regMaskTP mask = RBM_NONE; + if (tree->gtTreeID == 21) + //if (tree->IsIconHandle(GTF_ICON_TLS_HDL) && (tree->AsIntCon()->gtIconVal != 0) && (tree->gtFlags & GTF_ICON_SECREL_OFFSET)) + { + mask = genRegMask(REG_R0, TYP_I_IMPL); + } + RefPosition* def = BuildDef(tree, mask); def->getInterval()->isConstant = true; } break; diff --git a/src/coreclr/jit/lsrabuild.cpp b/src/coreclr/jit/lsrabuild.cpp index 0c1d3f74475c8d..404e07bf524d41 100644 --- a/src/coreclr/jit/lsrabuild.cpp +++ b/src/coreclr/jit/lsrabuild.cpp @@ -4129,6 +4129,14 @@ int LinearScan::BuildPutArgReg(GenTreeUnOp* node) int srcCount = 1; GenTree* op1 = node->gtGetOp1(); + //if (compiler->opts.disAsm) + //{ + // if ((op1->gtFlags & GTF_ICON_TLSGD_OFFSET)) + // { + // return 0; + // } + //} + // To avoid redundant moves, have the argument operand computed in the // register in which the argument is passed to the call. regMaskTP argMask = genRegMask(argReg); From 85b3c9898be2414d1e9c90b9e5b8ea0ab37f5793 Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Wed, 31 Jan 2024 20:14:49 -0800 Subject: [PATCH 03/22] more fix --- src/coreclr/jit/lsraarm64.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/jit/lsraarm64.cpp b/src/coreclr/jit/lsraarm64.cpp index c3b654b46c87e2..972aa96b926b46 100644 --- a/src/coreclr/jit/lsraarm64.cpp +++ b/src/coreclr/jit/lsraarm64.cpp @@ -700,7 +700,7 @@ int LinearScan::BuildNode(GenTree* tree) assert(dstCount == 1); regMaskTP mask = RBM_NONE; if (tree->gtTreeID == 21) - //if (tree->IsIconHandle(GTF_ICON_TLS_HDL) && (tree->AsIntCon()->gtIconVal != 0) && (tree->gtFlags & GTF_ICON_SECREL_OFFSET)) + if (((tree->gtFlags & GTF_ICON_SECREL_OFFSET) == GTF_ICON_SECREL_OFFSET)) { mask = genRegMask(REG_R0, TYP_I_IMPL); } From d5d2aa65f76856340e3a3fb8b7f93f7889882d6d Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Wed, 31 Jan 2024 20:17:12 -0800 Subject: [PATCH 04/22] missing build error --- src/coreclr/jit/lsraarm64.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/coreclr/jit/lsraarm64.cpp b/src/coreclr/jit/lsraarm64.cpp index 972aa96b926b46..62ada54354063f 100644 --- a/src/coreclr/jit/lsraarm64.cpp +++ b/src/coreclr/jit/lsraarm64.cpp @@ -699,7 +699,6 @@ int LinearScan::BuildNode(GenTree* tree) srcCount = 0; assert(dstCount == 1); regMaskTP mask = RBM_NONE; - if (tree->gtTreeID == 21) if (((tree->gtFlags & GTF_ICON_SECREL_OFFSET) == GTF_ICON_SECREL_OFFSET)) { mask = genRegMask(REG_R0, TYP_I_IMPL); From ea4b214e0e26ddb1ed81158311022c1cc0850684 Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Wed, 31 Jan 2024 23:44:04 -0800 Subject: [PATCH 05/22] wip --- src/coreclr/jit/codegenarm64.cpp | 16 +++++++++++++++- src/coreclr/jit/codegencommon.cpp | 2 +- src/coreclr/jit/emitarm64.cpp | 16 ++++++++++++---- src/coreclr/jit/helperexpansion.cpp | 18 ++++++++++++------ src/coreclr/jit/lsraarm64.cpp | 14 +++++++++++--- .../Compiler/DependencyAnalysis/Relocation.cs | 7 ++++--- .../tools/Common/JitInterface/CorInfoImpl.cs | 3 +++ 7 files changed, 58 insertions(+), 18 deletions(-) diff --git a/src/coreclr/jit/codegenarm64.cpp b/src/coreclr/jit/codegenarm64.cpp index f52eb6866d79fb..60fca1d24786d5 100644 --- a/src/coreclr/jit/codegenarm64.cpp +++ b/src/coreclr/jit/codegenarm64.cpp @@ -2335,9 +2335,23 @@ void CodeGen::genSetRegToConst(regNumber targetReg, var_types targetType, GenTre attr = EA_SET_FLG(attr, EA_CNS_RELOC_FLG); if (tree->IsIconHandle(GTF_ICON_TLS_HDL)) { - GetEmitter()->emitIns_R(INS_mrs_tpid0, attr, targetReg); + if (tree->AsIntCon()->gtIconVal == 0) + { + GetEmitter()->emitIns_R(INS_mrs_tpid0, attr, targetReg); + } + else + { + attr = EA_SET_FLG(attr, EA_CNS_TLSGD_RELOC); + GetEmitter()->emitIns_R_R_I(INS_ldr, attr, tree->GetReg(), REG_R0, tree->AsIntCon()->gtIconVal); + //GetEmitter()->emitInsLoadStoreOp(INS_lea, attr, targetReg, tree); + } break; } + //else if (tree->IsIconHandle(GTF_ICON_FTN_ADDR) && ((tree->gtFlags & GTF_TLS_GET_ADDR) == GTF_TLS_GET_ADDR)) + //{ + // GetEmitter()->emitIns_R_R(INS_lea, attr, tree->GetReg(), REG_R0); + // break; + //} else if (tree->IsIconHandle(GTF_ICON_TLSGD_OFFSET)) { attr = EA_SET_FLG(attr, EA_CNS_TLSGD_RELOC); diff --git a/src/coreclr/jit/codegencommon.cpp b/src/coreclr/jit/codegencommon.cpp index 639024bafb5f24..179480a06d8401 100644 --- a/src/coreclr/jit/codegencommon.cpp +++ b/src/coreclr/jit/codegencommon.cpp @@ -1695,7 +1695,7 @@ void CodeGen::genGenerateCode(void** codePtr, uint32_t* nativeSizeOfCode) this->codePtr = codePtr; this->nativeSizeOfCode = nativeSizeOfCode; - compiler->opts.dspCode = compiler->opts.disAsm; + //compiler->opts.dspCode = compiler->opts.disAsm; DoPhase(this, PHASE_GENERATE_CODE, &CodeGen::genGenerateMachineCode); DoPhase(this, PHASE_EMIT_CODE, &CodeGen::genEmitMachineCode); DoPhase(this, PHASE_EMIT_GCEH, &CodeGen::genEmitUnwindDebugGCandEH); diff --git a/src/coreclr/jit/emitarm64.cpp b/src/coreclr/jit/emitarm64.cpp index 0a5b6bfa386325..6ff20a8a639cf1 100644 --- a/src/coreclr/jit/emitarm64.cpp +++ b/src/coreclr/jit/emitarm64.cpp @@ -227,7 +227,7 @@ void emitter::emitInsSanityCheck(instrDesc* id) assert(isIntegerRegister(id->idReg1()) || // ZR isVectorRegister(id->idReg1())); assert(isIntegerRegister(id->idReg2())); // SP - assert(emitGetInsSC(id) == 0); + assert((emitGetInsSC(id) == 0) || (id->idIsTlsGD())); assert(insOptsNone(id->idInsOpt())); break; @@ -8359,7 +8359,7 @@ void emitter::emitIns_R_R_I( reg2 = encodingSPtoZR(reg2); ssize_t mask = (1 << scale) - 1; // the mask of low bits that must be zero to encode the immediate - if (imm == 0) + if (imm == 0 || EA_IS_CNS_TLSGD_RELOC(attr)) { assert(insOptsNone(opt)); // PRE/POST Index doesn't make sense with an immediate of zero @@ -8468,7 +8468,7 @@ void emitter::emitIns_R_R_I( id->idReg2(reg2); if (EA_IS_CNS_TLSGD_RELOC(attr)) { - id->idSetTlsGD(); + id->idSetTlsGD(); //TODO: This is getting called more than needed. Investigate. } dispIns(id); appendToCurIG(id); @@ -16124,6 +16124,10 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) sz = id->idIsLargeCall() ? sizeof(instrDescCGCA) : sizeof(instrDesc); dst += emitOutputCall(ig, dst, id, code); + if (id->idIsTlsGD()) + { + + } break; case IF_LS_1A: // LS_1A XX...V..iiiiiiii iiiiiiiiiiittttt Rt PC imm(1MB) @@ -16152,6 +16156,10 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) } code |= insEncodeReg_Rn(id->idReg2()); // nnnnn dst += emitOutput_Instr(dst, code); + if (id->idIsTlsGD() && id->idIsLargeCns()) + { + emitRecordRelocation(odst, (void*)emitGetInsSC(id), IMAGE_REL_AARCH64_TLSDESC_LD64_LO12); + } break; case IF_LS_2B: // LS_2B .X.......Xiiiiii iiiiiinnnnnttttt Rt Rn imm(0-4095) @@ -19213,7 +19221,7 @@ void emitter::emitDispInsHelp( case IF_LS_2A: // LS_2A .X.......X...... ......nnnnnttttt Rt Rn assert(insOptsNone(id->idInsOpt())); - assert(emitGetInsSC(id) == 0); + assert((emitGetInsSC(id) == 0) || id->idIsTlsGD()); emitDispReg(id->idReg1(), emitInsTargetRegSize(id), true); emitDispAddrRI(id->idReg2(), id->idInsOpt(), 0); break; diff --git a/src/coreclr/jit/helperexpansion.cpp b/src/coreclr/jit/helperexpansion.cpp index 023896078774fc..6652f486441e48 100644 --- a/src/coreclr/jit/helperexpansion.cpp +++ b/src/coreclr/jit/helperexpansion.cpp @@ -711,10 +711,15 @@ bool Compiler::fgExpandThreadLocalAccessForCallNativeAOT(BasicBlock** pBlock, St // gtCloneExpr( // tlsCallParam1)); // TODO: // // IMAGE_REL_AARCH64_TLSDESC_ADR_PAGE21gtCloneExpr(tlsValueUse); - //tlsCall1->SetContained(); - GenTree* tlsCallAddr = - gtNewIndir(TYP_I_IMPL, tlsCall1, - GTF_IND_NONFAULTING | GTF_IND_INVARIANT); // IMAGE_REL_AARCH64_TLSDESC_LD64_LO12 + ////tlsCall1->SetContained(); + //GenTree* tlsCallAddr = + // gtNewIndir(TYP_I_IMPL, tlsCall1, + // GTF_IND_NONFAULTING | GTF_IND_INVARIANT); // IMAGE_REL_AARCH64_TLSDESC_LD64_LO12 + + /*GenTree* tls_get_addr_val = + gtNewIconHandleNode((size_t)threadStaticInfo.tlsGetAddrFtnPtr.handle, GTF_ICON_TLS_HDL);*/ + //tls_get_addr_val->gtFlags |= GTF_TLS_GET_ADDR + //tls_get_addr_val->SetContained(); //// param1 //// @@ -724,14 +729,15 @@ bool Compiler::fgExpandThreadLocalAccessForCallNativeAOT(BasicBlock** pBlock, St // [000021] - GenTreeCall* tlsRefCall = gtNewIndCallNode(tlsCallAddr, TYP_I_IMPL); + GenTree* tlsCallIndir = gtCloneExpr(tlsRootOffset); + GenTreeCall* tlsRefCall = gtNewIndCallNode(tlsCallIndir, TYP_I_IMPL); tlsRefCall->gtFlags |= GTF_TLS_GET_ADDR; tlsRefCall->gtArgs.PushBack(this, NewCallArg::Primitive(tlsCallParam1)); tlsRefCall->gtArgs.PushBack(this, NewCallArg::Primitive(gtNewIconHandleNode(0, GTF_ICON_TLS_HDL))); fgMorphArgs(tlsRefCall); - tlsRefCall->gtFlags |= GTF_EXCEPT | (tlsCallAddr->gtFlags & GTF_GLOB_EFFECT); + tlsRefCall->gtFlags |= GTF_EXCEPT | (tlsCallIndir->gtFlags & GTF_GLOB_EFFECT); tlsRootAddr = tlsRefCall; } else diff --git a/src/coreclr/jit/lsraarm64.cpp b/src/coreclr/jit/lsraarm64.cpp index 62ada54354063f..fc8e5bba5865eb 100644 --- a/src/coreclr/jit/lsraarm64.cpp +++ b/src/coreclr/jit/lsraarm64.cpp @@ -699,9 +699,17 @@ int LinearScan::BuildNode(GenTree* tree) srcCount = 0; assert(dstCount == 1); regMaskTP mask = RBM_NONE; - if (((tree->gtFlags & GTF_ICON_SECREL_OFFSET) == GTF_ICON_SECREL_OFFSET)) - { - mask = genRegMask(REG_R0, TYP_I_IMPL); + //if (((tree->gtFlags & GTF_ICON_SECREL_OFFSET) == GTF_ICON_SECREL_OFFSET)) + //{ + // mask = genRegMask(REG_R0, TYP_I_IMPL); + //} + //else if (tree->IsIconHandle(GTF_ICON_TLS_HDL) && tree->AsIntCon()->IconValue() == 0) + //{ + // mask = genRegMask(REG_R1, TYP_I_IMPL); + //} + if (tree->IsIconHandle(GTF_ICON_TLS_HDL) && tree->AsIntCon()->IconValue() != 0) + { + mask = genRegMask(REG_R2, TYP_I_IMPL); //TODO: This also gets called for things unneeded // [000033] } RefPosition* def = BuildDef(tree, mask); def->getInterval()->isConstant = true; diff --git a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Relocation.cs b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Relocation.cs index 1ad30f4309dafc..c168e21832f379 100644 --- a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Relocation.cs +++ b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Relocation.cs @@ -475,9 +475,8 @@ public static unsafe void WriteValue(RelocType relocType, void* location, long v case RelocType.IMAGE_REL_TPOFF: case RelocType.IMAGE_REL_SYMBOL_SIZE: case RelocType.IMAGE_REL_FILE_ABSOLUTE: - case RelocType.IMAGE_REL_AARCH64_TLSDESC_ADR_PAGE21: - case RelocType.IMAGE_REL_AARCH64_TLSDESC_ADD_LO12: - * (int*)location = (int)value; + case RelocType.IMAGE_REL_AARCH64_TLSDESC_LD64_LO12: + *(int*)location = (int)value; break; case RelocType.IMAGE_REL_BASED_DIR64: *(long*)location = value; @@ -493,9 +492,11 @@ public static unsafe void WriteValue(RelocType relocType, void* location, long v PutArm64Rel28((uint*)location, value); break; case RelocType.IMAGE_REL_BASED_ARM64_PAGEBASE_REL21: + case RelocType.IMAGE_REL_AARCH64_TLSDESC_ADR_PAGE21: PutArm64Rel21((uint*)location, (int)value); break; case RelocType.IMAGE_REL_BASED_ARM64_PAGEOFFSET_12A: + case RelocType.IMAGE_REL_AARCH64_TLSDESC_ADD_LO12: PutArm64Rel12((uint*)location, (int)value); break; case RelocType.IMAGE_REL_BASED_LOONGARCH64_PC: diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs index c26c1a6f9005d3..0c226edd1ef5c1 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs @@ -3876,6 +3876,7 @@ private static RelocType GetRelocType(TargetArchitecture targetArchitecture, ush const ushort IMAGE_REL_ARM64_PAGEBASE_REL21 = 4; const ushort IMAGE_REL_ARM64_PAGEOFFSET_12A = 6; const ushort IMAGE_REL_ARM64_TLSDESC_ADR_PAGE21 = 0x107; + const ushort IMAGE_REL_ARM64_TLSDESC_LD64_LO12 = 0x108; const ushort IMAGE_REL_ARM64_TLSDESC_ADD_LO12 = 0x109; switch (fRelocType) @@ -3890,6 +3891,8 @@ private static RelocType GetRelocType(TargetArchitecture targetArchitecture, ush return RelocType.IMAGE_REL_AARCH64_TLSDESC_ADR_PAGE21; case IMAGE_REL_ARM64_TLSDESC_ADD_LO12: return RelocType.IMAGE_REL_AARCH64_TLSDESC_ADD_LO12; + case IMAGE_REL_ARM64_TLSDESC_LD64_LO12: + return RelocType.IMAGE_REL_AARCH64_TLSDESC_LD64_LO12; default: Debug.Fail("Invalid RelocType: " + fRelocType); return 0; From db02c45dbfd04b65659cc7f76dbbacf7529a99b0 Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Wed, 31 Jan 2024 23:59:40 -0800 Subject: [PATCH 06/22] fixes --- src/coreclr/jit/codegenarm64.cpp | 2 +- src/coreclr/jit/emitarm64.cpp | 2 +- .../tools/Common/Compiler/DependencyAnalysis/Relocation.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/coreclr/jit/codegenarm64.cpp b/src/coreclr/jit/codegenarm64.cpp index 60fca1d24786d5..c0dfdccfdd4a08 100644 --- a/src/coreclr/jit/codegenarm64.cpp +++ b/src/coreclr/jit/codegenarm64.cpp @@ -2342,7 +2342,7 @@ void CodeGen::genSetRegToConst(regNumber targetReg, var_types targetType, GenTre else { attr = EA_SET_FLG(attr, EA_CNS_TLSGD_RELOC); - GetEmitter()->emitIns_R_R_I(INS_ldr, attr, tree->GetReg(), REG_R0, tree->AsIntCon()->gtIconVal); + GetEmitter()->emitIns_R_R_I(INS_ldr, attr, tree->GetRegNum(), REG_R0, tree->AsIntCon()->gtIconVal); //GetEmitter()->emitInsLoadStoreOp(INS_lea, attr, targetReg, tree); } break; diff --git a/src/coreclr/jit/emitarm64.cpp b/src/coreclr/jit/emitarm64.cpp index 6ff20a8a639cf1..197c3cdc523b8f 100644 --- a/src/coreclr/jit/emitarm64.cpp +++ b/src/coreclr/jit/emitarm64.cpp @@ -16158,7 +16158,7 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) dst += emitOutput_Instr(dst, code); if (id->idIsTlsGD() && id->idIsLargeCns()) { - emitRecordRelocation(odst, (void*)emitGetInsSC(id), IMAGE_REL_AARCH64_TLSDESC_LD64_LO12); + emitRecordRelocation(dst, (void*)emitGetInsSC(id), IMAGE_REL_AARCH64_TLSDESC_LD64_LO12); } break; diff --git a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Relocation.cs b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Relocation.cs index c168e21832f379..6938b19290449c 100644 --- a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Relocation.cs +++ b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Relocation.cs @@ -539,6 +539,7 @@ public static unsafe long ReadValue(RelocType relocType, void* location) case RelocType.IMAGE_REL_TPOFF: case RelocType.IMAGE_REL_FILE_ABSOLUTE: case RelocType.IMAGE_REL_SYMBOL_SIZE: + case RelocType.IMAGE_REL_AARCH64_TLSDESC_LD64_LO12: return *(int*)location; case RelocType.IMAGE_REL_BASED_DIR64: return *(long*)location; @@ -553,7 +554,6 @@ public static unsafe long ReadValue(RelocType relocType, void* location) return GetArm64Rel21((uint*)location); case RelocType.IMAGE_REL_BASED_ARM64_PAGEOFFSET_12A: return GetArm64Rel12((uint*)location); - case RelocType.IMAGE_REL_AARCH64_TLSDESC_LD64_LO12: case RelocType.IMAGE_REL_AARCH64_TLSDESC_ADD_LO12: case RelocType.IMAGE_REL_AARCH64_TLSLE_ADD_TPREL_HI12: case RelocType.IMAGE_REL_AARCH64_TLSLE_ADD_TPREL_LO12_NC: From 349167b4a9ecec1f6f0e5adab9122f0412d9ee49 Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Thu, 1 Feb 2024 00:23:12 -0800 Subject: [PATCH 07/22] fix --- src/coreclr/jit/emitarm64.cpp | 2 +- .../tools/Common/Compiler/DependencyAnalysis/Relocation.cs | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/coreclr/jit/emitarm64.cpp b/src/coreclr/jit/emitarm64.cpp index 197c3cdc523b8f..6ff20a8a639cf1 100644 --- a/src/coreclr/jit/emitarm64.cpp +++ b/src/coreclr/jit/emitarm64.cpp @@ -16158,7 +16158,7 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) dst += emitOutput_Instr(dst, code); if (id->idIsTlsGD() && id->idIsLargeCns()) { - emitRecordRelocation(dst, (void*)emitGetInsSC(id), IMAGE_REL_AARCH64_TLSDESC_LD64_LO12); + emitRecordRelocation(odst, (void*)emitGetInsSC(id), IMAGE_REL_AARCH64_TLSDESC_LD64_LO12); } break; diff --git a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Relocation.cs b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Relocation.cs index 6938b19290449c..4321a900129e62 100644 --- a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Relocation.cs +++ b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Relocation.cs @@ -475,9 +475,10 @@ public static unsafe void WriteValue(RelocType relocType, void* location, long v case RelocType.IMAGE_REL_TPOFF: case RelocType.IMAGE_REL_SYMBOL_SIZE: case RelocType.IMAGE_REL_FILE_ABSOLUTE: - case RelocType.IMAGE_REL_AARCH64_TLSDESC_LD64_LO12: *(int*)location = (int)value; break; + case RelocType.IMAGE_REL_AARCH64_TLSDESC_LD64_LO12: + break; case RelocType.IMAGE_REL_BASED_DIR64: *(long*)location = value; break; From da88ed4a190843f4f57c0473ce63baa829893042 Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Thu, 1 Feb 2024 17:26:43 -0800 Subject: [PATCH 08/22] Add IMAGE_REL_AARCH64_TLSDESC_CALL --- src/coreclr/jit/codegenarmarch.cpp | 12 ++++++++++++ src/coreclr/jit/emitarm64.cpp | 7 ++++++- .../Common/Compiler/DependencyAnalysis/Relocation.cs | 1 + src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs | 4 ++++ 4 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/coreclr/jit/codegenarmarch.cpp b/src/coreclr/jit/codegenarmarch.cpp index cb04cf702f2b94..9a941473bfc5b1 100644 --- a/src/coreclr/jit/codegenarmarch.cpp +++ b/src/coreclr/jit/codegenarmarch.cpp @@ -3555,6 +3555,11 @@ void CodeGen::genCallInstruction(GenTreeCall* call) } } + if (call->gtFlags & GTF_TLS_GET_ADDR) + { + retSize = EA_SET_FLG(retSize, EA_CNS_TLSGD_RELOC); + } + DebugInfo di; // We need to propagate the debug information to the call instruction, so we can emit // an IL to native mapping record for the call, to support managed return value debugging. @@ -3623,6 +3628,13 @@ void CodeGen::genCallInstruction(GenTreeCall* call) // assert(genIsValidIntReg(target->GetRegNum())); + if (call->gtFlags & GTF_TLS_GET_ADDR) + { + GenTree* mthdHandle = (GenTree*)call->gtCallMethHnd; + assert(mthdHandle != nullptr && mthdHandle->IsIconHandle(GTF_ICON_TLS_HDL)); + methHnd = (CORINFO_METHOD_HANDLE) mthdHandle->AsIntCon()->gtIconVal; + } + // clang-format off genEmitCall(emitter::EC_INDIR_R, methHnd, diff --git a/src/coreclr/jit/emitarm64.cpp b/src/coreclr/jit/emitarm64.cpp index 6ff20a8a639cf1..9e4edf4804a3f7 100644 --- a/src/coreclr/jit/emitarm64.cpp +++ b/src/coreclr/jit/emitarm64.cpp @@ -13193,6 +13193,10 @@ void emitter::emitIns_Call(EmitCallType callType, id->idReg3(ireg); assert(xreg == REG_NA); + if (EA_IS_CNS_TLSGD_RELOC(retSize)) + { + id->idSetTlsGD(); + } } else { @@ -16126,7 +16130,8 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) dst += emitOutputCall(ig, dst, id, code); if (id->idIsTlsGD()) { - + emitRecordRelocation(odst, (CORINFO_METHOD_HANDLE)id->idDebugOnlyInfo()->idMemCookie, + IMAGE_REL_AARCH64_TLSDESC_CALL); } break; diff --git a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Relocation.cs b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Relocation.cs index 4321a900129e62..471fd45d5665c8 100644 --- a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Relocation.cs +++ b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Relocation.cs @@ -478,6 +478,7 @@ public static unsafe void WriteValue(RelocType relocType, void* location, long v *(int*)location = (int)value; break; case RelocType.IMAGE_REL_AARCH64_TLSDESC_LD64_LO12: + case RelocType.IMAGE_REL_AARCH64_TLSDESC_CALL: break; case RelocType.IMAGE_REL_BASED_DIR64: *(long*)location = value; diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs index 0c226edd1ef5c1..f2643a12daa9cc 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs @@ -3878,6 +3878,8 @@ private static RelocType GetRelocType(TargetArchitecture targetArchitecture, ush const ushort IMAGE_REL_ARM64_TLSDESC_ADR_PAGE21 = 0x107; const ushort IMAGE_REL_ARM64_TLSDESC_LD64_LO12 = 0x108; const ushort IMAGE_REL_ARM64_TLSDESC_ADD_LO12 = 0x109; + const ushort IMAGE_REL_ARM64_TLSDESC_CALL = 0x10A; + switch (fRelocType) { @@ -3893,6 +3895,8 @@ private static RelocType GetRelocType(TargetArchitecture targetArchitecture, ush return RelocType.IMAGE_REL_AARCH64_TLSDESC_ADD_LO12; case IMAGE_REL_ARM64_TLSDESC_LD64_LO12: return RelocType.IMAGE_REL_AARCH64_TLSDESC_LD64_LO12; + case IMAGE_REL_ARM64_TLSDESC_CALL: + return RelocType.IMAGE_REL_AARCH64_TLSDESC_CALL; default: Debug.Fail("Invalid RelocType: " + fRelocType); return 0; From 70d53bd0e568f02fe0702208a66b6eb462ad9107 Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Fri, 2 Feb 2024 07:34:18 -0800 Subject: [PATCH 09/22] Use GT_CALL to emit everything --- src/coreclr/jit/codegenarm64.cpp | 20 ++++---- src/coreclr/jit/codegenarmarch.cpp | 17 ++++++- src/coreclr/jit/helperexpansion.cpp | 73 +++++++++++++++++++++++------ src/coreclr/jit/lsraarmarch.cpp | 9 ++++ 4 files changed, 93 insertions(+), 26 deletions(-) diff --git a/src/coreclr/jit/codegenarm64.cpp b/src/coreclr/jit/codegenarm64.cpp index c0dfdccfdd4a08..c490492daede6a 100644 --- a/src/coreclr/jit/codegenarm64.cpp +++ b/src/coreclr/jit/codegenarm64.cpp @@ -2335,16 +2335,16 @@ void CodeGen::genSetRegToConst(regNumber targetReg, var_types targetType, GenTre attr = EA_SET_FLG(attr, EA_CNS_RELOC_FLG); if (tree->IsIconHandle(GTF_ICON_TLS_HDL)) { - if (tree->AsIntCon()->gtIconVal == 0) - { - GetEmitter()->emitIns_R(INS_mrs_tpid0, attr, targetReg); - } - else - { - attr = EA_SET_FLG(attr, EA_CNS_TLSGD_RELOC); - GetEmitter()->emitIns_R_R_I(INS_ldr, attr, tree->GetRegNum(), REG_R0, tree->AsIntCon()->gtIconVal); - //GetEmitter()->emitInsLoadStoreOp(INS_lea, attr, targetReg, tree); - } + //if (tree->AsIntCon()->gtIconVal == 0) + //{ + // GetEmitter()->emitIns_R(INS_mrs_tpid0, attr, targetReg); + //} + //else + //{ + // attr = EA_SET_FLG(attr, EA_CNS_TLSGD_RELOC); + // GetEmitter()->emitIns_R_R_I(INS_ldr, attr, tree->GetRegNum(), REG_R0, tree->AsIntCon()->gtIconVal); + // //GetEmitter()->emitInsLoadStoreOp(INS_lea, attr, targetReg, tree); + //} break; } //else if (tree->IsIconHandle(GTF_ICON_FTN_ADDR) && ((tree->gtFlags & GTF_TLS_GET_ADDR) == GTF_TLS_GET_ADDR)) diff --git a/src/coreclr/jit/codegenarmarch.cpp b/src/coreclr/jit/codegenarmarch.cpp index 9a941473bfc5b1..a3cf8a914546ab 100644 --- a/src/coreclr/jit/codegenarmarch.cpp +++ b/src/coreclr/jit/codegenarmarch.cpp @@ -3628,11 +3628,19 @@ void CodeGen::genCallInstruction(GenTreeCall* call) // assert(genIsValidIntReg(target->GetRegNum())); - if (call->gtFlags & GTF_TLS_GET_ADDR) + bool specialCase = call->gtFlags & GTF_TLS_GET_ADDR; + if (specialCase) { GenTree* mthdHandle = (GenTree*)call->gtCallMethHnd; assert(mthdHandle != nullptr && mthdHandle->IsIconHandle(GTF_ICON_TLS_HDL)); - methHnd = (CORINFO_METHOD_HANDLE) mthdHandle->AsIntCon()->gtIconVal; + GenTreeIntCon* iconNode = mthdHandle->AsIntCon(); + methHnd = (CORINFO_METHOD_HANDLE)iconNode->gtIconVal; + emitter* emit = GetEmitter(); + emitAttr attr = (emitAttr)(EA_CNS_TLSGD_RELOC | EA_CNS_RELOC_FLG | EA_8BYTE); + instGen_Set_Reg_To_Imm(attr, REG_R0, (ssize_t)methHnd, + INS_FLAGS_DONT_CARE DEBUGARG(iconNode->gtTargetHandle) DEBUGARG(iconNode->gtFlags)); + emit->emitIns_R(INS_mrs_tpid0, attr, REG_R1); + emit->emitIns_R_R_I(INS_ldr, attr, target->GetRegNum(), REG_R0, (ssize_t)methHnd); } // clang-format off @@ -3645,6 +3653,11 @@ void CodeGen::genCallInstruction(GenTreeCall* call) di, target->GetRegNum(), call->IsFastTailCall()); + + if (specialCase) + { + GetEmitter()->emitIns_R_R_R(INS_add, EA_8BYTE, REG_R0, REG_R1, REG_R0); + } // clang-format on } else diff --git a/src/coreclr/jit/helperexpansion.cpp b/src/coreclr/jit/helperexpansion.cpp index 6652f486441e48..bc26c94af3fadd 100644 --- a/src/coreclr/jit/helperexpansion.cpp +++ b/src/coreclr/jit/helperexpansion.cpp @@ -663,13 +663,13 @@ bool Compiler::fgExpandThreadLocalAccessForCallNativeAOT(BasicBlock** pBlock, St */ - unsigned tlsLclNum = lvaGrabTemp(true DEBUGARG("TLS access")); - lvaTable[tlsLclNum].lvType = TYP_I_IMPL; + /*unsigned tlsLclNum = lvaGrabTemp(true DEBUGARG("TLS access")); + lvaTable[tlsLclNum].lvType = TYP_I_IMPL;*/ GenTree* tlsRootOffset = gtNewIconHandleNode((size_t)tlsRootObject, GTF_ICON_TLS_HDL); // [000016] - GenTree* tlsValueDef = gtNewStoreLclVarNode(tlsLclNum, tlsRootOffset); // [000017] + //GenTree* tlsValueDef = gtNewStoreLclVarNode(tlsLclNum, tlsRootOffset); // [000017] //tlsValueDef->gtFlags - GenTree* tlsValueUse = gtNewLclVarNode(tlsLclNum); // [000018] - GenTree* tlsDefUse = gtNewOperNode(GT_COMMA, TYP_I_IMPL, tlsValueDef, tlsValueUse); + //GenTree* tlsValueUse = gtNewLclVarNode(tlsLclNum); // [000018] + //GenTree* tlsDefUse = gtNewOperNode(GT_COMMA, TYP_I_IMPL, tlsValueDef, tlsValueUse); //fgInsertStmtAtBeg(block, fgNewStmtFromTree(tlsValueDef)); @@ -678,9 +678,6 @@ bool Compiler::fgExpandThreadLocalAccessForCallNativeAOT(BasicBlock** pBlock, St newBlock->SetTarget(block); fgAddRefPred(block, newBlock);*/ - - - //tlsRootOffset->gtFlags |= GTF_ICON_SECREL_OFFSET; // param1 @@ -689,6 +686,8 @@ bool Compiler::fgExpandThreadLocalAccessForCallNativeAOT(BasicBlock** pBlock, St tlsCallParam1->gtFlags &= ~GTF_ICON_TLS_HDL; // [000017] tlsCallParam1->gtFlags |= GTF_ICON_TLSGD_OFFSET; // [000017] + GenTree* tlsCallParam2 = gtNewIconHandleNode(0, GTF_ICON_TLS_HDL); + //tlsCallParam2->SetContained(); //unsigned tlsRootAddrLclNum = lvaGrabTemp(true DEBUGARG("TlsRootAddr access")); @@ -704,9 +703,9 @@ bool Compiler::fgExpandThreadLocalAccessForCallNativeAOT(BasicBlock** pBlock, St // [000020] - GenTree* tlsCall1 = gtCloneExpr(tlsCallParam1); - tlsCall1->gtFlags &= ~GTF_ICON_TLSGD_OFFSET; - tlsCall1->gtFlags |= GTF_ICON_SECREL_OFFSET; + //GenTree* tlsCall1 = gtCloneExpr(tlsCallParam1); + //tlsCall1->gtFlags &= ~GTF_ICON_TLSGD_OFFSET; + //tlsCall1->gtFlags |= GTF_ICON_SECREL_OFFSET; //gtNewOperNode(GT_COMMA, TYP_I_IMPL, tlsValueDef, // gtCloneExpr( // tlsCallParam1)); // TODO: @@ -727,17 +726,63 @@ bool Compiler::fgExpandThreadLocalAccessForCallNativeAOT(BasicBlock** pBlock, St // gtNewIconNode(0, TYP_INT)); // IMAGE_REL_AARCH64_TLSDESC_ADD_LO12 - + //GenTree* newCallIndir = gtNewIconHandleNode((size_t)tlsRootObject, GTF_ICON_TLS_HDL); + //GenTree* newParam1 = gtNewIconHandleNode(0, GTF_ICON_TLS_HDL); + // [000021] GenTree* tlsCallIndir = gtCloneExpr(tlsRootOffset); GenTreeCall* tlsRefCall = gtNewIndCallNode(tlsCallIndir, TYP_I_IMPL); tlsRefCall->gtFlags |= GTF_TLS_GET_ADDR; - tlsRefCall->gtArgs.PushBack(this, NewCallArg::Primitive(tlsCallParam1)); - tlsRefCall->gtArgs.PushBack(this, NewCallArg::Primitive(gtNewIconHandleNode(0, GTF_ICON_TLS_HDL))); + //tlsRefCall->gtArgs.PushBack(this, NewCallArg::Primitive(tlsCallParam1)); + //tlsRefCall->gtArgs.PushBack(this, NewCallArg::Primitive(tlsCallParam2)); fgMorphArgs(tlsRefCall); tlsRefCall->gtFlags |= GTF_EXCEPT | (tlsCallIndir->gtFlags & GTF_GLOB_EFFECT); + + ////// For x0 = x1 + x0 + //unsigned tlsRefResultNum = lvaGrabTemp(true DEBUGARG("TLS call addr result")); + //lvaTable[tlsRefResultNum].lvType = TYP_I_IMPL; + //GenTree* tlsRefCallDef = gtNewStoreLclVarNode(tlsRefResultNum, tlsRefCall); + //GenTree* tlsRefCallUse = gtNewLclVarNode(tlsRefResultNum); + + ////unsigned tebNum = lvaGrabTemp(true DEBUGARG("MRS result")); + ////lvaTable[tebNum].lvType = TYP_I_IMPL; + ////GenTree* tebResultDef = gtNewStoreLclVarNode(tebNum, tlsCallParam2); + ////GenTree* tebResultUse = gtNewLclVarNode(tebNum); + + ////fgInsertStmtAtBeg(block, fgNewStmtFromTree(tlsRefCallDef)); + + + + //tlsRootAddr = gtNewOperNode(GT_ADD, TYP_I_IMPL, tlsRefCallUse, gtCloneExpr(tlsCallParam2)); + + if (verbose) + { + printf("tlsRootOffset:\n"); + DISPTREE(tlsRootOffset); + printf("tlsCallParam1:\n"); + DISPTREE(tlsCallParam1); + printf("tlsCallParam2:\n"); + DISPTREE(tlsCallParam2); + printf("tlsCallIndir:\n"); + DISPTREE(tlsCallIndir); + printf("tlsRefCall:\n"); + DISPTREE(tlsRefCall); + //printf("tlsRefCallDef:\n"); + //DISPTREE(tlsRefCallDef); + printf("tlsRootAddr:\n"); + DISPTREE(tlsRootAddr); + + //DISPTREE(tlsRefCallDef); + //printf("tlsRefCallUse:\n"); + //DISPTREE(tlsRefCallUse); + //printf("tebResultDef:\n"); + //DISPTREE(tebResultDef); + //printf("tebResultUse:\n"); + //DISPTREE(tebResultUse); + } + tlsRootAddr = tlsRefCall; } else diff --git a/src/coreclr/jit/lsraarmarch.cpp b/src/coreclr/jit/lsraarmarch.cpp index 8b1305caec52ae..e6e21d9bb63dc3 100644 --- a/src/coreclr/jit/lsraarmarch.cpp +++ b/src/coreclr/jit/lsraarmarch.cpp @@ -368,6 +368,15 @@ int LinearScan::BuildCall(GenTreeCall* call) if (ctrlExpr != nullptr) { + if (ctrlExpr->IsIconHandle(GTF_ICON_TLS_HDL) && call->gtArgs.CountArgs() == 0) + { + /*BuildUse(ctrlExpr, genRegMask(REG_R0)); + BuildUse(ctrlExpr, genRegMask(REG_R1));*/ + //addRefsForPhysRegMask(genRegMask(REG_R0) | genRegMask(REG_R1), currentLoc + 1, RefTypeFixedReg, true); + newRefPosition(REG_R0, currentLoc, RefTypeFixedReg, nullptr, genRegMask(REG_R0)); + newRefPosition(REG_R1, currentLoc, RefTypeFixedReg, nullptr, genRegMask(REG_R1)); + ctrlExprCandidates = genRegMask(REG_R2); + } BuildUse(ctrlExpr, ctrlExprCandidates); srcCount++; } From 3edff407d3caf756b2c64446e732d13696ca650e Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Fri, 2 Feb 2024 10:11:02 -0800 Subject: [PATCH 10/22] fix the loading of slow helper --- src/coreclr/jit/codegenarm64.cpp | 3 ++- src/coreclr/jit/codegenarmarch.cpp | 3 ++- src/coreclr/jit/helperexpansion.cpp | 1 + src/coreclr/jit/lsraarm64.cpp | 5 +++-- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/coreclr/jit/codegenarm64.cpp b/src/coreclr/jit/codegenarm64.cpp index c490492daede6a..75f56d3849895c 100644 --- a/src/coreclr/jit/codegenarm64.cpp +++ b/src/coreclr/jit/codegenarm64.cpp @@ -2335,6 +2335,7 @@ void CodeGen::genSetRegToConst(regNumber targetReg, var_types targetType, GenTre attr = EA_SET_FLG(attr, EA_CNS_RELOC_FLG); if (tree->IsIconHandle(GTF_ICON_TLS_HDL)) { + attr = EA_SET_FLG(attr, EA_CNS_TLSGD_RELOC); //if (tree->AsIntCon()->gtIconVal == 0) //{ // GetEmitter()->emitIns_R(INS_mrs_tpid0, attr, targetReg); @@ -2345,7 +2346,7 @@ void CodeGen::genSetRegToConst(regNumber targetReg, var_types targetType, GenTre // GetEmitter()->emitIns_R_R_I(INS_ldr, attr, tree->GetRegNum(), REG_R0, tree->AsIntCon()->gtIconVal); // //GetEmitter()->emitInsLoadStoreOp(INS_lea, attr, targetReg, tree); //} - break; + //break; } //else if (tree->IsIconHandle(GTF_ICON_FTN_ADDR) && ((tree->gtFlags & GTF_TLS_GET_ADDR) == GTF_TLS_GET_ADDR)) //{ diff --git a/src/coreclr/jit/codegenarmarch.cpp b/src/coreclr/jit/codegenarmarch.cpp index a3cf8a914546ab..12b8384226d56c 100644 --- a/src/coreclr/jit/codegenarmarch.cpp +++ b/src/coreclr/jit/codegenarmarch.cpp @@ -3632,7 +3632,8 @@ void CodeGen::genCallInstruction(GenTreeCall* call) if (specialCase) { GenTree* mthdHandle = (GenTree*)call->gtCallMethHnd; - assert(mthdHandle != nullptr && mthdHandle->IsIconHandle(GTF_ICON_TLS_HDL)); + GenTreeFlags tlsFlags = (GTF_ICON_TLSGD_OFFSET | GTF_ICON_TLS_HDL); + assert(mthdHandle != nullptr && ((mthdHandle->gtFlags & tlsFlags) == tlsFlags)); GenTreeIntCon* iconNode = mthdHandle->AsIntCon(); methHnd = (CORINFO_METHOD_HANDLE)iconNode->gtIconVal; emitter* emit = GetEmitter(); diff --git a/src/coreclr/jit/helperexpansion.cpp b/src/coreclr/jit/helperexpansion.cpp index bc26c94af3fadd..6735c2c12730c0 100644 --- a/src/coreclr/jit/helperexpansion.cpp +++ b/src/coreclr/jit/helperexpansion.cpp @@ -666,6 +666,7 @@ bool Compiler::fgExpandThreadLocalAccessForCallNativeAOT(BasicBlock** pBlock, St /*unsigned tlsLclNum = lvaGrabTemp(true DEBUGARG("TLS access")); lvaTable[tlsLclNum].lvType = TYP_I_IMPL;*/ GenTree* tlsRootOffset = gtNewIconHandleNode((size_t)tlsRootObject, GTF_ICON_TLS_HDL); // [000016] + tlsRootOffset->gtFlags |= GTF_ICON_TLSGD_OFFSET; //GenTree* tlsValueDef = gtNewStoreLclVarNode(tlsLclNum, tlsRootOffset); // [000017] //tlsValueDef->gtFlags //GenTree* tlsValueUse = gtNewLclVarNode(tlsLclNum); // [000018] diff --git a/src/coreclr/jit/lsraarm64.cpp b/src/coreclr/jit/lsraarm64.cpp index fc8e5bba5865eb..a3fee3de6b5101 100644 --- a/src/coreclr/jit/lsraarm64.cpp +++ b/src/coreclr/jit/lsraarm64.cpp @@ -707,9 +707,10 @@ int LinearScan::BuildNode(GenTree* tree) //{ // mask = genRegMask(REG_R1, TYP_I_IMPL); //} - if (tree->IsIconHandle(GTF_ICON_TLS_HDL) && tree->AsIntCon()->IconValue() != 0) + if ((tree->gtFlags & (GTF_ICON_TLSGD_OFFSET | GTF_ICON_TLS_HDL)) == + (GTF_ICON_TLSGD_OFFSET | GTF_ICON_TLS_HDL)) { - mask = genRegMask(REG_R2, TYP_I_IMPL); //TODO: This also gets called for things unneeded // [000033] + mask = genRegMask(REG_R2, TYP_I_IMPL); //TODO: This also gets called for things unneeded // [000029] } RefPosition* def = BuildDef(tree, mask); def->getInterval()->isConstant = true; From 4c927e2af23ae5822cc10a1586072190efadc61c Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Fri, 2 Feb 2024 10:12:41 -0800 Subject: [PATCH 11/22] fix build error --- src/coreclr/jit/codegenarmarch.cpp | 5 ++- src/coreclr/jit/helperexpansion.cpp | 50 ++++++++++++++--------------- 2 files changed, 29 insertions(+), 26 deletions(-) diff --git a/src/coreclr/jit/codegenarmarch.cpp b/src/coreclr/jit/codegenarmarch.cpp index 12b8384226d56c..eb209da83c6db9 100644 --- a/src/coreclr/jit/codegenarmarch.cpp +++ b/src/coreclr/jit/codegenarmarch.cpp @@ -3628,7 +3628,10 @@ void CodeGen::genCallInstruction(GenTreeCall* call) // assert(genIsValidIntReg(target->GetRegNum())); - bool specialCase = call->gtFlags & GTF_TLS_GET_ADDR; + bool specialCase = false; +#ifdef TARGET_ARM64 + specialCase = call->gtFlags & GTF_TLS_GET_ADDR; +#endif if (specialCase) { GenTree* mthdHandle = (GenTree*)call->gtCallMethHnd; diff --git a/src/coreclr/jit/helperexpansion.cpp b/src/coreclr/jit/helperexpansion.cpp index 6735c2c12730c0..b5c0a3b951ea07 100644 --- a/src/coreclr/jit/helperexpansion.cpp +++ b/src/coreclr/jit/helperexpansion.cpp @@ -758,31 +758,31 @@ bool Compiler::fgExpandThreadLocalAccessForCallNativeAOT(BasicBlock** pBlock, St //tlsRootAddr = gtNewOperNode(GT_ADD, TYP_I_IMPL, tlsRefCallUse, gtCloneExpr(tlsCallParam2)); - if (verbose) - { - printf("tlsRootOffset:\n"); - DISPTREE(tlsRootOffset); - printf("tlsCallParam1:\n"); - DISPTREE(tlsCallParam1); - printf("tlsCallParam2:\n"); - DISPTREE(tlsCallParam2); - printf("tlsCallIndir:\n"); - DISPTREE(tlsCallIndir); - printf("tlsRefCall:\n"); - DISPTREE(tlsRefCall); - //printf("tlsRefCallDef:\n"); - //DISPTREE(tlsRefCallDef); - printf("tlsRootAddr:\n"); - DISPTREE(tlsRootAddr); - - //DISPTREE(tlsRefCallDef); - //printf("tlsRefCallUse:\n"); - //DISPTREE(tlsRefCallUse); - //printf("tebResultDef:\n"); - //DISPTREE(tebResultDef); - //printf("tebResultUse:\n"); - //DISPTREE(tebResultUse); - } + //if (verbose) + //{ + // printf("tlsRootOffset:\n"); + // DISPTREE(tlsRootOffset); + // printf("tlsCallParam1:\n"); + // DISPTREE(tlsCallParam1); + // printf("tlsCallParam2:\n"); + // DISPTREE(tlsCallParam2); + // printf("tlsCallIndir:\n"); + // DISPTREE(tlsCallIndir); + // printf("tlsRefCall:\n"); + // DISPTREE(tlsRefCall); + // //printf("tlsRefCallDef:\n"); + // //DISPTREE(tlsRefCallDef); + // printf("tlsRootAddr:\n"); + // DISPTREE(tlsRootAddr); + + // //DISPTREE(tlsRefCallDef); + // //printf("tlsRefCallUse:\n"); + // //DISPTREE(tlsRefCallUse); + // //printf("tebResultDef:\n"); + // //DISPTREE(tebResultDef); + // //printf("tebResultUse:\n"); + // //DISPTREE(tebResultUse); + //} tlsRootAddr = tlsRefCall; } From 9daf11e06a753fb02772f89e28a9f3861875706b Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Fri, 2 Feb 2024 10:14:15 -0800 Subject: [PATCH 12/22] adjust the endif --- src/coreclr/jit/codegenarmarch.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/jit/codegenarmarch.cpp b/src/coreclr/jit/codegenarmarch.cpp index eb209da83c6db9..8d113150b64f00 100644 --- a/src/coreclr/jit/codegenarmarch.cpp +++ b/src/coreclr/jit/codegenarmarch.cpp @@ -3631,7 +3631,6 @@ void CodeGen::genCallInstruction(GenTreeCall* call) bool specialCase = false; #ifdef TARGET_ARM64 specialCase = call->gtFlags & GTF_TLS_GET_ADDR; -#endif if (specialCase) { GenTree* mthdHandle = (GenTree*)call->gtCallMethHnd; @@ -3646,6 +3645,7 @@ void CodeGen::genCallInstruction(GenTreeCall* call) emit->emitIns_R(INS_mrs_tpid0, attr, REG_R1); emit->emitIns_R_R_I(INS_ldr, attr, target->GetRegNum(), REG_R0, (ssize_t)methHnd); } +#endif // clang-format off genEmitCall(emitter::EC_INDIR_R, From 9830590d81354249fd3e17dc99e9260112b9365c Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Fri, 2 Feb 2024 11:14:56 -0800 Subject: [PATCH 13/22] fix the slow helper relocation --- src/coreclr/jit/codegenarm64.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/coreclr/jit/codegenarm64.cpp b/src/coreclr/jit/codegenarm64.cpp index 75f56d3849895c..3ef30424d4c130 100644 --- a/src/coreclr/jit/codegenarm64.cpp +++ b/src/coreclr/jit/codegenarm64.cpp @@ -2333,9 +2333,11 @@ void CodeGen::genSetRegToConst(regNumber targetReg, var_types targetType, GenTre if (con->ImmedValNeedsReloc(compiler)) { attr = EA_SET_FLG(attr, EA_CNS_RELOC_FLG); + GenTreeFlags tlsFlags = (GTF_ICON_TLSGD_OFFSET | GTF_ICON_TLS_HDL); + if (tree->IsIconHandle(GTF_ICON_TLS_HDL)) { - attr = EA_SET_FLG(attr, EA_CNS_TLSGD_RELOC); + //attr = EA_SET_FLG(attr, EA_CNS_TLSGD_RELOC); //if (tree->AsIntCon()->gtIconVal == 0) //{ // GetEmitter()->emitIns_R(INS_mrs_tpid0, attr, targetReg); @@ -2353,9 +2355,10 @@ void CodeGen::genSetRegToConst(regNumber targetReg, var_types targetType, GenTre // GetEmitter()->emitIns_R_R(INS_lea, attr, tree->GetReg(), REG_R0); // break; //} - else if (tree->IsIconHandle(GTF_ICON_TLSGD_OFFSET)) + else if ((tree->gtFlags & tlsFlags) == tlsFlags) { - attr = EA_SET_FLG(attr, EA_CNS_TLSGD_RELOC); + /*attr = EA_SET_FLG(attr, EA_CNS_TLSGD_RELOC);*/ + break; } } From 259df0bfe9af0222cba3c6544893bd87965c2b34 Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Fri, 2 Feb 2024 12:09:19 -0800 Subject: [PATCH 14/22] cleanup --- src/coreclr/jit/codegenarm64.cpp | 25 +--- src/coreclr/jit/codegenarmarch.cpp | 6 +- src/coreclr/jit/codegencommon.cpp | 1 - src/coreclr/jit/emitarm64.cpp | 7 +- src/coreclr/jit/helperexpansion.cpp | 111 ------------------ src/coreclr/jit/lsraarm64.cpp | 10 +- src/coreclr/jit/lsraarmarch.cpp | 3 - src/coreclr/jit/lsrabuild.cpp | 8 -- .../Compiler/DependencyAnalysis/Relocation.cs | 4 +- 9 files changed, 8 insertions(+), 167 deletions(-) diff --git a/src/coreclr/jit/codegenarm64.cpp b/src/coreclr/jit/codegenarm64.cpp index 3ef30424d4c130..852144f72a8ac2 100644 --- a/src/coreclr/jit/codegenarm64.cpp +++ b/src/coreclr/jit/codegenarm64.cpp @@ -2334,30 +2334,9 @@ void CodeGen::genSetRegToConst(regNumber targetReg, var_types targetType, GenTre { attr = EA_SET_FLG(attr, EA_CNS_RELOC_FLG); GenTreeFlags tlsFlags = (GTF_ICON_TLSGD_OFFSET | GTF_ICON_TLS_HDL); - - if (tree->IsIconHandle(GTF_ICON_TLS_HDL)) - { - //attr = EA_SET_FLG(attr, EA_CNS_TLSGD_RELOC); - //if (tree->AsIntCon()->gtIconVal == 0) - //{ - // GetEmitter()->emitIns_R(INS_mrs_tpid0, attr, targetReg); - //} - //else - //{ - // attr = EA_SET_FLG(attr, EA_CNS_TLSGD_RELOC); - // GetEmitter()->emitIns_R_R_I(INS_ldr, attr, tree->GetRegNum(), REG_R0, tree->AsIntCon()->gtIconVal); - // //GetEmitter()->emitInsLoadStoreOp(INS_lea, attr, targetReg, tree); - //} - //break; - } - //else if (tree->IsIconHandle(GTF_ICON_FTN_ADDR) && ((tree->gtFlags & GTF_TLS_GET_ADDR) == GTF_TLS_GET_ADDR)) - //{ - // GetEmitter()->emitIns_R_R(INS_lea, attr, tree->GetReg(), REG_R0); - // break; - //} - else if ((tree->gtFlags & tlsFlags) == tlsFlags) + if ((tree->gtFlags & tlsFlags) == tlsFlags) { - /*attr = EA_SET_FLG(attr, EA_CNS_TLSGD_RELOC);*/ + // no need to generate because we already generated it as part of GT_CALL break; } } diff --git a/src/coreclr/jit/codegenarmarch.cpp b/src/coreclr/jit/codegenarmarch.cpp index 8d113150b64f00..e742f15398ca93 100644 --- a/src/coreclr/jit/codegenarmarch.cpp +++ b/src/coreclr/jit/codegenarmarch.cpp @@ -3555,11 +3555,6 @@ void CodeGen::genCallInstruction(GenTreeCall* call) } } - if (call->gtFlags & GTF_TLS_GET_ADDR) - { - retSize = EA_SET_FLG(retSize, EA_CNS_TLSGD_RELOC); - } - DebugInfo di; // We need to propagate the debug information to the call instruction, so we can emit // an IL to native mapping record for the call, to support managed return value debugging. @@ -3644,6 +3639,7 @@ void CodeGen::genCallInstruction(GenTreeCall* call) INS_FLAGS_DONT_CARE DEBUGARG(iconNode->gtTargetHandle) DEBUGARG(iconNode->gtFlags)); emit->emitIns_R(INS_mrs_tpid0, attr, REG_R1); emit->emitIns_R_R_I(INS_ldr, attr, target->GetRegNum(), REG_R0, (ssize_t)methHnd); + retSize = EA_SET_FLG(retSize, EA_CNS_TLSGD_RELOC); } #endif diff --git a/src/coreclr/jit/codegencommon.cpp b/src/coreclr/jit/codegencommon.cpp index 179480a06d8401..66901eab857383 100644 --- a/src/coreclr/jit/codegencommon.cpp +++ b/src/coreclr/jit/codegencommon.cpp @@ -1695,7 +1695,6 @@ void CodeGen::genGenerateCode(void** codePtr, uint32_t* nativeSizeOfCode) this->codePtr = codePtr; this->nativeSizeOfCode = nativeSizeOfCode; - //compiler->opts.dspCode = compiler->opts.disAsm; DoPhase(this, PHASE_GENERATE_CODE, &CodeGen::genGenerateMachineCode); DoPhase(this, PHASE_EMIT_CODE, &CodeGen::genEmitMachineCode); DoPhase(this, PHASE_EMIT_GCEH, &CodeGen::genEmitUnwindDebugGCandEH); diff --git a/src/coreclr/jit/emitarm64.cpp b/src/coreclr/jit/emitarm64.cpp index 9e4edf4804a3f7..363d101a939a9c 100644 --- a/src/coreclr/jit/emitarm64.cpp +++ b/src/coreclr/jit/emitarm64.cpp @@ -8468,7 +8468,8 @@ void emitter::emitIns_R_R_I( id->idReg2(reg2); if (EA_IS_CNS_TLSGD_RELOC(attr)) { - id->idSetTlsGD(); //TODO: This is getting called more than needed. Investigate. + assert(imm != 0); + id->idSetTlsGD(); } dispIns(id); appendToCurIG(id); @@ -21059,10 +21060,6 @@ void emitter::emitInsLoadStoreOp(instruction ins, emitAttr attr, regNumber dataR } #endif // DEBUG - if (addr->gtFlags & GTF_ICON_TLSGD_OFFSET) - { - attr = EA_SET_FLG(attr, EA_CNS_TLSGD_RELOC); - } // Then load/store dataReg from/to [addrReg] emitIns_R_R(ins, attr, dataReg, addr->GetRegNum()); } diff --git a/src/coreclr/jit/helperexpansion.cpp b/src/coreclr/jit/helperexpansion.cpp index b5c0a3b951ea07..8ef9dba3218e3c 100644 --- a/src/coreclr/jit/helperexpansion.cpp +++ b/src/coreclr/jit/helperexpansion.cpp @@ -663,127 +663,16 @@ bool Compiler::fgExpandThreadLocalAccessForCallNativeAOT(BasicBlock** pBlock, St */ - /*unsigned tlsLclNum = lvaGrabTemp(true DEBUGARG("TLS access")); - lvaTable[tlsLclNum].lvType = TYP_I_IMPL;*/ GenTree* tlsRootOffset = gtNewIconHandleNode((size_t)tlsRootObject, GTF_ICON_TLS_HDL); // [000016] tlsRootOffset->gtFlags |= GTF_ICON_TLSGD_OFFSET; - //GenTree* tlsValueDef = gtNewStoreLclVarNode(tlsLclNum, tlsRootOffset); // [000017] - //tlsValueDef->gtFlags - //GenTree* tlsValueUse = gtNewLclVarNode(tlsLclNum); // [000018] - //GenTree* tlsDefUse = gtNewOperNode(GT_COMMA, TYP_I_IMPL, tlsValueDef, tlsValueUse); - //fgInsertStmtAtBeg(block, fgNewStmtFromTree(tlsValueDef)); - /*BasicBlock* oldBb = block; - BasicBlock* newBlock = fgNewBBFromTreeAfter(BBJ_ALWAYS, prevBb, tlsValueDef, debugInfo); - newBlock->SetTarget(block); - fgAddRefPred(block, newBlock);*/ - - //tlsRootOffset->gtFlags |= GTF_ICON_SECREL_OFFSET; - - // param1 - // - GenTree* tlsCallParam1 = gtCloneExpr(tlsRootOffset); // TODO: IMAGE_REL_AARCH64_TLSDESC_ADR_PAGE21 - tlsCallParam1->gtFlags &= ~GTF_ICON_TLS_HDL; // [000017] - tlsCallParam1->gtFlags |= GTF_ICON_TLSGD_OFFSET; // [000017] - - GenTree* tlsCallParam2 = gtNewIconHandleNode(0, GTF_ICON_TLS_HDL); - - //tlsCallParam2->SetContained(); - - //unsigned tlsRootAddrLclNum = lvaGrabTemp(true DEBUGARG("TlsRootAddr access")); - //lvaTable[tlsRootAddrLclNum].lvType = TYP_I_IMPL; - //GenTree* tlsRootAddrDef = gtNewStoreLclVarNode(tlsRootAddrLclNum, tlsRootOffset); - //GenTree* tlsRootAddrUse = gtNewLclVarNode(tlsRootAddrLclNum); - - //GenTree* cnsOffset = gtNewIconNode(0, TYP_INT); - //cnsOffset->gtFlags |= GTF_ICON_TLSGD_OFFSET; - - //GenTree* tlsCallOffset = - // gtNewOperNode(GT_ADD, TYP_I_IMPL, gtClone(tlsCallParam1), cnsOffset); - - - // [000020] - //GenTree* tlsCall1 = gtCloneExpr(tlsCallParam1); - //tlsCall1->gtFlags &= ~GTF_ICON_TLSGD_OFFSET; - //tlsCall1->gtFlags |= GTF_ICON_SECREL_OFFSET; - //gtNewOperNode(GT_COMMA, TYP_I_IMPL, tlsValueDef, - // gtCloneExpr( - // tlsCallParam1)); // TODO: - // // IMAGE_REL_AARCH64_TLSDESC_ADR_PAGE21gtCloneExpr(tlsValueUse); - ////tlsCall1->SetContained(); - //GenTree* tlsCallAddr = - // gtNewIndir(TYP_I_IMPL, tlsCall1, - // GTF_IND_NONFAULTING | GTF_IND_INVARIANT); // IMAGE_REL_AARCH64_TLSDESC_LD64_LO12 - - /*GenTree* tls_get_addr_val = - gtNewIconHandleNode((size_t)threadStaticInfo.tlsGetAddrFtnPtr.handle, GTF_ICON_TLS_HDL);*/ - //tls_get_addr_val->gtFlags |= GTF_TLS_GET_ADDR - //tls_get_addr_val->SetContained(); - - //// param1 - //// - //GenTree* tlsCallParam1 = gtNewOperNode(GT_ADD, TYP_I_IMPL, gtClone(tlsRootAddrUse), - // gtNewIconNode(0, TYP_INT)); // IMAGE_REL_AARCH64_TLSDESC_ADD_LO12 - - - //GenTree* newCallIndir = gtNewIconHandleNode((size_t)tlsRootObject, GTF_ICON_TLS_HDL); - //GenTree* newParam1 = gtNewIconHandleNode(0, GTF_ICON_TLS_HDL); - - // [000021] GenTree* tlsCallIndir = gtCloneExpr(tlsRootOffset); GenTreeCall* tlsRefCall = gtNewIndCallNode(tlsCallIndir, TYP_I_IMPL); tlsRefCall->gtFlags |= GTF_TLS_GET_ADDR; - //tlsRefCall->gtArgs.PushBack(this, NewCallArg::Primitive(tlsCallParam1)); - //tlsRefCall->gtArgs.PushBack(this, NewCallArg::Primitive(tlsCallParam2)); - fgMorphArgs(tlsRefCall); tlsRefCall->gtFlags |= GTF_EXCEPT | (tlsCallIndir->gtFlags & GTF_GLOB_EFFECT); - - ////// For x0 = x1 + x0 - //unsigned tlsRefResultNum = lvaGrabTemp(true DEBUGARG("TLS call addr result")); - //lvaTable[tlsRefResultNum].lvType = TYP_I_IMPL; - //GenTree* tlsRefCallDef = gtNewStoreLclVarNode(tlsRefResultNum, tlsRefCall); - //GenTree* tlsRefCallUse = gtNewLclVarNode(tlsRefResultNum); - - ////unsigned tebNum = lvaGrabTemp(true DEBUGARG("MRS result")); - ////lvaTable[tebNum].lvType = TYP_I_IMPL; - ////GenTree* tebResultDef = gtNewStoreLclVarNode(tebNum, tlsCallParam2); - ////GenTree* tebResultUse = gtNewLclVarNode(tebNum); - - ////fgInsertStmtAtBeg(block, fgNewStmtFromTree(tlsRefCallDef)); - - - - //tlsRootAddr = gtNewOperNode(GT_ADD, TYP_I_IMPL, tlsRefCallUse, gtCloneExpr(tlsCallParam2)); - - //if (verbose) - //{ - // printf("tlsRootOffset:\n"); - // DISPTREE(tlsRootOffset); - // printf("tlsCallParam1:\n"); - // DISPTREE(tlsCallParam1); - // printf("tlsCallParam2:\n"); - // DISPTREE(tlsCallParam2); - // printf("tlsCallIndir:\n"); - // DISPTREE(tlsCallIndir); - // printf("tlsRefCall:\n"); - // DISPTREE(tlsRefCall); - // //printf("tlsRefCallDef:\n"); - // //DISPTREE(tlsRefCallDef); - // printf("tlsRootAddr:\n"); - // DISPTREE(tlsRootAddr); - - // //DISPTREE(tlsRefCallDef); - // //printf("tlsRefCallUse:\n"); - // //DISPTREE(tlsRefCallUse); - // //printf("tebResultDef:\n"); - // //DISPTREE(tebResultDef); - // //printf("tebResultUse:\n"); - // //DISPTREE(tebResultUse); - //} - tlsRootAddr = tlsRefCall; } else diff --git a/src/coreclr/jit/lsraarm64.cpp b/src/coreclr/jit/lsraarm64.cpp index a3fee3de6b5101..9c84f5487e2ebe 100644 --- a/src/coreclr/jit/lsraarm64.cpp +++ b/src/coreclr/jit/lsraarm64.cpp @@ -699,18 +699,10 @@ int LinearScan::BuildNode(GenTree* tree) srcCount = 0; assert(dstCount == 1); regMaskTP mask = RBM_NONE; - //if (((tree->gtFlags & GTF_ICON_SECREL_OFFSET) == GTF_ICON_SECREL_OFFSET)) - //{ - // mask = genRegMask(REG_R0, TYP_I_IMPL); - //} - //else if (tree->IsIconHandle(GTF_ICON_TLS_HDL) && tree->AsIntCon()->IconValue() == 0) - //{ - // mask = genRegMask(REG_R1, TYP_I_IMPL); - //} if ((tree->gtFlags & (GTF_ICON_TLSGD_OFFSET | GTF_ICON_TLS_HDL)) == (GTF_ICON_TLSGD_OFFSET | GTF_ICON_TLS_HDL)) { - mask = genRegMask(REG_R2, TYP_I_IMPL); //TODO: This also gets called for things unneeded // [000029] + mask = genRegMask(REG_R2, TYP_I_IMPL); } RefPosition* def = BuildDef(tree, mask); def->getInterval()->isConstant = true; diff --git a/src/coreclr/jit/lsraarmarch.cpp b/src/coreclr/jit/lsraarmarch.cpp index e6e21d9bb63dc3..13003c74d89fff 100644 --- a/src/coreclr/jit/lsraarmarch.cpp +++ b/src/coreclr/jit/lsraarmarch.cpp @@ -370,9 +370,6 @@ int LinearScan::BuildCall(GenTreeCall* call) { if (ctrlExpr->IsIconHandle(GTF_ICON_TLS_HDL) && call->gtArgs.CountArgs() == 0) { - /*BuildUse(ctrlExpr, genRegMask(REG_R0)); - BuildUse(ctrlExpr, genRegMask(REG_R1));*/ - //addRefsForPhysRegMask(genRegMask(REG_R0) | genRegMask(REG_R1), currentLoc + 1, RefTypeFixedReg, true); newRefPosition(REG_R0, currentLoc, RefTypeFixedReg, nullptr, genRegMask(REG_R0)); newRefPosition(REG_R1, currentLoc, RefTypeFixedReg, nullptr, genRegMask(REG_R1)); ctrlExprCandidates = genRegMask(REG_R2); diff --git a/src/coreclr/jit/lsrabuild.cpp b/src/coreclr/jit/lsrabuild.cpp index 404e07bf524d41..0c1d3f74475c8d 100644 --- a/src/coreclr/jit/lsrabuild.cpp +++ b/src/coreclr/jit/lsrabuild.cpp @@ -4129,14 +4129,6 @@ int LinearScan::BuildPutArgReg(GenTreeUnOp* node) int srcCount = 1; GenTree* op1 = node->gtGetOp1(); - //if (compiler->opts.disAsm) - //{ - // if ((op1->gtFlags & GTF_ICON_TLSGD_OFFSET)) - // { - // return 0; - // } - //} - // To avoid redundant moves, have the argument operand computed in the // register in which the argument is passed to the call. regMaskTP argMask = genRegMask(argReg); diff --git a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Relocation.cs b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Relocation.cs index 471fd45d5665c8..bd733d2c397ca4 100644 --- a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Relocation.cs +++ b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Relocation.cs @@ -475,10 +475,10 @@ public static unsafe void WriteValue(RelocType relocType, void* location, long v case RelocType.IMAGE_REL_TPOFF: case RelocType.IMAGE_REL_SYMBOL_SIZE: case RelocType.IMAGE_REL_FILE_ABSOLUTE: + case RelocType.IMAGE_REL_AARCH64_TLSDESC_CALL: *(int*)location = (int)value; break; case RelocType.IMAGE_REL_AARCH64_TLSDESC_LD64_LO12: - case RelocType.IMAGE_REL_AARCH64_TLSDESC_CALL: break; case RelocType.IMAGE_REL_BASED_DIR64: *(long*)location = value; @@ -541,7 +541,6 @@ public static unsafe long ReadValue(RelocType relocType, void* location) case RelocType.IMAGE_REL_TPOFF: case RelocType.IMAGE_REL_FILE_ABSOLUTE: case RelocType.IMAGE_REL_SYMBOL_SIZE: - case RelocType.IMAGE_REL_AARCH64_TLSDESC_LD64_LO12: return *(int*)location; case RelocType.IMAGE_REL_BASED_DIR64: return *(long*)location; @@ -556,6 +555,7 @@ public static unsafe long ReadValue(RelocType relocType, void* location) return GetArm64Rel21((uint*)location); case RelocType.IMAGE_REL_BASED_ARM64_PAGEOFFSET_12A: return GetArm64Rel12((uint*)location); + case RelocType.IMAGE_REL_AARCH64_TLSDESC_LD64_LO12: case RelocType.IMAGE_REL_AARCH64_TLSDESC_ADD_LO12: case RelocType.IMAGE_REL_AARCH64_TLSLE_ADD_TPREL_HI12: case RelocType.IMAGE_REL_AARCH64_TLSLE_ADD_TPREL_LO12_NC: From 7de3d039c2be9201ab45c9b4877c062dd5a3238b Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Fri, 2 Feb 2024 14:51:37 -0800 Subject: [PATCH 15/22] fix iiaAddr() for TLS, add IsTlsIconHandle() --- src/coreclr/jit/codegenarm64.cpp | 3 +-- src/coreclr/jit/codegenarmarch.cpp | 10 ++++------ src/coreclr/jit/emitarm64.cpp | 24 +++++++++++++++++------- src/coreclr/jit/gentree.h | 10 ++++++++++ src/coreclr/jit/helperexpansion.cpp | 2 +- src/coreclr/jit/lsraarm64.cpp | 3 +-- src/coreclr/jit/lsraarmarch.cpp | 3 ++- 7 files changed, 36 insertions(+), 19 deletions(-) diff --git a/src/coreclr/jit/codegenarm64.cpp b/src/coreclr/jit/codegenarm64.cpp index 852144f72a8ac2..fa4b0eb7d92d50 100644 --- a/src/coreclr/jit/codegenarm64.cpp +++ b/src/coreclr/jit/codegenarm64.cpp @@ -2333,8 +2333,7 @@ void CodeGen::genSetRegToConst(regNumber targetReg, var_types targetType, GenTre if (con->ImmedValNeedsReloc(compiler)) { attr = EA_SET_FLG(attr, EA_CNS_RELOC_FLG); - GenTreeFlags tlsFlags = (GTF_ICON_TLSGD_OFFSET | GTF_ICON_TLS_HDL); - if ((tree->gtFlags & tlsFlags) == tlsFlags) + if (tree->IsTlsIconHandle()) { // no need to generate because we already generated it as part of GT_CALL break; diff --git a/src/coreclr/jit/codegenarmarch.cpp b/src/coreclr/jit/codegenarmarch.cpp index e742f15398ca93..2720c08d97328d 100644 --- a/src/coreclr/jit/codegenarmarch.cpp +++ b/src/coreclr/jit/codegenarmarch.cpp @@ -3625,16 +3625,14 @@ void CodeGen::genCallInstruction(GenTreeCall* call) bool specialCase = false; #ifdef TARGET_ARM64 - specialCase = call->gtFlags & GTF_TLS_GET_ADDR; + specialCase = target->IsTlsIconHandle(); if (specialCase) { - GenTree* mthdHandle = (GenTree*)call->gtCallMethHnd; - GenTreeFlags tlsFlags = (GTF_ICON_TLSGD_OFFSET | GTF_ICON_TLS_HDL); - assert(mthdHandle != nullptr && ((mthdHandle->gtFlags & tlsFlags) == tlsFlags)); - GenTreeIntCon* iconNode = mthdHandle->AsIntCon(); + assert(call->gtFlags & GTF_TLS_GET_ADDR); + GenTreeIntCon* iconNode = target->AsIntCon(); methHnd = (CORINFO_METHOD_HANDLE)iconNode->gtIconVal; emitter* emit = GetEmitter(); - emitAttr attr = (emitAttr)(EA_CNS_TLSGD_RELOC | EA_CNS_RELOC_FLG | EA_8BYTE); + emitAttr attr = (emitAttr)(EA_CNS_TLSGD_RELOC | EA_CNS_RELOC_FLG | retSize); instGen_Set_Reg_To_Imm(attr, REG_R0, (ssize_t)methHnd, INS_FLAGS_DONT_CARE DEBUGARG(iconNode->gtTargetHandle) DEBUGARG(iconNode->gtFlags)); emit->emitIns_R(INS_mrs_tpid0, attr, REG_R1); diff --git a/src/coreclr/jit/emitarm64.cpp b/src/coreclr/jit/emitarm64.cpp index 363d101a939a9c..9d90ec5daf8b53 100644 --- a/src/coreclr/jit/emitarm64.cpp +++ b/src/coreclr/jit/emitarm64.cpp @@ -13192,11 +13192,17 @@ void emitter::emitIns_Call(EmitCallType callType, id->idIns(ins); id->idInsFmt(fmt); - id->idReg3(ireg); + assert(xreg == REG_NA); if (EA_IS_CNS_TLSGD_RELOC(retSize)) { id->idSetTlsGD(); + id->idReg1(ireg); + id->idAddr()->iiaAddr = (BYTE*)methHnd; + } + else + { + id->idReg3(ireg); } } else @@ -16124,16 +16130,20 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) case IF_BR_1B: // BR_1B ................ ......nnnnn..... Rn assert(insOptsNone(id->idInsOpt())); assert((ins == INS_br_tail) || (ins == INS_blr)); - code = emitInsCode(ins, fmt); - code |= insEncodeReg_Rn(id->idReg3()); // nnnnn - - sz = id->idIsLargeCall() ? sizeof(instrDescCGCA) : sizeof(instrDesc); - dst += emitOutputCall(ig, dst, id, code); + code = emitInsCode(ins, fmt); + if (id->idIsTlsGD()) { - emitRecordRelocation(odst, (CORINFO_METHOD_HANDLE)id->idDebugOnlyInfo()->idMemCookie, + emitRecordRelocation(odst, (CORINFO_METHOD_HANDLE)id->idAddr()->iiaAddr, IMAGE_REL_AARCH64_TLSDESC_CALL); + code |= insEncodeReg_Rn(id->idReg1()); // nnnnn + } + else + { + code |= insEncodeReg_Rn(id->idReg3()); // nnnnn } + dst += emitOutputCall(ig, dst, id, code); + sz = id->idIsLargeCall() ? sizeof(instrDescCGCA) : sizeof(instrDesc); break; case IF_LS_1A: // LS_1A XX...V..iiiiiiii iiiiiiiiiiittttt Rt PC imm(1MB) diff --git a/src/coreclr/jit/gentree.h b/src/coreclr/jit/gentree.h index 3d94e5d90e3ae7..22940f27c13361 100644 --- a/src/coreclr/jit/gentree.h +++ b/src/coreclr/jit/gentree.h @@ -2232,6 +2232,16 @@ struct GenTree return (gtOper == GT_CNS_INT) ? (gtFlags & GTF_ICON_HDL_MASK) : GTF_EMPTY; } + bool IsTlsIconHandle() + { + if (IsIconHandle()) + { + GenTreeFlags tlsFlags = (GTF_ICON_TLSGD_OFFSET | GTF_ICON_TLS_HDL); + return ((gtFlags & tlsFlags) == tlsFlags); + } + return false; + } + #ifdef FEATURE_HW_INTRINSICS void ClearEmbRoundingMode() diff --git a/src/coreclr/jit/helperexpansion.cpp b/src/coreclr/jit/helperexpansion.cpp index 8ef9dba3218e3c..65b34d701b9598 100644 --- a/src/coreclr/jit/helperexpansion.cpp +++ b/src/coreclr/jit/helperexpansion.cpp @@ -663,7 +663,7 @@ bool Compiler::fgExpandThreadLocalAccessForCallNativeAOT(BasicBlock** pBlock, St */ - GenTree* tlsRootOffset = gtNewIconHandleNode((size_t)tlsRootObject, GTF_ICON_TLS_HDL); // [000016] + GenTree* tlsRootOffset = gtNewIconHandleNode((size_t)tlsRootObject, GTF_ICON_TLS_HDL); tlsRootOffset->gtFlags |= GTF_ICON_TLSGD_OFFSET; diff --git a/src/coreclr/jit/lsraarm64.cpp b/src/coreclr/jit/lsraarm64.cpp index 9c84f5487e2ebe..1d8e8c6737f052 100644 --- a/src/coreclr/jit/lsraarm64.cpp +++ b/src/coreclr/jit/lsraarm64.cpp @@ -699,8 +699,7 @@ int LinearScan::BuildNode(GenTree* tree) srcCount = 0; assert(dstCount == 1); regMaskTP mask = RBM_NONE; - if ((tree->gtFlags & (GTF_ICON_TLSGD_OFFSET | GTF_ICON_TLS_HDL)) == - (GTF_ICON_TLSGD_OFFSET | GTF_ICON_TLS_HDL)) + if (tree->IsTlsIconHandle()) { mask = genRegMask(REG_R2, TYP_I_IMPL); } diff --git a/src/coreclr/jit/lsraarmarch.cpp b/src/coreclr/jit/lsraarmarch.cpp index 13003c74d89fff..e429be7b9b1406 100644 --- a/src/coreclr/jit/lsraarmarch.cpp +++ b/src/coreclr/jit/lsraarmarch.cpp @@ -368,8 +368,9 @@ int LinearScan::BuildCall(GenTreeCall* call) if (ctrlExpr != nullptr) { - if (ctrlExpr->IsIconHandle(GTF_ICON_TLS_HDL) && call->gtArgs.CountArgs() == 0) + if ((call->gtArgs.CountArgs() == 0) && ctrlExpr->IsTlsIconHandle()) { + assert(call->gtFlags & GTF_TLS_GET_ADDR); newRefPosition(REG_R0, currentLoc, RefTypeFixedReg, nullptr, genRegMask(REG_R0)); newRefPosition(REG_R1, currentLoc, RefTypeFixedReg, nullptr, genRegMask(REG_R1)); ctrlExprCandidates = genRegMask(REG_R2); From adf64f59db21dc9659991ca2b1a72754a3398309 Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Fri, 2 Feb 2024 15:40:10 -0800 Subject: [PATCH 16/22] add comments --- src/coreclr/jit/codegenarm64.cpp | 2 +- src/coreclr/jit/codegenarmarch.cpp | 39 ++++++++++++++++++++++------- src/coreclr/jit/emitarm64.cpp | 32 ++++++++++------------- src/coreclr/jit/helperexpansion.cpp | 5 +--- src/coreclr/jit/lsraarm64.cpp | 7 +----- src/coreclr/jit/lsraarmarch.cpp | 10 +++++++- 6 files changed, 55 insertions(+), 40 deletions(-) diff --git a/src/coreclr/jit/codegenarm64.cpp b/src/coreclr/jit/codegenarm64.cpp index fa4b0eb7d92d50..9da1538cf628e3 100644 --- a/src/coreclr/jit/codegenarm64.cpp +++ b/src/coreclr/jit/codegenarm64.cpp @@ -2335,7 +2335,7 @@ void CodeGen::genSetRegToConst(regNumber targetReg, var_types targetType, GenTre attr = EA_SET_FLG(attr, EA_CNS_RELOC_FLG); if (tree->IsTlsIconHandle()) { - // no need to generate because we already generated it as part of GT_CALL + // no need to generate because we generate it as part of GT_CALL break; } } diff --git a/src/coreclr/jit/codegenarmarch.cpp b/src/coreclr/jit/codegenarmarch.cpp index 2720c08d97328d..7811db12d9d0e6 100644 --- a/src/coreclr/jit/codegenarmarch.cpp +++ b/src/coreclr/jit/codegenarmarch.cpp @@ -3623,21 +3623,41 @@ void CodeGen::genCallInstruction(GenTreeCall* call) // assert(genIsValidIntReg(target->GetRegNum())); - bool specialCase = false; + bool isTlsHandleTarget = false; #ifdef TARGET_ARM64 - specialCase = target->IsTlsIconHandle(); - if (specialCase) + isTlsHandleTarget = + compiler->IsTargetAbi(CORINFO_NATIVEAOT_ABI) && TargetOS::IsUnix && target->IsTlsIconHandle(); + + if (isTlsHandleTarget) { assert(call->gtFlags & GTF_TLS_GET_ADDR); + emitter* emitter = GetEmitter(); + emitAttr attr = (emitAttr)(EA_CNS_TLSGD_RELOC | EA_CNS_RELOC_FLG | retSize); GenTreeIntCon* iconNode = target->AsIntCon(); methHnd = (CORINFO_METHOD_HANDLE)iconNode->gtIconVal; - emitter* emit = GetEmitter(); - emitAttr attr = (emitAttr)(EA_CNS_TLSGD_RELOC | EA_CNS_RELOC_FLG | retSize); + retSize = EA_SET_FLG(retSize, EA_CNS_TLSGD_RELOC); + + // For NativeAOT, linux/arm64, linker wants the following pattern, so we will generate + // it as part of the call. Generating individual instructions is tricky to get it + // correct in the format the way linker needs. Also, we might end up spilling or + // reloading a register, which can break the pattern. + // + // adrp x0, :tlsdesc:tlsRoot ; R_AARCH64_TLSDESC_ADR_PAGE21 + // add x0, x0, #0 ; R_AARCH64_TLSDESC_ADD_LO12 + // mrs x1, tpidr_el0 + // ldr x2, [x0] ; R_AARCH64_TLSDESC_LD64_LO12 + // blr x2 ; R_AARCH64_TLSDESC_CALL + // add x0, x1, x0 + // We guaranteed in LSRA that r0, r1 and r2 are assigned to this node. + + // adrp/add instGen_Set_Reg_To_Imm(attr, REG_R0, (ssize_t)methHnd, INS_FLAGS_DONT_CARE DEBUGARG(iconNode->gtTargetHandle) DEBUGARG(iconNode->gtFlags)); - emit->emitIns_R(INS_mrs_tpid0, attr, REG_R1); - emit->emitIns_R_R_I(INS_ldr, attr, target->GetRegNum(), REG_R0, (ssize_t)methHnd); - retSize = EA_SET_FLG(retSize, EA_CNS_TLSGD_RELOC); + // mrs + emitter->emitIns_R(INS_mrs_tpid0, attr, REG_R1); + + // ldr + emitter->emitIns_R_R_I(INS_ldr, attr, target->GetRegNum(), REG_R0, (ssize_t)methHnd); } #endif @@ -3652,8 +3672,9 @@ void CodeGen::genCallInstruction(GenTreeCall* call) target->GetRegNum(), call->IsFastTailCall()); - if (specialCase) + if (isTlsHandleTarget) { + // add x0, x1, x0 GetEmitter()->emitIns_R_R_R(INS_add, EA_8BYTE, REG_R0, REG_R1, REG_R0); } // clang-format on diff --git a/src/coreclr/jit/emitarm64.cpp b/src/coreclr/jit/emitarm64.cpp index 9d90ec5daf8b53..f17bae0204d10b 100644 --- a/src/coreclr/jit/emitarm64.cpp +++ b/src/coreclr/jit/emitarm64.cpp @@ -13194,8 +13194,12 @@ void emitter::emitIns_Call(EmitCallType callType, assert(xreg == REG_NA); - if (EA_IS_CNS_TLSGD_RELOC(retSize)) + if (emitComp->IsTargetAbi(CORINFO_NATIVEAOT_ABI) && EA_IS_CNS_TLSGD_RELOC(retSize)) { + // For NativeAOT linux/arm64, we need to also record the relocation of methHnd + // Since we do not have space to embed it in instrDesc, we store the register in + // reg1 and instead use the `iiaAdd` to store the method handle. Likewise, during + // emitOutputInstr, we retrieve the register from reg1 for this specific case. id->idSetTlsGD(); id->idReg1(ireg); id->idAddr()->iiaAddr = (BYTE*)methHnd; @@ -16132,7 +16136,7 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) assert((ins == INS_br_tail) || (ins == INS_blr)); code = emitInsCode(ins, fmt); - if (id->idIsTlsGD()) + if (emitComp->IsTargetAbi(CORINFO_NATIVEAOT_ABI) && id->idIsTlsGD()) { emitRecordRelocation(odst, (CORINFO_METHOD_HANDLE)id->idAddr()->iiaAddr, IMAGE_REL_AARCH64_TLSDESC_CALL); @@ -16172,7 +16176,7 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) } code |= insEncodeReg_Rn(id->idReg2()); // nnnnn dst += emitOutput_Instr(dst, code); - if (id->idIsTlsGD() && id->idIsLargeCns()) + if (id->idIsTlsGD()) { emitRecordRelocation(odst, (void*)emitGetInsSC(id), IMAGE_REL_AARCH64_TLSDESC_LD64_LO12); } @@ -16441,14 +16445,9 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) code = emitInsCode(ins, fmt); code |= insEncodeReg_Rd(id->idReg1()); // ddddd dst += emitOutput_Instr(dst, code); - if (id->idIsTlsGD()) - { - emitRecordRelocation(odst, id->idAddr()->iiaAddr, IMAGE_REL_AARCH64_TLSDESC_ADR_PAGE21); - } - else - { - emitRecordRelocation(odst, id->idAddr()->iiaAddr, IMAGE_REL_ARM64_PAGEBASE_REL21); - } + emitRecordRelocation(odst, id->idAddr()->iiaAddr, + id->idIsTlsGD() ? IMAGE_REL_AARCH64_TLSDESC_ADR_PAGE21 + : IMAGE_REL_ARM64_PAGEBASE_REL21); } else { @@ -16491,14 +16490,9 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) { assert(sz == sizeof(instrDesc)); assert(id->idAddr()->iiaAddr != nullptr); - if (id->idIsTlsGD()) - { - emitRecordRelocation(odst, id->idAddr()->iiaAddr, IMAGE_REL_AARCH64_TLSDESC_ADD_LO12); - } - else - { - emitRecordRelocation(odst, id->idAddr()->iiaAddr, IMAGE_REL_ARM64_PAGEOFFSET_12A); - } + emitRecordRelocation(odst, id->idAddr()->iiaAddr, + id->idIsTlsGD() ? IMAGE_REL_AARCH64_TLSDESC_ADD_LO12 + : IMAGE_REL_ARM64_PAGEOFFSET_12A); } break; diff --git a/src/coreclr/jit/helperexpansion.cpp b/src/coreclr/jit/helperexpansion.cpp index 65b34d701b9598..7d98a18743b8d7 100644 --- a/src/coreclr/jit/helperexpansion.cpp +++ b/src/coreclr/jit/helperexpansion.cpp @@ -746,10 +746,7 @@ bool Compiler::fgExpandThreadLocalAccessForCallNativeAOT(BasicBlock** pBlock, St // fallback will just execute first time fallbackBb->bbSetRunRarely(); - //if (!(TargetOS::IsUnix && TargetArchitecture::IsArm64)) - { - fgRemoveRefPred(block, prevBb); - } + fgRemoveRefPred(block, prevBb); fgAddRefPred(tlsRootNullCondBB, prevBb); prevBb->SetTarget(tlsRootNullCondBB); diff --git a/src/coreclr/jit/lsraarm64.cpp b/src/coreclr/jit/lsraarm64.cpp index 1d8e8c6737f052..ea3bc9d7fb37e0 100644 --- a/src/coreclr/jit/lsraarm64.cpp +++ b/src/coreclr/jit/lsraarm64.cpp @@ -698,12 +698,7 @@ int LinearScan::BuildNode(GenTree* tree) { srcCount = 0; assert(dstCount == 1); - regMaskTP mask = RBM_NONE; - if (tree->IsTlsIconHandle()) - { - mask = genRegMask(REG_R2, TYP_I_IMPL); - } - RefPosition* def = BuildDef(tree, mask); + RefPosition* def = BuildDef(tree); def->getInterval()->isConstant = true; } break; diff --git a/src/coreclr/jit/lsraarmarch.cpp b/src/coreclr/jit/lsraarmarch.cpp index e429be7b9b1406..30544c393b9cf7 100644 --- a/src/coreclr/jit/lsraarmarch.cpp +++ b/src/coreclr/jit/lsraarmarch.cpp @@ -368,13 +368,21 @@ int LinearScan::BuildCall(GenTreeCall* call) if (ctrlExpr != nullptr) { - if ((call->gtArgs.CountArgs() == 0) && ctrlExpr->IsTlsIconHandle()) +#ifdef TARGET_ARM64 + if (compiler->IsTargetAbi(CORINFO_NATIVEAOT_ABI) && TargetOS::IsUnix && + (call->gtArgs.CountArgs() == 0) && ctrlExpr->IsTlsIconHandle()) { + // For NativeAOT linux/arm64, we generate the needed code as part of + // call node because the generated code has to be in specific format + // that linker can patch. As such, the code needs specific registers + // that we will attach to this node to guarantee that they are available + // during generating this node. assert(call->gtFlags & GTF_TLS_GET_ADDR); newRefPosition(REG_R0, currentLoc, RefTypeFixedReg, nullptr, genRegMask(REG_R0)); newRefPosition(REG_R1, currentLoc, RefTypeFixedReg, nullptr, genRegMask(REG_R1)); ctrlExprCandidates = genRegMask(REG_R2); } +#endif BuildUse(ctrlExpr, ctrlExprCandidates); srcCount++; } From 4e3bad858e7b48edfa8998c2f500ea2c0e88eb82 Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Fri, 2 Feb 2024 15:40:58 -0800 Subject: [PATCH 17/22] jit format --- src/coreclr/jit/codegenarmarch.cpp | 8 ++++---- src/coreclr/jit/emitarm64.cpp | 15 ++++++--------- src/coreclr/jit/helperexpansion.cpp | 1 - src/coreclr/jit/lsraarmarch.cpp | 4 ++-- 4 files changed, 12 insertions(+), 16 deletions(-) diff --git a/src/coreclr/jit/codegenarmarch.cpp b/src/coreclr/jit/codegenarmarch.cpp index 7811db12d9d0e6..78c430c0fb58ca 100644 --- a/src/coreclr/jit/codegenarmarch.cpp +++ b/src/coreclr/jit/codegenarmarch.cpp @@ -3631,11 +3631,11 @@ void CodeGen::genCallInstruction(GenTreeCall* call) if (isTlsHandleTarget) { assert(call->gtFlags & GTF_TLS_GET_ADDR); - emitter* emitter = GetEmitter(); - emitAttr attr = (emitAttr)(EA_CNS_TLSGD_RELOC | EA_CNS_RELOC_FLG | retSize); + emitter* emitter = GetEmitter(); + emitAttr attr = (emitAttr)(EA_CNS_TLSGD_RELOC | EA_CNS_RELOC_FLG | retSize); GenTreeIntCon* iconNode = target->AsIntCon(); methHnd = (CORINFO_METHOD_HANDLE)iconNode->gtIconVal; - retSize = EA_SET_FLG(retSize, EA_CNS_TLSGD_RELOC); + retSize = EA_SET_FLG(retSize, EA_CNS_TLSGD_RELOC); // For NativeAOT, linux/arm64, linker wants the following pattern, so we will generate // it as part of the call. Generating individual instructions is tricky to get it @@ -3657,7 +3657,7 @@ void CodeGen::genCallInstruction(GenTreeCall* call) emitter->emitIns_R(INS_mrs_tpid0, attr, REG_R1); // ldr - emitter->emitIns_R_R_I(INS_ldr, attr, target->GetRegNum(), REG_R0, (ssize_t)methHnd); + emitter->emitIns_R_R_I(INS_ldr, attr, target->GetRegNum(), REG_R0, (ssize_t)methHnd); } #endif diff --git a/src/coreclr/jit/emitarm64.cpp b/src/coreclr/jit/emitarm64.cpp index f17bae0204d10b..94fe601c2161e6 100644 --- a/src/coreclr/jit/emitarm64.cpp +++ b/src/coreclr/jit/emitarm64.cpp @@ -13192,7 +13192,6 @@ void emitter::emitIns_Call(EmitCallType callType, id->idIns(ins); id->idInsFmt(fmt); - assert(xreg == REG_NA); if (emitComp->IsTargetAbi(CORINFO_NATIVEAOT_ABI) && EA_IS_CNS_TLSGD_RELOC(retSize)) { @@ -16134,8 +16133,8 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) case IF_BR_1B: // BR_1B ................ ......nnnnn..... Rn assert(insOptsNone(id->idInsOpt())); assert((ins == INS_br_tail) || (ins == INS_blr)); - code = emitInsCode(ins, fmt); - + code = emitInsCode(ins, fmt); + if (emitComp->IsTargetAbi(CORINFO_NATIVEAOT_ABI) && id->idIsTlsGD()) { emitRecordRelocation(odst, (CORINFO_METHOD_HANDLE)id->idAddr()->iiaAddr, @@ -16445,9 +16444,8 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) code = emitInsCode(ins, fmt); code |= insEncodeReg_Rd(id->idReg1()); // ddddd dst += emitOutput_Instr(dst, code); - emitRecordRelocation(odst, id->idAddr()->iiaAddr, - id->idIsTlsGD() ? IMAGE_REL_AARCH64_TLSDESC_ADR_PAGE21 - : IMAGE_REL_ARM64_PAGEBASE_REL21); + emitRecordRelocation(odst, id->idAddr()->iiaAddr, id->idIsTlsGD() ? IMAGE_REL_AARCH64_TLSDESC_ADR_PAGE21 + : IMAGE_REL_ARM64_PAGEBASE_REL21); } else { @@ -16490,9 +16488,8 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) { assert(sz == sizeof(instrDesc)); assert(id->idAddr()->iiaAddr != nullptr); - emitRecordRelocation(odst, id->idAddr()->iiaAddr, - id->idIsTlsGD() ? IMAGE_REL_AARCH64_TLSDESC_ADD_LO12 - : IMAGE_REL_ARM64_PAGEOFFSET_12A); + emitRecordRelocation(odst, id->idAddr()->iiaAddr, id->idIsTlsGD() ? IMAGE_REL_AARCH64_TLSDESC_ADD_LO12 + : IMAGE_REL_ARM64_PAGEOFFSET_12A); } break; diff --git a/src/coreclr/jit/helperexpansion.cpp b/src/coreclr/jit/helperexpansion.cpp index 7d98a18743b8d7..82eeefd0e4f34c 100644 --- a/src/coreclr/jit/helperexpansion.cpp +++ b/src/coreclr/jit/helperexpansion.cpp @@ -666,7 +666,6 @@ bool Compiler::fgExpandThreadLocalAccessForCallNativeAOT(BasicBlock** pBlock, St GenTree* tlsRootOffset = gtNewIconHandleNode((size_t)tlsRootObject, GTF_ICON_TLS_HDL); tlsRootOffset->gtFlags |= GTF_ICON_TLSGD_OFFSET; - GenTree* tlsCallIndir = gtCloneExpr(tlsRootOffset); GenTreeCall* tlsRefCall = gtNewIndCallNode(tlsCallIndir, TYP_I_IMPL); tlsRefCall->gtFlags |= GTF_TLS_GET_ADDR; diff --git a/src/coreclr/jit/lsraarmarch.cpp b/src/coreclr/jit/lsraarmarch.cpp index 30544c393b9cf7..a0f27ba65b3058 100644 --- a/src/coreclr/jit/lsraarmarch.cpp +++ b/src/coreclr/jit/lsraarmarch.cpp @@ -369,8 +369,8 @@ int LinearScan::BuildCall(GenTreeCall* call) if (ctrlExpr != nullptr) { #ifdef TARGET_ARM64 - if (compiler->IsTargetAbi(CORINFO_NATIVEAOT_ABI) && TargetOS::IsUnix && - (call->gtArgs.CountArgs() == 0) && ctrlExpr->IsTlsIconHandle()) + if (compiler->IsTargetAbi(CORINFO_NATIVEAOT_ABI) && TargetOS::IsUnix && (call->gtArgs.CountArgs() == 0) && + ctrlExpr->IsTlsIconHandle()) { // For NativeAOT linux/arm64, we generate the needed code as part of // call node because the generated code has to be in specific format From 92f4eb686ff584a1302bd07b5e2e57ffd7f630c5 Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Fri, 2 Feb 2024 15:51:37 -0800 Subject: [PATCH 18/22] Remove EmitInlineTLSAccess() --- .../Target_ARM64/ARM64ReadyToRunHelperNode.cs | 97 +------------------ .../Target_X64/X64ReadyToRunHelperNode.cs | 32 +----- 2 files changed, 2 insertions(+), 127 deletions(-) diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_ARM64/ARM64ReadyToRunHelperNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_ARM64/ARM64ReadyToRunHelperNode.cs index 0fca02c971a4f1..40c3079b05ddf2 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_ARM64/ARM64ReadyToRunHelperNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_ARM64/ARM64ReadyToRunHelperNode.cs @@ -74,26 +74,7 @@ protected override void EmitCode(NodeFactory factory, ref ARM64Emitter encoder, ISortableSymbolNode index = factory.TypeThreadStaticIndex(target); if (index is TypeThreadStaticIndexNode ti && ti.IsInlined) { - if (!factory.PreinitializationManager.HasLazyStaticConstructor(target)) - { - EmitInlineTLSAccess(factory, ref encoder); - } - else - { - // First arg: unused address of the TypeManager - // encoder.EmitMOV(encoder.TargetRegister.Arg0, (ushort)0); - - // Second arg: ~0 (index of inlined storage) - encoder.EmitMVN(encoder.TargetRegister.Arg1, 0); - - encoder.EmitMOV(encoder.TargetRegister.Arg2, factory.TypeNonGCStaticsSymbol(target)); - encoder.EmitSUB(encoder.TargetRegister.Arg2, NonGCStaticsNode.GetClassConstructorContextSize(factory.Target)); - encoder.EmitLDR(encoder.TargetRegister.Arg3, encoder.TargetRegister.Arg2); - encoder.EmitCMP(encoder.TargetRegister.Arg3, 0); - - encoder.EmitJNE(factory.HelperEntrypoint(HelperEntrypoint.EnsureClassConstructorRunAndReturnThreadStaticBase)); - EmitInlineTLSAccess(factory, ref encoder); - } + throw new NotImplementedException(); } else { @@ -226,81 +207,5 @@ protected override void EmitCode(NodeFactory factory, ref ARM64Emitter encoder, throw new NotImplementedException(); } } - - // emits code that results in ThreadStaticBase referenced in X0. - // may trash volatile registers. (there are calls to the slow helper and possibly to the platform's TLS support) - private static void EmitInlineTLSAccess(NodeFactory factory, ref ARM64Emitter encoder) - { - ISymbolNode getInlinedThreadStaticBaseSlow = factory.HelperEntrypoint(HelperEntrypoint.GetInlinedThreadStaticBaseSlow); - ISymbolNode tlsRoot = factory.TlsRoot; - // IsSingleFileCompilation is not enough to guarantee that we can use "Initial Executable" optimizations. - // we need a special compiler flag analogous to /GA. Just assume "false" for now. - // bool isInitialExecutable = factory.CompilationModuleGroup.IsSingleFileCompilation; - bool isInitialExecutable = false; - - if (factory.Target.OperatingSystem == TargetOS.Linux) - { - if (isInitialExecutable) - { - // mrs x0, tpidr_el0 - encoder.Builder.EmitUInt(0xd53bd040); - - // add x0, x0, #:tprel_hi12:tlsRoot, lsl #12 - encoder.Builder.EmitReloc(tlsRoot, RelocType.IMAGE_REL_AARCH64_TLSLE_ADD_TPREL_HI12); - encoder.Builder.EmitUInt(0x91400000); - - // add x1, x0, #:tprel_lo12_nc:tlsRoot, lsl #0 - encoder.Builder.EmitReloc(tlsRoot, RelocType.IMAGE_REL_AARCH64_TLSLE_ADD_TPREL_LO12_NC); - encoder.Builder.EmitUInt(0x91000001); - } - else - { - // stp x29, x30, [sp, -16]! - encoder.Builder.EmitUInt(0xa9bf7bfd); - // mov x29, sp - encoder.Builder.EmitUInt(0x910003fd); - - // mrs x1, tpidr_el0 - encoder.Builder.EmitUInt(0xd53bd041); - - // adrp x0, :tlsdesc:tlsRoot - encoder.Builder.EmitReloc(tlsRoot, RelocType.IMAGE_REL_AARCH64_TLSDESC_ADR_PAGE21); - encoder.Builder.EmitUInt(0x90000000); - - // ldr x2, [x0, #:tlsdesc_lo12:tlsRoot] - encoder.Builder.EmitReloc(tlsRoot, RelocType.IMAGE_REL_AARCH64_TLSDESC_LD64_LO12); - encoder.Builder.EmitUInt(0xf9400002); - - // add x0, x0, :tlsdesc_lo12:tlsRoot - encoder.Builder.EmitReloc(tlsRoot, RelocType.IMAGE_REL_AARCH64_TLSDESC_ADD_LO12); - encoder.Builder.EmitUInt(0x91000000); - - // blr :tlsdesc_call:tlsRoot:x2 - encoder.Builder.EmitReloc(tlsRoot, RelocType.IMAGE_REL_AARCH64_TLSDESC_CALL); - encoder.Builder.EmitUInt(0xd63f0040); - - // add x1, x1, x0 - encoder.Builder.EmitUInt(0x8b000021); - - // ldp x29, x30, [sp], 16 - encoder.Builder.EmitUInt(0xa8c17bfd); - } - - encoder.EmitLDR(Register.X0, Register.X1); - - // here we have: - // X1: addr, X0: storage - // if the storage is already allocated, just return, otherwise do slow path. - - encoder.EmitCMP(Register.X0, 0); - encoder.EmitRETIfNotEqual(); - encoder.EmitMOV(Register.X0, Register.X1); - encoder.EmitJMP(getInlinedThreadStaticBaseSlow); - } - else - { - throw new NotImplementedException(); - } - } } } diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_X64/X64ReadyToRunHelperNode.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_X64/X64ReadyToRunHelperNode.cs index 6bab293d079e3b..5e50d0d3500b2b 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_X64/X64ReadyToRunHelperNode.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/Target_X64/X64ReadyToRunHelperNode.cs @@ -74,26 +74,7 @@ protected override void EmitCode(NodeFactory factory, ref X64Emitter encoder, bo ISortableSymbolNode index = factory.TypeThreadStaticIndex(target); if (index is TypeThreadStaticIndexNode ti && ti.IsInlined) { - if (!factory.PreinitializationManager.HasLazyStaticConstructor(target)) - { - EmitInlineTLSAccess(factory, ref encoder); - } - else - { - // First arg: unused address of the TypeManager - // encoder.EmitMOV(encoder.TargetRegister.Arg0, 0); - - // Second arg: -1 (index of inlined storage) - encoder.EmitMOV(encoder.TargetRegister.Arg1, -1); - - encoder.EmitLEAQ(encoder.TargetRegister.Arg2, factory.TypeNonGCStaticsSymbol(target), -NonGCStaticsNode.GetClassConstructorContextSize(factory.Target)); - - AddrMode initialized = new AddrMode(encoder.TargetRegister.Arg2, null, 0, 0, AddrModeSize.Int64); - encoder.EmitCMP(ref initialized, 0); - encoder.EmitJNE(factory.HelperEntrypoint(HelperEntrypoint.EnsureClassConstructorRunAndReturnThreadStaticBase)); - - EmitInlineTLSAccess(factory, ref encoder); - } + throw new NotImplementedException(); } else { @@ -225,16 +206,5 @@ protected override void EmitCode(NodeFactory factory, ref X64Emitter encoder, bo throw new NotImplementedException(); } } - - // emits code that results in ThreadStaticBase referenced in RAX. - // may trash volatile registers. (there are calls to the slow helper and possibly to platform's TLS support) - private static void EmitInlineTLSAccess(NodeFactory factory, ref X64Emitter encoder) - { - // For factory.Target.IsApplePlatform - // movq _\Var @TLVP(% rip), % rdi - // callq * (% rdi) - - throw new NotImplementedException(); - } } } From 19de2ae25ffa5a46b129df7bb6f82e39a1020730 Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Fri, 2 Feb 2024 20:30:29 -0800 Subject: [PATCH 19/22] update guid --- src/coreclr/inc/jiteeversionguid.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/coreclr/inc/jiteeversionguid.h b/src/coreclr/inc/jiteeversionguid.h index 5d63f9df9a80d4..6355fc20dd0fd5 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 = { /* b8a05f18-503e-47e4-9193-931c50b151d1 */ - 0xb8a05f18, - 0x503e, - 0x47e4, - {0x91, 0x93, 0x93, 0x1c, 0x50, 0xb1, 0x51, 0xd1} +constexpr GUID JITEEVersionIdentifier = { /* 0fb71692-0ee6-4914-88a8-6446e45f23e8 */ + 0x0fb71692, + 0x0ee6, + 0x4914, + {0x88, 0xa8, 0x64, 0x46, 0xe4, 0x5f, 0x23, 0xe8} }; ////////////////////////////////////////////////////////////////////////////////////////////////////////// From 1bc76ce648584c11e290b620dfd1da87b7f7d3e6 Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Tue, 6 Feb 2024 09:41:49 -0800 Subject: [PATCH 20/22] fix for sharedlibrary --- src/coreclr/jit/codegenarmarch.cpp | 17 +++--- src/coreclr/jit/emitarm64.cpp | 60 ++++++++++++++++--- src/coreclr/jit/emitarm64.h | 4 ++ .../JitInterface/CorInfoImpl.RyuJit.cs | 4 +- 4 files changed, 68 insertions(+), 17 deletions(-) diff --git a/src/coreclr/jit/codegenarmarch.cpp b/src/coreclr/jit/codegenarmarch.cpp index 78c430c0fb58ca..4548c53ff5747d 100644 --- a/src/coreclr/jit/codegenarmarch.cpp +++ b/src/coreclr/jit/codegenarmarch.cpp @@ -3623,9 +3623,8 @@ void CodeGen::genCallInstruction(GenTreeCall* call) // assert(genIsValidIntReg(target->GetRegNum())); - bool isTlsHandleTarget = false; #ifdef TARGET_ARM64 - isTlsHandleTarget = + bool isTlsHandleTarget = compiler->IsTargetAbi(CORINFO_NATIVEAOT_ABI) && TargetOS::IsUnix && target->IsTlsIconHandle(); if (isTlsHandleTarget) @@ -3642,22 +3641,22 @@ void CodeGen::genCallInstruction(GenTreeCall* call) // correct in the format the way linker needs. Also, we might end up spilling or // reloading a register, which can break the pattern. // - // adrp x0, :tlsdesc:tlsRoot ; R_AARCH64_TLSDESC_ADR_PAGE21 - // add x0, x0, #0 ; R_AARCH64_TLSDESC_ADD_LO12 // mrs x1, tpidr_el0 + // adrp x0, :tlsdesc:tlsRoot ; R_AARCH64_TLSDESC_ADR_PAGE21 // ldr x2, [x0] ; R_AARCH64_TLSDESC_LD64_LO12 + // add x0, x0, #0 ; R_AARCH64_TLSDESC_ADD_LO12 // blr x2 ; R_AARCH64_TLSDESC_CALL // add x0, x1, x0 // We guaranteed in LSRA that r0, r1 and r2 are assigned to this node. - // adrp/add - instGen_Set_Reg_To_Imm(attr, REG_R0, (ssize_t)methHnd, - INS_FLAGS_DONT_CARE DEBUGARG(iconNode->gtTargetHandle) DEBUGARG(iconNode->gtFlags)); // mrs emitter->emitIns_R(INS_mrs_tpid0, attr, REG_R1); + // adrp // ldr - emitter->emitIns_R_R_I(INS_ldr, attr, target->GetRegNum(), REG_R0, (ssize_t)methHnd); + // add + emitter->emitIns_Adrp_Ldr_Add(attr, REG_R0, target->GetRegNum(), (ssize_t)methHnd + DEBUGARG(iconNode->gtTargetHandle) DEBUGARG(iconNode->gtFlags)); } #endif @@ -3672,11 +3671,13 @@ void CodeGen::genCallInstruction(GenTreeCall* call) target->GetRegNum(), call->IsFastTailCall()); +#ifdef TARGET_ARM64 if (isTlsHandleTarget) { // add x0, x1, x0 GetEmitter()->emitIns_R_R_R(INS_add, EA_8BYTE, REG_R0, REG_R1, REG_R0); } +#endif // clang-format on } else diff --git a/src/coreclr/jit/emitarm64.cpp b/src/coreclr/jit/emitarm64.cpp index 5a5baaa850b87c..c3bb8c2705e77f 100644 --- a/src/coreclr/jit/emitarm64.cpp +++ b/src/coreclr/jit/emitarm64.cpp @@ -13004,6 +13004,58 @@ void emitter::emitIns_R_AR(instruction ins, emitAttr attr, regNumber ireg, regNu NYI("emitIns_R_AR"); } +// This computes address from the immediate which is relocatable. +void emitter::emitIns_Adrp_Ldr_Add(emitAttr attr, + regNumber ireg, regNumber reg2, + ssize_t addr DEBUGARG(size_t targetHandle) DEBUGARG(GenTreeFlags gtFlags)) +{ + assert(EA_IS_RELOC(attr)); + assert(EA_IS_CNS_TLSGD_RELOC(attr)); + + emitAttr size = EA_SIZE(attr); + insFormat fmt = IF_DI_1E; + bool needAdd = false; + instrDescJmp* id = emitNewInstrJmp(); + + // adrp + id->idIns(INS_adrp); + id->idInsFmt(fmt); + id->idInsOpt(INS_OPTS_NONE); + id->idOpSize(size); + id->idAddr()->iiaAddr = (BYTE*)addr; + id->idReg1(ireg); + id->idSetIsDspReloc(); + id->idSetTlsGD(); + +#ifdef DEBUG + id->idDebugOnlyInfo()->idMemCookie = targetHandle; + id->idDebugOnlyInfo()->idFlags = gtFlags; +#endif + + dispIns(id); + appendToCurIG(id); + + // ldr + emitIns_R_R_I(INS_ldr, attr, reg2, ireg, (ssize_t)addr); + + // add + fmt = IF_DI_2A; + instrDesc* addId = emitNewInstr(attr); + assert(id->idIsReloc()); + + addId->idIns(INS_add); + addId->idInsFmt(fmt); + addId->idInsOpt(INS_OPTS_NONE); + addId->idOpSize(size); + addId->idAddr()->iiaAddr = (BYTE*)addr; + addId->idReg1(ireg); + addId->idReg2(ireg); + addId->idSetTlsGD(); + + dispIns(addId); + appendToCurIG(addId); +} + // This computes address from the immediate which is relocatable. void emitter::emitIns_R_AI(instruction ins, emitAttr attr, @@ -13036,10 +13088,6 @@ void emitter::emitIns_R_AI(instruction ins, id->idAddr()->iiaAddr = (BYTE*)addr; id->idReg1(ireg); id->idSetIsDspReloc(); - if (EA_IS_CNS_TLSGD_RELOC(attr)) - { - id->idSetTlsGD(); - } #ifdef DEBUG id->idDebugOnlyInfo()->idMemCookie = targetHandle; id->idDebugOnlyInfo()->idFlags = gtFlags; @@ -13063,10 +13111,6 @@ void emitter::emitIns_R_AI(instruction ins, id->idAddr()->iiaAddr = (BYTE*)addr; id->idReg1(ireg); id->idReg2(ireg); - if (EA_IS_CNS_TLSGD_RELOC(attr)) - { - id->idSetTlsGD(); - } dispIns(id); appendToCurIG(id); diff --git a/src/coreclr/jit/emitarm64.h b/src/coreclr/jit/emitarm64.h index 2dcdf13bb93799..3ea420cadc5fb6 100644 --- a/src/coreclr/jit/emitarm64.h +++ b/src/coreclr/jit/emitarm64.h @@ -1316,6 +1316,10 @@ void emitIns_I_AR(instruction ins, emitAttr attr, int val, regNumber reg, int of void emitIns_R_AR(instruction ins, emitAttr attr, regNumber ireg, regNumber reg, int offs); +void emitIns_Adrp_Ldr_Add(emitAttr attr, + regNumber ireg, regNumber reg2, + ssize_t disp DEBUGARG(size_t targetHandle = 0) DEBUGARG(GenTreeFlags gtFlags = GTF_EMPTY)); + void emitIns_R_AI(instruction ins, emitAttr attr, regNumber ireg, diff --git a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs index 06e83c415273a7..0ee017b4b7c340 100644 --- a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs +++ b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs @@ -2176,7 +2176,9 @@ private void getFieldInfo(ref CORINFO_RESOLVED_TOKEN pResolvedToken, CORINFO_MET else if (field.IsThreadStatic) { if ((MethodBeingCompiled.Context.Target.IsWindows && MethodBeingCompiled.Context.Target.Architecture == TargetArchitecture.X64) || - (MethodBeingCompiled.Context.Target.OperatingSystem == TargetOS.Linux)) + ((MethodBeingCompiled.Context.Target.OperatingSystem == TargetOS.Linux) && + ((MethodBeingCompiled.Context.Target.Architecture == TargetArchitecture.X64) || + (MethodBeingCompiled.Context.Target.Architecture == TargetArchitecture.ARM64)))) { ISortableSymbolNode index = _compilation.NodeFactory.TypeThreadStaticIndex((MetadataType)field.OwningType); if (index is TypeThreadStaticIndexNode ti) From 2e0a7f40c706138827af110ff8405d3966104e75 Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Tue, 6 Feb 2024 11:04:46 -0800 Subject: [PATCH 21/22] misc changes --- src/coreclr/jit/codegenarmarch.cpp | 5 +++-- src/coreclr/jit/emitarm64.cpp | 23 +++++++++++++---------- src/coreclr/jit/emitarm64.h | 7 ++++--- 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/src/coreclr/jit/codegenarmarch.cpp b/src/coreclr/jit/codegenarmarch.cpp index 4548c53ff5747d..92e99471956f0d 100644 --- a/src/coreclr/jit/codegenarmarch.cpp +++ b/src/coreclr/jit/codegenarmarch.cpp @@ -3655,8 +3655,9 @@ void CodeGen::genCallInstruction(GenTreeCall* call) // adrp // ldr // add - emitter->emitIns_Adrp_Ldr_Add(attr, REG_R0, target->GetRegNum(), (ssize_t)methHnd - DEBUGARG(iconNode->gtTargetHandle) DEBUGARG(iconNode->gtFlags)); + emitter->emitIns_Adrp_Ldr_Add(attr, REG_R0, target->GetRegNum(), + (ssize_t)methHnd DEBUGARG(iconNode->gtTargetHandle) + DEBUGARG(iconNode->gtFlags)); } #endif diff --git a/src/coreclr/jit/emitarm64.cpp b/src/coreclr/jit/emitarm64.cpp index c3bb8c2705e77f..0ba639250e8051 100644 --- a/src/coreclr/jit/emitarm64.cpp +++ b/src/coreclr/jit/emitarm64.cpp @@ -13004,11 +13004,14 @@ void emitter::emitIns_R_AR(instruction ins, emitAttr attr, regNumber ireg, regNu NYI("emitIns_R_AR"); } -// This computes address from the immediate which is relocatable. -void emitter::emitIns_Adrp_Ldr_Add(emitAttr attr, - regNumber ireg, regNumber reg2, - ssize_t addr DEBUGARG(size_t targetHandle) DEBUGARG(GenTreeFlags gtFlags)) -{ +// This generates code to populate the access for TLS on linux +void emitter::emitIns_Adrp_Ldr_Add(emitAttr attr, + regNumber reg1, + regNumber reg2, + ssize_t addr DEBUGARG(size_t targetHandle) DEBUGARG(GenTreeFlags gtFlags)) +{ + assert(emitComp->IsTargetAbi(CORINFO_NATIVEAOT_ABI)); + assert(TargetOS::IsUnix); assert(EA_IS_RELOC(attr)); assert(EA_IS_CNS_TLSGD_RELOC(attr)); @@ -13023,7 +13026,7 @@ void emitter::emitIns_Adrp_Ldr_Add(emitAttr attr, id->idInsOpt(INS_OPTS_NONE); id->idOpSize(size); id->idAddr()->iiaAddr = (BYTE*)addr; - id->idReg1(ireg); + id->idReg1(reg1); id->idSetIsDspReloc(); id->idSetTlsGD(); @@ -13036,10 +13039,10 @@ void emitter::emitIns_Adrp_Ldr_Add(emitAttr attr, appendToCurIG(id); // ldr - emitIns_R_R_I(INS_ldr, attr, reg2, ireg, (ssize_t)addr); + emitIns_R_R_I(INS_ldr, attr, reg2, reg1, (ssize_t)addr); // add - fmt = IF_DI_2A; + fmt = IF_DI_2A; instrDesc* addId = emitNewInstr(attr); assert(id->idIsReloc()); @@ -13048,8 +13051,8 @@ void emitter::emitIns_Adrp_Ldr_Add(emitAttr attr, addId->idInsOpt(INS_OPTS_NONE); addId->idOpSize(size); addId->idAddr()->iiaAddr = (BYTE*)addr; - addId->idReg1(ireg); - addId->idReg2(ireg); + addId->idReg1(reg1); + addId->idReg2(reg1); addId->idSetTlsGD(); dispIns(addId); diff --git a/src/coreclr/jit/emitarm64.h b/src/coreclr/jit/emitarm64.h index 3ea420cadc5fb6..7ecc456fa1655f 100644 --- a/src/coreclr/jit/emitarm64.h +++ b/src/coreclr/jit/emitarm64.h @@ -1316,9 +1316,10 @@ void emitIns_I_AR(instruction ins, emitAttr attr, int val, regNumber reg, int of void emitIns_R_AR(instruction ins, emitAttr attr, regNumber ireg, regNumber reg, int offs); -void emitIns_Adrp_Ldr_Add(emitAttr attr, - regNumber ireg, regNumber reg2, - ssize_t disp DEBUGARG(size_t targetHandle = 0) DEBUGARG(GenTreeFlags gtFlags = GTF_EMPTY)); +void emitIns_Adrp_Ldr_Add(emitAttr attr, + regNumber reg1, + regNumber reg2, + ssize_t addr DEBUGARG(size_t targetHandle = 0) DEBUGARG(GenTreeFlags gtFlags = GTF_EMPTY)); void emitIns_R_AI(instruction ins, emitAttr attr, From b7a43f9b9f7b9d19da5a5c9b607213019cb83cd3 Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Mon, 12 Feb 2024 11:08:02 -0800 Subject: [PATCH 22/22] Review feedback --- src/coreclr/jit/emitarm64.cpp | 12 ++++++++++-- .../JitInterface/CorInfoImpl.RyuJit.cs | 8 ++++---- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/coreclr/jit/emitarm64.cpp b/src/coreclr/jit/emitarm64.cpp index 0ba639250e8051..dad97ec04ed719 100644 --- a/src/coreclr/jit/emitarm64.cpp +++ b/src/coreclr/jit/emitarm64.cpp @@ -215,7 +215,15 @@ void emitter::emitInsSanityCheck(instrDesc* id) break; case IF_BR_1B: // BR_1B ................ ......nnnnn..... Rn - assert(isGeneralRegister(id->idReg3())); + if (emitComp->IsTargetAbi(CORINFO_NATIVEAOT_ABI) && id->idIsTlsGD()) + { + assert(isGeneralRegister(id->idReg1())); + assert(id->idAddr()->iiaAddr != nullptr); + } + else + { + assert(isGeneralRegister(id->idReg3())); + } break; case IF_LS_1A: // LS_1A .X......iiiiiiii iiiiiiiiiiittttt Rt PC imm(1MB) @@ -13575,7 +13583,7 @@ void emitter::emitIns_Call(EmitCallType callType, assert(xreg == REG_NA); if (emitComp->IsTargetAbi(CORINFO_NATIVEAOT_ABI) && EA_IS_CNS_TLSGD_RELOC(retSize)) { - // For NativeAOT linux/arm64, we need to also record the relocation of methHnd + // For NativeAOT linux/arm64, we need to also record the relocation of methHnd. // Since we do not have space to embed it in instrDesc, we store the register in // reg1 and instead use the `iiaAdd` to store the method handle. Likewise, during // emitOutputInstr, we retrieve the register from reg1 for this specific case. diff --git a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs index 0ee017b4b7c340..0a0207e2a2afdf 100644 --- a/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs +++ b/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs @@ -2175,10 +2175,10 @@ private void getFieldInfo(ref CORINFO_RESOLVED_TOKEN pResolvedToken, CORINFO_MET } else if (field.IsThreadStatic) { - if ((MethodBeingCompiled.Context.Target.IsWindows && MethodBeingCompiled.Context.Target.Architecture == TargetArchitecture.X64) || - ((MethodBeingCompiled.Context.Target.OperatingSystem == TargetOS.Linux) && - ((MethodBeingCompiled.Context.Target.Architecture == TargetArchitecture.X64) || - (MethodBeingCompiled.Context.Target.Architecture == TargetArchitecture.ARM64)))) + var target = MethodBeingCompiled.Context.Target; + if ((target.IsWindows && target.Architecture is TargetArchitecture.X64) || + ((target.OperatingSystem == TargetOS.Linux) && + (target.Architecture is TargetArchitecture.X64 or TargetArchitecture.ARM64))) { ISortableSymbolNode index = _compilation.NodeFactory.TypeThreadStaticIndex((MetadataType)field.OwningType); if (index is TypeThreadStaticIndexNode ti)