diff --git a/src/coreclr/jit/codegen.h b/src/coreclr/jit/codegen.h index 65cf32b02020d..6a78dc3515439 100644 --- a/src/coreclr/jit/codegen.h +++ b/src/coreclr/jit/codegen.h @@ -1155,7 +1155,10 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX void genConsumeHWIntrinsicOperands(GenTreeHWIntrinsic* tree); #endif // FEATURE_HW_INTRINSICS void genEmitGSCookieCheck(bool pushReg); - void genSetRegToIcon(regNumber reg, ssize_t val, var_types type = TYP_INT, insFlags flags = INS_FLAGS_DONT_CARE); + void genSetRegToIcon(regNumber reg, + ssize_t val, + var_types type = TYP_INT, + insFlags flags = INS_FLAGS_DONT_CARE DEBUGARG(GenTreeFlags gtFlags = GTF_EMPTY)); void genCodeForShift(GenTree* tree); #if defined(TARGET_X86) || defined(TARGET_ARM) @@ -1490,7 +1493,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX regNumber reg, ssize_t imm, insFlags flags = INS_FLAGS_DONT_CARE DEBUGARG(size_t targetHandle = 0) - DEBUGARG(unsigned gtFlags = 0)); + DEBUGARG(GenTreeFlags gtFlags = GTF_EMPTY)); void instGen_Compare_Reg_To_Zero(emitAttr size, regNumber reg); diff --git a/src/coreclr/jit/codegenarm.cpp b/src/coreclr/jit/codegenarm.cpp index 49fc8c9c3038e..fec8809683da1 100644 --- a/src/coreclr/jit/codegenarm.cpp +++ b/src/coreclr/jit/codegenarm.cpp @@ -159,7 +159,7 @@ void CodeGen::genEHCatchRet(BasicBlock* block) void CodeGen::instGen_Set_Reg_To_Imm(emitAttr size, regNumber reg, ssize_t imm, - insFlags flags DEBUGARG(size_t targetHandle) DEBUGARG(unsigned gtFlags)) + insFlags flags DEBUGARG(size_t targetHandle) DEBUGARG(GenTreeFlags gtFlags)) { // reg cannot be a FP register assert(!genIsValidFloatReg(reg)); diff --git a/src/coreclr/jit/codegenarm64.cpp b/src/coreclr/jit/codegenarm64.cpp index b0dd9ad60a8ac..ae1d953ba3603 100644 --- a/src/coreclr/jit/codegenarm64.cpp +++ b/src/coreclr/jit/codegenarm64.cpp @@ -1594,7 +1594,7 @@ void CodeGen::genEHCatchRet(BasicBlock* block) void CodeGen::instGen_Set_Reg_To_Imm(emitAttr size, regNumber reg, ssize_t imm, - insFlags flags DEBUGARG(size_t targetHandle) DEBUGARG(unsigned gtFlags)) + insFlags flags DEBUGARG(size_t targetHandle) DEBUGARG(GenTreeFlags gtFlags)) { // reg cannot be a FP register assert(!genIsValidFloatReg(reg)); diff --git a/src/coreclr/jit/codegenarmarch.cpp b/src/coreclr/jit/codegenarmarch.cpp index 292df210aab22..1953f93e076b9 100644 --- a/src/coreclr/jit/codegenarmarch.cpp +++ b/src/coreclr/jit/codegenarmarch.cpp @@ -560,7 +560,7 @@ void CodeGen::genCodeForTreeNode(GenTree* treeNode) //------------------------------------------------------------------------ // genSetRegToIcon: Generate code that will set the given register to the integer constant. // -void CodeGen::genSetRegToIcon(regNumber reg, ssize_t val, var_types type, insFlags flags) +void CodeGen::genSetRegToIcon(regNumber reg, ssize_t val, var_types type, insFlags flags DEBUGARG(GenTreeFlags gtFlags)) { // Reg cannot be a FP reg assert(!genIsValidFloatReg(reg)); @@ -603,7 +603,7 @@ void CodeGen::genSetGSSecurityCookie(regNumber initReg, bool* pInitRegZeroed) else { instGen_Set_Reg_To_Imm(EA_PTR_DSP_RELOC, initReg, (ssize_t)compiler->gsGlobalSecurityCookieAddr, - INS_FLAGS_DONT_CARE DEBUGARG((size_t)THT_SetGSCookie) DEBUGARG(0)); + INS_FLAGS_DONT_CARE DEBUGARG((size_t)THT_SetGSCookie) DEBUGARG(GTF_EMPTY)); GetEmitter()->emitIns_R_R_I(INS_ldr, EA_PTRSIZE, initReg, initReg, 0); regSet.verifyRegUsed(initReg); GetEmitter()->emitIns_S_R(INS_str, EA_PTRSIZE, initReg, compiler->lvaGSSecurityCookie, 0); diff --git a/src/coreclr/jit/codegencommon.cpp b/src/coreclr/jit/codegencommon.cpp index 73e6f196cae11..e423827fee25b 100644 --- a/src/coreclr/jit/codegencommon.cpp +++ b/src/coreclr/jit/codegencommon.cpp @@ -1799,7 +1799,7 @@ void CodeGen::genEmitGSCookieCheck(bool pushReg) { // Ngen case - GS cookie constant needs to be accessed through an indirection. instGen_Set_Reg_To_Imm(EA_HANDLE_CNS_RELOC, regGSConst, (ssize_t)compiler->gsGlobalSecurityCookieAddr, - INS_FLAGS_DONT_CARE DEBUGARG((size_t)THT_GSCookieCheck) DEBUGARG(0)); + INS_FLAGS_DONT_CARE DEBUGARG((size_t)THT_GSCookieCheck) DEBUGARG(GTF_EMPTY)); GetEmitter()->emitIns_R_R_I(INS_ldr, EA_PTRSIZE, regGSConst, regGSConst, 0); } // Load this method's GS value from the stack frame diff --git a/src/coreclr/jit/codegenxarch.cpp b/src/coreclr/jit/codegenxarch.cpp index 6f605e5514bdc..cd40138a695da 100644 --- a/src/coreclr/jit/codegenxarch.cpp +++ b/src/coreclr/jit/codegenxarch.cpp @@ -28,7 +28,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX * Generate code that will set the given register to the integer constant. */ -void CodeGen::genSetRegToIcon(regNumber reg, ssize_t val, var_types type, insFlags flags) +void CodeGen::genSetRegToIcon(regNumber reg, ssize_t val, var_types type, insFlags flags DEBUGARG(GenTreeFlags gtFlags)) { // Reg cannot be a FP reg assert(!genIsValidFloatReg(reg)); @@ -45,7 +45,7 @@ void CodeGen::genSetRegToIcon(regNumber reg, ssize_t val, var_types type, insFla else { // TODO-XArch-CQ: needs all the optimized cases - GetEmitter()->emitIns_R_I(INS_mov, emitActualTypeSize(type), reg, val); + GetEmitter()->emitIns_R_I(INS_mov, emitActualTypeSize(type), reg, val DEBUGARG(gtFlags)); } } @@ -440,7 +440,7 @@ void CodeGen::genEHFinallyOrFilterRet(BasicBlock* block) void CodeGen::instGen_Set_Reg_To_Imm(emitAttr size, regNumber reg, ssize_t imm, - insFlags flags DEBUGARG(size_t targetHandle) DEBUGARG(unsigned gtFlags)) + insFlags flags DEBUGARG(size_t targetHandle) DEBUGARG(GenTreeFlags gtFlags)) { // reg cannot be a FP register assert(!genIsValidFloatReg(reg)); @@ -505,7 +505,7 @@ void CodeGen::genSetRegToConst(regNumber targetReg, var_types targetType, GenTre } else { - genSetRegToIcon(targetReg, cnsVal, targetType); + genSetRegToIcon(targetReg, cnsVal, targetType, INS_FLAGS_DONT_CARE DEBUGARG(tree->gtFlags)); } } break; diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index 21e37879eed7e..2488118c7a33c 100644 --- a/src/coreclr/jit/emit.cpp +++ b/src/coreclr/jit/emit.cpp @@ -3904,6 +3904,114 @@ void emitter::emitRecomputeIGoffsets() #endif } +//---------------------------------------------------------------------------------------- +// emitDispCommentForHandle: +// Displays a comment for a handle, e.g. displays a raw string for GTF_ICON_STR_HDL +// or a class name for GTF_ICON_CLASS_HDL +// +// Arguments: +// handle - a constant value to display a comment for +// flags - a flag that the describes the handle +// +void emitter::emitDispCommentForHandle(size_t handle, GenTreeFlags flag) +{ +#ifdef DEBUG + if (handle == 0) + { + return; + } + +#ifdef TARGET_XARCH + const char* commentPrefix = " ;"; +#else + const char* commentPrefix = " //"; +#endif + + flag &= GTF_ICON_HDL_MASK; + const char* str = nullptr; + + if (flag == GTF_ICON_STR_HDL) + { + const WCHAR* wstr = emitComp->eeGetCPString(handle); + // NOTE: eGetCPString always returns nullptr on Linux/ARM + if (wstr == nullptr) + { + printf("%s string handle", commentPrefix); + } + else + { + const size_t actualLen = wcslen(wstr); + const size_t maxLength = 63; + const size_t newLen = min(maxLength, actualLen); + + // +1 for null terminator + WCHAR buf[maxLength + 1] = {0}; + wcsncpy(buf, wstr, newLen); + for (size_t i = 0; i < newLen; i++) + { + // Escape \n and \r symbols + if (buf[i] == L'\n' || buf[i] == L'\r') + { + buf[i] = L' '; + } + } + if (actualLen > maxLength) + { + // Append "..." for long strings + buf[maxLength - 3] = L'.'; + buf[maxLength - 2] = L'.'; + buf[maxLength - 1] = L'.'; + } + printf("%s \"%S\"", commentPrefix, buf); + } + } + else if (flag == GTF_ICON_CLASS_HDL) + { + str = emitComp->eeGetClassName(reinterpret_cast(handle)); + } +#ifndef TARGET_XARCH + // These are less useful for xarch: + else if (flag == GTF_ICON_CONST_PTR) + { + str = "const ptr"; + } + else if (flag == GTF_ICON_GLOBAL_PTR) + { + str = "global ptr"; + } + else if (flag == GTF_ICON_FIELD_HDL) + { + str = emitComp->eeGetFieldName(reinterpret_cast(handle)); + } + else if (flag == GTF_ICON_STATIC_HDL) + { + str = "static handle"; + } + else if (flag == GTF_ICON_METHOD_HDL) + { + str = emitComp->eeGetMethodFullName(reinterpret_cast(handle)); + } + else if (flag == GTF_ICON_FTN_ADDR) + { + str = "function address"; + } + else if (flag == GTF_ICON_TOKEN_HDL) + { + str = "token handle"; + } + else + { + str = "unknown"; + } +#endif // TARGET_XARCH + + if (str != nullptr) + { + printf("%s %s", commentPrefix, str); + } +#endif // DEBUG +} + /***************************************************************************** * Bind targets of relative jumps to choose the smallest possible encoding. * X86 and AMD64 have a small and large encoding. diff --git a/src/coreclr/jit/emit.h b/src/coreclr/jit/emit.h index ef67148ea962a..4776f14648221 100644 --- a/src/coreclr/jit/emit.h +++ b/src/coreclr/jit/emit.h @@ -510,6 +510,8 @@ class emitter void emitRecomputeIGoffsets(); + void emitDispCommentForHandle(size_t handle, GenTreeFlags flags); + /************************************************************************/ /* The following describes a single instruction */ /************************************************************************/ @@ -545,7 +547,7 @@ class emitter size_t idSize; // size of the instruction descriptor unsigned idVarRefOffs; // IL offset for LclVar reference size_t idMemCookie; // for display of method name (also used by switch table) - unsigned idFlags; // for determining type of handle in idMemCookie + GenTreeFlags idFlags; // for determining type of handle in idMemCookie bool idFinallyCall; // Branch instruction is a call to finally bool idCatchRet; // Instruction is for a catch 'return' CORINFO_SIG_INFO* idCallSig; // Used to report native call site signatures to the EE diff --git a/src/coreclr/jit/emitarm.cpp b/src/coreclr/jit/emitarm.cpp index 5b01adbd14a5d..0519ddc9e0314 100644 --- a/src/coreclr/jit/emitarm.cpp +++ b/src/coreclr/jit/emitarm.cpp @@ -1701,8 +1701,11 @@ void emitter::emitIns_R(instruction ins, emitAttr attr, regNumber reg) * Add an instruction referencing a register and a constant. */ -void emitter::emitIns_R_I( - instruction ins, emitAttr attr, regNumber reg, target_ssize_t imm, insFlags flags /* = INS_FLAGS_DONT_CARE */) +void emitter::emitIns_R_I(instruction ins, + emitAttr attr, + regNumber reg, + target_ssize_t imm, + insFlags flags /* = INS_FLAGS_DONT_CARE */ DEBUGARG(GenTreeFlags gtFlags)) { insFormat fmt = IF_NONE; @@ -2006,6 +2009,7 @@ void emitter::emitIns_R_I( id->idInsSize(isz); id->idInsFlags(sf); id->idReg1(reg); + INDEBUG(id->idDebugOnlyInfo()->idFlags = gtFlags); dispIns(id); appendToCurIG(id); diff --git a/src/coreclr/jit/emitarm.h b/src/coreclr/jit/emitarm.h index ac6e4f139db7f..6da0ceaa7ee26 100644 --- a/src/coreclr/jit/emitarm.h +++ b/src/coreclr/jit/emitarm.h @@ -220,8 +220,11 @@ void emitIns_I(instruction ins, emitAttr attr, target_ssize_t imm); void emitIns_R(instruction ins, emitAttr attr, regNumber reg); -void emitIns_R_I( - instruction ins, emitAttr attr, regNumber reg, target_ssize_t imm, insFlags flags = INS_FLAGS_DONT_CARE); +void emitIns_R_I(instruction ins, + emitAttr attr, + regNumber reg, + target_ssize_t imm, + insFlags flags = INS_FLAGS_DONT_CARE DEBUGARG(GenTreeFlags gtFlags = GTF_EMPTY)); void emitIns_MovRelocatableImmediate(instruction ins, emitAttr attr, regNumber reg, BYTE* addr); void emitIns_Mov(instruction ins, diff --git a/src/coreclr/jit/emitarm64.cpp b/src/coreclr/jit/emitarm64.cpp index 84c49d94723d4..771ce88ec849c 100644 --- a/src/coreclr/jit/emitarm64.cpp +++ b/src/coreclr/jit/emitarm64.cpp @@ -3715,7 +3715,11 @@ void emitter::emitIns_R(instruction ins, emitAttr attr, regNumber reg) * Add an instruction referencing a register and a constant. */ -void emitter::emitIns_R_I(instruction ins, emitAttr attr, regNumber reg, ssize_t imm, insOpts opt /* = INS_OPTS_NONE */) +void emitter::emitIns_R_I(instruction ins, + emitAttr attr, + regNumber reg, + ssize_t imm, + insOpts opt /* = INS_OPTS_NONE */ DEBUGARG(GenTreeFlags gtFlags)) { emitAttr size = EA_SIZE(attr); emitAttr elemsize = EA_UNKNOWN; @@ -3965,6 +3969,7 @@ void emitter::emitIns_R_I(instruction ins, emitAttr attr, regNumber reg, ssize_t id->idInsOpt(opt); id->idReg1(reg); + INDEBUG(id->idDebugOnlyInfo()->idFlags = gtFlags); dispIns(id); appendToCurIG(id); @@ -8098,7 +8103,7 @@ void emitter::emitIns_R_AR(instruction ins, emitAttr attr, regNumber ireg, regNu void emitter::emitIns_R_AI(instruction ins, emitAttr attr, regNumber ireg, - ssize_t addr DEBUGARG(size_t targetHandle) DEBUGARG(unsigned gtFlags)) + ssize_t addr DEBUGARG(size_t targetHandle) DEBUGARG(GenTreeFlags gtFlags)) { assert(EA_IS_RELOC(attr)); emitAttr size = EA_SIZE(attr); @@ -12257,7 +12262,6 @@ void emitter::emitDispIns( ssize_t index2; unsigned registerListSize; const char* targetName; - const WCHAR* stringLiteral; case IF_BI_0A: // BI_0A ......iiiiiiiiii iiiiiiiiiiiiiiii simm26:00 case IF_BI_0B: // BI_0B ......iiiiiiiiii iiiiiiiiiii..... simm19:00 @@ -12363,9 +12367,8 @@ void emitter::emitDispIns( case IF_LARGEADR: assert(insOptsNone(id->idInsOpt())); emitDispReg(id->idReg1(), size, true); - imm = emitGetInsSC(id); - targetName = nullptr; - stringLiteral = nullptr; + imm = emitGetInsSC(id); + targetName = nullptr; /* Is this actually a reference to a data section? */ if (fmt == IF_LARGEADR) @@ -12398,8 +12401,7 @@ void emitter::emitDispIns( { printf("HIGH RELOC "); emitDispImm((ssize_t)id->idAddr()->iiaAddr, false); - size_t targetHandle = id->idDebugOnlyInfo()->idMemCookie; - unsigned idFlags = id->idDebugOnlyInfo()->idFlags & GTF_ICON_HDL_MASK; + size_t targetHandle = id->idDebugOnlyInfo()->idMemCookie; if (targetHandle == THT_IntializeArrayIntrinsics) { @@ -12413,53 +12415,6 @@ void emitter::emitDispIns( { targetName = "SetGlobalSecurityCookie"; } - else if (idFlags == GTF_ICON_CONST_PTR) - { - targetName = "const ptr"; - } - else if (idFlags == GTF_ICON_GLOBAL_PTR) - { - targetName = "global ptr"; - } - else if (idFlags == GTF_ICON_STR_HDL) - { - stringLiteral = emitComp->eeGetCPString(targetHandle); - // Note that eGetCPString isn't currently implemented on Linux/ARM - // and instead always returns nullptr. However, use it here, so in - // future, once it is is implemented, no changes will be needed here. - if (stringLiteral == nullptr) - { - targetName = "String handle"; - } - } - else if (idFlags == GTF_ICON_FIELD_HDL) - { - targetName = emitComp->eeGetFieldName((CORINFO_FIELD_HANDLE)targetHandle); - } - else if (idFlags == GTF_ICON_STATIC_HDL) - { - targetName = "Static handle"; - } - else if (idFlags == GTF_ICON_METHOD_HDL) - { - targetName = emitComp->eeGetMethodFullName((CORINFO_METHOD_HANDLE)targetHandle); - } - else if (idFlags == GTF_ICON_FTN_ADDR) - { - targetName = "Function address"; - } - else if (idFlags == GTF_ICON_CLASS_HDL) - { - targetName = emitComp->eeGetClassName((CORINFO_CLASS_HANDLE)targetHandle); - } - else if (idFlags == GTF_ICON_TOKEN_HDL) - { - targetName = "Token handle"; - } - else - { - targetName = "Unknown"; - } } else if (id->idIsBound()) { @@ -12475,9 +12430,9 @@ void emitter::emitDispIns( { printf(" // [%s]", targetName); } - else if (stringLiteral != nullptr) + else { - printf(" // [%S]", stringLiteral); + emitDispCommentForHandle(id->idDebugOnlyInfo()->idMemCookie, id->idDebugOnlyInfo()->idFlags); } break; diff --git a/src/coreclr/jit/emitarm64.h b/src/coreclr/jit/emitarm64.h index b25659368c1d1..a5e98d24b569a 100644 --- a/src/coreclr/jit/emitarm64.h +++ b/src/coreclr/jit/emitarm64.h @@ -728,7 +728,11 @@ void emitIns_I(instruction ins, emitAttr attr, ssize_t imm); void emitIns_R(instruction ins, emitAttr attr, regNumber reg); -void emitIns_R_I(instruction ins, emitAttr attr, regNumber reg, ssize_t imm, insOpts opt = INS_OPTS_NONE); +void emitIns_R_I(instruction ins, + emitAttr attr, + regNumber reg, + ssize_t imm, + insOpts opt = INS_OPTS_NONE DEBUGARG(GenTreeFlags gtFlags = GTF_EMPTY)); void emitIns_R_F(instruction ins, emitAttr attr, regNumber reg, double immDbl, insOpts opt = INS_OPTS_NONE); @@ -827,7 +831,7 @@ void emitIns_R_AR(instruction ins, emitAttr attr, regNumber ireg, regNumber reg, void emitIns_R_AI(instruction ins, emitAttr attr, regNumber ireg, - ssize_t disp DEBUGARG(size_t targetHandle = 0) DEBUGARG(unsigned gtFlags = 0)); + ssize_t disp DEBUGARG(size_t targetHandle = 0) DEBUGARG(GenTreeFlags gtFlags = GTF_EMPTY)); void emitIns_AR_R(instruction ins, emitAttr attr, regNumber ireg, regNumber reg, int offs); diff --git a/src/coreclr/jit/emitxarch.cpp b/src/coreclr/jit/emitxarch.cpp index c35a6675fe757..63b2e044e1105 100644 --- a/src/coreclr/jit/emitxarch.cpp +++ b/src/coreclr/jit/emitxarch.cpp @@ -3965,7 +3965,7 @@ void emitter::emitIns_R(instruction ins, emitAttr attr, regNumber reg) * Add an instruction referencing a register and a constant. */ -void emitter::emitIns_R_I(instruction ins, emitAttr attr, regNumber reg, ssize_t val) +void emitter::emitIns_R_I(instruction ins, emitAttr attr, regNumber reg, ssize_t val DEBUGARG(GenTreeFlags gtFlags)) { emitAttr size = EA_SIZE(attr); @@ -4089,8 +4089,8 @@ void emitter::emitIns_R_I(instruction ins, emitAttr attr, regNumber reg, ssize_t id->idIns(ins); id->idInsFmt(fmt); id->idReg1(reg); - id->idCodeSize(sz); + INDEBUG(id->idDebugOnlyInfo()->idFlags = gtFlags); dispIns(id); emitCurIGsize += sz; @@ -8872,6 +8872,8 @@ void emitter::emitDispIns( { // (val < 0) printf("-0x%IX", -val); } + + emitDispCommentForHandle(val, id->idDebugOnlyInfo()->idFlags & GTF_ICON_HDL_MASK); } break; diff --git a/src/coreclr/jit/emitxarch.h b/src/coreclr/jit/emitxarch.h index f952a6f649f44..632fd95bcb140 100644 --- a/src/coreclr/jit/emitxarch.h +++ b/src/coreclr/jit/emitxarch.h @@ -327,7 +327,7 @@ void emitIns_R(instruction ins, emitAttr attr, regNumber reg); void emitIns_C(instruction ins, emitAttr attr, CORINFO_FIELD_HANDLE fdlHnd, int offs); -void emitIns_R_I(instruction ins, emitAttr attr, regNumber reg, ssize_t val); +void emitIns_R_I(instruction ins, emitAttr attr, regNumber reg, ssize_t val DEBUGARG(GenTreeFlags gtFlags = GTF_EMPTY)); void emitIns_Mov(instruction ins, emitAttr attr, regNumber dstReg, regNumber srgReg, bool canSkip);