Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix some missing debug info #62018

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/coreclr/jit/block.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -774,15 +774,15 @@ bool BasicBlock::CloneBlockState(

for (Statement* const fromStmt : from->Statements())
{
auto newExpr = compiler->gtCloneExpr(fromStmt->GetRootNode(), GTF_EMPTY, varNum, varVal);
GenTree* newExpr = compiler->gtCloneExpr(fromStmt->GetRootNode(), GTF_EMPTY, varNum, varVal);
if (!newExpr)
{
// gtCloneExpr doesn't handle all opcodes, so may fail to clone a statement.
// When that happens, it returns nullptr; abandon the rest of this block and
// return `false` to the caller to indicate that cloning was unsuccessful.
return false;
}
compiler->fgInsertStmtAtEnd(to, compiler->fgNewStmtFromTree(newExpr));
compiler->fgInsertStmtAtEnd(to, compiler->fgNewStmtFromTree(newExpr, fromStmt->GetDebugInfo()));
}
return true;
}
Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/jit/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -4508,10 +4508,10 @@ class Compiler
void impEndTreeList(BasicBlock* block, Statement* firstStmt, Statement* lastStmt);
void impEndTreeList(BasicBlock* block);
void impAppendStmtCheck(Statement* stmt, unsigned chkLevel);
void impAppendStmt(Statement* stmt, unsigned chkLevel);
void impAppendStmt(Statement* stmt, unsigned chkLevel, bool checkConsumedDebugInfo = true);
void impAppendStmt(Statement* stmt);
void impInsertStmtBefore(Statement* stmt, Statement* stmtBefore);
Statement* impAppendTree(GenTree* tree, unsigned chkLevel, const DebugInfo& di);
Statement* impAppendTree(GenTree* tree, unsigned chkLevel, const DebugInfo& di, bool checkConsumedDebugInfo = true);
void impInsertTreeBefore(GenTree* tree, const DebugInfo& di, Statement* stmtBefore);
void impAssignTempGen(unsigned tmp,
GenTree* val,
Expand Down
62 changes: 44 additions & 18 deletions src/coreclr/jit/importer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -527,14 +527,22 @@ inline void Compiler::impAppendStmtCheck(Statement* stmt, unsigned chkLevel)
#endif
}

/*****************************************************************************
*
* Append the given statement to the current block's tree list.
* [0..chkLevel) is the portion of the stack which we will check for
* interference with stmt and spill if needed.
*/

inline void Compiler::impAppendStmt(Statement* stmt, unsigned chkLevel)
//------------------------------------------------------------------------
// impAppendStmt: Append the given statement to the current block's tree list.
//
//
// Arguments:
// stmt - The statement to add.
// chkLevel - [0..chkLevel) is the portion of the stack which we will check
// for interference with stmt and spill if needed.
// checkConsumedDebugInfo - Whether to check for consumption of impCurStmtDI. impCurStmtDI
// marks the debug info of the current boundary and is set when we
// start importing IL at that boundary. If this parameter is true,
// then the function checks if 'stmt' has been associated with the
// current boundary, and if so, clears it so that we do not attach
// it to more upcoming statements.
//
void Compiler::impAppendStmt(Statement* stmt, unsigned chkLevel, bool checkConsumedDebugInfo)
{
if (chkLevel == (unsigned)CHECK_SPILL_ALL)
{
Expand Down Expand Up @@ -620,7 +628,8 @@ inline void Compiler::impAppendStmt(Statement* stmt, unsigned chkLevel)
// offsets here instead of debug info, since we do not set the "is call"
// bit in impCurStmtDI.

if (impLastStmt->GetDebugInfo().GetLocation().GetOffset() == impCurStmtDI.GetLocation().GetOffset())
if (checkConsumedDebugInfo &&
(impLastStmt->GetDebugInfo().GetLocation().GetOffset() == impCurStmtDI.GetLocation().GetOffset()))
{
impCurStmtOffsSet(BAD_IL_OFFSET);
}
Expand Down Expand Up @@ -709,13 +718,26 @@ inline void Compiler::impInsertStmtBefore(Statement* stmt, Statement* stmtBefore
stmtBefore->SetPrevStmt(stmt);
}

/*****************************************************************************
*
* Append the given expression tree to the current block's tree list.
* Return the newly created statement.
*/

Statement* Compiler::impAppendTree(GenTree* tree, unsigned chkLevel, const DebugInfo& di)
//------------------------------------------------------------------------
// impAppendTree: Append the given expression tree to the current block's tree list.
//
//
// Arguments:
// tree - The tree that will be the root of the newly created statement.
// chkLevel - [0..chkLevel) is the portion of the stack which we will check
// for interference with stmt and spill if needed.
// di - Debug information to associate with the statement.
// checkConsumedDebugInfo - Whether to check for consumption of impCurStmtDI. impCurStmtDI
// marks the debug info of the current boundary and is set when we
// start importing IL at that boundary. If this parameter is true,
// then the function checks if 'stmt' has been associated with the
// current boundary, and if so, clears it so that we do not attach
// it to more upcoming statements.
//
// Return value:
// The newly created statement.
//
Statement* Compiler::impAppendTree(GenTree* tree, unsigned chkLevel, const DebugInfo& di, bool checkConsumedDebugInfo)
{
assert(tree);

Expand All @@ -725,7 +747,7 @@ Statement* Compiler::impAppendTree(GenTree* tree, unsigned chkLevel, const Debug

/* Append the statement to the current block's stmt list */

impAppendStmt(stmt, chkLevel);
impAppendStmt(stmt, chkLevel, checkConsumedDebugInfo);

return stmt;
}
Expand Down Expand Up @@ -9785,7 +9807,11 @@ var_types Compiler::impImportCall(OPCODE opcode,
assert(!isFatPointerCandidate); // We should not try to inline calli.

// Make the call its own tree (spill the stack if needed).
impAppendTree(call, (unsigned)CHECK_SPILL_ALL, impCurStmtDI);
// Do not consume the debug info here. This is particularly
// important if we give up on the inline, in which case the
// call will typically end up in the statement that contains
// the GT_RET_EXPR that we leave on the stack.
impAppendTree(call, (unsigned)CHECK_SPILL_ALL, impCurStmtDI, false);

// TODO: Still using the widened type.
GenTree* retExpr = gtNewInlineCandidateReturnExpr(call, genActualType(callRetTyp), compCurBB->bbFlags);
Expand Down
5 changes: 2 additions & 3 deletions src/tests/JIT/Directed/debugging/debuginfo/tests.il
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
{
.custom instance void [attribute]ExpectedILMappings::.ctor() = {
property int32[] Debug = int32[2]( 0 6 )
// property int32[] Opts = int32[2]( 0 6 ) // Currently the 6 will not get a mapping due to a bug
property int32[] Opts = int32[2]( 0 6 )
}
.maxstack 2
.locals init (int32 V_0)
Expand Down Expand Up @@ -97,8 +97,7 @@
// as this is used for the managed-ret-val feature, but the debugger filters out these mappings and does not
// report them in the ETW event. We should probably change this, those mappings should be useful in any case.
property int32[] Debug = int32[10]( 0x0 0x6 0xe 0x12 0x1a 0x1c 0x24 0x28 0x2c 0x34 )
// some entries commented due to a bug with some failing inline candidates
property int32[] Opts = int32[3]( 0x0 0x6 /* 0x12 */ 0x1c /* 0x2c */ )
property int32[] Opts = int32[5]( 0x0 0x6 0x12 0x1c 0x2c )
}
.maxstack 2
.locals init (int32 V_0)
Expand Down