Skip to content

Commit

Permalink
Add JitDisasmWithDebugInfo (#61780)
Browse files Browse the repository at this point in the history
Add COMPlus_JitDisasmWithDebugInfo. When set and in verbose/disasm mode,
JIT will display inline comments with debug information before the
instructions that debug info applies to. Change superpmi with
--debuginfo to use this mode. Also small change to dotnet-pgo flow graph
dump to write offsets in the same format.
  • Loading branch information
jakobbotsch committed Nov 19, 2021
1 parent 4269db9 commit c159108
Show file tree
Hide file tree
Showing 12 changed files with 105 additions and 42 deletions.
5 changes: 4 additions & 1 deletion src/coreclr/jit/codegenlinear.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,9 @@ void CodeGen::genCodeForBBlist()
}
}
}

bool addPreciseMappings =
(JitConfig.JitDumpPreciseDebugInfoFile() != nullptr) || (JitConfig.JitDisasmWithDebugInfo() != 0);
#endif // DEBUG

DebugInfo currentDI;
Expand All @@ -443,7 +446,7 @@ void CodeGen::genCodeForBBlist()
}

#ifdef DEBUG
if ((JitConfig.JitDumpPreciseDebugInfoFile() != nullptr) && ilOffset->gtStmtDI.IsValid())
if (addPreciseMappings && ilOffset->gtStmtDI.IsValid())
{
genAddPreciseIPMappingHere(ilOffset->gtStmtDI);
}
Expand Down
43 changes: 40 additions & 3 deletions src/coreclr/jit/emit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3381,15 +3381,24 @@ const size_t hexEncodingSize = 11;

#ifdef DEBUG
//------------------------------------------------------------------------
// emitDispInsIndent: Print indentation corresponding to an instruction's
// indentation.
//
void emitter::emitDispInsIndent()
{
size_t indent = emitComp->opts.disDiffable ? basicIndent : basicIndent + hexEncodingSize;
printf("%.*s", indent, " ");
}
//------------------------------------------------------------------------
// emitDispGCDeltaTitle: Print an appropriately indented title for a GC info delta
//
// Arguments:
// title - The type of GC info delta we're printing
//
void emitter::emitDispGCDeltaTitle(const char* title)
{
size_t indent = emitComp->opts.disDiffable ? basicIndent : basicIndent + hexEncodingSize;
printf("%.*s; %s", indent, " ", title);
emitDispInsIndent();
printf("; %s", title);
}

