[llvm-dev] [SROA][DebugInfo][GSoC] Testing SROA on amalgamated sqlite source

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|

[llvm-dev] [SROA][DebugInfo][GSoC] Testing SROA on amalgamated sqlite source

U.Mutlu via llvm-dev
Introduction
============

  `SROA' is an early stage pass running at the very beginning of the
  pipeline in `-O{1,2,3}'. Greg Bedwell's report from his DExTer tool
  shows SROA on function as one of the major culprits of Debug Info
  loss.

  With debugify-each partially done I tried testing this on the
  amalgamated sqlite source.

  The steps are as follows:
  ,----
  | # generate IR file without debug info and optnone
  | clang -O0 -Xclang -disable-O0-optnone -S -emit-llvm sqlite3.c -o sqlite
  |
  | # run opt
  | opt -sroa -debugify-each sqlite -disable-output 2> results
  `----


Results
=======

  [Here] is the full results file.

  The results were gather by `grep -c`'ing the results file according to
  the error's message.

   SROA runs | FAIL | PASS | empty DebugLoc | Missing line warnings
  -----------|------|------|----------------|-----------------------
        1978 | 1100 |  878 |           5214 |                 75166

  What's worth noticing is that the only error that SROA produces is
  that of empty debug locations. It does not report any missing
  DILocalVariables or llvm.dbg.value intrinsics. Thus all of the 1100
  SROA runs that failed are due to empty debug locations.

  Also, while skimming through the results file I noticed that the
  instructions with missing DL were `phi' instructions. To confirm this
  I did:

    $ grep "ERROR: Instruction" results | grep phi -c

  witch gives us a result of `5214' and this means that all the
  instructions with missing Debug Loc are `phi' instructions.


[Here] https://gramanas.github.io/sroa-results.csv


Conclusion
==========

  This implies SROA does a pretty good job of preserving debug values.

  The DExTer results are not in line with what I've found though. This
  might be for a number of reasons. E.g. it could score so low due to
  the DebugLoc loss. Also debugify doesn't test the backend so it's
  going to detect a narrower set of issues.

  Do you have any ideas as to why this happens? Can you confirm the
  results?

  @Adrian, @Greg any thoughts would be appreciated!
_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] [SROA][DebugInfo][GSoC] Testing SROA on amalgamated sqlite source

U.Mutlu via llvm-dev


> On May 30, 2018, at 8:37 AM, Anast Gramm <[hidden email]> wrote:
>
> Introduction
> ============
>
>  `SROA' is an early stage pass running at the very beginning of the
>  pipeline in `-O{1,2,3}'. Greg Bedwell's report from his DExTer tool
>  shows SROA on function as one of the major culprits of Debug Info
>  loss.
>
>  With debugify-each partially done I tried testing this on the
>  amalgamated sqlite source.
>
>  The steps are as follows:
>  ,----
>  | # generate IR file without debug info and optnone
>  | clang -O0 -Xclang -disable-O0-optnone -S -emit-llvm sqlite3.c -o sqlite
>  |
>  | # run opt
>  | opt -sroa -debugify-each sqlite -disable-output 2> results
>  `----
>
>
> Results
> =======
>
>  [Here] is the full results file.
>
>  The results were gather by `grep -c`'ing the results file according to
>  the error's message.
>
>   SROA runs | FAIL | PASS | empty DebugLoc | Missing line warnings
>  -----------|------|------|----------------|-----------------------
>        1978 | 1100 |  878 |           5214 |                 75166
>
>  What's worth noticing is that the only error that SROA produces is
>  that of empty debug locations. It does not report any missing
>  DILocalVariables or llvm.dbg.value intrinsics. Thus all of the 1100
>  SROA runs that failed are due to empty debug locations.

>
>  Also, while skimming through the results file I noticed that the
>  instructions with missing DL were `phi' instructions. To confirm this
>  I did:
>
>    $ grep "ERROR: Instruction" results | grep phi -c
>
>  witch gives us a result of `5214' and this means that all the
>  instructions with missing Debug Loc are `phi' instructions.
>
>
> [Here] https://gramanas.github.io/sroa-results.csv
>
>
> Conclusion
> ==========
>
>  This implies SROA does a pretty good job of preserving debug values.
>

