Re: VTA guality assessment: better than -O0 ;-)
On Sun, Jun 14, 2009 at 11:17:32AM -0400, Daniel Jacobowitz wrote: On Sat, Jun 13, 2009 at 10:08:39PM +0200, Jakub Jelinek wrote: I really think we need to do (limited) -fvar-tracking even for -O0, it is really bad that most arguments have wrong locations through the prologue, while at -O1 or above they often have correct location. We should just do the tracking inside of the prologue or for register variables, those that are stored into memory during the prologue and live in memory shouldn't be tracked outside of the prologue at -O0. I completely agree, this would make GDB more useful. --- gcc/var-tracking.c.jj 2009-05-04 16:46:38.0 +0200 +++ gcc/var-tracking.c 2009-06-17 17:48:58.0 +0200 @@ -1652,6 +1652,8 @@ track_expr_p (tree expr) if (MEM_SIZE (decl_rtl) INTVAL (MEM_SIZE (decl_rtl)) MAX_VAR_PARTS) return 0; + if (!optimize TREE_CODE (expr) == VAR_DECL) + return 0; } return 1; decreased the -O0 -g -fvar-tracking debuginfo on the trunk quite a bit, I don't think there is any point in tracking VAR_DECLs that live in MEM, only PARM_DECLs (which during the prologue might move from registers) and VAR_DECLs that don't have MEM decl_rtl (at -O0 those are just vars with register keyword I believe from the ones var-tracking would track). Still, I think for -O0 -g -fvar-tracking we should note that the parms moved into their desired slots immediately (e.g. by pretending the register from which they have been stored was also clobbered on the same instruction). Jakub
Re: VTA guality assessment: better than -O0 ;-)
On Sat, Jun 13, 2009 at 10:08:39PM +0200, Jakub Jelinek wrote: I really think we need to do (limited) -fvar-tracking even for -O0, it is really bad that most arguments have wrong locations through the prologue, while at -O1 or above they often have correct location. We should just do the tracking inside of the prologue or for register variables, those that are stored into memory during the prologue and live in memory shouldn't be tracked outside of the prologue at -O0. I completely agree, this would make GDB more useful. -- Daniel Jacobowitz CodeSourcery
VTA guality assessment: better than -O0 ;-)
So, after I tested and installed this patch http://gcc.gnu.org/ml/gcc-patches/2009-06/msg00903.html I started looking closely at the guality (debug info quality) test results. So far, I have only added two very simple tests to the guality testsuite, but they already show very promising results. GUALCHKXPRVAL(expr, value, maybe_dead_p) checks whether expr, evaluated by the debugger, matches value, evaluated at run time. maybe_dead_p indicates whether, if the debugger fails to compute expr (say, optimized away or missing debug info), we get an UNRESOLVED or a FAIL. If expr is evaluated successfully but it doesn't match the expected value, we get a FAIL, otherwise a PASS. GUALCHKXPR(expr) is the same as GUALCHKXPRVAL(expr,(expr),1) GUALCHKFLA(expr) is nearly equivalent to GUALCHKXPRVAL(expr,(expr),0), except that (expr) is saved in a temporary and stored in a volatile memory location after the check, so expr *must* be live at the point of check. FLA stands for Forced Live After. Ok, on to some test results (on x86_64-linux-gnu): guality.c: int main (int argc, char *argv[]) { int i = argc+1; int j = argc-2; int k = 5; GUALCHKXPR (argc); GUALCHKXPR (i); GUALCHKXPR (j); GUALCHKXPR (k); GUALCHKXPR (i); GUALCHKFLA (argc); GUALCHKFLA (i); GUALCHKFLA (j); GUALCHKXPR (i); GUALCHKXPR (j); GUALCHKXPRVAL (k, 5, 1); GUALCHKXPRVAL (0x40, 64, 0); } -O0 (implied -fno-var-tracking-assignments) PASS: argc is 1 PASS: i is 2 FAIL: j is 32767, not -1 FAIL: k is 2028276576, not 5 PASS: i is 140735221664248 PASS: argc is 1 PASS: i is 2 FAIL: j is 32767, not -1 PASS: i is 2 FAIL: j is 32767, not -1 FAIL: k is 2028276576, not 5 PASS: 0x40 is 64 FAIL: 7 PASS, 5 FAIL, 0 UNRESOLVED -O1 -fno-var-tracking-assignments PASS: argc is 1 FAIL: i is 0, not 2 PASS: j is -1 UNRESOLVED: k is not computable, expected 5 UNRESOLVED: i is not computable, expected 140733781777644 PASS: argc is 1 PASS: i is 2 PASS: j is -1 FAIL: i is 0, not 2 PASS: j is -1 UNRESOLVED: k is not computable, expected 5 PASS: 0x40 is 64 FAIL: 7 PASS, 2 FAIL, 3 UNRESOLVED We see that debug info got better for j, and k is no longer wrong: it is completely dropped from debug information, even though it could have been encoded in standard debug info, for its value is the same constant throughout its entire lifetime. For some reason, although i is addressable, it's not uniformly computable: taking its address doesn't work in between two sucessful evaluations of i, and i actually works in the debugger at those surrounding execution points. -O1 -fvar-tracking-assignments PASS: argc is 1 UNRESOLVED: i is optimized away, expected 2 PASS: j is -1 UNRESOLVED: k is not computable, expected 5 UNRESOLVED: i is not computable, expected 140735863643740 PASS: argc is 1 PASS: i is 2 PASS: j is -1 UNRESOLVED: i is optimized away, expected 2 PASS: j is -1 UNRESOLVED: k is not computable, expected 5 PASS: 0x40 is 64 PASS: 7 PASS, 0 FAIL, 5 UNRESOLVED Yay, PASS! With Jakub's patch to encode constants in location lists, the two UNRESOLVED tests for k will become PASS. I haven't looked into why i is taken as optimized away. What I do know is that i isn't tracked by VTA, for VTA only tracks variables that aren't addressable. Not convinced yet? Why, sure, VTA (+ DW_OP_implicit_value) has *only* gone from totally broken j and k at -O0 to totally correct debug info, while somehow *fixing* additional errors for i that is not even tracked by VTA. From 0% to 100% correctness, and 100% completeness for all VTA-tracked variables. But it gets better. Remember those examples from the slides in the VTA presentation in last year's GCC Summit? http://people.redhat.com/~aoliva/papers/vta/ I've turned them into another guality test, that runs with GUALCHK(expr) defined GUALCHKXPRVAL(expr, expr, 0), i.e., it requires variables to be available and computable. typedef struct list { struct list *n; int v; } elt, *node; node find_val (node c, int v, node e) { while (c e) { GUALCHK (c); GUALCHK (v); GUALCHK (e); if (c-v == v) return c; GUALCHK (c); GUALCHK (v); GUALCHK (e); c++; } return NULL; } node find_prev (node c, node w) { while (c) { node o = c; c = c-n; GUALCHK (c); GUALCHK (o); GUALCHK (w); if (c == w) return o; GUALCHK (c); GUALCHK (o); GUALCHK (w); } return NULL; } node check_arr (node c, node e) { if (c == e) return NULL; e--; while (c e) { GUALCHK (c); GUALCHK (e); if (c-v (c+1)-v) return c; GUALCHK (c); GUALCHK (e); c++; } return NULL; } node check_list (node c, node t) { while (c != t) { node n = c-n; GUALCHK (c); GUALCHK (n); GUALCHK (t); if (c-v n-v) return c; GUALCHK (c); GUALCHK (n); GUALCHK (t); c = n; } return NULL; } struct list testme[] = { {
Re: VTA guality assessment: better than -O0 ;-)
On Sat, Jun 13, 2009 at 9:29 AM, Alexandre Olivaaol...@redhat.com wrote: So, after I tested and installed this patch http://gcc.gnu.org/ml/gcc-patches/2009-06/msg00903.html I started looking closely at the guality (debug info quality) test results. So far, I have only added two very simple tests to the guality testsuite, but they already show very promising results. GUALCHKXPRVAL(expr, value, maybe_dead_p) checks whether expr, evaluated by the debugger, matches value, evaluated at run time. maybe_dead_p indicates whether, if the debugger fails to compute expr (say, optimized away or missing debug info), we get an UNRESOLVED or a FAIL. If expr is evaluated successfully but it doesn't match the expected value, we get a FAIL, otherwise a PASS. GUALCHKXPR(expr) is the same as GUALCHKXPRVAL(expr,(expr),1) GUALCHKFLA(expr) is nearly equivalent to GUALCHKXPRVAL(expr,(expr),0), except that (expr) is saved in a temporary and stored in a volatile memory location after the check, so expr *must* be live at the point of check. FLA stands for Forced Live After. Ok, on to some test results (on x86_64-linux-gnu): guality.c: int main (int argc, char *argv[]) { int i = argc+1; int j = argc-2; int k = 5; GUALCHKXPR (argc); GUALCHKXPR (i); GUALCHKXPR (j); GUALCHKXPR (k); GUALCHKXPR (i); GUALCHKFLA (argc); GUALCHKFLA (i); GUALCHKFLA (j); GUALCHKXPR (i); GUALCHKXPR (j); GUALCHKXPRVAL (k, 5, 1); GUALCHKXPRVAL (0x40, 64, 0); } -O0 (implied -fno-var-tracking-assignments) PASS: argc is 1 PASS: i is 2 FAIL: j is 32767, not -1 FAIL: k is 2028276576, not 5 PASS: i is 140735221664248 PASS: argc is 1 PASS: i is 2 FAIL: j is 32767, not -1 PASS: i is 2 FAIL: j is 32767, not -1 FAIL: k is 2028276576, not 5 PASS: 0x40 is 64 FAIL: 7 PASS, 5 FAIL, 0 UNRESOLVED -O1 -fno-var-tracking-assignments PASS: argc is 1 FAIL: i is 0, not 2 PASS: j is -1 UNRESOLVED: k is not computable, expected 5 UNRESOLVED: i is not computable, expected 140733781777644 PASS: argc is 1 PASS: i is 2 PASS: j is -1 FAIL: i is 0, not 2 PASS: j is -1 UNRESOLVED: k is not computable, expected 5 PASS: 0x40 is 64 FAIL: 7 PASS, 2 FAIL, 3 UNRESOLVED We see that debug info got better for j, and k is no longer wrong: it is completely dropped from debug information, even though it could have been encoded in standard debug info, for its value is the same constant throughout its entire lifetime. For some reason, although i is addressable, it's not uniformly computable: taking its address doesn't work in between two sucessful evaluations of i, and i actually works in the debugger at those surrounding execution points. -O1 -fvar-tracking-assignments PASS: argc is 1 UNRESOLVED: i is optimized away, expected 2 PASS: j is -1 UNRESOLVED: k is not computable, expected 5 UNRESOLVED: i is not computable, expected 140735863643740 PASS: argc is 1 PASS: i is 2 PASS: j is -1 UNRESOLVED: i is optimized away, expected 2 PASS: j is -1 UNRESOLVED: k is not computable, expected 5 PASS: 0x40 is 64 PASS: 7 PASS, 0 FAIL, 5 UNRESOLVED Yay, PASS! With Jakub's patch to encode constants in location lists, the two UNRESOLVED tests for k will become PASS. I haven't looked into why i is taken as optimized away. What I do know is that i isn't tracked by VTA, for VTA only tracks variables that aren't addressable. Not convinced yet? Why, sure, VTA (+ DW_OP_implicit_value) has *only* gone from totally broken j and k at -O0 to totally correct debug info, while somehow *fixing* additional errors for i that is not even tracked by VTA. From 0% to 100% correctness, and 100% completeness for all VTA-tracked variables. But it gets better. Remember those examples from the slides in the VTA presentation in last year's GCC Summit? http://people.redhat.com/~aoliva/papers/vta/ I've turned them into another guality test, that runs with GUALCHK(expr) defined GUALCHKXPRVAL(expr, expr, 0), i.e., it requires variables to be available and computable. typedef struct list { struct list *n; int v; } elt, *node; node find_val (node c, int v, node e) { while (c e) { GUALCHK (c); GUALCHK (v); GUALCHK (e); if (c-v == v) return c; GUALCHK (c); GUALCHK (v); GUALCHK (e); c++; } return NULL; } node find_prev (node c, node w) { while (c) { node o = c; c = c-n; GUALCHK (c); GUALCHK (o); GUALCHK (w); if (c == w) return o; GUALCHK (c); GUALCHK (o); GUALCHK (w); } return NULL; } node check_arr (node c, node e) { if (c == e) return NULL; e--; while (c e) { GUALCHK (c); GUALCHK (e); if (c-v (c+1)-v) return c; GUALCHK (c); GUALCHK (e); c++; } return NULL; } node check_list (node c, node t) { while (c != t) { node n = c-n; GUALCHK (c); GUALCHK (n);
Re: VTA guality assessment: better than -O0 ;-)
Yes, I don't like -O0 producing worse debug info - what does the -O0 -fvar-tracking-assignments results look like? I'd do the opposite: totally disable VTA at -O0 like we do for -fvar-tracking. We once tried to enable -fvar-tracking with -O0 at AdaCore and ended up with bloated and inferior debug info. I think we shouldn't need to do anything at -O0 apart from sufficiently curbing the code generator to get correct naive debug info; the sophisticated stuff should be reserved to -O and above. -- Eric Botcazou
Re: VTA guality assessment: better than -O0 ;-)
On Sat, Jun 13, 2009 at 8:00 PM, Eric Botcazouebotca...@adacore.com wrote: Yes, I don't like -O0 producing worse debug info - what does the -O0 -fvar-tracking-assignments results look like? I'd do the opposite: totally disable VTA at -O0 like we do for -fvar-tracking. We once tried to enable -fvar-tracking with -O0 at AdaCore and ended up with bloated and inferior debug info. I think we shouldn't need to do anything at -O0 apart from sufficiently curbing the code generator to get correct naive debug info; the sophisticated stuff should be reserved to -O and above. Well, I see FAILs for -O0 compared to -O1 with VTA - that doesn't look right. How we fix this is not relevant - but we should try to do so. Richard.
Re: VTA guality assessment: better than -O0 ;-)
Well, I see FAILs for -O0 compared to -O1 with VTA - that doesn't look right. How we fix this is not relevant - but we should try to do so. It would be better not to artificially introduce them in the first place. -- Eric Botcazou
Re: VTA guality assessment: better than -O0 ;-)
On Jun 13, 2009, Richard Guenther richard.guent...@gmail.com wrote: Yes, I don't like -O0 producing worse debug info - what does the -O0 -fvar-tracking-assignments results look like? No difference, -fvar-tracking is disabled at -O0, so either -fvar-tracking-assignments gets disabled as well with a warning (as in the vta patchset I posted before) or it produces and maintains the annotations and discards them where vartrack would have turned them into (the implementation of your suggestion in that regard) -- Alexandre Oliva, freedom fighterhttp://FSFLA.org/~lxoliva/ You must be the change you wish to see in the world. -- Gandhi Be Free! -- http://FSFLA.org/ FSF Latin America board member Free Software Evangelist Red Hat Brazil Compiler Engineer
Re: VTA guality assessment: better than -O0 ;-)
On Sat, Jun 13, 2009 at 08:00:35PM +0200, Eric Botcazou wrote: Yes, I don't like -O0 producing worse debug info - what does the -O0 -fvar-tracking-assignments results look like? I'd do the opposite: totally disable VTA at -O0 like we do for -fvar-tracking. We once tried to enable -fvar-tracking with -O0 at AdaCore and ended up with bloated and inferior debug info. I think we shouldn't need to do anything at -O0 apart from sufficiently curbing the code generator to get correct naive debug info; the sophisticated stuff should be reserved to -O and above. I really think we need to do (limited) -fvar-tracking even for -O0, it is really bad that most arguments have wrong locations through the prologue, while at -O1 or above they often have correct location. We should just do the tracking inside of the prologue or for register variables, those that are stored into memory during the prologue and live in memory shouldn't be tracked outside of the prologue at -O0. Jakub