//------------------------------------------------------------------------
Expand Down Expand Up @@ -6233,7 +6242,8 @@ unsigned emitter::emitEndCodeGen(Compiler* comp,
#define DEFAULT_CODE_BUFFER_INIT 0xcc

#ifdef DEBUG
*instrCount = 0;
*instrCount = 0;
PreciseIPMapping* nextMapping = emitComp->genPreciseIPMappingsHead;
#endif
for (insGroup* ig = emitIGlist; ig != nullptr; ig = ig->igNext)
{
Expand Down Expand Up @@ -6402,6 +6412,33 @@ unsigned emitter::emitEndCodeGen(Compiler* comp,
#ifdef DEBUG
size_t curInstrAddr = (size_t)cp;
instrDesc* curInstrDesc = id;

if ((emitComp->opts.disAsm || emitComp->verbose) && (JitConfig.JitDisasmWithDebugInfo() != 0))
{
UNATIVE_OFFSET curCodeOffs = emitCurCodeOffs(cp);
while (nextMapping != nullptr)
{
UNATIVE_OFFSET mappingOffs = nextMapping->nativeLoc.CodeOffset(this);

if (mappingOffs > curCodeOffs)
{
// Still haven't reached instruction that next mapping belongs to.
break;
}

// We reached the mapping or went past it.
if (mappingOffs == curCodeOffs)
{
emitDispInsIndent();
printf("; ");
nextMapping->debugInfo.Dump(true);
printf("\n");
}

nextMapping = nextMapping->next;
}
}

#endif

castto(id, BYTE*) += emitIssue1Instr(ig, id, &cp);
Expand Down
9 changes: 9 additions & 0 deletions src/coreclr/jit/emit.h
Original file line number Diff line number Diff line change
Expand Up @@ -1548,6 +1548,7 @@ class emitter
regPtrDsc* debugPrevRegPtrDsc;
regMaskTP debugPrevGCrefRegs;
regMaskTP debugPrevByrefRegs;
void emitDispInsIndent();
void emitDispGCDeltaTitle(const char* title);
void emitDispGCRegDelta(const char* title, regMaskTP prevRegs, regMaskTP curRegs);
void emitDispGCVarDelta();
Expand All @@ -1563,6 +1564,14 @@ class emitter
void emitDispInsAddr(BYTE* code);
void emitDispInsOffs(unsigned offs, bool doffs);
void emitDispInsHex(instrDesc* id, BYTE* code, size_t sz);
void emitDispIns(instrDesc* id,
bool isNew,
bool doffs,
bool asmfm,
unsigned offs = 0,
BYTE* pCode = nullptr,
size_t sz = 0,
insGroup* ig = nullptr);

#else // !DEBUG
#define emitVarRefOffs 0
Expand Down
16 changes: 16 additions & 0 deletions src/coreclr/jit/emitarm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7670,6 +7670,22 @@ void emitter::emitDispInsHelp(
printf("\n");
}

//--------------------------------------------------------------------
// emitDispIns: Dump the given instruction to jitstdout.
//
// Arguments:
// id - The instruction
// isNew - Whether the instruction is newly generated (before encoding).
// doffs - If true, always display the passed-in offset.
// asmfm - Whether the instruction should be displayed in assembly format.
// If false some additional information may be printed for the instruction.
// offset - The offset of the instruction. Only displayed if doffs is true or if
// !isNew && !asmfm.
// code - Pointer to the actual code, used for displaying the address and encoded bytes
// if turned on.
// sz - The size of the instruction, used to display the encoded bytes.
// ig - The instruction group containing the instruction.
//
void emitter::emitDispIns(
instrDesc* id, bool isNew, bool doffs, bool asmfm, unsigned offset, BYTE* code, size_t sz, insGroup* ig)
{
Expand Down
8 changes: 0 additions & 8 deletions src/coreclr/jit/emitarm.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,6 @@ void emitDispInsHelp(instrDesc* id,
BYTE* code = 0,
size_t sz = 0,
insGroup* ig = NULL);
void emitDispIns(instrDesc* id,
bool isNew,
bool doffs,
bool asmfm,
unsigned offs = 0,
BYTE* code = 0,
size_t sz = 0,
insGroup* ig = NULL);

#endif // DEBUG

Expand Down
21 changes: 16 additions & 5 deletions src/coreclr/jit/emitarm64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12228,11 +12228,22 @@ void emitter::emitDispInsHex(instrDesc* id, BYTE* code, size_t sz)
}
}

/****************************************************************************
*
* Display the given instruction.
*/

//--------------------------------------------------------------------
// emitDispIns: Dump the given instruction to jitstdout.
//
// Arguments:
// id - The instruction
// isNew - Whether the instruction is newly generated (before encoding).
// doffs - If true, always display the passed-in offset.
// asmfm - Whether the instruction should be displayed in assembly format.
// If false some additional information may be printed for the instruction.
// offset - The offset of the instruction. Only displayed if doffs is true or if
// !isNew && !asmfm.
// code - Pointer to the actual code, used for displaying the address and encoded bytes
// if turned on.
// sz - The size of the instruction, used to display the encoded bytes.
// ig - The instruction group containing the instruction.
//
void emitter::emitDispIns(
instrDesc* id, bool isNew, bool doffs, bool asmfm, unsigned offset, BYTE* pCode, size_t sz, insGroup* ig)
{
Expand Down
9 changes: 0 additions & 9 deletions src/coreclr/jit/emitarm64.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,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);

void emitDispIns(instrDesc* id,
bool isNew,
bool doffs,
bool asmfm,
unsigned offs = 0,
BYTE* pCode = 0,
size_t sz = 0,
insGroup* ig = NULL);
#endif // DEBUG

/************************************************************************/
Expand Down
21 changes: 16 additions & 5 deletions src/coreclr/jit/emitxarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8722,11 +8722,22 @@ void emitter::emitDispInsHex(instrDesc* id, BYTE* code, size_t sz)
}
}