That is good to hear / expected, since we went though great lengths to ensure that SROA preserves variable debug info.

Have you looked at the location-less phi instructions? Does empty mean line 0 or do you mean they have no debug location whatsoever? Are they empty for good reasons or does it look more like an oversight in the implementation?

-- adrian

>  The DExTer results are not in line with what I've found though. This
>  might be for a number of reasons. E.g. it could score so low due to
>  the DebugLoc loss. Also debugify doesn't test the backend so it's
>  going to detect a narrower set of issues.
>
>  Do you have any ideas as to why this happens? Can you confirm the
>  results?
>
>  @Adrian, @Greg any thoughts would be appreciated!

_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] [SROA][DebugInfo][GSoC] Testing SROA on amalgamated sqlite source

U.Mutlu via llvm-dev
In reply to this post by U.Mutlu via llvm-dev

  `SROA' is an early stage pass running at the very beginning of the
  pipeline in `-O{1,2,3}'. Greg Bedwell's report from his DExTer tool
  shows SROA on function as one of the major culprits of Debug Info
  loss.


The methodology I used is with the opt-bisect-limit option on clang, so it's not strictly the case that the results presented show that the loss in "debugability" occurs during the SROA pass itself directly but rather that the effect of running SROA is some loss in debugability to the final program.  I didn't make that point clear enough during my lightning talk session!  

Looking at some of the results in more detail, I think the reason that the reason our results differ is because what I'm measuring is not actually variable info loss directly, but as a consequence of the impact on stepping.  My standard disclaimer with all results from this tool is that a non-perfect debugging experience score is not necessarily indicative of something wrong, but should be looked at in conjunction with all the other factors such as what the pass is trying to achieve optimization-wise, etc etc.  That is to say, it's not necessarily a bug, but it can be (especially when observed as a regression between compiler revisions).

Using the standard Fibonacci example with clang and lldb from this afternoon:

 1 #ifdef _MSC_VER
 2 # define DEX_NOINLINE __declspec(noinline)
 3 #else
 4 # define DEX_NOINLINE __attribute__((__noinline__))
 5 #endif
 6
 7 DEX_NOINLINE
 8 void Fibonacci(int terms, int& total)
 9 {
10   int first = 0;
11   int second = 1;
12
13   for (int i = 0; i < terms; ++i)
14   {
15     int next = first + second; // DexWatch('i', 'first', 'second', 'total')
16     total += first;            // DexWatch('i', 'first', 'second', 'total', 'next')
17     first = second;            // DexWatch('i', 'first', 'second', 'total', 'next')
18     second = next;             // DexWatch('i', 'first', 'second', 'total', 'next')
19   }
20 }
21
22 int main()
23 {
24   int total = 0;
25   Fibonacci(5, total);
26   return total;
27 }

not running  "SROA on function (_Z9FibonacciiRi)" the DExTer trace output is:

