On Mon, Jul 20, 2015 at 07:55:46PM +0300, Nikolai Bozhenov wrote: > On 07/17/2015 08:31 PM, Michael Eager wrote: > >On 07/17/2015 03:43 AM, Nikolai Bozhenov wrote: > >>Consider the following example: > >> > >> 1 extern void bar(int *i1, int *i2, int *i3); > >> 2 > >> 3 int __attribute__((noinline)) foo(int i1, int i2) { > >> 4 int a, b, c; > >> 5 a = i1 << i2; > >> 6 b = (i1 + i2) * i1; > >> 7 c = (b + i1); > >> 8 bar(&a, &b, &c); > >> 9 } > >> 10 > >> 11 int main() { > >> 12 foo(42, 12); > >> 13 } > >> > >>Let's compile it: > >> > >> $ gcc-trunk tst.c -g -fvar-tracking-uninit -O2
First of all, -fvar-tracking-uninit is misdesigned mess that really should have never been added to GCC, so please don't consider DW_OP_GNU_uninit as something that should be used in any approach for this. As for the reduction of ranges, you've chosen a testcase where it is perhaps possible to track down the first writes to an addressable variable and reduce .debug_loc extents where the corresponding memory is documented as holding the value of the variable. Generally, it is significantly harder though. Consider void foo (int x, int y, int z) { int a; if (x) a = x + 3; if (y) a = y + 2; if (z) a = z - 1; bar (&a, 0, 0); } Where would you consider the range of var a to start? It is initialized conditionally, in some cases it might not be initialized at all before calling bar. Or would you consider a function taking address of a variable known not to be initialized yet as the start of the range? That function might store there a value, but might not (conditionally or unconditionally). Also, think about loop unrolling, if you have: for (int i = 0; i < 16; i++) { { int a; bar (0); a = i; bar (&a); } baz (); } If this is unrolled and a as addressable var is assigned some stack slot, how would you find out which unrolled statement touching the var is from which iteration (and whether to represent the location info as multiple shorter ranges from the a = i; statements to bar (&a); and then again make it optimized away)? Jakub