/*****************************************************************************
*
* Display the given instruction.
*/

//--------------------------------------------------------------------
// emitDispIns: Dump the given instruction to jitstdout.
//
// Arguments:
// id - The instruction
// isNew - Whether the instruction is newly generated (before encoding).
// doffs - If true, always display the passed-in offset.
// asmfm - Whether the instruction should be displayed in assembly format.
// If false some additional information may be printed for the instruction.
// offset - The offset of the instruction. Only displayed if doffs is true or if
// !isNew && !asmfm.
// code - Pointer to the actual code, used for displaying the address and encoded bytes
// if turned on.
// sz - The size of the instruction, used to display the encoded bytes.
// ig - The instruction group containing the instruction. Not used on xarch.
//
void emitter::emitDispIns(
instrDesc* id, bool isNew, bool doffs, bool asmfm, unsigned offset, BYTE* code, size_t sz, insGroup* ig)
{
Expand Down
9 changes: 0 additions & 9 deletions src/coreclr/jit/emitxarch.h
Original file line number Diff line number Diff line change
Expand Up @@ -222,15 +222,6 @@ void emitDispReloc(ssize_t value);
void emitDispAddrMode(instrDesc* id, bool noDetail = false);
void emitDispShift(instruction ins, int cnt = 0);

void emitDispIns(instrDesc* id,
bool isNew,
bool doffs,
bool asmfm,
unsigned offs = 0,
BYTE* code = nullptr,
size_t sz = 0,
insGroup* ig = nullptr);

const char* emitXMMregName(unsigned reg);
const char* emitYMMregName(unsigned reg);

Expand Down
1 change: 1 addition & 0 deletions src/coreclr/jit/jitconfigvalues.h
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@ CONFIG_INTEGER(JitDumpFgBlockID, W("JitDumpFgBlockID"), 0) // 0 == display block
// bbNum and bbID

CONFIG_STRING(JitDumpPreciseDebugInfoFile, W("JitDumpPreciseDebugInfoFile"))
CONFIG_INTEGER(JitDisasmWithDebugInfo, W("JitDisasmWithDebugInfo"), 0)

CONFIG_STRING(JitLateDisasmTo, W("JITLateDisasmTo"))
CONFIG_STRING(JitRange, W("JitRange"))
Expand Down
3 changes: 2 additions & 1 deletion src/coreclr/scripts/superpmi.py
Original file line number Diff line number Diff line change
Expand Up @@ -1363,7 +1363,8 @@ def replay_with_asm_diffs(self):
if self.coreclr_args.debuginfo:
asm_complus_vars.update({
"COMPlus_JitDebugDump": "*",
"COMPlus_NgenDebugDump": "*" })
"COMPlus_NgenDebugDump": "*",
"COMPlus_JitDisasmWithDebugInfo": "1" })

jit_dump_complus_vars = asm_complus_vars.copy()
jit_dump_complus_vars.update({
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/tools/dotnet-pgo/PgoCompareMethodFlowGraph.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ string createWeightLabel(long weight1, long totalWeight1, long weight2, long tot

string getLabel(PgoCompareMethodBasicBlock bb)
{
string label = $"@ {bb.ILOffset:000}";
string label = $"@ {bb.ILOffset:x3}";
if (ProfilesHadBasicBlocks && (totalBlockCount1 != 0 || totalBlockCount2 != 0))
{
label += $"\\n{createWeightLabel(bb.BlockCount1, totalBlockCount1, bb.BlockCount2, totalBlockCount2)}";
Expand Down

0 comments on commit c159108

Please sign in to comment.