## BEGIN ##
[1, "main", "tests/fibonacci/test.cpp", 24, 6, "BREAKPOINT", "FUNC", {}]
[2, "main", "tests/fibonacci/test.cpp", 25, 2, "BREAKPOINT", "FORWARD", {}]
.   [3, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 10, 6, "BREAKPOINT", "FUNC", {}]
.   [4, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 11, 6, "BREAKPOINT", "FORWARD", {}]
.   [5, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 13, 11, "BREAKPOINT", "FORWARD", {}]
.   [6, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 15, 14, "BREAKPOINT", "FORWARD", {"i": "0", "second": "1", "total": "0", "first": "0"}]
.   [7, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 16, 12, "BREAKPOINT", "FORWARD", {"i": "0", "second": "1", "total": "0", "first": "0", "next": "1"}]
.   [8, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 17, 11, "BREAKPOINT", "FORWARD", {"i": "0", "second": "1", "total": "0", "first": "0", "next": "1"}]
.   [9, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 18, 12, "BREAKPOINT", "FORWARD", {"i": "0", "second": "1", "total": "0", "first": "1", "next": "1"}]
.   [10, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 13, 29, "STEP", "BACKWARD", {}]
.   [11, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 15, 14, "BREAKPOINT", "FORWARD", {"i": "1", "second": "1", "total": "0", "first": "1"}]
.   [12, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 16, 12, "BREAKPOINT", "FORWARD", {"i": "1", "second": "1", "total": "0", "first": "1", "next": "2"}]
.   [13, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 17, 11, "BREAKPOINT", "FORWARD", {"i": "1", "second": "1", "total": "1", "first": "1", "next": "2"}]
.   [14, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 18, 12, "BREAKPOINT", "FORWARD", {"i": "1", "second": "1", "total": "1", "first": "1", "next": "2"}]
.   [15, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 13, 29, "STEP", "BACKWARD", {}]
.   [16, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 15, 14, "BREAKPOINT", "FORWARD", {"i": "2", "second": "2", "total": "1", "first": "1"}]
.   [17, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 16, 12, "BREAKPOINT", "FORWARD", {"i": "2", "second": "2", "total": "1", "first": "1", "next": "3"}]
.   [18, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 17, 11, "BREAKPOINT", "FORWARD", {"i": "2", "second": "2", "total": "2", "first": "1", "next": "3"}]
.   [19, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 18, 12, "BREAKPOINT", "FORWARD", {"i": "2", "second": "2", "total": "2", "first": "2", "next": "3"}]
.   [20, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 13, 29, "STEP", "BACKWARD", {}]
.   [21, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 15, 14, "BREAKPOINT", "FORWARD", {"i": "3", "second": "3", "total": "2", "first": "2"}]
.   [22, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 16, 12, "BREAKPOINT", "FORWARD", {"i": "3", "second": "3", "total": "2", "first": "2", "next": "5"}]
.   [23, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 17, 11, "BREAKPOINT", "FORWARD", {"i": "3", "second": "3", "total": "4", "first": "2", "next": "5"}]
.   [24, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 18, 12, "BREAKPOINT", "FORWARD", {"i": "3", "second": "3", "total": "4", "first": "3", "next": "5"}]
.   [25, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 13, 29, "STEP", "BACKWARD", {}]
.   [26, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 15, 14, "BREAKPOINT", "FORWARD", {"i": "4", "second": "5", "total": "4", "first": "3"}]
.   [27, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 16, 12, "BREAKPOINT", "FORWARD", {"i": "4", "second": "5", "total": "4", "first": "3", "next": "8"}]
.   [28, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 17, 11, "BREAKPOINT", "FORWARD", {"i": "4", "second": "5", "total": "7", "first": "3", "next": "8"}]
.   [29, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 18, 12, "BREAKPOINT", "FORWARD", {"i": "4", "second": "5", "total": "7", "first": "5", "next": "8"}]
.   [30, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 13, 29, "STEP", "BACKWARD", {}]
.   [31, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 20, 1, "BREAKPOINT", "FORWARD", {}]
[32, "main", "tests/fibonacci/test.cpp", 26, 9, "BREAKPOINT", "FUNC", {}]
## END (32 steps) ##

So we do a couple of steps in main, before stepping into Fibonacci(int, int&) at step 3.  It's fairly easy to see that we iterate the loop 5 times, stepping on lines 13, 15, 16, 17 and 18 in order each time.

After "SROA on function (_Z9FibonacciiRi)" we now get:

