Skip to content

Some more precise debug info improvements - #61419

Merged
jakobbotsch merged 3 commits into
dotnet:mainfrom
jakobbotsch:more-debug-info
Nov 11, 2021
Merged

Some more precise debug info improvements#61419
jakobbotsch merged 3 commits into
dotnet:mainfrom
jakobbotsch:more-debug-info

Conversation

@jakobbotsch

Copy link
Copy Markdown
Member
  • We were not recording precise info in inlinees except for at IL offset
    0 because most of the logic that handles determining when to attach
    debug info did not run for inlinees. There are no changes in what the
    EE sees since we were normalizing debug info back to the root anyway.

  • Propagate debug info even further than just until rationalization, to
    make it simpler to dump the precise debug info. This means we create
    some more GT_IL_OFFSET nodes, in particular when the inlinee debug
    info is valid but the root info is invalid. This is currently
    happening for newobj IL instructions when the constructor is inlined.
    We generate two statements:
    GT_ASG(GT_LCL_VAR(X), ALLOCOBJ(CLS));
    GT_CALL(CTOR, GT_LCL_VAR(X))
    and the first statement ends up "consuming" the debug info, meaning we
    end up with no debug info for the GT_CALL, which eventually propagates
    into the inline tree. I have held off on fixing this for now since it
    causes debug info diffs in the data reported back to the EE.

    The additional nodes in LIR result in 0.15% more memory use and 0.015%
    more instructions retired for SPMI over libraries.

There is also a small fix in gtlist.h for GT_BFIZ when
MEASURE_NODE_SIZES is defined.

No SPMI diffs.

* We were not recording precise info in inlinees except for at IL offset
0 because most of the logic that handles determining when to attach
debug info did not run for inlinees. There are no changes in what the
EE sees since we were normalizing debug info back to the root anyway.
* Propagate debug info even further than just until rationalization, to
make it simpler to dump the precise debug info. This means we create
some more GT_IL_OFFSET nodes, in particular when the inlinee debug
info is valid but the root info is invalid. This is currently
happening for newobj IL instructions when the constructor is inlined.
We generate two statements:
GT_ASG(GT_LCL_VAR(X), ALLOCOBJ(CLS));
GT_CALL(CTOR, GT_LCL_VAR(X))
and the first statement ends up "consuming" the debug info, meaning we
end up with no debug info for the GT_CALL, which eventually propagates
into the inline tree. I have held off on fixing this for now since it
causes debug info diffs in the data reported back to the EE.
The additional nodes in LIR result in 0.15% more memory use and 0.015%
more instructions retired for SPMI over libraries.
There is also a small fix in gtlist.h for GT_BFIZ when
MEASURE_NODE_SIZES is defined.
No SPMI diffs.
@ghostghost added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Nov 10, 2021
@ghost

Copy link
Copy Markdown

Tagging subscribers to this area: @JulieLeeMSFT
See info in area-owners.md if you want to be subscribed.

Issue Details
  • We were not recording precise info in inlinees except for at IL offset
    0 because most of the logic that handles determining when to attach
    debug info did not run for inlinees. There are no changes in what the
    EE sees since we were normalizing debug info back to the root anyway.

  • Propagate debug info even further than just until rationalization, to
    make it simpler to dump the precise debug info. This means we create
    some more GT_IL_OFFSET nodes, in particular when the inlinee debug
    info is valid but the root info is invalid. This is currently
    happening for newobj IL instructions when the constructor is inlined.
    We generate two statements:
    GT_ASG(GT_LCL_VAR(X), ALLOCOBJ(CLS));
    GT_CALL(CTOR, GT_LCL_VAR(X))
    and the first statement ends up "consuming" the debug info, meaning we
    end up with no debug info for the GT_CALL, which eventually propagates
    into the inline tree. I have held off on fixing this for now since it
    causes debug info diffs in the data reported back to the EE.

    The additional nodes in LIR result in 0.15% more memory use and 0.015%
    more instructions retired for SPMI over libraries.

There is also a small fix in gtlist.h for GT_BFIZ when
MEASURE_NODE_SIZES is defined.

No SPMI diffs.

Author:jakobbotsch
Assignees:-
Labels:

area-CodeGen-coreclr

Milestone:-

@jakobbotsch

jakobbotsch commented Nov 10, 2021

Copy link
Copy Markdown
MemberAuthor

For

usingSystem.Runtime.CompilerServices;publicclassProgram{publicstaticvoidMain(){System.Console.WriteLine(1);Foo();System.Console.WriteLine(6);}[MethodImpl(MethodImplOptions.AggressiveInlining)]privatestaticvoidFoo(){System.Console.WriteLine(2);Bar();System.Console.WriteLine(5);}[MethodImpl(MethodImplOptions.AggressiveInlining)]privatestaticvoidBar(){System.Console.WriteLine(3);System.Console.WriteLine(4);}}

we now see

