From bf756bc167d1004cad4c06b3a0330d5491b9736a Mon Sep 17 00:00:00 2001 From: EgorBo Date: Tue, 2 Aug 2022 01:04:19 +0200 Subject: [PATCH 01/32] Use liberal vn for tls indirects --- src/coreclr/jit/valuenum.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index 957669bd9a812..8a31c4e5f34ad 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -10421,6 +10421,26 @@ void Compiler::fgValueNumberAddExceptionSetForIndirection(GenTree* tree, GenTree vnStore->VNExcSetSingleton(vnStore->VNForFunc(TYP_REF, VNF_NullPtrExc, vnpBaseNorm.GetConservative()))); } + VNFuncApp func; + if (vnStore->GetVNFunc(vnpBaseNorm.GetConservative(), &func) && + (func.m_func == VNF_GetsharedGcthreadstaticBaseNoctor)) + { + switch (func.m_func) + { + case VNF_GetgenericsGcthreadstaticBase: + case VNF_GetgenericsNongcthreadstaticBase: + case VNF_GetsharedGcthreadstaticBase: + case VNF_GetsharedNongcthreadstaticBase: + case VNF_GetsharedGcthreadstaticBaseNoctor: + case VNF_GetsharedNongcthreadstaticBaseNoctor: + case VNF_GetsharedGcthreadstaticBaseDynamicclass: + case VNF_GetsharedNongcthreadstaticBaseDynamicclass: + tree->gtVNPair.SetConservative(tree->gtVNPair.GetLiberal()); + break; + default: + break; + } + } // Add the NullPtrExc to "tree"'s value numbers. tree->gtVNPair = vnStore->VNPWithExc(tree->gtVNPair, excChkSet); } From 24fc8a626beb187df02788a47fadd292f597b121 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Thu, 4 Aug 2022 09:40:41 +0200 Subject: [PATCH 02/32] Initial impl --- src/coreclr/jit/codegencommon.cpp | 15 +++++++++++-- src/coreclr/jit/compiler.cpp | 37 ++++++++++++++++++++++++++++--- src/coreclr/jit/compiler.h | 6 ++--- src/coreclr/jit/emit.cpp | 20 ++++++++++++----- src/coreclr/jit/emit.h | 2 -- src/coreclr/jit/jitconfigvalues.h | 10 +++++++-- 6 files changed, 73 insertions(+), 17 deletions(-) diff --git a/src/coreclr/jit/codegencommon.cpp b/src/coreclr/jit/codegencommon.cpp index 4a575febcf440..894c61d693143 100644 --- a/src/coreclr/jit/codegencommon.cpp +++ b/src/coreclr/jit/codegencommon.cpp @@ -1740,11 +1740,18 @@ void CodeGen::genGenerateMachineCode() { compiler->opts.disAsm = true; } +#endif compiler->compCurBB = compiler->fgFirstBB; if (compiler->opts.disAsm) { - printf("; Assembly listing for method %s\n", compiler->info.compFullName); +#ifdef DEBUG + const char* fullName = compiler->info.compFullName; +#else + const char* fullName = compiler->eeGetMethodFullName(compiler->info.compMethodHnd); +#endif + + printf("; Assembly listing for method %s\n", fullName); printf("; Emitting "); @@ -1905,7 +1912,6 @@ void CodeGen::genGenerateMachineCode() printf("; invoked as altjit\n"); } } -#endif // DEBUG // We compute the final frame layout before code generation. This is because LSRA // has already computed exactly the maximum concurrent number of spill temps of each type that are @@ -2057,6 +2063,11 @@ void CodeGen::genEmitMachineCode() printf("*************** After end code gen, before unwindEmit()\n"); GetEmitter()->emitDispIGlist(true); } +#else + if (compiler->opts.disAsm) + { + printf("\n; Total bytes of code %d\n", codeSize); + } #endif *nativeSizeOfCode = codeSize; diff --git a/src/coreclr/jit/compiler.cpp b/src/coreclr/jit/compiler.cpp index 78ad80d23352c..1f1adb62cf0cc 100644 --- a/src/coreclr/jit/compiler.cpp +++ b/src/coreclr/jit/compiler.cpp @@ -2819,14 +2819,15 @@ void Compiler::compInitOptions(JitFlags* jitFlags) opts.compJitEarlyExpandMDArrays = (JitConfig.JitEarlyExpandMDArrays() != 0); + opts.disAsm = false; + opts.disDiffable = false; + opts.dspDiffable = false; #ifdef DEBUG opts.dspInstrs = false; opts.dspLines = false; opts.varNames = false; opts.dmpHex = false; - opts.disAsm = false; opts.disAsmSpilled = false; - opts.disDiffable = false; opts.disAddr = false; opts.disAlignment = false; opts.dspCode = false; @@ -3069,8 +3070,38 @@ void Compiler::compInitOptions(JitFlags* jitFlags) } s_pJitFunctionFileInitialized = true; } +#else // DEBUG + if (!jitFlags->IsSet(JitFlags::JIT_FLAG_PREJIT)) + { + if (!JitConfig.JitDisasm().isEmpty()) + { + const char* methodName = info.compCompHnd->getMethodName(info.compMethodHnd, nullptr); + const char* className = info.compCompHnd->getClassName(info.compClassHnd); -#endif // DEBUG + if (JitConfig.JitDisasm().contains(methodName, className, &info.compMethodInfo->args)) + { + opts.disAsm = true; + } + } + } + else + { + if (!JitConfig.NgenDisasm().isEmpty()) + { + const char* methodName = info.compCompHnd->getMethodName(info.compMethodHnd, nullptr); + const char* className = info.compCompHnd->getClassName(info.compClassHnd); + + if (JitConfig.NgenDisasm().contains(methodName, className, &info.compMethodInfo->args)) + { + opts.disAsm = true; + } + } + } + + bool diffable = JitConfig.DiffableDasm(); + opts.disDiffable = diffable; + opts.dspDiffable = diffable; +#endif // !DEBUG //------------------------------------------------------------------------- diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index 2bfa7d81c8468..5646bb634e895 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -9170,6 +9170,9 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX bool optRepeat; // Repeat optimizer phases k times #endif + bool disAsm; // Display native code as it is generated + bool dspDiffable; // Makes the Jit Dump 'diff-able' (currently uses same COMPlus_* flag as disDiffable) + bool disDiffable; // Makes the Disassembly code 'diff-able' #ifdef DEBUG bool compProcedureSplittingEH; // Separate cold code from hot code for functions with EH bool dspCode; // Display native code generated @@ -9179,16 +9182,13 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX bool dspLines; // Display source-code lines intermixed with native code output bool dmpHex; // Display raw bytes in hex of native code output bool varNames; // Display variables names in native code output - bool disAsm; // Display native code as it is generated bool disAsmSpilled; // Display native code when any register spilling occurs bool disasmWithGC; // Display GC info interleaved with disassembly. - bool disDiffable; // Makes the Disassembly code 'diff-able' bool disAddr; // Display process address next to each instruction in disassembly code bool disAlignment; // Display alignment boundaries in disassembly code bool disAsm2; // Display native code after it is generated using external disassembler bool dspOrder; // Display names of each of the methods that we ngen/jit bool dspUnwind; // Display the unwind info output - bool dspDiffable; // Makes the Jit Dump 'diff-able' (currently uses same COMPlus_* flag as disDiffable) bool compLongAddress; // Force using large pseudo instructions for long address // (IF_LARGEJMP/IF_LARGEADR/IF_LARGLDC) bool dspGCtbls; // Display the GC tables diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index 430b9ec8e2b89..4d8a08426d8ca 100644 --- a/src/coreclr/jit/emit.cpp +++ b/src/coreclr/jit/emit.cpp @@ -2638,15 +2638,17 @@ void* emitter::emitAddInlineLabel() return emitCurIG; } -#ifdef DEBUG - //----------------------------------------------------------------------------- // emitPrintLabel: Print the assembly label for an insGroup. We could use emitter::emitLabelString() // to be consistent, but that seems silly. // void emitter::emitPrintLabel(insGroup* ig) { +#ifdef DEBUG printf("G_M%03u_IG%02u", emitComp->compMethodID, ig->igNum); +#else + printf("IG_%02u", ig->igNum); +#endif } //----------------------------------------------------------------------------- @@ -2664,14 +2666,16 @@ const char* emitter::emitLabelString(insGroup* ig) static char buf[4][TEMP_BUFFER_LEN]; const char* retbuf; +#ifdef DEBUG sprintf_s(buf[curBuf], TEMP_BUFFER_LEN, "G_M%03u_IG%02u", emitComp->compMethodID, ig->igNum); +#else + sprintf_s(buf[curBuf], TEMP_BUFFER_LEN, "IG_%02u", ig->igNum); +#endif retbuf = buf[curBuf]; curBuf = (curBuf + 1) % 4; return retbuf; } -#endif // DEBUG - #if defined(TARGET_ARMARCH) || defined(TARGET_LOONGARCH64) // Does the argument location point to an IG at the end of a function or funclet? @@ -6675,7 +6679,13 @@ unsigned emitter::emitEndCodeGen(Compiler* comp, printf("\n"); } } -#endif // DEBUG +#else // DEBUG + if (emitComp->opts.disAsm) + { + printf("\n%s:", emitLabelString(ig)); + printf("\n"); + } +#endif // !DEBUG BYTE* bp = cp; diff --git a/src/coreclr/jit/emit.h b/src/coreclr/jit/emit.h index 658da7d577564..0ab57e5755627 100644 --- a/src/coreclr/jit/emit.h +++ b/src/coreclr/jit/emit.h @@ -2184,10 +2184,8 @@ class emitter // continues to track GC info as if there was no label. void* emitAddInlineLabel(); -#ifdef DEBUG void emitPrintLabel(insGroup* ig); const char* emitLabelString(insGroup* ig); -#endif #if defined(TARGET_ARMARCH) || defined(TARGET_LOONGARCH64) diff --git a/src/coreclr/jit/jitconfigvalues.h b/src/coreclr/jit/jitconfigvalues.h index 673502f379d95..8ece90a6d6fd0 100644 --- a/src/coreclr/jit/jitconfigvalues.h +++ b/src/coreclr/jit/jitconfigvalues.h @@ -218,7 +218,6 @@ CONFIG_METHODSET(JitUnwindDump, W("JitUnwindDump")) // Dump the unwind codes for /// /// NGEN /// -CONFIG_METHODSET(NgenDisasm, W("NgenDisasm")) // Same as JitDisasm, but for ngen CONFIG_METHODSET(NgenDump, W("NgenDump")) // Same as JitDump, but for ngen CONFIG_METHODSET(NgenEHDump, W("NgenEHDump")) // Dump the EH table for the method, as reported to the VM CONFIG_METHODSET(NgenGCDump, W("NgenGCDump")) @@ -270,7 +269,14 @@ CONFIG_STRING(NgenDumpFgFile, W("NgenDumpFgFile")) // Ngen Xml/Dot flowgraph dum CONFIG_INTEGER(EnableIncompleteISAClass, W("EnableIncompleteISAClass"), 0) // Enable testing not-yet-implemented // intrinsic classes -#endif // defined(DEBUG) +#else // defined(DEBUG) + +// JitDisasm works in Release too +CONFIG_METHODSET(JitDisasm, W("JitDisasm")) +CONFIG_INTEGER(DiffableDasm, W("JitDiffableDasm"), 0) +CONFIG_METHODSET(NgenDisasm, W("NgenDisasm")) // Same as JitDisasm, but for R2R/ILC + +#endif // !defined(DEBUG) CONFIG_INTEGER(RichDebugInfo, W("RichDebugInfo"), 0) // If 1, keep rich debug info and report it back to the EE From 75db09933ca3e5c1c0dcc3f1f9be68741847fa66 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Thu, 4 Aug 2022 12:23:40 +0200 Subject: [PATCH 03/32] Enable JitDisasm in Release --- src/coreclr/jit/codegen.h | 2 - src/coreclr/jit/compiler.cpp | 14 +++--- src/coreclr/jit/compiler.h | 8 +-- src/coreclr/jit/emit.cpp | 29 +++-------- src/coreclr/jit/emit.h | 29 ++--------- src/coreclr/jit/emitarm.cpp | 24 +++++---- src/coreclr/jit/emitarm.h | 4 -- src/coreclr/jit/emitarm64.cpp | 38 ++++++++------ src/coreclr/jit/emitarm64.h | 3 -- src/coreclr/jit/emitxarch.cpp | 93 ++++++++++++++++++++--------------- src/coreclr/jit/emitxarch.h | 4 -- src/coreclr/jit/instr.cpp | 8 --- src/coreclr/jit/jit.h | 20 +------- src/coreclr/jit/target.h | 2 - src/coreclr/jit/utils.cpp | 2 - 15 files changed, 113 insertions(+), 167 deletions(-) diff --git a/src/coreclr/jit/codegen.h b/src/coreclr/jit/codegen.h index fc9aae292d5e9..214be8247d8c5 100644 --- a/src/coreclr/jit/codegen.h +++ b/src/coreclr/jit/codegen.h @@ -196,7 +196,6 @@ class CodeGen final : public CodeGenInterface void* coldCodePtr; void* consPtr; -#ifdef DEBUG // Last instr we have displayed for dspInstrs unsigned genCurDispOffset; @@ -204,7 +203,6 @@ class CodeGen final : public CodeGenInterface const char* genInsDisplayName(emitter::instrDesc* id); static const char* genSizeStr(emitAttr size); -#endif // DEBUG void genInitialize(); diff --git a/src/coreclr/jit/compiler.cpp b/src/coreclr/jit/compiler.cpp index 1f1adb62cf0cc..340e696d2dda1 100644 --- a/src/coreclr/jit/compiler.cpp +++ b/src/coreclr/jit/compiler.cpp @@ -2076,10 +2076,6 @@ unsigned char Compiler::compGetJitDefaultFill(Compiler* comp) return defaultFill; } -#endif // DEBUG - -/*****************************************************************************/ -#ifdef DEBUG /*****************************************************************************/ VarName Compiler::compVarName(regNumber reg, bool isFloatReg) @@ -2124,13 +2120,15 @@ VarName Compiler::compVarName(regNumber reg, bool isFloatReg) return nullptr; } +#endif // DEBUG + const char* Compiler::compRegVarName(regNumber reg, bool displayVar, bool isFloatReg) { - #ifdef TARGET_ARM isFloatReg = genIsValidFloatReg(reg); #endif +#ifdef DEBUG if (displayVar && (reg != REG_NA)) { VarName varName = compVarName(reg, isFloatReg); @@ -2148,6 +2146,7 @@ const char* Compiler::compRegVarName(regNumber reg, bool displayVar, bool isFloa return nameVarReg[index]; } } +#endif /* no debug info required or no variable in that register -> return standard name */ @@ -2194,6 +2193,7 @@ const char* Compiler::compRegNameForSize(regNumber reg, size_t size) return sizeNames[reg][size - 1]; } +#ifdef DEBUG const char* Compiler::compLocalVarName(unsigned varNum, unsigned offs) { unsigned i; @@ -2214,9 +2214,8 @@ const char* Compiler::compLocalVarName(unsigned varNum, unsigned offs) return nullptr; } +#endif -/*****************************************************************************/ -#endif // DEBUG /*****************************************************************************/ void Compiler::compSetProcessor() @@ -6763,6 +6762,7 @@ int Compiler::compCompileHelper(CORINFO_MODULE_HANDLE classPtr, } #endif + compMethodID = 0; #ifdef DEBUG /* Give the function a unique number */ diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index 5646bb634e895..7f3cb3fb33df9 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -9298,7 +9298,6 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX static MethodSet* s_pJitMethodSet; #endif // DEBUG -#ifdef DEBUG // silence warning of cast to greater size. It is easier to silence than construct code the compiler is happy with, and // it is safe in this case #pragma warning(push) @@ -9316,6 +9315,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX return (o == ZERO) ? ZERO : (opts.dspDiffable ? T(0xD1FFAB1E) : o); } #pragma warning(pop) +#ifdef DEBUG static int dspTreeID(GenTree* tree) { @@ -9787,8 +9787,8 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX #endif public: -#ifdef DEBUG LONG compMethodID; +#ifdef DEBUG unsigned compGenTreeID; unsigned compStatementID; unsigned compBasicBlockID; @@ -10000,12 +10000,12 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX const char* compLocalVarName(unsigned varNum, unsigned offs); VarName compVarName(regNumber reg, bool isFloatReg = false); - const char* compRegVarName(regNumber reg, bool displayVar = false, bool isFloatReg = false); - const char* compRegNameForSize(regNumber reg, size_t size); const char* compFPregVarName(unsigned fpReg, bool displayVar = false); void compDspSrcLinesByNativeIP(UNATIVE_OFFSET curIP); void compDspSrcLinesByLineNum(unsigned line, bool seek = false); #endif // DEBUG + const char* compRegNameForSize(regNumber reg, size_t size); + const char* compRegVarName(regNumber reg, bool displayVar = false, bool isFloatReg = false); //------------------------------------------------------------------------- diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index 4d8a08426d8ca..f62fad2ef3cda 100644 --- a/src/coreclr/jit/emit.cpp +++ b/src/coreclr/jit/emit.cpp @@ -104,8 +104,6 @@ void emitLocation::Print(LONG compMethodID) const * Return the name of an instruction format. */ -#if defined(DEBUG) || EMITTER_STATS - const char* emitter::emitIfName(unsigned f) { static const char* const ifNames[] = { @@ -124,8 +122,6 @@ const char* emitter::emitIfName(unsigned f) return errBuff; } -#endif - /*****************************************************************************/ #if EMITTER_STATS @@ -1363,14 +1359,14 @@ void emitter::appendToCurIG(instrDesc* id) * Display (optionally) an instruction offset. */ -#ifdef DEBUG - void emitter::emitDispInsAddr(BYTE* code) { +#ifdef DEBUG if (emitComp->opts.disAddr) { printf(FMT_ADDR, DBG_ADDR(code)); } +#endif } void emitter::emitDispInsOffs(unsigned offs, bool doffs) @@ -1385,8 +1381,6 @@ void emitter::emitDispInsOffs(unsigned offs, bool doffs) } } -#endif // DEBUG - #ifdef JIT32_GCENCODER /***************************************************************************** @@ -1512,7 +1506,6 @@ void* emitter::emitAllocAnyInstr(size_t sz, emitAttr opsz) emitInsCount++; -#if defined(DEBUG) /* In debug mode we clear/set some additional fields */ instrDescDebugInfo* info = (instrDescDebugInfo*)emitGetMem(sizeof(*info)); @@ -1528,7 +1521,6 @@ void* emitter::emitAllocAnyInstr(size_t sz, emitAttr opsz) id->idDebugOnlyInfo(info); -#endif // defined(DEBUG) /* Store the size and handle the two special values that indicate GCref and ByRef */ @@ -2644,11 +2636,7 @@ void* emitter::emitAddInlineLabel() // void emitter::emitPrintLabel(insGroup* ig) { -#ifdef DEBUG printf("G_M%03u_IG%02u", emitComp->compMethodID, ig->igNum); -#else - printf("IG_%02u", ig->igNum); -#endif } //----------------------------------------------------------------------------- @@ -7704,14 +7692,14 @@ void emitter::emitOutputDataSec(dataSecDsc* sec, BYTE* dst) printf("\nEmitting data sections: %u total bytes\n", sec->dsdOffs); } + unsigned secNum = 0; +#endif + if (emitComp->opts.disAsm) { emitDispDataSec(sec, dst); } - unsigned secNum = 0; -#endif - assert(dst); assert(sec->dsdOffs); assert(sec->dsdList); @@ -7820,8 +7808,6 @@ void emitter::emitOutputDataSec(dataSecDsc* sec, BYTE* dst) } } -#ifdef DEBUG - //------------------------------------------------------------------------ // emitDispDataSec: Dump a data section to stdout. // @@ -7842,10 +7828,12 @@ void emitter::emitDispDataSec(dataSecDsc* section, BYTE* dst) for (dataSection* data = section->dsdList; data != nullptr; data = data->dsNext) { +#ifdef DEBUG if (emitComp->opts.disAddr) { printf("; @" FMT_ADDR "\n", DBG_ADDR(dst)); } +#endif const char* labelFormat = "%-7s"; char label[64]; @@ -7947,7 +7935,7 @@ void emitter::emitDispDataSec(dataSecDsc* section, BYTE* dst) { case TYP_FLOAT: assert(data->dsSize >= 4); - printf("\tdd\t%08llXh\t", *reinterpret_cast(&data->dsCont[i])); + printf("\tdd\t%08llXh\t", (UINT64)*reinterpret_cast(&data->dsCont[i])); printf("\t; %9.6g", *reinterpret_cast(&data->dsCont[i])); i += 4; break; @@ -8022,7 +8010,6 @@ void emitter::emitDispDataSec(dataSecDsc* section, BYTE* dst) } } } -#endif /*****************************************************************************/ /***************************************************************************** diff --git a/src/coreclr/jit/emit.h b/src/coreclr/jit/emit.h index 0ab57e5755627..2787a8a56d5b9 100644 --- a/src/coreclr/jit/emit.h +++ b/src/coreclr/jit/emit.h @@ -554,8 +554,6 @@ class emitter #endif // TARGET_XARCH -#ifdef DEBUG // This information is used in DEBUG builds for additional diagnostics - struct instrDesc; struct instrDescDebugInfo @@ -570,8 +568,6 @@ class emitter CORINFO_SIG_INFO* idCallSig; // Used to report native call site signatures to the EE }; -#endif // DEBUG - #ifdef TARGET_ARM unsigned insEncodeSetFlags(insFlags sf); @@ -810,8 +806,6 @@ class emitter //////////////////////////////////////////////////////////////////////// CLANG_FORMAT_COMMENT_ANCHOR; -#ifdef DEBUG - instrDescDebugInfo* _idDebugOnlyInfo; public: @@ -825,7 +819,6 @@ class emitter } private: -#endif // DEBUG CLANG_FORMAT_COMMENT_ANCHOR; @@ -849,11 +842,7 @@ class emitter emitter::emitAllocInstr() to clear them. */ -#if DEBUG #define SMALL_IDSC_DEBUG_EXTRA (sizeof(void*)) -#else -#define SMALL_IDSC_DEBUG_EXTRA (0) -#endif #define SMALL_IDSC_SIZE (8 + SMALL_IDSC_DEBUG_EXTRA) @@ -1681,9 +1670,7 @@ class emitter ssize_t emitGetInsCIdisp(instrDesc* id); unsigned emitGetInsCIargs(instrDesc* id); -#ifdef DEBUG inline static emitAttr emitGetMemOpSize(instrDesc* id); -#endif // DEBUG // Return the argument count for a direct call "id". int emitGetInsCDinfo(instrDesc* id); @@ -1697,15 +1684,13 @@ class emitter /* A few routines used for debug display purposes */ /************************************************************************/ -#if defined(DEBUG) || EMITTER_STATS - static const char* emitIfName(unsigned f); -#endif // defined(DEBUG) || EMITTER_STATS - #ifdef DEBUG - unsigned emitVarRefOffs; +#else // !DEBUG +#define emitVarRefOffs 0 +#endif // !DEBUG const char* emitRegName(regNumber reg, emitAttr size = EA_PTRSIZE, bool varName = true); const char* emitFloatRegName(regNumber reg, emitAttr size = EA_PTRSIZE, bool varName = true); @@ -1747,10 +1732,6 @@ class emitter size_t sz = 0, insGroup* ig = nullptr); -#else // !DEBUG -#define emitVarRefOffs 0 -#endif // !DEBUG - /************************************************************************/ /* Method prolog and epilog */ /************************************************************************/ @@ -2557,9 +2538,7 @@ class emitter dataSection* emitDataSecCur; void emitOutputDataSec(dataSecDsc* sec, BYTE* dst); -#ifdef DEBUG void emitDispDataSec(dataSecDsc* section, BYTE* dst); -#endif /************************************************************************/ /* Handles to the current class and method. */ @@ -3107,7 +3086,6 @@ inline unsigned emitter::emitGetInsCIargs(instrDesc* id) } } -#ifdef DEBUG //----------------------------------------------------------------------------- // emitGetMemOpSize: Get the memory operand size of instrDesc. // @@ -3275,7 +3253,6 @@ inline unsigned emitter::emitGetInsCIargs(instrDesc* id) } } } -#endif // DEBUG #endif // TARGET_XARCH diff --git a/src/coreclr/jit/emitarm.cpp b/src/coreclr/jit/emitarm.cpp index 5e172a0914a6d..1d06416f72d4f 100644 --- a/src/coreclr/jit/emitarm.cpp +++ b/src/coreclr/jit/emitarm.cpp @@ -644,8 +644,6 @@ bool emitter::emitInsMayWriteMultipleRegs(instrDesc* id) } } -/*****************************************************************************/ -#ifdef DEBUG /***************************************************************************** * * Return a string that represents the given register. @@ -672,7 +670,6 @@ const char* emitter::emitFloatRegName(regNumber reg, emitAttr attr, bool varName return rn; } -#endif // DEBUG /***************************************************************************** * @@ -4839,10 +4836,9 @@ void emitter::emitIns_Call(EmitCallType callType, VarSetOps::ToString(emitComp, ((instrDescCGCA*)id)->idcGCvars)); } } - - id->idDebugOnlyInfo()->idMemCookie = (size_t)methHnd; // method token id->idDebugOnlyInfo()->idCallSig = sigInfo; #endif // DEBUG + id->idDebugOnlyInfo()->idMemCookie = (size_t)methHnd; // method token #ifdef LATE_DISASM if (addr != nullptr) @@ -6696,6 +6692,14 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) { emitDispGCInfoDelta(); } +#else + size_t expected = emitSizeOfInsDsc(id); + assert(sz == expected); + + if (emitComp->opts.disAsm) + { + emitDispIns(id, false, 0, true, emitCurCodeOffs(odst), *dp, (dst - *dp), ig); + } #endif /* All instructions are expected to generate code */ @@ -6710,8 +6714,6 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) /*****************************************************************************/ /*****************************************************************************/ -#ifdef DEBUG - static bool insAlwaysSetFlags(instruction ins) { bool result = false; @@ -7096,6 +7098,7 @@ void emitter::emitDispInsHex(instrDesc* id, BYTE* code, size_t sz) void emitter::emitDispInsHelp( instrDesc* id, bool isNew, bool doffs, bool asmfm, unsigned offset, BYTE* code, size_t sz, insGroup* ig) { +#ifdef DEBUG if (EMITVERBOSE) { unsigned idNum = id->idDebugOnlyInfo()->idNum; // Do not remove this! It is needed for VisualStudio @@ -7103,6 +7106,7 @@ void emitter::emitDispInsHelp( printf("IN%04x: ", idNum); } +#endif if (code == NULL) sz = 0; @@ -7645,7 +7649,7 @@ void emitter::emitDispInsHelp( UNATIVE_OFFSET srcOffs = ig->igOffs + emitFindOffset(ig, insNum + 1); UNATIVE_OFFSET dstOffs = ig->igOffs + emitFindOffset(ig, insNum + 1 + instrCount); ssize_t relOffs = (ssize_t)(emitOffsetToPtr(dstOffs) - emitOffsetToPtr(srcOffs)); - printf("pc%s%d (%d instructions)", (relOffs >= 0) ? "+" : "", relOffs, instrCount); + printf("pc%s%d (%d instructions)", (relOffs >= 0) ? "+" : "", (int)relOffs, (int)instrCount); } } else if (id->idIsBound()) @@ -7785,6 +7789,7 @@ void emitter::emitDispIns( void emitter::emitDispFrameRef(int varx, int disp, int offs, bool asmfm) { +#ifdef DEBUG printf("["); if (varx < 0) @@ -7815,10 +7820,9 @@ void emitter::emitDispFrameRef(int varx, int disp, int offs, bool asmfm) printf("'"); } } +#endif } -#endif // DEBUG - void emitter::emitInsLoadStoreOp(instruction ins, emitAttr attr, regNumber dataReg, GenTreeIndir* indir) { // Handle unaligned floating point loads/stores diff --git a/src/coreclr/jit/emitarm.h b/src/coreclr/jit/emitarm.h index 5640e8077a31f..e1c281a6fccf1 100644 --- a/src/coreclr/jit/emitarm.h +++ b/src/coreclr/jit/emitarm.h @@ -27,8 +27,6 @@ unsigned emitOutput_Thumb2Instr(BYTE* dst, code_t code); /* Debug-only routines to display instructions */ /************************************************************************/ -#ifdef DEBUG - void emitDispInst(instruction ins, insFlags flags); void emitDispImm(int imm, bool addComma, bool alwaysHex = false); void emitDispReloc(BYTE* addr); @@ -61,8 +59,6 @@ void emitDispInsHelp(instrDesc* id, size_t sz = 0, insGroup* ig = NULL); -#endif // DEBUG - /************************************************************************/ /* Private members that deal with target-dependent instr. descriptors */ /************************************************************************/ diff --git a/src/coreclr/jit/emitarm64.cpp b/src/coreclr/jit/emitarm64.cpp index fbc72a53d54fa..cd7871fe2d565 100644 --- a/src/coreclr/jit/emitarm64.cpp +++ b/src/coreclr/jit/emitarm64.cpp @@ -1269,7 +1269,6 @@ emitAttr emitter::emitInsLoadStoreSize(instrDesc* id) } /*****************************************************************************/ -#ifdef DEBUG // clang-format off static const char * const xRegNames[] = @@ -1392,8 +1391,6 @@ const char* emitter::emitVectorRegName(regNumber reg) return vRegNames[index]; } -#endif // DEBUG - /***************************************************************************** * * Returns the base encoding of the given CPU instruction. @@ -8703,10 +8700,9 @@ void emitter::emitIns_Call(EmitCallType callType, VarSetOps::ToString(emitComp, ((instrDescCGCA*)id)->idcGCvars)); } } - - id->idDebugOnlyInfo()->idMemCookie = (size_t)methHnd; // method token - id->idDebugOnlyInfo()->idCallSig = sigInfo; + id->idDebugOnlyInfo()->idCallSig = sigInfo; #endif // DEBUG + id->idDebugOnlyInfo()->idMemCookie = (size_t)methHnd; // method token #ifdef LATE_DISASM if (addr != nullptr) @@ -11742,6 +11738,14 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) { emitDispGCInfoDelta(); } +#else + size_t expected = emitSizeOfInsDsc(id); + assert(sz == expected); + + if (emitComp->opts.disAsm) + { + emitDispIns(id, false, 0, true, emitCurCodeOffs(odst), *dp, (dst - *dp), ig); + } #endif /* All instructions are expected to generate code */ @@ -11756,8 +11760,6 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) /*****************************************************************************/ /*****************************************************************************/ -#ifdef DEBUG - /***************************************************************************** * * Display the instruction name @@ -11804,7 +11806,7 @@ void emitter::emitDispImm(ssize_t imm, bool addComma, bool alwaysHex /* =false * if (!alwaysHex && (imm > -1000) && (imm < 1000)) { - printf("%d", imm); + printf("%d", (int)imm); } else { @@ -11820,7 +11822,7 @@ void emitter::emitDispImm(ssize_t imm, bool addComma, bool alwaysHex /* =false * } else { - printf("0x%02x", imm); + printf("0x%02x", (unsigned)imm); } } @@ -12018,7 +12020,7 @@ void emitter::emitDispVectorRegIndex(regNumber reg, emitAttr elemsize, ssize_t i assert(isVectorRegister(reg)); printf(emitVectorRegName(reg)); emitDispElemsize(elemsize); - printf("[%d]", index); + printf("[%d]", (int)index); if (addComma) printf(", "); @@ -12482,6 +12484,7 @@ void emitter::emitDispIns( void emitter::emitDispInsHelp( instrDesc* id, bool isNew, bool doffs, bool asmfm, unsigned offset, BYTE* pCode, size_t sz, insGroup* ig) { +#ifdef DEBUG if (EMITVERBOSE) { unsigned idNum = @@ -12489,6 +12492,7 @@ void emitter::emitDispInsHelp( printf("IN%04x: ", idNum); } +#endif if (pCode == NULL) { @@ -12583,7 +12587,7 @@ void emitter::emitDispInsHelp( UNATIVE_OFFSET srcOffs = ig->igOffs + emitFindOffset(ig, insNum + 1); UNATIVE_OFFSET dstOffs = ig->igOffs + emitFindOffset(ig, insNum + 1 + instrCount); ssize_t relOffs = (ssize_t)(emitOffsetToPtr(dstOffs) - emitOffsetToPtr(srcOffs)); - printf("pc%s%d (%d instructions)", (relOffs >= 0) ? "+" : "", relOffs, instrCount); + printf("pc%s%d (%d instructions)", (relOffs >= 0) ? "+" : "", (int)relOffs, (int)instrCount); } } else if (id->idIsBound()) @@ -12627,7 +12631,7 @@ void emitter::emitDispInsHelp( UNATIVE_OFFSET srcOffs = ig->igOffs + emitFindOffset(ig, insNum + 1); UNATIVE_OFFSET dstOffs = ig->igOffs + emitFindOffset(ig, insNum + 1 + instrCount); ssize_t relOffs = (ssize_t)(emitOffsetToPtr(dstOffs) - emitOffsetToPtr(srcOffs)); - printf("pc%s%d (%d instructions)", (relOffs >= 0) ? "+" : "", relOffs, instrCount); + printf("pc%s%d (%d instructions)", (relOffs >= 0) ? "+" : "", (int)relOffs, (int)instrCount); } } else if (id->idIsBound()) @@ -12694,6 +12698,7 @@ void emitter::emitDispInsHelp( emitDispImm((ssize_t)id->idAddr()->iiaAddr, false); size_t targetHandle = id->idDebugOnlyInfo()->idMemCookie; +#ifdef DEBUG if (targetHandle == THT_InitializeArrayIntrinsics) { targetName = "InitializeArrayIntrinsics"; @@ -12706,6 +12711,7 @@ void emitter::emitDispInsHelp( { targetName = "SetGlobalSecurityCookie"; } +#endif } else if (id->idIsBound()) { @@ -13486,7 +13492,7 @@ void emitter::emitDispInsHelp( size = id->idOpSize(); emitDispVectorReg(id->idReg2(), (size == EA_8BYTE) ? INS_OPTS_8B : INS_OPTS_16B, true); index = emitGetInsSC(id); - printf("%s.4b[%d]", emitVectorRegName(id->idReg3()), index); + printf("%s.4b[%d]", emitVectorRegName(id->idReg3()), (int)index); } else { @@ -13682,6 +13688,7 @@ void emitter::emitDispInsHelp( void emitter::emitDispFrameRef(int varx, int disp, int offs, bool asmfm) { +#ifdef DEBUG printf("["); if (varx < 0) @@ -13712,10 +13719,9 @@ void emitter::emitDispFrameRef(int varx, int disp, int offs, bool asmfm) printf("'"); } } +#endif } -#endif // DEBUG - // Generate code for a load or store operation with a potentially complex addressing mode // This method handles the case of a GT_IND with contained GT_LEA op1 of the x86 form [base + index*scale + offset] // Since Arm64 does not directly support this complex of an addressing mode diff --git a/src/coreclr/jit/emitarm64.h b/src/coreclr/jit/emitarm64.h index dd9f6f25830e1..30ceeb4f34b80 100644 --- a/src/coreclr/jit/emitarm64.h +++ b/src/coreclr/jit/emitarm64.h @@ -15,8 +15,6 @@ static bool strictArmAsm; /* Routines that compute the size of / encode instructions */ /************************************************************************/ -#ifdef DEBUG - /************************************************************************/ /* Debug-only routines to display instructions */ /************************************************************************/ @@ -49,7 +47,6 @@ void emitDispShiftedReg(regNumber reg, insOpts opt, ssize_t imm, emitAttr attr); void emitDispExtendReg(regNumber reg, insOpts opt, ssize_t imm); void emitDispAddrRI(regNumber reg, insOpts opt, ssize_t imm); void emitDispAddrRRExt(regNumber reg1, regNumber reg2, insOpts opt, bool isScaled, emitAttr size); -#endif // DEBUG /************************************************************************/ /* Private members that deal with target-dependent instr. descriptors */ diff --git a/src/coreclr/jit/emitxarch.cpp b/src/coreclr/jit/emitxarch.cpp index bff896749a84b..d58bf816c6815 100644 --- a/src/coreclr/jit/emitxarch.cpp +++ b/src/coreclr/jit/emitxarch.cpp @@ -4367,10 +4367,7 @@ void emitter::emitIns_IJ(emitAttr attr, regNumber reg, unsigned base) id->idAddr()->iiaAddrMode.amBaseReg = REG_NA; id->idAddr()->iiaAddrMode.amIndxReg = reg; id->idAddr()->iiaAddrMode.amScale = emitter::OPSZP; - -#ifdef DEBUG id->idDebugOnlyInfo()->idMemCookie = base; -#endif id->idCodeSize(sz); @@ -7991,18 +7988,9 @@ void emitter::emitIns_Call(EmitCallType callType, } #ifdef DEBUG - if (emitComp->verbose && 0) - { - if (id->idIsLargeCall()) - { - printf("[%02u] Rec call GC vars = %s\n", id->idDebugOnlyInfo()->idNum, - VarSetOps::ToString(emitComp, ((instrDescCGCA*)id)->idcGCvars)); - } - } - + id->idDebugOnlyInfo()->idCallSig = sigInfo; +#endif // DEBUG id->idDebugOnlyInfo()->idMemCookie = (size_t)methHnd; // method token - id->idDebugOnlyInfo()->idCallSig = sigInfo; -#endif // DEBUG #ifdef LATE_DISASM if (addr != nullptr) @@ -8173,8 +8161,6 @@ size_t emitter::emitSizeOfInsDsc(instrDesc* id) return sizeof(instrDesc); } -/*****************************************************************************/ -#ifdef DEBUG /***************************************************************************** * * Return a string that represents the given register. @@ -8412,13 +8398,13 @@ void emitter::emitDispClsVar(CORINFO_FIELD_HANDLE fldHnd, ssize_t offs, bool rel if (fldHnd == FLD_GLOBAL_FS) { - printf("FS:[0x%04X]", offs); + printf("FS:[0x%04X]", (unsigned)offs); return; } if (fldHnd == FLD_GLOBAL_DS) { - printf("[0x%04X]", offs); + printf("[0x%04X]", (unsigned)offs); return; } @@ -8449,7 +8435,7 @@ void emitter::emitDispClsVar(CORINFO_FIELD_HANDLE fldHnd, ssize_t offs, bool rel } else { - printf("classVar[%#x]", emitComp->dspPtr(fldHnd)); + printf("classVar[%#p]", (void*)emitComp->dspPtr(fldHnd)); if (offs) { @@ -8459,6 +8445,7 @@ void emitter::emitDispClsVar(CORINFO_FIELD_HANDLE fldHnd, ssize_t offs, bool rel printf("]"); +#ifdef DEBUG if (emitComp->opts.varNames && offs < 0) { printf("'%s", emitComp->eeGetFieldName(fldHnd)); @@ -8468,6 +8455,7 @@ void emitter::emitDispClsVar(CORINFO_FIELD_HANDLE fldHnd, ssize_t offs, bool rel } printf("'"); } +#endif } /***************************************************************************** @@ -8550,7 +8538,7 @@ void emitter::emitDispFrameRef(int varx, int disp, int offs, bool asmfm) } printf("]"); - +#ifdef DEBUG if (varx >= 0 && emitComp->opts.varNames) { const char* varName = emitComp->compLocalVarName(varx, offs); @@ -8571,6 +8559,7 @@ void emitter::emitDispFrameRef(int varx, int disp, int offs, bool asmfm) printf("'"); } } +#endif } /***************************************************************************** @@ -8644,7 +8633,7 @@ void emitter::emitDispAddrMode(instrDesc* id, bool noDetail) { printf("reloc "); } - printf("J_M%03u_DS%02u", emitComp->compMethodID, id->idDebugOnlyInfo()->idMemCookie); + printf("J_M%03u_DS%02u", emitComp->compMethodID, (unsigned)id->idDebugOnlyInfo()->idMemCookie); disp -= id->idDebugOnlyInfo()->idMemCookie; } @@ -8678,7 +8667,7 @@ void emitter::emitDispAddrMode(instrDesc* id, bool noDetail) } if (scale > 1) { - printf("%u*", scale); + printf("%u*", (unsigned)scale); } printf("%s", emitRegName(id->idAddr()->iiaAddrMode.amIndxReg)); nsep = true; @@ -8712,34 +8701,34 @@ void emitter::emitDispAddrMode(instrDesc* id, bool noDetail) } if (frameRef) { - printf("%02XH", disp); + printf("%02XH", (unsigned)disp); } else if (disp < 1000) { - printf("%d", disp); + printf("%d", (unsigned)disp); } else if (disp <= 0xFFFF) { - printf("%04XH", disp); + printf("%04XH", (unsigned)disp); } else { - printf("%08XH", disp); + printf("%08XH", (unsigned)disp); } } else if (disp < 0) { if (frameRef) { - printf("-%02XH", -disp); + printf("-%02XH", (unsigned)-disp); } else if (disp > -1000) { - printf("-%d", -disp); + printf("-%d", (unsigned)-disp); } else if (disp >= -0xFFFF) { - printf("-%04XH", -disp); + printf("-%04XH", (unsigned)-disp); } else if (disp < -0xFFFFFF) { @@ -8747,22 +8736,23 @@ void emitter::emitDispAddrMode(instrDesc* id, bool noDetail) { printf("+"); } - printf("%08XH", disp); + printf("%08XH", (unsigned)disp); } else { - printf("-%08XH", -disp); + printf("-%08XH", (unsigned)-disp); } } else if (!nsep) { - printf("%04XH", disp); + printf("%04XH", (unsigned)disp); } } printf("]"); // pretty print string if it looks like one +#ifdef DEBUG if ((id->idGCref() == GCT_GCREF) && (id->idIns() == INS_mov) && (id->idAddr()->iiaAddrMode.amBaseReg == REG_NA)) { const WCHAR* str = emitComp->eeGetCPString(disp); @@ -8771,6 +8761,7 @@ void emitter::emitDispAddrMode(instrDesc* id, bool noDetail) printf(" '%S'", str); } } +#endif if (jdsc && !noDetail) { @@ -8868,7 +8859,7 @@ void emitter::emitDispInsHex(instrDesc* id, BYTE* code, size_t sz) if (sz < digits) { - printf("%.*s", 2 * (digits - sz), " "); + printf("%.*s", (int)(2 * (digits - sz)), " "); } } } @@ -8897,11 +8888,13 @@ void emitter::emitDispIns( instruction ins = id->idIns(); +#ifdef DEBUG if (emitComp->verbose) { unsigned idNum = id->idDebugOnlyInfo()->idNum; printf("IN%04x: ", idNum); } +#endif #define ID_INFO_DSP_RELOC ((bool)(id->idIsDspReloc())) @@ -9128,15 +9121,15 @@ void emitter::emitDispIns( } if ((val > -1000) && (val < 1000)) { - printf("%d", val); + printf("%d", (int)val); } else if ((val > 0) || (val < -0xFFFFFF)) { - printf("0x%IX", val); + printf("0x%IX", (INT64)val); } else { // (val < 0) - printf("-0x%IX", -val); + printf("-0x%IX", (INT64)-val); } emitDispCommentForHandle(srcVal, id->idDebugOnlyInfo()->idMemCookie, id->idDebugOnlyInfo()->idFlags); } @@ -9371,8 +9364,10 @@ void emitter::emitDispIns( emitCurStackLvl -= sizeof(int); #endif +#ifdef DEBUG emitDispFrameRef(id->idAddr()->iiaLclVar.lvaVarNum(), id->idAddr()->iiaLclVar.lvaOffset(), id->idDebugOnlyInfo()->idVarRefOffs, asmfm); +#endif #if !FEATURE_FIXED_OUT_ARGS if (ins == INS_pop) @@ -9388,8 +9383,10 @@ void emitter::emitDispIns( printf("%s", sstr); +#ifdef DEBUG emitDispFrameRef(id->idAddr()->iiaLclVar.lvaVarNum(), id->idAddr()->iiaLclVar.lvaOffset(), id->idDebugOnlyInfo()->idVarRefOffs, asmfm); +#endif printf(", %s", emitRegName(id->idReg1(), attr)); break; @@ -9401,8 +9398,10 @@ void emitter::emitDispIns( printf("%s", sstr); +#ifdef DEBUG emitDispFrameRef(id->idAddr()->iiaLclVar.lvaVarNum(), id->idAddr()->iiaLclVar.lvaOffset(), id->idDebugOnlyInfo()->idVarRefOffs, asmfm); +#endif emitGetInsCns(id, &cnsVal); val = cnsVal.cnsVal; @@ -9435,8 +9434,10 @@ void emitter::emitDispIns( printf("%s", sstr); +#ifdef DEBUG emitDispFrameRef(id->idAddr()->iiaLclVar.lvaVarNum(), id->idAddr()->iiaLclVar.lvaOffset(), id->idDebugOnlyInfo()->idVarRefOffs, asmfm); +#endif printf(", %s", emitRegName(id->idReg1(), attr)); @@ -9475,8 +9476,10 @@ void emitter::emitDispIns( } printf("%s, %s", emitRegName(id->idReg1(), attr), sstr); +#ifdef DEBUG emitDispFrameRef(id->idAddr()->iiaLclVar.lvaVarNum(), id->idAddr()->iiaLclVar.lvaOffset(), id->idDebugOnlyInfo()->idVarRefOffs, asmfm); +#endif break; @@ -9484,8 +9487,10 @@ void emitter::emitDispIns( case IF_RWR_SRD_CNS: { printf("%s, %s", emitRegName(id->idReg1(), attr), sstr); +#ifdef DEBUG emitDispFrameRef(id->idAddr()->iiaLclVar.lvaVarNum(), id->idAddr()->iiaLclVar.lvaOffset(), id->idDebugOnlyInfo()->idVarRefOffs, asmfm); +#endif emitGetInsCns(id, &cnsVal); val = cnsVal.cnsVal; @@ -9504,15 +9509,19 @@ void emitter::emitDispIns( case IF_RWR_RRD_SRD: printf("%s, %s, %s", emitRegName(id->idReg1(), attr), emitRegName(id->idReg2(), attr), sstr); +#ifdef DEBUG emitDispFrameRef(id->idAddr()->iiaLclVar.lvaVarNum(), id->idAddr()->iiaLclVar.lvaOffset(), id->idDebugOnlyInfo()->idVarRefOffs, asmfm); +#endif break; case IF_RWR_RRD_SRD_CNS: { printf("%s, %s, %s", emitRegName(id->idReg1(), attr), emitRegName(id->idReg2(), attr), sstr); +#ifdef DEBUG emitDispFrameRef(id->idAddr()->iiaLclVar.lvaVarNum(), id->idAddr()->iiaLclVar.lvaOffset(), id->idDebugOnlyInfo()->idVarRefOffs, asmfm); +#endif emitGetInsCns(id, &cnsVal); val = cnsVal.cnsVal; @@ -9533,8 +9542,10 @@ void emitter::emitDispIns( { printf("%s, ", emitRegName(id->idReg1(), attr)); printf("%s, ", emitRegName(id->idReg2(), attr)); +#ifdef DEBUG emitDispFrameRef(id->idAddr()->iiaLclVar.lvaVarNum(), id->idAddr()->iiaLclVar.lvaOffset(), id->idDebugOnlyInfo()->idVarRefOffs, asmfm); +#endif emitGetInsCns(id, &cnsVal); val = (cnsVal.cnsVal >> 4) + XMMBASE; @@ -10016,18 +10027,17 @@ void emitter::emitDispIns( break; } +#ifdef DEBUG if (sz != 0 && sz != id->idCodeSize() && (!asmfm || emitComp->verbose)) { // Code size in the instrDesc is different from the actual code size we've been given! printf(" (ECS:%d, ACS:%d)", id->idCodeSize(), sz); } +#endif printf("\n"); } -/*****************************************************************************/ -#endif - /***************************************************************************** * * Output nBytes bytes of NOP instructions @@ -14756,6 +14766,11 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) { emitDispIns(id, false, dspOffs, true, emitCurCodeOffs(*dp), *dp, (dst - *dp)); } +#else + if (emitComp->opts.disAsm&& !emitJmpInstHasNoCode(id)) + { + emitDispIns(id, false, 0, true, emitCurCodeOffs(*dp), *dp, (dst - *dp)); + } #endif #if FEATURE_LOOP_ALIGN diff --git a/src/coreclr/jit/emitxarch.h b/src/coreclr/jit/emitxarch.h index c744e40dbd41e..6334e5a0ddf92 100644 --- a/src/coreclr/jit/emitxarch.h +++ b/src/coreclr/jit/emitxarch.h @@ -220,8 +220,6 @@ bool isPrefetch(instruction ins) /* Debug-only routines to display instructions */ /************************************************************************/ -#ifdef DEBUG - void emitDispReloc(ssize_t value); void emitDispAddrMode(instrDesc* id, bool noDetail = false); void emitDispShift(instruction ins, int cnt = 0); @@ -229,8 +227,6 @@ void emitDispShift(instruction ins, int cnt = 0); const char* emitXMMregName(unsigned reg); const char* emitYMMregName(unsigned reg); -#endif - /************************************************************************/ /* Private members that deal with target-dependent instr. descriptors */ /************************************************************************/ diff --git a/src/coreclr/jit/instr.cpp b/src/coreclr/jit/instr.cpp index 9843482bbef6c..44feba2ddee90 100644 --- a/src/coreclr/jit/instr.cpp +++ b/src/coreclr/jit/instr.cpp @@ -22,7 +22,6 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX #include "emit.h" /*****************************************************************************/ -#ifdef DEBUG //----------------------------------------------------------------------------- // genInsName: Returns the string representation of the given CPU instruction, as @@ -147,16 +146,11 @@ const char* CodeGen::genInsDisplayName(emitter::instrDesc* id) return insName; } -/*****************************************************************************/ -#endif // DEBUG - /***************************************************************************** * * Return the size string (e.g. "word ptr") appropriate for the given size. */ -#ifdef DEBUG - const char* CodeGen::genSizeStr(emitAttr attr) { // clang-format off @@ -213,8 +207,6 @@ const char* CodeGen::genSizeStr(emitAttr attr) } } -#endif - /***************************************************************************** * * Generate an instruction. diff --git a/src/coreclr/jit/jit.h b/src/coreclr/jit/jit.h index f229cae217031..f5b206fbb7407 100644 --- a/src/coreclr/jit/jit.h +++ b/src/coreclr/jit/jit.h @@ -798,6 +798,7 @@ inline bool IsUninitialized(T data) { return data == UninitializedWord(JitTls::GetCompiler()); } +#else // !defined(DEBUG) #pragma warning(push) #pragma warning(disable : 4312) @@ -819,25 +820,6 @@ T dspOffset(T o) } #pragma warning(pop) -#else // !defined(DEBUG) - -//**************************************************************************** -// -// Non-Debug template definitions for dspPtr, dspOffset -// - This is a nop in non-Debug builds -// -template -T dspPtr(T p) -{ - return p; -} - -template -T dspOffset(T o) -{ - return o; -} - #endif // !defined(DEBUG) struct LikelyClassMethodRecord diff --git a/src/coreclr/jit/target.h b/src/coreclr/jit/target.h index c01ba5b476d66..392a541714139 100644 --- a/src/coreclr/jit/target.h +++ b/src/coreclr/jit/target.h @@ -315,10 +315,8 @@ class Target static const enum ArgOrder g_tgtUnmanagedArgOrder; }; -#if defined(DEBUG) || defined(LATE_DISASM) || DUMP_GC_TABLES const char* getRegName(unsigned reg); // this is for gcencode.cpp and disasm.cpp that don't use the regNumber type const char* getRegName(regNumber reg); -#endif // defined(DEBUG) || defined(LATE_DISASM) || DUMP_GC_TABLES #ifdef DEBUG const char* getRegNameFloat(regNumber reg, var_types type); diff --git a/src/coreclr/jit/utils.cpp b/src/coreclr/jit/utils.cpp index 5d58995f3377f..3898d338d138a 100644 --- a/src/coreclr/jit/utils.cpp +++ b/src/coreclr/jit/utils.cpp @@ -115,7 +115,6 @@ const char* varTypeName(var_types vt) return varTypeNames[vt]; } -#if defined(DEBUG) || defined(LATE_DISASM) || DUMP_GC_TABLES /***************************************************************************** * * Return the name of the given register. @@ -145,7 +144,6 @@ const char* getRegName(unsigned reg) // this is for gcencode.cpp and disasm.cpp { return getRegName((regNumber)reg); } -#endif // defined(DEBUG) || defined(LATE_DISASM) || DUMP_GC_TABLES #if defined(DEBUG) From 98a2a9dec054904f0884df40a479e0d36535146d Mon Sep 17 00:00:00 2001 From: EgorBo Date: Thu, 4 Aug 2022 15:56:53 +0200 Subject: [PATCH 04/32] Fix compilation errors --- src/coreclr/jit/compiler.cpp | 31 +++++-------------------------- src/coreclr/jit/compiler.h | 20 ++++++++++++++++++-- src/coreclr/jit/emit.cpp | 24 +++++++++++++++--------- src/coreclr/jit/emitxarch.cpp | 4 ++-- src/coreclr/jit/jit.h | 20 +++++++++++++++++++- src/coreclr/jit/jitconfigvalues.h | 1 + src/coreclr/jit/valuenum.cpp | 20 -------------------- 7 files changed, 60 insertions(+), 60 deletions(-) diff --git a/src/coreclr/jit/compiler.cpp b/src/coreclr/jit/compiler.cpp index 340e696d2dda1..e2ba69b39210a 100644 --- a/src/coreclr/jit/compiler.cpp +++ b/src/coreclr/jit/compiler.cpp @@ -3070,36 +3070,15 @@ void Compiler::compInitOptions(JitFlags* jitFlags) s_pJitFunctionFileInitialized = true; } #else // DEBUG - if (!jitFlags->IsSet(JitFlags::JIT_FLAG_PREJIT)) + if (!JitConfig.JitDisasm().isEmpty()) { - if (!JitConfig.JitDisasm().isEmpty()) + const char* methodName = info.compCompHnd->getMethodName(info.compMethodHnd, nullptr); + const char* className = info.compCompHnd->getClassName(info.compClassHnd); + if (JitConfig.JitDisasm().contains(methodName, className, &info.compMethodInfo->args)) { - const char* methodName = info.compCompHnd->getMethodName(info.compMethodHnd, nullptr); - const char* className = info.compCompHnd->getClassName(info.compClassHnd); - - if (JitConfig.JitDisasm().contains(methodName, className, &info.compMethodInfo->args)) - { - opts.disAsm = true; - } - } - } - else - { - if (!JitConfig.NgenDisasm().isEmpty()) - { - const char* methodName = info.compCompHnd->getMethodName(info.compMethodHnd, nullptr); - const char* className = info.compCompHnd->getClassName(info.compClassHnd); - - if (JitConfig.NgenDisasm().contains(methodName, className, &info.compMethodInfo->args)) - { - opts.disAsm = true; - } + opts.disAsm = true; } } - - bool diffable = JitConfig.DiffableDasm(); - opts.disDiffable = diffable; - opts.dspDiffable = diffable; #endif // !DEBUG //------------------------------------------------------------------------- diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index 7f3cb3fb33df9..930356488f89f 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -9296,7 +9296,6 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX static bool s_pJitFunctionFileInitialized; static MethodSet* s_pJitMethodSet; -#endif // DEBUG // silence warning of cast to greater size. It is easier to silence than construct code the compiler is happy with, and // it is safe in this case @@ -9315,6 +9314,23 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX return (o == ZERO) ? ZERO : (opts.dspDiffable ? T(0xD1FFAB1E) : o); } #pragma warning(pop) +#else +#pragma warning(push) +#pragma warning(disable : 4312) + template + T dspPtr(T p) + { + return p; + } + + template + T dspOffset(T o) + { + return o; + } +#pragma warning(pop) +#endif + #ifdef DEBUG static int dspTreeID(GenTree* tree) @@ -9787,12 +9803,12 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX #endif public: - LONG compMethodID; #ifdef DEBUG unsigned compGenTreeID; unsigned compStatementID; unsigned compBasicBlockID; #endif + LONG compMethodID; BasicBlock* compCurBB; // the current basic block in process Statement* compCurStmt; // the current statement in process diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index f62fad2ef3cda..7debce3cfe3eb 100644 --- a/src/coreclr/jit/emit.cpp +++ b/src/coreclr/jit/emit.cpp @@ -1506,8 +1506,6 @@ void* emitter::emitAllocAnyInstr(size_t sz, emitAttr opsz) emitInsCount++; - /* In debug mode we clear/set some additional fields */ - instrDescDebugInfo* info = (instrDescDebugInfo*)emitGetMem(sizeof(*info)); info->idNum = emitInsCount; @@ -2654,11 +2652,7 @@ const char* emitter::emitLabelString(insGroup* ig) static char buf[4][TEMP_BUFFER_LEN]; const char* retbuf; -#ifdef DEBUG sprintf_s(buf[curBuf], TEMP_BUFFER_LEN, "G_M%03u_IG%02u", emitComp->compMethodID, ig->igNum); -#else - sprintf_s(buf[curBuf], TEMP_BUFFER_LEN, "IG_%02u", ig->igNum); -#endif retbuf = buf[curBuf]; curBuf = (curBuf + 1) % 4; return retbuf; @@ -4060,7 +4054,6 @@ void emitter::emitRecomputeIGoffsets() // void emitter::emitDispCommentForHandle(size_t handle, size_t cookie, GenTreeFlags flag) { -#ifdef DEBUG #ifdef TARGET_XARCH const char* commentPrefix = " ;"; #else @@ -4099,6 +4092,7 @@ void emitter::emitDispCommentForHandle(size_t handle, size_t cookie, GenTreeFlag const char* str = nullptr; if (flag == GTF_ICON_STR_HDL) { +#ifdef DEBUG const WCHAR* wstr = emitComp->eeGetCPString(handle); // NOTE: eGetCPString always returns nullptr on Linux/ARM if (wstr == nullptr) @@ -4131,6 +4125,9 @@ void emitter::emitDispCommentForHandle(size_t handle, size_t cookie, GenTreeFlag } printf("%s \"%S\"", commentPrefix, buf); } +#else + str = "string handle"; +#endif } else if (flag == GTF_ICON_CLASS_HDL) { @@ -4169,7 +4166,6 @@ void emitter::emitDispCommentForHandle(size_t handle, size_t cookie, GenTreeFlag { printf("%s %s", commentPrefix, str); } -#endif // DEBUG } //**************************************************************************** @@ -6671,6 +6667,10 @@ unsigned emitter::emitEndCodeGen(Compiler* comp, if (emitComp->opts.disAsm) { printf("\n%s:", emitLabelString(ig)); + if (!emitComp->opts.disDiffable) + { + printf(" ;; offset=%04XH", emitCurCodeOffs(cp)); + } printf("\n"); } #endif // !DEBUG @@ -6914,7 +6914,13 @@ unsigned emitter::emitEndCodeGen(Compiler* comp, ig->igPerfScore); } *instrCount += ig->igInsCnt; -#endif // DEBUG +#else // DEBUG + if (emitComp->opts.disAsm) + { + // Separate IGs with a blank line + printf(" "); + } +#endif // !DEBUG emitCurIG = nullptr; diff --git a/src/coreclr/jit/emitxarch.cpp b/src/coreclr/jit/emitxarch.cpp index d58bf816c6815..6af288238145e 100644 --- a/src/coreclr/jit/emitxarch.cpp +++ b/src/coreclr/jit/emitxarch.cpp @@ -9125,11 +9125,11 @@ void emitter::emitDispIns( } else if ((val > 0) || (val < -0xFFFFFF)) { - printf("0x%IX", (INT64)val); + printf("0x%IX", (ssize_t)val); } else { // (val < 0) - printf("-0x%IX", (INT64)-val); + printf("-0x%IX", (ssize_t)-val); } emitDispCommentForHandle(srcVal, id->idDebugOnlyInfo()->idMemCookie, id->idDebugOnlyInfo()->idFlags); } diff --git a/src/coreclr/jit/jit.h b/src/coreclr/jit/jit.h index f5b206fbb7407..f229cae217031 100644 --- a/src/coreclr/jit/jit.h +++ b/src/coreclr/jit/jit.h @@ -798,7 +798,6 @@ inline bool IsUninitialized(T data) { return data == UninitializedWord(JitTls::GetCompiler()); } -#else // !defined(DEBUG) #pragma warning(push) #pragma warning(disable : 4312) @@ -820,6 +819,25 @@ T dspOffset(T o) } #pragma warning(pop) +#else // !defined(DEBUG) + +//**************************************************************************** +// +// Non-Debug template definitions for dspPtr, dspOffset +// - This is a nop in non-Debug builds +// +template +T dspPtr(T p) +{ + return p; +} + +template +T dspOffset(T o) +{ + return o; +} + #endif // !defined(DEBUG) struct LikelyClassMethodRecord diff --git a/src/coreclr/jit/jitconfigvalues.h b/src/coreclr/jit/jitconfigvalues.h index 8ece90a6d6fd0..6a2a924d11449 100644 --- a/src/coreclr/jit/jitconfigvalues.h +++ b/src/coreclr/jit/jitconfigvalues.h @@ -218,6 +218,7 @@ CONFIG_METHODSET(JitUnwindDump, W("JitUnwindDump")) // Dump the unwind codes for /// /// NGEN /// +CONFIG_METHODSET(NgenDisasm, W("NgenDisasm")) // Same as JitDisasm, but for ngen CONFIG_METHODSET(NgenDump, W("NgenDump")) // Same as JitDump, but for ngen CONFIG_METHODSET(NgenEHDump, W("NgenEHDump")) // Dump the EH table for the method, as reported to the VM CONFIG_METHODSET(NgenGCDump, W("NgenGCDump")) diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index 2d445ed6f0d91..0ffb254761bc6 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -10421,26 +10421,6 @@ void Compiler::fgValueNumberAddExceptionSetForIndirection(GenTree* tree, GenTree vnStore->VNExcSetSingleton(vnStore->VNForFunc(TYP_REF, VNF_NullPtrExc, vnpBaseNorm.GetConservative()))); } - VNFuncApp func; - if (vnStore->GetVNFunc(vnpBaseNorm.GetConservative(), &func) && - (func.m_func == VNF_GetsharedGcthreadstaticBaseNoctor)) - { - switch (func.m_func) - { - case VNF_GetgenericsGcthreadstaticBase: - case VNF_GetgenericsNongcthreadstaticBase: - case VNF_GetsharedGcthreadstaticBase: - case VNF_GetsharedNongcthreadstaticBase: - case VNF_GetsharedGcthreadstaticBaseNoctor: - case VNF_GetsharedNongcthreadstaticBaseNoctor: - case VNF_GetsharedGcthreadstaticBaseDynamicclass: - case VNF_GetsharedNongcthreadstaticBaseDynamicclass: - tree->gtVNPair.SetConservative(tree->gtVNPair.GetLiberal()); - break; - default: - break; - } - } // Add the NullPtrExc to "tree"'s value numbers. tree->gtVNPair = vnStore->VNPWithExc(tree->gtVNPair, excChkSet); } From 3952560307ff2c1fb5f9ade27a9f104cc41bae8e Mon Sep 17 00:00:00 2001 From: EgorBo Date: Thu, 4 Aug 2022 16:34:09 +0200 Subject: [PATCH 05/32] Run jit-format --- src/coreclr/jit/compiler.cpp | 8 ++++---- src/coreclr/jit/compiler.h | 14 +++++++------- src/coreclr/jit/emit.cpp | 9 ++++----- src/coreclr/jit/emit.h | 7 +++---- src/coreclr/jit/emitarm.cpp | 4 ++-- src/coreclr/jit/emitarm64.cpp | 2 +- src/coreclr/jit/emitxarch.cpp | 8 ++++---- src/coreclr/jit/jitconfigvalues.h | 7 ++----- 8 files changed, 27 insertions(+), 32 deletions(-) diff --git a/src/coreclr/jit/compiler.cpp b/src/coreclr/jit/compiler.cpp index e2ba69b39210a..dedf9b1abdc1f 100644 --- a/src/coreclr/jit/compiler.cpp +++ b/src/coreclr/jit/compiler.cpp @@ -2818,9 +2818,9 @@ void Compiler::compInitOptions(JitFlags* jitFlags) opts.compJitEarlyExpandMDArrays = (JitConfig.JitEarlyExpandMDArrays() != 0); - opts.disAsm = false; - opts.disDiffable = false; - opts.dspDiffable = false; + opts.disAsm = false; + opts.disDiffable = false; + opts.dspDiffable = false; #ifdef DEBUG opts.dspInstrs = false; opts.dspLines = false; @@ -3069,7 +3069,7 @@ void Compiler::compInitOptions(JitFlags* jitFlags) } s_pJitFunctionFileInitialized = true; } -#else // DEBUG +#else // DEBUG if (!JitConfig.JitDisasm().isEmpty()) { const char* methodName = info.compCompHnd->getMethodName(info.compMethodHnd, nullptr); diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index 930356488f89f..1f56235633e5c 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -9170,9 +9170,9 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX bool optRepeat; // Repeat optimizer phases k times #endif - bool disAsm; // Display native code as it is generated - bool dspDiffable; // Makes the Jit Dump 'diff-able' (currently uses same COMPlus_* flag as disDiffable) - bool disDiffable; // Makes the Disassembly code 'diff-able' + bool disAsm; // Display native code as it is generated + bool dspDiffable; // Makes the Jit Dump 'diff-able' (currently uses same COMPlus_* flag as disDiffable) + bool disDiffable; // Makes the Disassembly code 'diff-able' #ifdef DEBUG bool compProcedureSplittingEH; // Separate cold code from hot code for functions with EH bool dspCode; // Display native code generated @@ -9189,9 +9189,9 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX bool disAsm2; // Display native code after it is generated using external disassembler bool dspOrder; // Display names of each of the methods that we ngen/jit bool dspUnwind; // Display the unwind info output - bool compLongAddress; // Force using large pseudo instructions for long address - // (IF_LARGEJMP/IF_LARGEADR/IF_LARGLDC) - bool dspGCtbls; // Display the GC tables + bool compLongAddress; // Force using large pseudo instructions for long address + // (IF_LARGEJMP/IF_LARGEADR/IF_LARGLDC) + bool dspGCtbls; // Display the GC tables #endif bool compExpandCallsEarly; // True if we should expand virtual call targets early for this method @@ -9808,7 +9808,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX unsigned compStatementID; unsigned compBasicBlockID; #endif - LONG compMethodID; + LONG compMethodID; BasicBlock* compCurBB; // the current basic block in process Statement* compCurStmt; // the current statement in process diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index 7debce3cfe3eb..077647d5c26fc 100644 --- a/src/coreclr/jit/emit.cpp +++ b/src/coreclr/jit/emit.cpp @@ -1519,7 +1519,6 @@ void* emitter::emitAllocAnyInstr(size_t sz, emitAttr opsz) id->idDebugOnlyInfo(info); - /* Store the size and handle the two special values that indicate GCref and ByRef */ @@ -4126,7 +4125,7 @@ void emitter::emitDispCommentForHandle(size_t handle, size_t cookie, GenTreeFlag printf("%s \"%S\"", commentPrefix, buf); } #else - str = "string handle"; + str = "string handle"; #endif } else if (flag == GTF_ICON_CLASS_HDL) @@ -6663,7 +6662,7 @@ unsigned emitter::emitEndCodeGen(Compiler* comp, printf("\n"); } } -#else // DEBUG +#else // DEBUG if (emitComp->opts.disAsm) { printf("\n%s:", emitLabelString(ig)); @@ -6914,7 +6913,7 @@ unsigned emitter::emitEndCodeGen(Compiler* comp, ig->igPerfScore); } *instrCount += ig->igInsCnt; -#else // DEBUG +#else // DEBUG if (emitComp->opts.disAsm) { // Separate IGs with a blank line @@ -7941,7 +7940,7 @@ void emitter::emitDispDataSec(dataSecDsc* section, BYTE* dst) { case TYP_FLOAT: assert(data->dsSize >= 4); - printf("\tdd\t%08llXh\t", (UINT64)*reinterpret_cast(&data->dsCont[i])); + printf("\tdd\t%08llXh\t", (UINT64) * reinterpret_cast(&data->dsCont[i])); printf("\t; %9.6g", *reinterpret_cast(&data->dsCont[i])); i += 4; break; diff --git a/src/coreclr/jit/emit.h b/src/coreclr/jit/emit.h index 2787a8a56d5b9..0014899f047cb 100644 --- a/src/coreclr/jit/emit.h +++ b/src/coreclr/jit/emit.h @@ -819,7 +819,6 @@ class emitter } private: - CLANG_FORMAT_COMMENT_ANCHOR; // @@ -1680,9 +1679,9 @@ class emitter cnsval_ssize_t emitGetInsSC(instrDesc* id); unsigned emitInsCount; -/************************************************************************/ -/* A few routines used for debug display purposes */ -/************************************************************************/ + /************************************************************************/ + /* A few routines used for debug display purposes */ + /************************************************************************/ static const char* emitIfName(unsigned f); diff --git a/src/coreclr/jit/emitarm.cpp b/src/coreclr/jit/emitarm.cpp index 1d06416f72d4f..df71ab356cd2b 100644 --- a/src/coreclr/jit/emitarm.cpp +++ b/src/coreclr/jit/emitarm.cpp @@ -4836,8 +4836,8 @@ void emitter::emitIns_Call(EmitCallType callType, VarSetOps::ToString(emitComp, ((instrDescCGCA*)id)->idcGCvars)); } } - id->idDebugOnlyInfo()->idCallSig = sigInfo; -#endif // DEBUG + id->idDebugOnlyInfo()->idCallSig = sigInfo; +#endif id->idDebugOnlyInfo()->idMemCookie = (size_t)methHnd; // method token #ifdef LATE_DISASM diff --git a/src/coreclr/jit/emitarm64.cpp b/src/coreclr/jit/emitarm64.cpp index cd7871fe2d565..3500227140d59 100644 --- a/src/coreclr/jit/emitarm64.cpp +++ b/src/coreclr/jit/emitarm64.cpp @@ -8701,7 +8701,7 @@ void emitter::emitIns_Call(EmitCallType callType, } } id->idDebugOnlyInfo()->idCallSig = sigInfo; -#endif // DEBUG +#endif id->idDebugOnlyInfo()->idMemCookie = (size_t)methHnd; // method token #ifdef LATE_DISASM diff --git a/src/coreclr/jit/emitxarch.cpp b/src/coreclr/jit/emitxarch.cpp index 6af288238145e..7ed229e702a29 100644 --- a/src/coreclr/jit/emitxarch.cpp +++ b/src/coreclr/jit/emitxarch.cpp @@ -4367,7 +4367,7 @@ void emitter::emitIns_IJ(emitAttr attr, regNumber reg, unsigned base) id->idAddr()->iiaAddrMode.amBaseReg = REG_NA; id->idAddr()->iiaAddrMode.amIndxReg = reg; id->idAddr()->iiaAddrMode.amScale = emitter::OPSZP; - id->idDebugOnlyInfo()->idMemCookie = base; + id->idDebugOnlyInfo()->idMemCookie = base; id->idCodeSize(sz); @@ -7989,7 +7989,7 @@ void emitter::emitIns_Call(EmitCallType callType, #ifdef DEBUG id->idDebugOnlyInfo()->idCallSig = sigInfo; -#endif // DEBUG +#endif id->idDebugOnlyInfo()->idMemCookie = (size_t)methHnd; // method token #ifdef LATE_DISASM @@ -8751,7 +8751,7 @@ void emitter::emitDispAddrMode(instrDesc* id, bool noDetail) printf("]"); - // pretty print string if it looks like one +// pretty print string if it looks like one #ifdef DEBUG if ((id->idGCref() == GCT_GCREF) && (id->idIns() == INS_mov) && (id->idAddr()->iiaAddrMode.amBaseReg == REG_NA)) { @@ -14767,7 +14767,7 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) emitDispIns(id, false, dspOffs, true, emitCurCodeOffs(*dp), *dp, (dst - *dp)); } #else - if (emitComp->opts.disAsm&& !emitJmpInstHasNoCode(id)) + if (emitComp->opts.disAsm && !emitJmpInstHasNoCode(id)) { emitDispIns(id, false, 0, true, emitCurCodeOffs(*dp), *dp, (dst - *dp)); } diff --git a/src/coreclr/jit/jitconfigvalues.h b/src/coreclr/jit/jitconfigvalues.h index 6a2a924d11449..4571c1a3bdcb1 100644 --- a/src/coreclr/jit/jitconfigvalues.h +++ b/src/coreclr/jit/jitconfigvalues.h @@ -270,13 +270,10 @@ CONFIG_STRING(NgenDumpFgFile, W("NgenDumpFgFile")) // Ngen Xml/Dot flowgraph dum CONFIG_INTEGER(EnableIncompleteISAClass, W("EnableIncompleteISAClass"), 0) // Enable testing not-yet-implemented // intrinsic classes -#else // defined(DEBUG) +#else // defined(DEBUG) -// JitDisasm works in Release too +// JitDisasm is supported in Release too CONFIG_METHODSET(JitDisasm, W("JitDisasm")) -CONFIG_INTEGER(DiffableDasm, W("JitDiffableDasm"), 0) -CONFIG_METHODSET(NgenDisasm, W("NgenDisasm")) // Same as JitDisasm, but for R2R/ILC - #endif // !defined(DEBUG) CONFIG_INTEGER(RichDebugInfo, W("RichDebugInfo"), 0) // If 1, keep rich debug info and report it back to the EE From c2d397a35bafea10c6bbfa7604503569598564eb Mon Sep 17 00:00:00 2001 From: EgorBo Date: Fri, 5 Aug 2022 00:59:07 +0200 Subject: [PATCH 06/32] Don't allocate instrDescDebugInfo when JitDisasm is not set --- src/coreclr/jit/emit.cpp | 27 ++++++++++++++------------- src/coreclr/jit/emit.h | 26 +++++++------------------- src/coreclr/jit/emitarm.cpp | 8 +++++++- src/coreclr/jit/emitarm64.cpp | 7 ++++++- src/coreclr/jit/emitxarch.cpp | 15 ++++++++++++++- 5 files changed, 48 insertions(+), 35 deletions(-) diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index 077647d5c26fc..abe62cbb597b0 100644 --- a/src/coreclr/jit/emit.cpp +++ b/src/coreclr/jit/emit.cpp @@ -1506,18 +1506,19 @@ void* emitter::emitAllocAnyInstr(size_t sz, emitAttr opsz) emitInsCount++; - instrDescDebugInfo* info = (instrDescDebugInfo*)emitGetMem(sizeof(*info)); - - info->idNum = emitInsCount; - info->idSize = sz; - info->idVarRefOffs = 0; - info->idMemCookie = 0; - info->idFlags = GTF_EMPTY; - info->idFinallyCall = false; - info->idCatchRet = false; - info->idCallSig = nullptr; - - id->idDebugOnlyInfo(info); + if (emitComp->opts.disAsm) + { + instrDescDebugInfo* info = (instrDescDebugInfo*)emitGetMem(sizeof(*info)); + info->idNum = emitInsCount; + info->idSize = sz; + info->idVarRefOffs = 0; + info->idMemCookie = 0; + info->idFlags = GTF_EMPTY; + info->idFinallyCall = false; + info->idCatchRet = false; + info->idCallSig = nullptr; + id->idDebugOnlyInfo(info); + } /* Store the size and handle the two special values that indicate GCref and ByRef */ @@ -4259,12 +4260,12 @@ void emitter::emitRemoveJumpToNextInst() emitDispIG(targetGroup, nullptr, false); assert(jmp == id); } -#endif // DEBUG JITDUMP("IG%02u IN%04x is the last instruction in the group and jumps to the next instruction group " "IG%02u %s, removing.\n", jmpGroup->igNum, jmp->idDebugOnlyInfo()->idNum, targetGroup->igNum, emitLabelString(targetGroup)); +#endif // DEBUG // Unlink the jump from emitJumpList while keeping the previousJmp the same. if (previousJmp != nullptr) diff --git a/src/coreclr/jit/emit.h b/src/coreclr/jit/emit.h index 0014899f047cb..3a06e9192e4c9 100644 --- a/src/coreclr/jit/emit.h +++ b/src/coreclr/jit/emit.h @@ -822,28 +822,19 @@ class emitter CLANG_FORMAT_COMMENT_ANCHOR; // -// This is the end of the 'small' instrDesc which is the same on all -// platforms (except 64-bit DEBUG which is a little bigger). -// Non-DEBUG sizes: -// x86/amd64/arm/arm64: 64 bits -// DEBUG sizes (includes one pointer): +// This is the end of the 'small' instrDesc which is the same on all platforms +// Sizes (includes one pointer): // x86: 2 DWORDs, 96 bits // amd64: 4 DWORDs, 128 bits // arm: 3 DWORDs, 96 bits // arm64: 4 DWORDs, 128 bits -// There should no padding or alignment issues on any platform or -// configuration (including DEBUG which has 1 extra pointer). +// There should no padding or alignment issues on any platform or configuration. // +// If you add lots more fields that need to be cleared (such +// as various flags), you might need to update the body of +// emitter::emitAllocInstr() to clear them. -/* - If you add lots more fields that need to be cleared (such - as various flags), you might need to update the body of - emitter::emitAllocInstr() to clear them. - */ - -#define SMALL_IDSC_DEBUG_EXTRA (sizeof(void*)) - -#define SMALL_IDSC_SIZE (8 + SMALL_IDSC_DEBUG_EXTRA) +#define SMALL_IDSC_SIZE (8 + sizeof(void*)) void checkSizes(); @@ -2688,10 +2679,7 @@ class emitter inline void emitter::instrDesc::checkSizes() { -#ifdef DEBUG C_ASSERT(SMALL_IDSC_SIZE == (offsetof(instrDesc, _idDebugOnlyInfo) + sizeof(instrDescDebugInfo*))); -#endif - C_ASSERT(SMALL_IDSC_SIZE == offsetof(instrDesc, _idAddrUnion)); } /***************************************************************************** diff --git a/src/coreclr/jit/emitarm.cpp b/src/coreclr/jit/emitarm.cpp index df71ab356cd2b..05047d91a877c 100644 --- a/src/coreclr/jit/emitarm.cpp +++ b/src/coreclr/jit/emitarm.cpp @@ -4837,8 +4837,14 @@ void emitter::emitIns_Call(EmitCallType callType, } } id->idDebugOnlyInfo()->idCallSig = sigInfo; -#endif id->idDebugOnlyInfo()->idMemCookie = (size_t)methHnd; // method token +#else + if (emitComp->opts.disAsm) + { + id->idDebugOnlyInfo()->idMemCookie = (size_t)methHnd; // method token + } +#endif + #ifdef LATE_DISASM if (addr != nullptr) diff --git a/src/coreclr/jit/emitarm64.cpp b/src/coreclr/jit/emitarm64.cpp index 3500227140d59..e875d97e7be81 100644 --- a/src/coreclr/jit/emitarm64.cpp +++ b/src/coreclr/jit/emitarm64.cpp @@ -8701,8 +8701,13 @@ void emitter::emitIns_Call(EmitCallType callType, } } id->idDebugOnlyInfo()->idCallSig = sigInfo; -#endif id->idDebugOnlyInfo()->idMemCookie = (size_t)methHnd; // method token +#else + if (emitComp->opts.disAsm) + { + id->idDebugOnlyInfo()->idMemCookie = (size_t)methHnd; // method token + } +#endif #ifdef LATE_DISASM if (addr != nullptr) diff --git a/src/coreclr/jit/emitxarch.cpp b/src/coreclr/jit/emitxarch.cpp index 7ed229e702a29..ee5459e7dc021 100644 --- a/src/coreclr/jit/emitxarch.cpp +++ b/src/coreclr/jit/emitxarch.cpp @@ -4367,7 +4367,15 @@ void emitter::emitIns_IJ(emitAttr attr, regNumber reg, unsigned base) id->idAddr()->iiaAddrMode.amBaseReg = REG_NA; id->idAddr()->iiaAddrMode.amIndxReg = reg; id->idAddr()->iiaAddrMode.amScale = emitter::OPSZP; + +#ifdef DEBUG id->idDebugOnlyInfo()->idMemCookie = base; +#else + if (emitComp->opts.disAsm) + { + id->idDebugOnlyInfo()->idMemCookie = base; + } +#endif id->idCodeSize(sz); @@ -7989,8 +7997,13 @@ void emitter::emitIns_Call(EmitCallType callType, #ifdef DEBUG id->idDebugOnlyInfo()->idCallSig = sigInfo; -#endif id->idDebugOnlyInfo()->idMemCookie = (size_t)methHnd; // method token +#else + if (emitComp->opts.disAsm) + { + id->idDebugOnlyInfo()->idMemCookie = (size_t)methHnd; // method token + } +#endif #ifdef LATE_DISASM if (addr != nullptr) From f760723884def304ec3df3c5346772ac339d6155 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Fri, 5 Aug 2022 02:00:25 +0200 Subject: [PATCH 07/32] fix build --- src/coreclr/jit/emit.cpp | 18 ++++++++++-------- src/coreclr/jit/emitarm.cpp | 3 +-- src/coreclr/jit/emitarm64.cpp | 2 +- src/coreclr/jit/emitxarch.cpp | 6 +++--- 4 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index abe62cbb597b0..54a71d5dcc6b5 100644 --- a/src/coreclr/jit/emit.cpp +++ b/src/coreclr/jit/emit.cpp @@ -1506,17 +1506,19 @@ void* emitter::emitAllocAnyInstr(size_t sz, emitAttr opsz) emitInsCount++; +#ifndef DEBUG if (emitComp->opts.disAsm) +#endif { instrDescDebugInfo* info = (instrDescDebugInfo*)emitGetMem(sizeof(*info)); - info->idNum = emitInsCount; - info->idSize = sz; - info->idVarRefOffs = 0; - info->idMemCookie = 0; - info->idFlags = GTF_EMPTY; - info->idFinallyCall = false; - info->idCatchRet = false; - info->idCallSig = nullptr; + info->idNum = emitInsCount; + info->idSize = sz; + info->idVarRefOffs = 0; + info->idMemCookie = 0; + info->idFlags = GTF_EMPTY; + info->idFinallyCall = false; + info->idCatchRet = false; + info->idCallSig = nullptr; id->idDebugOnlyInfo(info); } diff --git a/src/coreclr/jit/emitarm.cpp b/src/coreclr/jit/emitarm.cpp index 05047d91a877c..1f28e9e66f819 100644 --- a/src/coreclr/jit/emitarm.cpp +++ b/src/coreclr/jit/emitarm.cpp @@ -4836,7 +4836,7 @@ void emitter::emitIns_Call(EmitCallType callType, VarSetOps::ToString(emitComp, ((instrDescCGCA*)id)->idcGCvars)); } } - id->idDebugOnlyInfo()->idCallSig = sigInfo; + id->idDebugOnlyInfo()->idCallSig = sigInfo; id->idDebugOnlyInfo()->idMemCookie = (size_t)methHnd; // method token #else if (emitComp->opts.disAsm) @@ -4845,7 +4845,6 @@ void emitter::emitIns_Call(EmitCallType callType, } #endif - #ifdef LATE_DISASM if (addr != nullptr) { diff --git a/src/coreclr/jit/emitarm64.cpp b/src/coreclr/jit/emitarm64.cpp index e875d97e7be81..9f27961c51bd5 100644 --- a/src/coreclr/jit/emitarm64.cpp +++ b/src/coreclr/jit/emitarm64.cpp @@ -8700,7 +8700,7 @@ void emitter::emitIns_Call(EmitCallType callType, VarSetOps::ToString(emitComp, ((instrDescCGCA*)id)->idcGCvars)); } } - id->idDebugOnlyInfo()->idCallSig = sigInfo; + id->idDebugOnlyInfo()->idCallSig = sigInfo; id->idDebugOnlyInfo()->idMemCookie = (size_t)methHnd; // method token #else if (emitComp->opts.disAsm) diff --git a/src/coreclr/jit/emitxarch.cpp b/src/coreclr/jit/emitxarch.cpp index ee5459e7dc021..0ef50bd8cf670 100644 --- a/src/coreclr/jit/emitxarch.cpp +++ b/src/coreclr/jit/emitxarch.cpp @@ -4368,8 +4368,8 @@ void emitter::emitIns_IJ(emitAttr attr, regNumber reg, unsigned base) id->idAddr()->iiaAddrMode.amIndxReg = reg; id->idAddr()->iiaAddrMode.amScale = emitter::OPSZP; -#ifdef DEBUG - id->idDebugOnlyInfo()->idMemCookie = base; +#ifdef DEBUG + id->idDebugOnlyInfo()->idMemCookie = base; #else if (emitComp->opts.disAsm) { @@ -7996,7 +7996,7 @@ void emitter::emitIns_Call(EmitCallType callType, } #ifdef DEBUG - id->idDebugOnlyInfo()->idCallSig = sigInfo; + id->idDebugOnlyInfo()->idCallSig = sigInfo; id->idDebugOnlyInfo()->idMemCookie = (size_t)methHnd; // method token #else if (emitComp->opts.disAsm) From 99c92548573f5417a0faaad5cdc913b13c541ea3 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Fri, 5 Aug 2022 18:32:48 +0200 Subject: [PATCH 08/32] clean up --- src/coreclr/jit/emitarm.cpp | 3 +-- src/coreclr/jit/emitarm64.cpp | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/coreclr/jit/emitarm.cpp b/src/coreclr/jit/emitarm.cpp index 1f28e9e66f819..759ce24a1e09a 100644 --- a/src/coreclr/jit/emitarm.cpp +++ b/src/coreclr/jit/emitarm.cpp @@ -6697,10 +6697,9 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) { emitDispGCInfoDelta(); } -#else size_t expected = emitSizeOfInsDsc(id); assert(sz == expected); - +#else if (emitComp->opts.disAsm) { emitDispIns(id, false, 0, true, emitCurCodeOffs(odst), *dp, (dst - *dp), ig); diff --git a/src/coreclr/jit/emitarm64.cpp b/src/coreclr/jit/emitarm64.cpp index 9f27961c51bd5..d4d152e1b0738 100644 --- a/src/coreclr/jit/emitarm64.cpp +++ b/src/coreclr/jit/emitarm64.cpp @@ -11743,10 +11743,9 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) { emitDispGCInfoDelta(); } -#else size_t expected = emitSizeOfInsDsc(id); assert(sz == expected); - +#else if (emitComp->opts.disAsm) { emitDispIns(id, false, 0, true, emitCurCodeOffs(odst), *dp, (dst - *dp), ig); From 7fe359681bb607c203363056966fcc041e21a1e4 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Fri, 5 Aug 2022 19:51:46 +0200 Subject: [PATCH 09/32] fix build --- src/coreclr/jit/emitarm.cpp | 4 ++-- src/coreclr/jit/emitarm64.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/coreclr/jit/emitarm.cpp b/src/coreclr/jit/emitarm.cpp index 759ce24a1e09a..febcb7940012e 100644 --- a/src/coreclr/jit/emitarm.cpp +++ b/src/coreclr/jit/emitarm.cpp @@ -6697,11 +6697,11 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) { emitDispGCInfoDelta(); } - size_t expected = emitSizeOfInsDsc(id); - assert(sz == expected); #else if (emitComp->opts.disAsm) { + size_t expected = emitSizeOfInsDsc(id); + assert(sz == expected); emitDispIns(id, false, 0, true, emitCurCodeOffs(odst), *dp, (dst - *dp), ig); } #endif diff --git a/src/coreclr/jit/emitarm64.cpp b/src/coreclr/jit/emitarm64.cpp index d4d152e1b0738..4e364dd757761 100644 --- a/src/coreclr/jit/emitarm64.cpp +++ b/src/coreclr/jit/emitarm64.cpp @@ -11743,11 +11743,11 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) { emitDispGCInfoDelta(); } - size_t expected = emitSizeOfInsDsc(id); - assert(sz == expected); #else if (emitComp->opts.disAsm) { + size_t expected = emitSizeOfInsDsc(id); + assert(sz == expected); emitDispIns(id, false, 0, true, emitCurCodeOffs(odst), *dp, (dst - *dp), ig); } #endif From 4d776af704fd3bbe0e69266bc9e918441fef3d05 Mon Sep 17 00:00:00 2001 From: EgorBo Date: Sat, 6 Aug 2022 11:42:23 +0200 Subject: [PATCH 10/32] Apply Jakob's patch --- src/coreclr/jit/emit.cpp | 46 +++++++++++++++++++++++----------------- src/coreclr/jit/emit.h | 12 +++++------ 2 files changed, 32 insertions(+), 26 deletions(-) diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index 54a71d5dcc6b5..fef63439fbdb0 100644 --- a/src/coreclr/jit/emit.cpp +++ b/src/coreclr/jit/emit.cpp @@ -615,8 +615,13 @@ unsigned emitLclVarAddr::lvaOffset() // returns the offset into the variable to void emitter::emitBegCG(Compiler* comp, COMP_HANDLE cmpHandle) { - emitComp = comp; - emitCmpHandle = cmpHandle; + emitComp = comp; + emitCmpHandle = cmpHandle; + m_debugInfoSize = sizeof(instrDescDebugInfo*); +#ifndef DEBUG + if (!comp->opts.disAsm) + m_debugInfoSize = 0; +#endif } void emitter::emitEndCG() @@ -1475,6 +1480,8 @@ void* emitter::emitAllocAnyInstr(size_t sz, emitAttr opsz) // Make sure we have enough space for the new instruction. // `igInsCnt` is currently a byte, so we can't have more than 255 instructions in a single insGroup. + sz += m_debugInfoSize; + if ((emitCurIGfreeNext + sz >= emitCurIGfreeEndp) || emitForceNewIG || (emitCurIGinsCnt >= 255)) { emitNxtIG(true); @@ -1482,11 +1489,12 @@ void* emitter::emitAllocAnyInstr(size_t sz, emitAttr opsz) /* Grab the space for the instruction */ - emitLastIns = id = (instrDesc*)emitCurIGfreeNext; + memset(emitCurIGfreeNext, 0, sz); + + emitLastIns = id = (instrDesc*)(emitCurIGfreeNext + m_debugInfoSize); emitCurIGfreeNext += sz; assert(sz >= sizeof(void*)); - memset(id, 0, sz); // These fields should have been zero-ed by the above assert(id->idReg1() == regNumber(0)); @@ -1506,13 +1514,11 @@ void* emitter::emitAllocAnyInstr(size_t sz, emitAttr opsz) emitInsCount++; -#ifndef DEBUG - if (emitComp->opts.disAsm) -#endif + if (m_debugInfoSize > 0) { instrDescDebugInfo* info = (instrDescDebugInfo*)emitGetMem(sizeof(*info)); info->idNum = emitInsCount; - info->idSize = sz; + info->idSize = sz - m_debugInfoSize; info->idVarRefOffs = 0; info->idMemCookie = 0; info->idFlags = GTF_EMPTY; @@ -2927,7 +2933,7 @@ bool emitter::emitGetLocationInfo(emitLocation* emitLoc, int i; for (i = 0; i != insNum; ++i) { - castto(id, BYTE*) += emitSizeOfInsDsc(id); + castto(id, BYTE*) += emitSizeOfInsDsc(id) + m_debugInfoSize; } // Return the info we found @@ -2955,7 +2961,7 @@ bool emitter::emitNextID(insGroup*& ig, instrDesc*& id, int& insRemaining) { if (insRemaining > 0) { - castto(id, BYTE*) += emitSizeOfInsDsc(id); + castto(id, BYTE*) += emitSizeOfInsDsc(id) + m_debugInfoSize; --insRemaining; return true; } @@ -3797,7 +3803,7 @@ void emitter::emitDispIG(insGroup* ig, insGroup* igPrev, bool verbose) if (verbose) { - BYTE* ins = ig->igData; + BYTE* ins = ig->igData + m_debugInfoSize; UNATIVE_OFFSET ofs = ig->igOffs; unsigned cnt = ig->igInsCnt; @@ -3821,7 +3827,7 @@ void emitter::emitDispIG(insGroup* ig, insGroup* igPrev, bool verbose) #endif emitDispIns(id, false, true, false, ofs, nullptr, 0, ig); - ins += emitSizeOfInsDsc(id); + ins += emitSizeOfInsDsc(id) + m_debugInfoSize; ofs += id->idCodeSize(); } while (--cnt); @@ -4239,11 +4245,11 @@ void emitter::emitRemoveJumpToNextInst() assert(instructionCount > 0); instrDesc* id = nullptr; { - BYTE* dataPtr = jmpGroup->igData; + BYTE* dataPtr = jmpGroup->igData + m_debugInfoSize; while (instructionCount > 0) { id = (instrDesc*)dataPtr; - dataPtr += emitSizeOfInsDsc(id); + dataPtr += emitSizeOfInsDsc(id) + m_debugInfoSize; instructionCount -= 1; } } @@ -6643,7 +6649,7 @@ unsigned emitter::emitEndCodeGen(Compiler* comp, // if it were the instruction following a call. emitGenGCInfoIfFuncletRetTarget(ig, cp); - instrDesc* id = (instrDesc*)ig->igData; + instrDesc* id = (instrDesc*)(ig->igData + m_debugInfoSize); #ifdef DEBUG /* Print the IG label, but only if it is a branch label */ @@ -6819,7 +6825,7 @@ unsigned emitter::emitEndCodeGen(Compiler* comp, #endif - castto(id, BYTE*) += emitIssue1Instr(ig, id, &cp); + castto(id, BYTE*) += emitIssue1Instr(ig, id, &cp) + m_debugInfoSize; #ifdef DEBUG // Print the alignment boundary @@ -7185,7 +7191,7 @@ void emitter::emitGenGCInfoIfFuncletRetTarget(insGroup* ig, BYTE* cp) unsigned emitter::emitFindInsNum(insGroup* ig, instrDesc* idMatch) { - instrDesc* id = (instrDesc*)ig->igData; + instrDesc* id = (instrDesc*)(ig->igData + m_debugInfoSize); // Check if we are the first instruction in the group if (id == idMatch) @@ -7199,7 +7205,7 @@ unsigned emitter::emitFindInsNum(insGroup* ig, instrDesc* idMatch) while (insRemaining > 0) { - castto(id, BYTE*) += emitSizeOfInsDsc(id); + castto(id, BYTE*) += emitSizeOfInsDsc(id) + m_debugInfoSize; insNum++; insRemaining--; @@ -7221,7 +7227,7 @@ unsigned emitter::emitFindInsNum(insGroup* ig, instrDesc* idMatch) UNATIVE_OFFSET emitter::emitFindOffset(insGroup* ig, unsigned insNum) { - instrDesc* id = (instrDesc*)ig->igData; + instrDesc* id = (instrDesc*)(ig->igData + m_debugInfoSize); UNATIVE_OFFSET of = 0; #ifdef DEBUG @@ -7236,7 +7242,7 @@ UNATIVE_OFFSET emitter::emitFindOffset(insGroup* ig, unsigned insNum) { of += id->idCodeSize(); - castto(id, BYTE*) += emitSizeOfInsDsc(id); + castto(id, BYTE*) += emitSizeOfInsDsc(id) + m_debugInfoSize; insNum--; } diff --git a/src/coreclr/jit/emit.h b/src/coreclr/jit/emit.h index 3a06e9192e4c9..f1ef1ee45b37f 100644 --- a/src/coreclr/jit/emit.h +++ b/src/coreclr/jit/emit.h @@ -461,6 +461,8 @@ class emitter GCInfo* gcInfo; CodeGen* codeGen; + size_t m_debugInfoSize; + typedef GCInfo::varPtrDsc varPtrDsc; typedef GCInfo::regPtrDsc regPtrDsc; typedef GCInfo::CallDsc callDsc; @@ -806,16 +808,14 @@ class emitter //////////////////////////////////////////////////////////////////////// CLANG_FORMAT_COMMENT_ANCHOR; - instrDescDebugInfo* _idDebugOnlyInfo; - public: instrDescDebugInfo* idDebugOnlyInfo() const { - return _idDebugOnlyInfo; + return ((instrDescDebugInfo**)(this))[-1]; } void idDebugOnlyInfo(instrDescDebugInfo* info) { - _idDebugOnlyInfo = info; + ((instrDescDebugInfo**)this)[-1] = info; } private: @@ -834,7 +834,7 @@ class emitter // as various flags), you might need to update the body of // emitter::emitAllocInstr() to clear them. -#define SMALL_IDSC_SIZE (8 + sizeof(void*)) +#define SMALL_IDSC_SIZE 8 void checkSizes(); @@ -2679,7 +2679,7 @@ class emitter inline void emitter::instrDesc::checkSizes() { - C_ASSERT(SMALL_IDSC_SIZE == (offsetof(instrDesc, _idDebugOnlyInfo) + sizeof(instrDescDebugInfo*))); + C_ASSERT(SMALL_IDSC_SIZE == offsetof(instrDesc, _idAddrUnion)); } /***************************************************************************** From e95daa8798025ea2e93cbe328ecd541c89f05ef1 Mon Sep 17 00:00:00 2001 From: Jakob Botsch Nielsen Date: Sat, 6 Aug 2022 14:36:18 +0200 Subject: [PATCH 11/32] Remove some #ifdef DEBUG for displaying frame refs --- src/coreclr/jit/emitxarch.cpp | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/src/coreclr/jit/emitxarch.cpp b/src/coreclr/jit/emitxarch.cpp index 0ef50bd8cf670..3cd176c84fba7 100644 --- a/src/coreclr/jit/emitxarch.cpp +++ b/src/coreclr/jit/emitxarch.cpp @@ -9377,10 +9377,8 @@ void emitter::emitDispIns( emitCurStackLvl -= sizeof(int); #endif -#ifdef DEBUG emitDispFrameRef(id->idAddr()->iiaLclVar.lvaVarNum(), id->idAddr()->iiaLclVar.lvaOffset(), id->idDebugOnlyInfo()->idVarRefOffs, asmfm); -#endif #if !FEATURE_FIXED_OUT_ARGS if (ins == INS_pop) @@ -9396,10 +9394,8 @@ void emitter::emitDispIns( printf("%s", sstr); -#ifdef DEBUG emitDispFrameRef(id->idAddr()->iiaLclVar.lvaVarNum(), id->idAddr()->iiaLclVar.lvaOffset(), id->idDebugOnlyInfo()->idVarRefOffs, asmfm); -#endif printf(", %s", emitRegName(id->idReg1(), attr)); break; @@ -9411,10 +9407,8 @@ void emitter::emitDispIns( printf("%s", sstr); -#ifdef DEBUG emitDispFrameRef(id->idAddr()->iiaLclVar.lvaVarNum(), id->idAddr()->iiaLclVar.lvaOffset(), id->idDebugOnlyInfo()->idVarRefOffs, asmfm); -#endif emitGetInsCns(id, &cnsVal); val = cnsVal.cnsVal; @@ -9447,10 +9441,8 @@ void emitter::emitDispIns( printf("%s", sstr); -#ifdef DEBUG emitDispFrameRef(id->idAddr()->iiaLclVar.lvaVarNum(), id->idAddr()->iiaLclVar.lvaOffset(), id->idDebugOnlyInfo()->idVarRefOffs, asmfm); -#endif printf(", %s", emitRegName(id->idReg1(), attr)); @@ -9489,10 +9481,8 @@ void emitter::emitDispIns( } printf("%s, %s", emitRegName(id->idReg1(), attr), sstr); -#ifdef DEBUG emitDispFrameRef(id->idAddr()->iiaLclVar.lvaVarNum(), id->idAddr()->iiaLclVar.lvaOffset(), id->idDebugOnlyInfo()->idVarRefOffs, asmfm); -#endif break; @@ -9500,10 +9490,8 @@ void emitter::emitDispIns( case IF_RWR_SRD_CNS: { printf("%s, %s", emitRegName(id->idReg1(), attr), sstr); -#ifdef DEBUG emitDispFrameRef(id->idAddr()->iiaLclVar.lvaVarNum(), id->idAddr()->iiaLclVar.lvaOffset(), id->idDebugOnlyInfo()->idVarRefOffs, asmfm); -#endif emitGetInsCns(id, &cnsVal); val = cnsVal.cnsVal; @@ -9522,19 +9510,15 @@ void emitter::emitDispIns( case IF_RWR_RRD_SRD: printf("%s, %s, %s", emitRegName(id->idReg1(), attr), emitRegName(id->idReg2(), attr), sstr); -#ifdef DEBUG emitDispFrameRef(id->idAddr()->iiaLclVar.lvaVarNum(), id->idAddr()->iiaLclVar.lvaOffset(), id->idDebugOnlyInfo()->idVarRefOffs, asmfm); -#endif break; case IF_RWR_RRD_SRD_CNS: { printf("%s, %s, %s", emitRegName(id->idReg1(), attr), emitRegName(id->idReg2(), attr), sstr); -#ifdef DEBUG emitDispFrameRef(id->idAddr()->iiaLclVar.lvaVarNum(), id->idAddr()->iiaLclVar.lvaOffset(), id->idDebugOnlyInfo()->idVarRefOffs, asmfm); -#endif emitGetInsCns(id, &cnsVal); val = cnsVal.cnsVal; @@ -9555,10 +9539,8 @@ void emitter::emitDispIns( { printf("%s, ", emitRegName(id->idReg1(), attr)); printf("%s, ", emitRegName(id->idReg2(), attr)); -#ifdef DEBUG emitDispFrameRef(id->idAddr()->iiaLclVar.lvaVarNum(), id->idAddr()->iiaLclVar.lvaOffset(), id->idDebugOnlyInfo()->idVarRefOffs, asmfm); -#endif emitGetInsCns(id, &cnsVal); val = (cnsVal.cnsVal >> 4) + XMMBASE; From 7255863f712d97d180a873fd23f139cbc4fd9ecb Mon Sep 17 00:00:00 2001 From: Jakob Botsch Nielsen Date: Sat, 6 Aug 2022 15:24:58 +0200 Subject: [PATCH 12/32] Fix alignment insertion assuming only emitForceNewIG can create new IGs --- src/coreclr/jit/emit.cpp | 29 +++++------------------------ 1 file changed, 5 insertions(+), 24 deletions(-) diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index fef63439fbdb0..96b0769c4ccef 100644 --- a/src/coreclr/jit/emit.cpp +++ b/src/coreclr/jit/emit.cpp @@ -5185,32 +5185,13 @@ void emitter::emitCheckAlignFitInCurIG(unsigned nAlignInstr) // void emitter::emitLoopAlign(unsigned paddingBytes, bool isFirstAlign DEBUG_ARG(bool isPlacedBehindJmp)) { - // Determine if 'align' instruction about to be generated will - // fall in current IG or next. - bool alignInstrInNewIG = emitForceNewIG; - - if (!alignInstrInNewIG) - { - // If align fits in current IG, then mark that it contains alignment - // instruction in the end. - emitCurIG->igFlags |= IGF_HAS_ALIGN; - } - - /* Insert a pseudo-instruction to ensure that we align - the next instruction properly */ + // Insert a pseudo-instruction to ensure that we align + // the next instruction properly instrDescAlign* id = emitNewInstrAlign(); - if (alignInstrInNewIG) - { - // Mark this IG has alignment in the end, so during emitter we can check the instruction count - // heuristics of all IGs that follows this IG that participate in a loop. - emitCurIG->igFlags |= IGF_HAS_ALIGN; - } - else - { - // Otherwise, make sure it was already marked such. - assert(emitCurIG->endsWithAlignInstr()); - } + // Mark this IG has alignment in the end, so during emitter we can check the instruction count + // heuristics of all IGs that follows this IG that participate in a loop. + emitCurIG->igFlags |= IGF_HAS_ALIGN; #if defined(TARGET_XARCH) assert(paddingBytes <= MAX_ENCODED_SIZE); From be9777371f0ae21ee202db76e6867dab1688ed7e Mon Sep 17 00:00:00 2001 From: Jakob Botsch Nielsen Date: Sat, 6 Aug 2022 15:33:50 +0200 Subject: [PATCH 13/32] Account for debug info when allocating IG buffers --- src/coreclr/jit/emit.cpp | 4 +++- src/coreclr/jit/emit.h | 6 ++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index 96b0769c4ccef..3b1af4bf93581 100644 --- a/src/coreclr/jit/emit.cpp +++ b/src/coreclr/jit/emit.cpp @@ -676,7 +676,9 @@ void emitter::emitGenIG(insGroup* ig) if (emitCurIGfreeBase == nullptr) { - emitIGbuffSize = SC_IG_BUFFER_SIZE; + emitIGbuffSize = + (SC_IG_BUFFER_NUM_SMALL_DESCS * (SMALL_IDSC_SIZE + m_debugInfoSize)) + + (SC_IG_BUFFER_NUM_LARGE_DESCS * (sizeof(emitter::instrDesc) + m_debugInfoSize)); emitCurIGfreeBase = (BYTE*)emitGetMem(emitIGbuffSize); } diff --git a/src/coreclr/jit/emit.h b/src/coreclr/jit/emit.h index f1ef1ee45b37f..6c3311031e735 100644 --- a/src/coreclr/jit/emit.h +++ b/src/coreclr/jit/emit.h @@ -1965,10 +1965,12 @@ class emitter // movk xip1, #2 LSL #16 // ldr w8, [fp, xip1] // [V10 arg10] // which eats up our insGroup buffer. -#define SC_IG_BUFFER_SIZE (200 * sizeof(emitter::instrDesc)) +#define SC_IG_BUFFER_NUM_SMALL_DESCS 0 +#define SC_IG_BUFFER_NUM_LARGE_DESCS 200 #else -#define SC_IG_BUFFER_SIZE (50 * sizeof(emitter::instrDesc) + 14 * SMALL_IDSC_SIZE) +#define SC_IG_BUFFER_NUM_SMALL_DESCS 14 +#define SC_IG_BUFFER_NUM_LARGE_DESCS 50 #endif // !(TARGET_ARMARCH || TARGET_LOONGARCH64) size_t emitIGbuffSize; From 8f66d906560e3ada10698219b187e252ef06bc51 Mon Sep 17 00:00:00 2001 From: Jakob Botsch Nielsen Date: Sat, 6 Aug 2022 16:01:05 +0200 Subject: [PATCH 14/32] C++ify accessors --- src/coreclr/jit/emit.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/coreclr/jit/emit.h b/src/coreclr/jit/emit.h index 6c3311031e735..9cc58b65b6ef6 100644 --- a/src/coreclr/jit/emit.h +++ b/src/coreclr/jit/emit.h @@ -811,11 +811,13 @@ class emitter public: instrDescDebugInfo* idDebugOnlyInfo() const { - return ((instrDescDebugInfo**)(this))[-1]; + const char* addr = reinterpret_cast(this); + return *reinterpret_cast(addr - sizeof(instrDescDebugInfo*)); } void idDebugOnlyInfo(instrDescDebugInfo* info) { - ((instrDescDebugInfo**)this)[-1] = info; + char* addr = reinterpret_cast(this); + *reinterpret_cast(addr - sizeof(instrDescDebugInfo*)) = info; } private: From 611b9d268baab1e979c47d90ff72fd0d362f5477 Mon Sep 17 00:00:00 2001 From: Jakob Botsch Nielsen Date: Sat, 6 Aug 2022 16:08:05 +0200 Subject: [PATCH 15/32] Run jit-format --- src/coreclr/jit/emit.cpp | 5 ++--- src/coreclr/jit/emit.h | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index 3b1af4bf93581..2374561e67536 100644 --- a/src/coreclr/jit/emit.cpp +++ b/src/coreclr/jit/emit.cpp @@ -676,9 +676,8 @@ void emitter::emitGenIG(insGroup* ig) if (emitCurIGfreeBase == nullptr) { - emitIGbuffSize = - (SC_IG_BUFFER_NUM_SMALL_DESCS * (SMALL_IDSC_SIZE + m_debugInfoSize)) + - (SC_IG_BUFFER_NUM_LARGE_DESCS * (sizeof(emitter::instrDesc) + m_debugInfoSize)); + emitIGbuffSize = (SC_IG_BUFFER_NUM_SMALL_DESCS * (SMALL_IDSC_SIZE + m_debugInfoSize)) + + (SC_IG_BUFFER_NUM_LARGE_DESCS * (sizeof(emitter::instrDesc) + m_debugInfoSize)); emitCurIGfreeBase = (BYTE*)emitGetMem(emitIGbuffSize); } diff --git a/src/coreclr/jit/emit.h b/src/coreclr/jit/emit.h index 9cc58b65b6ef6..0b9cbb268904d 100644 --- a/src/coreclr/jit/emit.h +++ b/src/coreclr/jit/emit.h @@ -812,11 +812,11 @@ class emitter instrDescDebugInfo* idDebugOnlyInfo() const { const char* addr = reinterpret_cast(this); - return *reinterpret_cast(addr - sizeof(instrDescDebugInfo*)); + return *reinterpret_cast(addr - sizeof(instrDescDebugInfo*)); } void idDebugOnlyInfo(instrDescDebugInfo* info) { - char* addr = reinterpret_cast(this); + char* addr = reinterpret_cast(this); *reinterpret_cast(addr - sizeof(instrDescDebugInfo*)) = info; } From adb7772cffe8ab64b04230df3a63d9112c1adaa2 Mon Sep 17 00:00:00 2001 From: Jakob Botsch Nielsen Date: Sat, 6 Aug 2022 17:12:22 +0200 Subject: [PATCH 16/32] Fix a missing m_debugInfoSize add --- src/coreclr/jit/emit.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index 2374561e67536..5d0c58357f780 100644 --- a/src/coreclr/jit/emit.cpp +++ b/src/coreclr/jit/emit.cpp @@ -2840,12 +2840,12 @@ void emitter::emitGetInstrDescs(insGroup* ig, instrDesc** id, int* insCnt) assert(!(ig->igFlags & IGF_PLACEHOLDER)); if (ig == emitCurIG) { - *id = (instrDesc*)emitCurIGfreeBase; + *id = (instrDesc*)(emitCurIGfreeBase + m_debugInfoSize); *insCnt = emitCurIGinsCnt; } else { - *id = (instrDesc*)ig->igData; + *id = (instrDesc*)(ig->igData + m_debugInfoSize); *insCnt = ig->igInsCnt; } From 5e020ca8046471deeb1aa0f2997c0ad131921336 Mon Sep 17 00:00:00 2001 From: Jakob Botsch Nielsen Date: Sat, 6 Aug 2022 17:13:42 +0200 Subject: [PATCH 17/32] Couple of small cleanups --- src/coreclr/jit/emitarm.cpp | 11 +++++------ src/coreclr/jit/emitxarch.cpp | 10 +++------- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/src/coreclr/jit/emitarm.cpp b/src/coreclr/jit/emitarm.cpp index febcb7940012e..b083753bf71b1 100644 --- a/src/coreclr/jit/emitarm.cpp +++ b/src/coreclr/jit/emitarm.cpp @@ -4836,14 +4836,13 @@ void emitter::emitIns_Call(EmitCallType callType, VarSetOps::ToString(emitComp, ((instrDescCGCA*)id)->idcGCvars)); } } - id->idDebugOnlyInfo()->idCallSig = sigInfo; - id->idDebugOnlyInfo()->idMemCookie = (size_t)methHnd; // method token -#else - if (emitComp->opts.disAsm) +#endif + + if (m_debugInfoSize > 0) { - id->idDebugOnlyInfo()->idMemCookie = (size_t)methHnd; // method token + INDEBUG(id->idDebugOnlyInfo()->idCallSig = sigInfo); + id->idDebugOnlyInfo()->idMemCookie = (size_t)methHnd; // method token } -#endif #ifdef LATE_DISASM if (addr != nullptr) diff --git a/src/coreclr/jit/emitxarch.cpp b/src/coreclr/jit/emitxarch.cpp index 3cd176c84fba7..cdbe29a75537c 100644 --- a/src/coreclr/jit/emitxarch.cpp +++ b/src/coreclr/jit/emitxarch.cpp @@ -7995,15 +7995,11 @@ void emitter::emitIns_Call(EmitCallType callType, } } -#ifdef DEBUG - id->idDebugOnlyInfo()->idCallSig = sigInfo; - id->idDebugOnlyInfo()->idMemCookie = (size_t)methHnd; // method token -#else - if (emitComp->opts.disAsm) + if (m_debugInfoSize > 0) { - id->idDebugOnlyInfo()->idMemCookie = (size_t)methHnd; // method token + INDEBUG(id->idDebugOnlyInfo()->idCallSig = sigInfo); + id->idDebugOnlyInfo()->idMemCookie = (size_t)methHnd; // method token } -#endif #ifdef LATE_DISASM if (addr != nullptr) From 9fa3367dac734894c03716a251263a6fb4667d02 Mon Sep 17 00:00:00 2001 From: Jakob Botsch Nielsen Date: Sat, 6 Aug 2022 17:13:34 +0200 Subject: [PATCH 18/32] Delete instrDesc constructors Make accidental bugs due to stack allocated instrDescs harder. Introduce inlineInstrDesc and use it for the few places we do this. --- src/coreclr/jit/emit.h | 42 +++++++++++++++++++++++++++++++++++ src/coreclr/jit/emitarm.cpp | 6 ++--- src/coreclr/jit/emitarm64.cpp | 8 +++---- src/coreclr/jit/emitxarch.cpp | 13 ++++++----- 4 files changed, 55 insertions(+), 14 deletions(-) diff --git a/src/coreclr/jit/emit.h b/src/coreclr/jit/emit.h index 0b9cbb268904d..0b1aa86623b57 100644 --- a/src/coreclr/jit/emit.h +++ b/src/coreclr/jit/emit.h @@ -622,6 +622,8 @@ class emitter #endif public: + instrDesc() = delete; // Do not stack alloc this due to debug info that has to come before it. + instruction idIns() const { return _idIns; @@ -1509,6 +1511,8 @@ class emitter struct instrDescJmp : instrDesc { + instrDescJmp() = delete; + instrDescJmp* idjNext; // next jump in the group/method insGroup* idjIG; // containing group @@ -1536,6 +1540,8 @@ class emitter #if FEATURE_LOOP_ALIGN struct instrDescAlign : instrDesc { + instrDescAlign() = delete; + instrDescAlign* idaNext; // next align in the group/method insGroup* idaIG; // containing group insGroup* idaLoopHeadPredIG; // The IG before the loop IG. @@ -1571,16 +1577,22 @@ class emitter struct instrDescCns : instrDesc // large const { + instrDescCns() = delete; + cnsval_ssize_t idcCnsVal; }; struct instrDescDsp : instrDesc // large displacement { + instrDescDsp() = delete; + target_ssize_t iddDspVal; }; struct instrDescCnsDsp : instrDesc // large cons + disp { + instrDescCnsDsp() = delete; + target_ssize_t iddcCnsVal; int iddcDspVal; }; @@ -1589,11 +1601,15 @@ class emitter struct instrDescAmd : instrDesc // large addrmode disp { + instrDescAmd() = delete; + ssize_t idaAmdVal; }; struct instrDescCnsAmd : instrDesc // large cons + addrmode disp { + instrDescCnsAmd() = delete; + ssize_t idacCnsVal; ssize_t idacAmdVal; }; @@ -1602,6 +1618,8 @@ class emitter struct instrDescCGCA : instrDesc // call with ... { + instrDescCGCA() = delete; + VARSET_TP idcGCvars; // ... updated GC vars or ssize_t idcDisp; // ... big addrmode disp regMaskTP idcGcrefRegs; // ... gcref registers @@ -1631,10 +1649,34 @@ class emitter #endif // MULTIREG_HAS_SECOND_GC_RET }; + // TODO-Cleanup: Uses of stack-allocated instrDescs should be refactored to be unnecessary. + template + struct inlineInstrDesc + { + private: + instrDescDebugInfo* idDebugInfo; + char idStorage[sizeof(T)]; + + public: + inlineInstrDesc() + : idDebugInfo(nullptr) + , idStorage() + { + static_assert_no_msg(offsetof(inlineInstrDesc, idStorage) == sizeof(instrDescDebugInfo*)); + } + + T* id() + { + return reinterpret_cast(idStorage); + } + }; + #ifdef TARGET_ARM struct instrDescReloc : instrDesc { + instrDescReloc() = delete; + BYTE* idrRelocVal; }; diff --git a/src/coreclr/jit/emitarm.cpp b/src/coreclr/jit/emitarm.cpp index b083753bf71b1..cd7c6933b6bf1 100644 --- a/src/coreclr/jit/emitarm.cpp +++ b/src/coreclr/jit/emitarm.cpp @@ -7696,10 +7696,8 @@ void emitter::emitDispLargeJmp( // Note: don't touch the actual instrDesc. If we accidentally messed it up, it would create a very // difficult to find bug. - instrDescJmp idJmp; - instrDescJmp* pidJmp = &idJmp; - - memset(&idJmp, 0, sizeof(idJmp)); + inlineInstrDesc idJmp; + instrDescJmp* pidJmp = idJmp.id(); pidJmp->idIns(emitJumpKindToIns(emitReverseJumpKind(emitInsToJumpKind(id->idIns())))); // reverse the // conditional diff --git a/src/coreclr/jit/emitarm64.cpp b/src/coreclr/jit/emitarm64.cpp index 4e364dd757761..4b8a717163892 100644 --- a/src/coreclr/jit/emitarm64.cpp +++ b/src/coreclr/jit/emitarm64.cpp @@ -12367,10 +12367,8 @@ void emitter::emitDispLargeJmp( // Note: don't touch the actual instrDesc. If we accidentally messed it up, it would create a very // difficult-to-find bug. - instrDescJmp idJmp; - instrDescJmp* pidJmp = &idJmp; - - memset(&idJmp, 0, sizeof(idJmp)); + inlineInstrDesc idJmp; + instrDescJmp* pidJmp = idJmp.id(); const instruction ins = id->idIns(); instruction reverseIns; @@ -12416,7 +12414,7 @@ void emitter::emitDispLargeJmp( // Next, display the unconditional branch. // Reset the local instrDesc. - memset(&idJmp, 0, sizeof(idJmp)); + memset(pidJmp, 0, sizeof(instrDescJmp)); pidJmp->idIns(INS_b); pidJmp->idInsFmt(IF_LARGEJMP); diff --git a/src/coreclr/jit/emitxarch.cpp b/src/coreclr/jit/emitxarch.cpp index cdbe29a75537c..14c2b92c064bd 100644 --- a/src/coreclr/jit/emitxarch.cpp +++ b/src/coreclr/jit/emitxarch.cpp @@ -13505,11 +13505,14 @@ BYTE* emitter::emitOutputLJ(insGroup* ig, BYTE* dst, instrDesc* i) // Make an instrDesc that looks like IF_RWR_ARD so that emitOutputAM emits the r/m32 for us. // We basically are doing what emitIns_R_AI does. // TODO-XArch-Cleanup: revisit this. - instrDescAmd idAmdStackLocal; - instrDescAmd* idAmd = &idAmdStackLocal; - *(instrDesc*)idAmd = *(instrDesc*)id; // copy all the "core" fields - memset((BYTE*)idAmd + sizeof(instrDesc), 0, - sizeof(instrDescAmd) - sizeof(instrDesc)); // zero out the tail that wasn't copied + inlineInstrDesc idAmdStackLocal; + instrDescAmd* idAmd = idAmdStackLocal.id(); + *(instrDesc*)idAmd = *(instrDesc*)id; // copy all the "core" fields + + if (m_debugInfoSize > 0) + { + idAmd->idDebugOnlyInfo(id->idDebugOnlyInfo()); + } idAmd->idInsFmt(IF_RWR_ARD); idAmd->idAddr()->iiaAddrMode.amBaseReg = REG_NA; From c0cb6dadc485efce5965868d8040eff51b94123a Mon Sep 17 00:00:00 2001 From: Jakob Botsch Nielsen Date: Sat, 6 Aug 2022 18:00:19 +0200 Subject: [PATCH 19/32] Run jit-format --- src/coreclr/jit/emit.h | 8 +++----- src/coreclr/jit/emitarm.cpp | 2 +- src/coreclr/jit/emitarm64.cpp | 2 +- src/coreclr/jit/emitxarch.cpp | 4 ++-- 4 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/coreclr/jit/emit.h b/src/coreclr/jit/emit.h index 0b1aa86623b57..8806f256a4446 100644 --- a/src/coreclr/jit/emit.h +++ b/src/coreclr/jit/emit.h @@ -1650,17 +1650,15 @@ class emitter }; // TODO-Cleanup: Uses of stack-allocated instrDescs should be refactored to be unnecessary. - template + template struct inlineInstrDesc { private: instrDescDebugInfo* idDebugInfo; - char idStorage[sizeof(T)]; + char idStorage[sizeof(T)]; public: - inlineInstrDesc() - : idDebugInfo(nullptr) - , idStorage() + inlineInstrDesc() : idDebugInfo(nullptr), idStorage() { static_assert_no_msg(offsetof(inlineInstrDesc, idStorage) == sizeof(instrDescDebugInfo*)); } diff --git a/src/coreclr/jit/emitarm.cpp b/src/coreclr/jit/emitarm.cpp index cd7c6933b6bf1..c474fc3d1324c 100644 --- a/src/coreclr/jit/emitarm.cpp +++ b/src/coreclr/jit/emitarm.cpp @@ -7697,7 +7697,7 @@ void emitter::emitDispLargeJmp( // difficult to find bug. inlineInstrDesc idJmp; - instrDescJmp* pidJmp = idJmp.id(); + instrDescJmp* pidJmp = idJmp.id(); pidJmp->idIns(emitJumpKindToIns(emitReverseJumpKind(emitInsToJumpKind(id->idIns())))); // reverse the // conditional diff --git a/src/coreclr/jit/emitarm64.cpp b/src/coreclr/jit/emitarm64.cpp index 4b8a717163892..168e5e3c4af3f 100644 --- a/src/coreclr/jit/emitarm64.cpp +++ b/src/coreclr/jit/emitarm64.cpp @@ -12368,7 +12368,7 @@ void emitter::emitDispLargeJmp( // difficult-to-find bug. inlineInstrDesc idJmp; - instrDescJmp* pidJmp = idJmp.id(); + instrDescJmp* pidJmp = idJmp.id(); const instruction ins = id->idIns(); instruction reverseIns; diff --git a/src/coreclr/jit/emitxarch.cpp b/src/coreclr/jit/emitxarch.cpp index 14c2b92c064bd..a8671faef71e6 100644 --- a/src/coreclr/jit/emitxarch.cpp +++ b/src/coreclr/jit/emitxarch.cpp @@ -13506,8 +13506,8 @@ BYTE* emitter::emitOutputLJ(insGroup* ig, BYTE* dst, instrDesc* i) // We basically are doing what emitIns_R_AI does. // TODO-XArch-Cleanup: revisit this. inlineInstrDesc idAmdStackLocal; - instrDescAmd* idAmd = idAmdStackLocal.id(); - *(instrDesc*)idAmd = *(instrDesc*)id; // copy all the "core" fields + instrDescAmd* idAmd = idAmdStackLocal.id(); + *(instrDesc*)idAmd = *(instrDesc*)id; // copy all the "core" fields if (m_debugInfoSize > 0) { From 8768b0e27d1e7d7c2f381fa9a4282baef2c59f84 Mon Sep 17 00:00:00 2001 From: Jakob Botsch Nielsen Date: Sat, 6 Aug 2022 18:02:32 +0200 Subject: [PATCH 20/32] Ensure alignment in inlineInstrDesc --- src/coreclr/jit/emit.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/jit/emit.h b/src/coreclr/jit/emit.h index 8806f256a4446..4d3b2dd5e8d6b 100644 --- a/src/coreclr/jit/emit.h +++ b/src/coreclr/jit/emit.h @@ -1655,7 +1655,7 @@ class emitter { private: instrDescDebugInfo* idDebugInfo; - char idStorage[sizeof(T)]; + alignas(alignof(T)) char idStorage[sizeof(T)]; public: inlineInstrDesc() : idDebugInfo(nullptr), idStorage() From 29f7c62232e95a7d9b41b9e96a23607d012bb9d1 Mon Sep 17 00:00:00 2001 From: Jakob Botsch Nielsen Date: Sat, 6 Aug 2022 21:29:58 +0200 Subject: [PATCH 21/32] Update emitCheckAlignFitInCurIG --- src/coreclr/jit/emit.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index 5d0c58357f780..a1d5ee897bb44 100644 --- a/src/coreclr/jit/emit.cpp +++ b/src/coreclr/jit/emit.cpp @@ -1529,6 +1529,8 @@ void* emitter::emitAllocAnyInstr(size_t sz, emitAttr opsz) id->idDebugOnlyInfo(info); } + JITDUMP("Allocating %d for ins %d\n", sz, emitInsCount); + /* Store the size and handle the two special values that indicate GCref and ByRef */ @@ -5165,7 +5167,7 @@ void emitter::emitJumpDistBind() // void emitter::emitCheckAlignFitInCurIG(unsigned nAlignInstr) { - unsigned instrDescSize = nAlignInstr * sizeof(instrDescAlign); + size_t instrDescSize = nAlignInstr * (m_debugInfoSize + sizeof(instrDescAlign)); // Ensure that all align instructions fall in same IG. if (emitCurIGfreeNext + instrDescSize >= emitCurIGfreeEndp) From 6a1c872c893c88dacf52138cfd760020c48c3d00 Mon Sep 17 00:00:00 2001 From: Jakob Botsch Nielsen Date: Sat, 6 Aug 2022 21:30:28 +0200 Subject: [PATCH 22/32] Revert "Fix alignment insertion assuming only emitForceNewIG can create new IGs" This reverts commit 7255863f712d97d180a873fd23f139cbc4fd9ecb. --- src/coreclr/jit/emit.cpp | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index a1d5ee897bb44..2ccad265d76e0 100644 --- a/src/coreclr/jit/emit.cpp +++ b/src/coreclr/jit/emit.cpp @@ -5188,13 +5188,32 @@ void emitter::emitCheckAlignFitInCurIG(unsigned nAlignInstr) // void emitter::emitLoopAlign(unsigned paddingBytes, bool isFirstAlign DEBUG_ARG(bool isPlacedBehindJmp)) { - // Insert a pseudo-instruction to ensure that we align - // the next instruction properly + // Determine if 'align' instruction about to be generated will + // fall in current IG or next. + bool alignInstrInNewIG = emitForceNewIG; + + if (!alignInstrInNewIG) + { + // If align fits in current IG, then mark that it contains alignment + // instruction in the end. + emitCurIG->igFlags |= IGF_HAS_ALIGN; + } + + /* Insert a pseudo-instruction to ensure that we align + the next instruction properly */ instrDescAlign* id = emitNewInstrAlign(); - // Mark this IG has alignment in the end, so during emitter we can check the instruction count - // heuristics of all IGs that follows this IG that participate in a loop. - emitCurIG->igFlags |= IGF_HAS_ALIGN; + if (alignInstrInNewIG) + { + // Mark this IG has alignment in the end, so during emitter we can check the instruction count + // heuristics of all IGs that follows this IG that participate in a loop. + emitCurIG->igFlags |= IGF_HAS_ALIGN; + } + else + { + // Otherwise, make sure it was already marked such. + assert(emitCurIG->endsWithAlignInstr()); + } #if defined(TARGET_XARCH) assert(paddingBytes <= MAX_ENCODED_SIZE); From f2668068f3c0c538514bed8abfd641603a0a0b29 Mon Sep 17 00:00:00 2001 From: Jakob Botsch Nielsen Date: Sat, 6 Aug 2022 21:33:38 +0200 Subject: [PATCH 23/32] Oops --- src/coreclr/jit/emit.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index 2ccad265d76e0..5163ea9d4baae 100644 --- a/src/coreclr/jit/emit.cpp +++ b/src/coreclr/jit/emit.cpp @@ -1529,8 +1529,6 @@ void* emitter::emitAllocAnyInstr(size_t sz, emitAttr opsz) id->idDebugOnlyInfo(info); } - JITDUMP("Allocating %d for ins %d\n", sz, emitInsCount); - /* Store the size and handle the two special values that indicate GCref and ByRef */ From 829b019ce207a30f323420ef98f04cd322e552be Mon Sep 17 00:00:00 2001 From: Jakob Botsch Nielsen Date: Sat, 6 Aug 2022 21:42:54 +0200 Subject: [PATCH 24/32] Minor assertion nit --- src/coreclr/jit/emit.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/coreclr/jit/emit.h b/src/coreclr/jit/emit.h index 4d3b2dd5e8d6b..a0670527c6408 100644 --- a/src/coreclr/jit/emit.h +++ b/src/coreclr/jit/emit.h @@ -1660,7 +1660,8 @@ class emitter public: inlineInstrDesc() : idDebugInfo(nullptr), idStorage() { - static_assert_no_msg(offsetof(inlineInstrDesc, idStorage) == sizeof(instrDescDebugInfo*)); + static_assert_no_msg((offsetof(inlineInstrDesc, idStorage) - sizeof(instrDescDebugInfo*)) == + offsetof(inlineInstrDesc, idDebugInfo)); } T* id() From 13190b8dd2d688ba66afe9a1c4d64202d7cb7f44 Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Mon, 8 Aug 2022 11:35:48 +0200 Subject: [PATCH 25/32] Update codegencommon.cpp --- src/coreclr/jit/codegencommon.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/jit/codegencommon.cpp b/src/coreclr/jit/codegencommon.cpp index 894c61d693143..bd3396e1ebafc 100644 --- a/src/coreclr/jit/codegencommon.cpp +++ b/src/coreclr/jit/codegencommon.cpp @@ -2066,7 +2066,7 @@ void CodeGen::genEmitMachineCode() #else if (compiler->opts.disAsm) { - printf("\n; Total bytes of code %d\n", codeSize); + printf("\n; Total bytes of code %d\n\n", codeSize); } #endif From b075a03dc02adb2d32609cd33c626f9ea9dbf0df Mon Sep 17 00:00:00 2001 From: Jakob Botsch Nielsen Date: Mon, 8 Aug 2022 11:45:52 +0200 Subject: [PATCH 26/32] Tiny optimization --- src/coreclr/jit/emit.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index 5163ea9d4baae..18071807873f8 100644 --- a/src/coreclr/jit/emit.cpp +++ b/src/coreclr/jit/emit.cpp @@ -1481,19 +1481,19 @@ void* emitter::emitAllocAnyInstr(size_t sz, emitAttr opsz) // Make sure we have enough space for the new instruction. // `igInsCnt` is currently a byte, so we can't have more than 255 instructions in a single insGroup. - sz += m_debugInfoSize; + size_t fullSize = sz + m_debugInfoSize; - if ((emitCurIGfreeNext + sz >= emitCurIGfreeEndp) || emitForceNewIG || (emitCurIGinsCnt >= 255)) + if ((emitCurIGfreeNext + fullSize >= emitCurIGfreeEndp) || emitForceNewIG || (emitCurIGinsCnt >= 255)) { emitNxtIG(true); } /* Grab the space for the instruction */ - memset(emitCurIGfreeNext, 0, sz); - emitLastIns = id = (instrDesc*)(emitCurIGfreeNext + m_debugInfoSize); - emitCurIGfreeNext += sz; + emitCurIGfreeNext += fullSize; + + memset(id, 0, sz); assert(sz >= sizeof(void*)); @@ -1519,7 +1519,7 @@ void* emitter::emitAllocAnyInstr(size_t sz, emitAttr opsz) { instrDescDebugInfo* info = (instrDescDebugInfo*)emitGetMem(sizeof(*info)); info->idNum = emitInsCount; - info->idSize = sz - m_debugInfoSize; + info->idSize = sz; info->idVarRefOffs = 0; info->idMemCookie = 0; info->idFlags = GTF_EMPTY; From d6759c2825850050021002cb1644630059f80d0b Mon Sep 17 00:00:00 2001 From: Jakob Botsch Nielsen Date: Mon, 8 Aug 2022 11:45:58 +0200 Subject: [PATCH 27/32] Switch a couple of checks to m_debugInfoSize > 0 --- src/coreclr/jit/emitarm64.cpp | 9 ++++----- src/coreclr/jit/emitxarch.cpp | 6 +----- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/coreclr/jit/emitarm64.cpp b/src/coreclr/jit/emitarm64.cpp index 168e5e3c4af3f..c682726c402b6 100644 --- a/src/coreclr/jit/emitarm64.cpp +++ b/src/coreclr/jit/emitarm64.cpp @@ -8700,14 +8700,13 @@ void emitter::emitIns_Call(EmitCallType callType, VarSetOps::ToString(emitComp, ((instrDescCGCA*)id)->idcGCvars)); } } - id->idDebugOnlyInfo()->idCallSig = sigInfo; - id->idDebugOnlyInfo()->idMemCookie = (size_t)methHnd; // method token -#else - if (emitComp->opts.disAsm) +#endif + + if (m_debugInfoSize > 0) { + INDEBUG(id->idDebugOnlyInfo()->idCallSig = sigInfo); id->idDebugOnlyInfo()->idMemCookie = (size_t)methHnd; // method token } -#endif #ifdef LATE_DISASM if (addr != nullptr) diff --git a/src/coreclr/jit/emitxarch.cpp b/src/coreclr/jit/emitxarch.cpp index a8671faef71e6..1e645ad73fdb0 100644 --- a/src/coreclr/jit/emitxarch.cpp +++ b/src/coreclr/jit/emitxarch.cpp @@ -4368,14 +4368,10 @@ void emitter::emitIns_IJ(emitAttr attr, regNumber reg, unsigned base) id->idAddr()->iiaAddrMode.amIndxReg = reg; id->idAddr()->iiaAddrMode.amScale = emitter::OPSZP; -#ifdef DEBUG - id->idDebugOnlyInfo()->idMemCookie = base; -#else - if (emitComp->opts.disAsm) + if (m_debugInfoSize > 0) { id->idDebugOnlyInfo()->idMemCookie = base; } -#endif id->idCodeSize(sz); From 00e754b976dff9f419121eaf83d9689fca3d459e Mon Sep 17 00:00:00 2001 From: Jakob Botsch Nielsen Date: Mon, 8 Aug 2022 11:49:25 +0200 Subject: [PATCH 28/32] Move assert back --- src/coreclr/jit/emit.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index 18071807873f8..35b9586ffa328 100644 --- a/src/coreclr/jit/emit.cpp +++ b/src/coreclr/jit/emit.cpp @@ -1493,9 +1493,8 @@ void* emitter::emitAllocAnyInstr(size_t sz, emitAttr opsz) emitLastIns = id = (instrDesc*)(emitCurIGfreeNext + m_debugInfoSize); emitCurIGfreeNext += fullSize; - memset(id, 0, sz); - assert(sz >= sizeof(void*)); + memset(id, 0, sz); // These fields should have been zero-ed by the above assert(id->idReg1() == regNumber(0)); From 318f2756c7d74235930a73ac6ca05a453c9af804 Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Mon, 8 Aug 2022 12:14:54 +0200 Subject: [PATCH 29/32] Update emitarm64.cpp --- src/coreclr/jit/emitarm64.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/jit/emitarm64.cpp b/src/coreclr/jit/emitarm64.cpp index c682726c402b6..f4e5896bdb533 100644 --- a/src/coreclr/jit/emitarm64.cpp +++ b/src/coreclr/jit/emitarm64.cpp @@ -8705,7 +8705,7 @@ void emitter::emitIns_Call(EmitCallType callType, if (m_debugInfoSize > 0) { INDEBUG(id->idDebugOnlyInfo()->idCallSig = sigInfo); - id->idDebugOnlyInfo()->idMemCookie = (size_t)methHnd; // method token + id->idDebugOnlyInfo()->idMemCookie = (size_t)methHnd; // method token } #ifdef LATE_DISASM From 963596d026727d0b1f5559b1a954a9665b125d96 Mon Sep 17 00:00:00 2001 From: Jakob Botsch Nielsen Date: Tue, 9 Aug 2022 19:50:10 +0200 Subject: [PATCH 30/32] Add emitFirstInstrDesc and emitAdvanceInstrDesc Consolidate most uses of m_debugInfoSize into these functions. --- src/coreclr/jit/emit.cpp | 66 +++++++++++++++++++++++++++++----------- src/coreclr/jit/emit.h | 2 ++ 2 files changed, 51 insertions(+), 17 deletions(-) diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index 35b9586ffa328..25082cbc7bc2d 100644 --- a/src/coreclr/jit/emit.cpp +++ b/src/coreclr/jit/emit.cpp @@ -2839,12 +2839,12 @@ void emitter::emitGetInstrDescs(insGroup* ig, instrDesc** id, int* insCnt) assert(!(ig->igFlags & IGF_PLACEHOLDER)); if (ig == emitCurIG) { - *id = (instrDesc*)(emitCurIGfreeBase + m_debugInfoSize); + *id = emitFirstInstrDesc(emitCurIGfreeBase); *insCnt = emitCurIGinsCnt; } else { - *id = (instrDesc*)(ig->igData + m_debugInfoSize); + *id = emitFirstInstrDesc(ig->igData); *insCnt = ig->igInsCnt; } @@ -2933,7 +2933,7 @@ bool emitter::emitGetLocationInfo(emitLocation* emitLoc, int i; for (i = 0; i != insNum; ++i) { - castto(id, BYTE*) += emitSizeOfInsDsc(id) + m_debugInfoSize; + emitAdvanceInstrDesc(&id, emitSizeOfInsDsc(id)); } // Return the info we found @@ -2961,7 +2961,7 @@ bool emitter::emitNextID(insGroup*& ig, instrDesc*& id, int& insRemaining) { if (insRemaining > 0) { - castto(id, BYTE*) += emitSizeOfInsDsc(id) + m_debugInfoSize; + emitAdvanceInstrDesc(&id, emitSizeOfInsDsc(id)); --insRemaining; return true; } @@ -3803,7 +3803,7 @@ void emitter::emitDispIG(insGroup* ig, insGroup* igPrev, bool verbose) if (verbose) { - BYTE* ins = ig->igData + m_debugInfoSize; + instrDesc* id = emitFirstInstrDesc(ig->igData); UNATIVE_OFFSET ofs = ig->igOffs; unsigned cnt = ig->igInsCnt; @@ -3813,8 +3813,6 @@ void emitter::emitDispIG(insGroup* ig, insGroup* igPrev, bool verbose) do { - instrDesc* id = (instrDesc*)ins; - #ifdef TARGET_XARCH if (emitJmpInstHasNoCode(id)) { @@ -3827,8 +3825,8 @@ void emitter::emitDispIG(insGroup* ig, insGroup* igPrev, bool verbose) #endif emitDispIns(id, false, true, false, ofs, nullptr, 0, ig); - ins += emitSizeOfInsDsc(id) + m_debugInfoSize; ofs += id->idCodeSize(); + emitAdvanceInstrDesc(&id, emitSizeOfInsDsc(id)); } while (--cnt); @@ -3922,6 +3920,40 @@ void emitter::emitDispJumpList() #endif // DEBUG +//------------------------------------------------------------------------ +// emitSizeOfInsDscAndDebugInfo: +// Get the size of the instrDesc plus the size of optional debug info that +// may come before it (or before the next instrDesc). +// +// Parameters: +// id - the instrDesc +// +// Returns: +// The (variable) size of the instrDesc plus the debug info size. +// +void emitter::emitAdvanceInstrDesc(instrDesc** id, size_t idSize) +{ + assert(idSize == emitSizeOfInsDsc(id)); + char* idReinterp = reinterpret_cast(*id); + *id = reinterpret_cast(idReinterp + idSize + m_debugInfoSize); +} + +//------------------------------------------------------------------------ +// emitFirstInstrDesc: +// Given a pointer to an instruction desc buffer, return a pointer to the +// first instrDesc taking optional debug info into account. +// +// Parameters: +// idData - the data +// +// Returns: +// A pointer to the first instrDesc. +// +instrDesc* emitter::emitFirstInstrDesc(BYTE* idData) +{ + return reinterpret_cast(idData + m_debugInfoSize); +} + /***************************************************************************** * * Issue the given instruction. Basically, this is just a thin wrapper around @@ -4245,11 +4277,10 @@ void emitter::emitRemoveJumpToNextInst() assert(instructionCount > 0); instrDesc* id = nullptr; { - BYTE* dataPtr = jmpGroup->igData + m_debugInfoSize; + id = emitFirstInstrDesc(jmpGroup->igData); while (instructionCount > 0) { - id = (instrDesc*)dataPtr; - dataPtr += emitSizeOfInsDsc(id) + m_debugInfoSize; + emitAdvanceInstrDesc(&id, emitSizeOfInsDsc(id)); instructionCount -= 1; } } @@ -6649,7 +6680,7 @@ unsigned emitter::emitEndCodeGen(Compiler* comp, // if it were the instruction following a call. emitGenGCInfoIfFuncletRetTarget(ig, cp); - instrDesc* id = (instrDesc*)(ig->igData + m_debugInfoSize); + instrDesc* id = emitFirstInstrDesc(ig->igData); #ifdef DEBUG /* Print the IG label, but only if it is a branch label */ @@ -6825,7 +6856,8 @@ unsigned emitter::emitEndCodeGen(Compiler* comp, #endif - castto(id, BYTE*) += emitIssue1Instr(ig, id, &cp) + m_debugInfoSize; + size_t insSize = emitIssue1Instr(ig, id, &cp); + emitAdvanceInstrDesc(&id, insSize); #ifdef DEBUG // Print the alignment boundary @@ -7191,7 +7223,7 @@ void emitter::emitGenGCInfoIfFuncletRetTarget(insGroup* ig, BYTE* cp) unsigned emitter::emitFindInsNum(insGroup* ig, instrDesc* idMatch) { - instrDesc* id = (instrDesc*)(ig->igData + m_debugInfoSize); + instrDesc* id = emitFirstInstrDesc(ig->igData); // Check if we are the first instruction in the group if (id == idMatch) @@ -7205,7 +7237,7 @@ unsigned emitter::emitFindInsNum(insGroup* ig, instrDesc* idMatch) while (insRemaining > 0) { - castto(id, BYTE*) += emitSizeOfInsDsc(id) + m_debugInfoSize; + emitAdvanceInstrDesc(&id, emitSizeOfInsDsc(id)); insNum++; insRemaining--; @@ -7227,7 +7259,7 @@ unsigned emitter::emitFindInsNum(insGroup* ig, instrDesc* idMatch) UNATIVE_OFFSET emitter::emitFindOffset(insGroup* ig, unsigned insNum) { - instrDesc* id = (instrDesc*)(ig->igData + m_debugInfoSize); + instrDesc* id = emitFirstInstrDesc(ig->igData); UNATIVE_OFFSET of = 0; #ifdef DEBUG @@ -7242,7 +7274,7 @@ UNATIVE_OFFSET emitter::emitFindOffset(insGroup* ig, unsigned insNum) { of += id->idCodeSize(); - castto(id, BYTE*) += emitSizeOfInsDsc(id) + m_debugInfoSize; + emitAdvanceInstrDesc(&id, emitSizeOfInsDsc(id)); insNum--; } diff --git a/src/coreclr/jit/emit.h b/src/coreclr/jit/emit.h index a0670527c6408..c5d245ba83c66 100644 --- a/src/coreclr/jit/emit.h +++ b/src/coreclr/jit/emit.h @@ -1927,6 +1927,8 @@ class emitter unsigned int emitCounts_INS_OPTS_J; #endif // TARGET_LOONGARCH64 + instrDesc* emitFirstInstrDesc(BYTE* idData); + void emitAdvanceInstrDesc(instrDesc** id, size_t idSize); size_t emitIssue1Instr(insGroup* ig, instrDesc* id, BYTE** dp); size_t emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp); From 840f26ec54ffce8a0264ee9efe953e407978821c Mon Sep 17 00:00:00 2001 From: Jakob Botsch Nielsen Date: Tue, 9 Aug 2022 20:04:33 +0200 Subject: [PATCH 31/32] Fix function header --- src/coreclr/jit/emit.cpp | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index 25082cbc7bc2d..95423067a9ead 100644 --- a/src/coreclr/jit/emit.cpp +++ b/src/coreclr/jit/emit.cpp @@ -3921,21 +3921,19 @@ void emitter::emitDispJumpList() #endif // DEBUG //------------------------------------------------------------------------ -// emitSizeOfInsDscAndDebugInfo: -// Get the size of the instrDesc plus the size of optional debug info that -// may come before it (or before the next instrDesc). +// emitAdvanceInstrDesc: +// Advance to the next instrDesc in the buffer of instrDescs, taking optional +// debug info into account. // // Parameters: -// id - the instrDesc -// -// Returns: -// The (variable) size of the instrDesc plus the debug info size. +// id - the pointer to the current instrDesc +// idSize - the size of the current instrDesc // void emitter::emitAdvanceInstrDesc(instrDesc** id, size_t idSize) { assert(idSize == emitSizeOfInsDsc(id)); - char* idReinterp = reinterpret_cast(*id); - *id = reinterpret_cast(idReinterp + idSize + m_debugInfoSize); + char* idData = reinterpret_cast(*id); + *id = reinterpret_cast(idData + idSize + m_debugInfoSize); } //------------------------------------------------------------------------ From 4057d73a3783ff3a1433c7640b67125af5a94ddc Mon Sep 17 00:00:00 2001 From: Jakob Botsch Nielsen Date: Tue, 9 Aug 2022 20:24:57 +0200 Subject: [PATCH 32/32] Fix build, fix bad refactor --- src/coreclr/jit/emit.cpp | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index 95423067a9ead..b9130fa443efd 100644 --- a/src/coreclr/jit/emit.cpp +++ b/src/coreclr/jit/emit.cpp @@ -3931,7 +3931,7 @@ void emitter::emitDispJumpList() // void emitter::emitAdvanceInstrDesc(instrDesc** id, size_t idSize) { - assert(idSize == emitSizeOfInsDsc(id)); + assert(idSize == emitSizeOfInsDsc(*id)); char* idData = reinterpret_cast(*id); *id = reinterpret_cast(idData + idSize + m_debugInfoSize); } @@ -3947,7 +3947,7 @@ void emitter::emitAdvanceInstrDesc(instrDesc** id, size_t idSize) // Returns: // A pointer to the first instrDesc. // -instrDesc* emitter::emitFirstInstrDesc(BYTE* idData) +emitter::instrDesc* emitter::emitFirstInstrDesc(BYTE* idData) { return reinterpret_cast(idData + m_debugInfoSize); } @@ -4273,14 +4273,10 @@ void emitter::emitRemoveJumpToNextInst() #ifdef DEBUG unsigned instructionCount = jmpGroup->igInsCnt; assert(instructionCount > 0); - instrDesc* id = nullptr; + instrDesc* id = emitFirstInstrDesc(jmpGroup->igData); + for (unsigned i = 0; i < instructionCount - 1; i++) { - id = emitFirstInstrDesc(jmpGroup->igData); - while (instructionCount > 0) - { - emitAdvanceInstrDesc(&id, emitSizeOfInsDsc(id)); - instructionCount -= 1; - } + emitAdvanceInstrDesc(&id, emitSizeOfInsDsc(id)); } assert(id != nullptr); if (jmp != id)