## BEGIN ##
[1, "main", "tests/fibonacci/test.cpp", 24, 6, "BREAKPOINT", "FUNC", {}]
[2, "main", "tests/fibonacci/test.cpp", 25, 2, "BREAKPOINT", "FORWARD", {}]
.   [3, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 13, 20, "BREAKPOINT", "FUNC", {}]
.   [4, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 15, 20, "BREAKPOINT", "FORWARD", {"i": "0", "second": "1", "total": "0", "first": "0"}]
.   [5, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 16, 9, "BREAKPOINT", "FORWARD", {"i": "0", "second": "1", "total": "0", "first": "0", "next": "1"}]
.   [6, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 13, 29, "STEP", "BACKWARD", {}]
.   [7, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 13, 20, "BREAKPOINT", "BACKWARD", {}]
.   [8, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 15, 20, "BREAKPOINT", "FORWARD", {"i": "1", "second": "1", "total": "0", "first": "1"}]
.   [9, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 16, 9, "BREAKPOINT", "FORWARD", {"i": "1", "second": "1", "total": "0", "first": "1", "next": "2"}]
.   [10, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 13, 29, "STEP", "BACKWARD", {}]
.   [11, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 13, 20, "BREAKPOINT", "BACKWARD", {}]
.   [12, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 15, 20, "BREAKPOINT", "FORWARD", {"i": "2", "second": "2", "total": "1", "first": "1"}]
.   [13, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 16, 9, "BREAKPOINT", "FORWARD", {"i": "2", "second": "2", "total": "1", "first": "1", "next": "3"}]
.   [14, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 13, 29, "STEP", "BACKWARD", {}]
.   [15, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 13, 20, "BREAKPOINT", "BACKWARD", {}]
.   [16, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 15, 20, "BREAKPOINT", "FORWARD", {"i": "3", "second": "3", "total": "2", "first": "2"}]
.   [17, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 16, 9, "BREAKPOINT", "FORWARD", {"i": "3", "second": "3", "total": "2", "first": "2", "next": "5"}]
.   [18, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 13, 29, "STEP", "BACKWARD", {}]
.   [19, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 13, 20, "BREAKPOINT", "BACKWARD", {}]
.   [20, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 15, 20, "BREAKPOINT", "FORWARD", {"i": "4", "second": "5", "total": "4", "first": "3"}]
.   [21, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 16, 9, "BREAKPOINT", "FORWARD", {"i": "4", "second": "5", "total": "4", "first": "3", "next": "8"}]
.   [22, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 13, 29, "STEP", "BACKWARD", {}]
.   [23, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 13, 20, "BREAKPOINT", "BACKWARD", {}]
.   [24, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 20, 1, "BREAKPOINT", "FORWARD", {}]
[25, "main", "tests/fibonacci/test.cpp", 26, 9, "BREAKPOINT", "FUNC", {}]
## END (25 steps) ##

So we've now gained some extra steps at line 13, but at different columns (the "++i" and "i < terms" are now treated as separate steps), but we're now also no longer ever stepping onto lines 17 or 18 at all.  Whether these are the expected effects of SROA are not something DExTer is in the business of deciding, but it does score it as a difference because it now, at no point, sees the expression "first" evaluate to a value of 5, or "total" to a value of 8 which it did previously.  From the source-level debugging experience, the variables now just get updated between iterations.

So in short, it seems SROA is having some effect on debugging but it seems that it's not in the form of failing to preserve variable info.




_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] [SROA][DebugInfo][GSoC] Testing SROA on amalgamated sqlite source

U.Mutlu via llvm-dev
is in the business of deciding, but it does score it as a difference because it now, at no point, sees the expression "first" evaluate to a value of 5, or "total" to a value of 8 which it did previously.  From the source-level debugging experience, the variables now just get updated between iterations.

Obviously should've been 7 for that value of "total".

To try and be a bit more helpful there's definitely something dodgy happening to variable visibility on the fibonacci example in LICM.

With "BISECT: NOT running pass (32) Loop Invariant Code Motion on loop":

