- 
                Notifications
    You must be signed in to change notification settings 
- Fork 5.2k
Some more precise debug info improvements #61419
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
Conversation
* 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.
| Tagging subscribers to this area: @JulieLeeMSFT Issue Details
 There is also a small fix in gtlist.h for GT_BFIZ when No SPMI diffs. 
 | 
| For using System.Runtime.CompilerServices;
public class Program
{
    public static void Main()
    {
        System.Console.WriteLine(1);
        Foo();
        System.Console.WriteLine(6);
    }
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    private static void Foo()
    {
        System.Console.WriteLine(2);
        Bar();
        System.Console.WriteLine(5);
    }
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    private static void Bar()
    {
        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   $100cc @dotnet/jit-contrib | 
| { | ||
| nxtStmtOffs = | ||
| (nxtStmtIndex < info.compStmtOffsetsCount) ? info.compStmtOffsets[nxtStmtIndex] : BAD_IL_OFFSET; | ||
| nxtStmtOffs = | 
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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).
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.