This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Basic infrastructure for substitution tracking
- From: Alexandre Oliva <aoliva at redhat dot com>
- To: Jan Hubicka <hubicka at ucw dot cz>
- Cc: gcc-patches at gcc dot gnu dot org, jakub at redhat dot com, rguenther at suse dot de
- Date: Wed, 23 Sep 2009 05:42:18 -0300
- Subject: Re: Basic infrastructure for substitution tracking
- References: <20090920153428.GA19087@kam.mff.cuni.cz>
On Sep 20, 2009, Jan Hubicka <hubicka@ucw.cz> wrote:
> Most interesting part is handling in inliner - basically when VAR is getting
> replaced by expression, simplify_value is called first to reconstruct (if
> possible) simple generic expression that reffers to user vars instead of
> temporaries so there is good chance we will be able to work out the value
> of exrpession when outputting debug info.
I'm a bit concerned with the apparent confusion between compiler and
source concepts.
Consider, for example, a function like this:
int f(int i) {
int j = i+1;
...
i = j;
...
}
This could very well be optimized to code that does modify i, say:
int f(int i) {
int j;
j_2 = i_1(D) + 1;
# DEBUG j => j_2
...
# DEBUG i => j_2
...
}
and then, AFAICT, your patch would decide that user variable i is never
modified, just because the âimplementationâ variable i isn't. It would
then proceed to nonlocalize i. Oops.
Conversely, the VAR_VALUE expressions refer to names in the
âimplementationâ namespace, rather than in the âsourceâ namespace. But
then, IIUC, at the time of emitting debug information, you'd interpret
them as if they referred to âsourceâ concepts. This would lead to other
kinds of errors. Consider:
int g(int a) {
int b = a + 1;
k(b);
b = a++;
f(a);
}
Early (pre-inline) optimizations could turn this into:
int g(int a) {
int b;
b_2 = a_1(D);
# DEBUG b => b_2
k(b_2);
# DEBUG b => a_1(D)
# DEBUG a => b_2
f(b_2);
}
Now, if you inline f and decide you should map f's i to g's b, as it
might seem like you should do, you lose, because the implementation name
b_2 at that point holds the value for user variable a, not for b.
As such, I don't see much benefit for nonlocalizing VTA-trackable
variables. For variables that are correctly amenable to this kind of
mapping, we should have no more than the inlined-entry-point debug stmt
for the parameter, which should end up as a single const_value or
location expression, applicable to the entire range, and without mixing
up and confusing source concepts with implementation concepts that could
result in incorrect debug information.
As for variables that currently aren't tracked by VTA...
For fully-scalarized variables (i.e., those for which a structure does
not survive), each component variable could in in theory be handled as a
VTA-trackable (one-part) variable, getting its own debug stmts and all.
Nothing actually prevents SR decls from showing up in debug stmts, and
all we have to do to deal with them properly at debug info generation
time is to consolidate the location lists for each part of the aggregate
source variable into a single location list. AFAIK there's no reason to
actually *combine* the separate parts into location list entries. I.e.,
for a variable of type struct { int a, b; }, we could emit location
lists such as:
[PC1, PC2) <location for a> DW_OP_piece 4 [missing] DW_OP_piece 4
[PC2, PC3) <location for a> DW_OP_piece 4 [missing] DW_OP_piece 4
...
[PC1, PC3) [missing] DW_OP_piece 4 <location for b> DW_OP_piece 4
[PC3, PC4) [missing] DW_OP_piece 4 <location for b> DW_OP_piece 4
...
Partially-scalarized variables (i.e., those that retain an aggregate
variable, and fields are extracted from or stored in it), similar
arrangements could work, at least for the scalarized variables, that
should get debug stmts when they get extracted or stored in the
structure. However, non-scalarized components might require more than
an initial bind statement, for aliasing memory stores may cause the
value binding to be invalidated. To deal properly with aliased memory
locations, we'd need a location bind, rather than a value bind, so that
memory stores don't invalidate the association between source name and
memory location. The alternative would be to emit additional debug
stmts at every aliasing store, which would be wasteful.
As for non-scalarizable variables, these are always (?) addressable (no
benefit from var-tracking, because their location is constant) or fully
removed (could be handled just like fully-scalarized variables). I can
see how NONLOCALIZED vars could help improve debug info for the latter
case, at least for as long as VTA can't deal with the scalarized cases.
--
Alexandre Oliva, freedom fighter http://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