## BEGIN ##
[1, "main", "tests/fibonacci/test.cpp", 24, 6, "BREAKPOINT", "FUNC", {}]
[2, "main", "tests/fibonacci/test.cpp", 25, 2, "BREAKPOINT", "FORWARD", {}]
.   [3, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 13, 20, "BREAKPOINT", "FUNC", {}]
.   [4, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 15, 20, "BREAKPOINT", "FORWARD", {"i": "0", "second": "1", "total": "0", "first": "0"}]
.   [5, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 16, 9, "BREAKPOINT", "FORWARD", {"i": "0", "second": "1", "total": "0", "first": "0", "next": "1"}]
.   [6, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 13, 29, "STEP", "BACKWARD", {}]
.   [7, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 15, 20, "BREAKPOINT", "FORWARD", {"i": "1", "second": "1", "total": "0", "first": "1"}]
.   [8, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 16, 9, "BREAKPOINT", "FORWARD", {"i": "1", "second": "1", "total": "0", "first": "1", "next": "2"}]
.   [9, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 13, 29, "STEP", "BACKWARD", {}]
.   [10, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 15, 20, "BREAKPOINT", "FORWARD", {"i": "2", "second": "2", "total": "1", "first": "1"}]
.   [11, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 16, 9, "BREAKPOINT", "FORWARD", {"i": "2", "second": "2", "total": "1", "first": "1", "next": "3"}]
.   [12, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 13, 29, "STEP", "BACKWARD", {}]
.   [13, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 15, 20, "BREAKPOINT", "FORWARD", {"i": "3", "second": "3", "total": "2", "first": "2"}]
.   [14, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 16, 9, "BREAKPOINT", "FORWARD", {"i": "3", "second": "3", "total": "2", "first": "2", "next": "5"}]
.   [15, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 13, 29, "STEP", "BACKWARD", {}]
.   [16, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 15, 20, "BREAKPOINT", "FORWARD", {"i": "4", "second": "5", "total": "4", "first": "3"}]
.   [17, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 16, 9, "BREAKPOINT", "FORWARD", {"i": "4", "second": "5", "total": "4", "first": "3", "next": "8"}]
.   [18, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 13, 29, "STEP", "BACKWARD", {}]
.   [19, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 20, 1, "BREAKPOINT", "FORWARD", {}]
[20, "main", "tests/fibonacci/test.cpp", 26, 9, "BREAKPOINT", "FUNC", {}]
## END (20 steps) ##

But with: "BISECT: running pass (32) Loop Invariant Code Motion on loop":

## BEGIN ##
[1, "main", "tests/fibonacci/test.cpp", 24, 6, "BREAKPOINT", "FUNC", {}]
[2, "main", "tests/fibonacci/test.cpp", 25, 2, "BREAKPOINT", "FORWARD", {}]
.   [3, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 13, 20, "BREAKPOINT", "FUNC", {}]
.   [4, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 16, 9, "BREAKPOINT", "FORWARD", {"i": "0", "second": "1", "total": "0", "first": "0", "next": null}]
.   [5, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 13, 2, "STEP", "BACKWARD", {}]
.   [6, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 15, 20, "BREAKPOINT", "FORWARD", {"i": "0", "second": "1", "total": "0", "first": "0"}]
.   [7, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 16, 9, "STEP", "FORWARD", {"i": "0", "second": "1", "total": "0", "first": "0", "next": "1"}]
.   [8, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 13, 29, "STEP", "BACKWARD", {}]
.   [9, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 15, 20, "BREAKPOINT", "FORWARD", {"i": "1", "second": "1", "total": "0", "first": "1"}]
.   [10, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 16, 9, "STEP", "FORWARD", {"i": "1", "second": "1", "total": "0", "first": "1", "next": "2"}]
.   [11, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 13, 29, "STEP", "BACKWARD", {}]
.   [12, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 15, 20, "BREAKPOINT", "FORWARD", {"i": "2", "second": "2", "total": "0", "first": "1"}]
.   [13, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 16, 9, "STEP", "FORWARD", {"i": "2", "second": "2", "total": "0", "first": "1", "next": "3"}]
.   [14, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 13, 29, "STEP", "BACKWARD", {}]
.   [15, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 15, 20, "BREAKPOINT", "FORWARD", {"i": "3", "second": "3", "total": "0", "first": "2"}]
.   [16, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 16, 9, "STEP", "FORWARD", {"i": "3", "second": "3", "total": "0", "first": "2", "next": "5"}]
.   [17, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 13, 29, "STEP", "BACKWARD", {}]
.   [18, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 15, 20, "BREAKPOINT", "FORWARD", {"i": "4", "second": "5", "total": "0", "first": "3"}]
.   [19, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 16, 9, "STEP", "FORWARD", {"i": "4", "second": "5", "total": "0", "first": "3", "next": "8"}]
.   [20, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 13, 29, "STEP", "BACKWARD", {}]
.   [21, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 16, 9, "STEP", "FORWARD", {"i": "5", "second": "8", "total": "0", "first": "5", "next": "8"}]
.   [22, "Fibonacci(int, int&)", "tests/fibonacci/test.cpp", 20, 1, "BREAKPOINT", "FORWARD", {}]
[23, "main", "tests/fibonacci/test.cpp", 26, 9, "BREAKPOINT", "FUNC", {}]
## END (23 steps) ##