***** BB01
STMT00000 ( 0x000[E-] ... 0x011 )
[000001] --C-G------- ▌ CALL void System.Console.WriteLine
[000000] ------------ arg0 └──▌ CNS_INT int 1
***** BB01
STMT00004 ( INL01 @ 0x000[E-] ... ??? ) <- INLRT @ 0x006[E-]
[000007] --C-G------- ▌ CALL void System.Console.WriteLine
[000006] ------------ arg0 └──▌ CNS_INT int 2
***** BB01
-STMT00007 ( INL02 @ 0x000[E-] ... ??? ) <- INL01 @ ??? <- INLRT @ 0x006[E-]+STMT00007 ( INL02 @ 0x000[E-] ... ??? ) <- INL01 @ 0x006[E-] <- INLRT @ 0x006[E-]
[000013] --C-G------- ▌ CALL void System.Console.WriteLine
[000012] ------------ arg0 └──▌ CNS_INT int 3
***** BB01
-STMT00008 ( INL02 @ ??? ... ??? ) <- INL01 @ ??? <- INLRT @ 0x006[E-]+STMT00008 ( INL02 @ 0x006[E-] ... ??? ) <- INL01 @ 0x006[E-] <- INLRT @ 0x006[E-]
[000015] --C-G------- ▌ CALL void System.Console.WriteLine
[000014] ------------ arg0 └──▌ CNS_INT int 4
***** BB01
-STMT00006 ( INL01 @ ??? ... ??? ) <- INLRT @ 0x006[E-]+STMT00006 ( INL01 @ 0x00B[E-] ... ??? ) <- INLRT @ 0x006[E-]
[000010] --C-G------- ▌ CALL void System.Console.WriteLine
[000009] ------------ arg0 └──▌ CNS_INT int 5
***** BB01
STMT00002 ( 0x00B[E-] ... ??? )
[000004] --C-G------- ▌ CALL void System.Console.WriteLine
[000003] ------------ arg0 └──▌ CNS_INT int 6
***** BB01
STMT00003 ( 0x011[E-] ... ??? )
[000005] ------------ ▌ RETURN void 

and as a bonus, we get the following in LIR dump output:

 ------------ BB01 [000..012) (return), preds={} succs={}
- [000023] ------------ IL_OFFSET void IL offset: 0x0+ [000023] ------------ IL_OFFSET void INLRT @ 0x000[E-]
N002 ( 1, 1) [000000] ------------ t0 = CNS_INT int 1 $41
┌──▌ t0 int arg0 in rcx
N003 ( 15, 7) [000001] --CXG------- ▌ CALL void System.Console.WriteLine $VN.Void
- [000024] ------------ IL_OFFSET void IL offset: 0x6+ [000024] ------------ IL_OFFSET void INL01 @ 0x000[E-] <- INLRT @ 0x006[E-]
N002 ( 1, 1) [000006] ------------ t6 = CNS_INT int 2 $42
┌──▌ t6 int arg0 in rcx
N003 ( 15, 7) [000007] --CXG------- ▌ CALL void System.Console.WriteLine $VN.Void
- [000025] ------------ IL_OFFSET void IL offset: 0x6+ [000025] ------------ IL_OFFSET void INL02 @ 0x000[E-] <- INL01 @ 0x006[E-] <- INLRT @ 0x006[E-]
N002 ( 1, 1) [000012] ------------ t12 = CNS_INT int 3 $43
┌──▌ t12 int arg0 in rcx
N003 ( 15, 7) [000013] --CXG------- ▌ CALL void System.Console.WriteLine $VN.Void
- [000026] ------------ IL_OFFSET void IL offset: 0x6+ [000026] ------------ IL_OFFSET void INL02 @ 0x006[E-] <- INL01 @ 0x006[E-] <- INLRT @ 0x006[E-]
N002 ( 1, 1) [000014] ------------ t14 = CNS_INT int 4 $44
┌──▌ t14 int arg0 in rcx
N003 ( 15, 7) [000015] --CXG------- ▌ CALL void System.Console.WriteLine $VN.Void
- [000027] ------------ IL_OFFSET void IL offset: 0x6+ [000027] ------------ IL_OFFSET void INL01 @ 0x00B[E-] <- INLRT @ 0x006[E-]
N002 ( 1, 1) [000009] ------------ t9 = CNS_INT int 5 $45
┌──▌ t9 int arg0 in rcx
N003 ( 15, 7) [000010] --CXG------- ▌ CALL void System.Console.WriteLine $VN.Void
- [000028] ------------ IL_OFFSET void IL offset: 0xb+ [000028] ------------ IL_OFFSET void INLRT @ 0x00B[E-]
N002 ( 1, 1) [000003] ------------ t3 = CNS_INT int 6 $46
┌──▌ t3 int arg0 in rcx
N003 ( 15, 7) [000004] --CXG------- ▌ CALL void System.Console.WriteLine $VN.Void
- [000029] ------------ IL_OFFSET void IL offset: 0x11+ [000029] ------------ IL_OFFSET void INLRT @ 0x011[E-]
N001 ( 0, 0) [000005] ------------ RETURN void $100

cc @dotnet/jit-contrib

{
nxtStmtOffs =
(nxtStmtIndex < info.compStmtOffsetsCount) ? info.compStmtOffsets[nxtStmtIndex] : BAD_IL_OFFSET;
nxtStmtOffs =

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW I've always though the logic in this bit of code was convoluted. But it looks like all that's happened here is that you removed the exclusion for inlinees?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's the only change here (it's easier to see if you check "Hide whitespace" under the review settings).

Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@jakobbotsch@AndyAyersMS