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 |
> 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 |
In reply to this post by Bruce Hoult via llvm-dev
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 |
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 |
In reply to this post by Bruce Hoult 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 |
In reply to this post by Bruce Hoult 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 |
In reply to this post by Bruce Hoult 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 |
In reply to this post by Bruce Hoult 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, _______________________________________________ LLVM Developers mailing list [hidden email] http://lists.llvm.org/cgi-bin/mailman/listinfo/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 |
> 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, _______________________________________________ LLVM Developers mailing list [hidden email] http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev |
Free forum by Nabble | Edit this page |