The difference here that really sticks out as a problem to me is reported by the heuristic like this:

  test.cpp:15-18 [total] [21/21]
    expected encountered values:
      0

    missing values:
      1 [+6]
      2 [+6]
      4 [+6]
      7 [+3]

So, "total" evaluates to 0 for the duration of Fibonacci(int, int&) which definitely smells wrong to me.  Prior to that it was evaluating to 0, 1, 2 and 4 in order (we stopped seeing 7 after SROA).

-Greg



_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] [SROA][DebugInfo][GSoC] Testing SROA on amalgamated sqlite source

U.Mutlu via llvm-dev
In reply to this post by U.Mutlu via llvm-dev
> That is good to hear / expected, since we went though great lengths to ensure that SROA preserves variable debug info.
>
> Have you looked at the location-less phi instructions?
> Does empty mean line 0 or do you mean they have no debug location whatsoever?

Most of them have line 0, only 12 are locationless.

> Are they empty for good reasons or does it look more like an oversight in the implementation?

How can I approach this? My guess is that all these phi's are with line 0 because they are made
of stores and allocas that aren't actual code, and are instead generated by clang. Like here
https://reviews.llvm.org/D47097 at test1
_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] [SROA][DebugInfo][GSoC] Testing SROA on amalgamated sqlite source

U.Mutlu via llvm-dev
In reply to this post by U.Mutlu via llvm-dev
Thanks,
These are very helpful.

As I understand it, SROA and LICM render some variables
"useless" by optimizing the code to not use them. Hence we can't debug them.

_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] [SROA][DebugInfo][GSoC] Testing SROA on amalgamated sqlite source

U.Mutlu via llvm-dev
In reply to this post by U.Mutlu via llvm-dev


> On May 31, 2018, at 5:11 AM, Anast Gramm <[hidden email]> wrote:
>
>> That is good to hear / expected, since we went though great lengths to ensure that SROA preserves variable debug info.
>>
>> Have you looked at the location-less phi instructions?
>> Does empty mean line 0 or do you mean they have no debug location whatsoever?
>
> Most of them have line 0, only 12 are locationless.
>
>> Are they empty for good reasons or does it look more like an oversight in the implementation?
>
> How can I approach this? My guess is that all these phi's are with line 0 because they are made
> of stores and allocas that aren't actual code, and are instead generated by clang. Like here
> https://reviews.llvm.org/D47097 at test1

My guess is that the ones with line 0 are intentional and deliberately set the location to line 0 because someone already put thought into this, and the ones without location are more likely to be bugs. Since there are only 12 you can probably just look at them individually and determine where they are generated and then we can decide whether the code is behaving correctly or not.

-- adrian

_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] [SROA][DebugInfo][GSoC] Testing SROA on amalgamated sqlite source

U.Mutlu via llvm-dev
In reply to this post by U.Mutlu via llvm-dev
FWIW, I've raised the LICM issue here: https://bugs.llvm.org/show_bug.cgi?id=37682

On 31 May 2018 at 13:28, Anast Gramm <[hidden email]> wrote:
Thanks,
These are very helpful.

As I understand it, SROA and LICM render some variables
"useless" by optimizing the code to not use them. Hence we can't debug them.



_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] [SROA][DebugInfo][GSoC] Testing SROA on amalgamated sqlite source

U.Mutlu via llvm-dev
Hi Greg,

> On Jun 4, 2018, at 2:18 PM, Greg Bedwell via llvm-dev <[hidden email]> wrote:
>
> FWIW, I've raised the LICM issue here: https://bugs.llvm.org/show_bug.cgi?id=37682

LICM's behavior seems reasonable/desirable to me. I've shared my thoughts on llvm.org/PR37682. To summarize, I don't think it's feasible to assert that the debugger show updated values for 'total' within this loop, because it amounts to a demand that LICM never happen. Alternatives such as marking 'total' as unavailable, or making it appear as a non-pointer type, have serious tradeoffs and/or can't properly model the effects of aliasing.

vedant

>
> On 31 May 2018 at 13:28, Anast Gramm <[hidden email]> wrote:
> Thanks,
> These are very helpful.
>
> As I understand it, SROA and LICM render some variables
> "useless" by optimizing the code to not use them. Hence we can't debug them.
>
>
> _______________________________________________
> LLVM Developers mailing list
> [hidden email]
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev

_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] [SROA][DebugInfo][GSoC] Testing SROA on amalgamated sqlite source

U.Mutlu via llvm-dev
> LICM's behavior seems reasonable/desirable to me. I've shared my thoughts on llvm.org/PR37682. To summarize, I don't think it's feasible to assert that the debugger show updated values for 'total' within this loop, because it 
> amounts to a demand that LICM never happen. Alternatives such as marking 'total' as unavailable, or making it appear as a non-pointer type, have serious tradeoffs and/or can't properly model the effects of aliasing.

Thanks for taking a look.  Let's continue the discussion if there's any more follow-up in the bug to prevent derailing this thread.  I agree with everything you say, but it still makes me feel uneasy that we have a situation where we have the information available according to the semantics of the code the user wrote (that "total" gets updated on every iteration, where we have that value in a register) but we aren't able to present that to the user because it conflicts with the reality of the optimized code ("total" is a memory location that has the value 0 until the loop terminates when the contents of the register are stored to it).  I'd love a third option where we could somehow convey that information to the user.  If that's not an option currently, we should consider a solution for -Og mode at least.  As I mentioned in the bug, we come across poorly compared to MSVC here in terms of quality of debugging, but vaguely amusingly purely because it doesn't appear to hoist the store.

-Greg



On 5 June 2018 at 23:17, Vedant Kumar <[hidden email]> wrote:
Hi Greg,

> On Jun 4, 2018, at 2:18 PM, Greg Bedwell via llvm-dev <[hidden email]> wrote:
>
> FWIW, I've raised the LICM issue here: https://bugs.llvm.org/show_bug.cgi?id=37682

LICM's behavior seems reasonable/desirable to me. I've shared my thoughts on llvm.org/PR37682. To summarize, I don't think it's feasible to assert that the debugger show updated values for 'total' within this loop, because it amounts to a demand that LICM never happen. Alternatives such as marking 'total' as unavailable, or making it appear as a non-pointer type, have serious tradeoffs and/or can't properly model the effects of aliasing.

vedant

>
> On 31 May 2018 at 13:28, Anast Gramm <[hidden email]> wrote:
> Thanks,
> These are very helpful.
>
> As I understand it, SROA and LICM render some variables
> "useless" by optimizing the code to not use them. Hence we can't debug them.
>
>
> _______________________________________________
> LLVM Developers mailing list
> [hidden email]
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev



_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev