Message ID | or62tkfs5p.fsf@livre.localdomain |
---|---|
State | New |
Headers | show |
On Wed, Jan 19, 2011 at 11:24 PM, Alexandre Oliva <aoliva@redhat.com> wrote: > Ping? > > On Nov 24, 2010, Alexandre Oliva <aoliva@redhat.com> wrote: > >> Dropping type decls from block locals before inlining affects DECL_UID >> ordering, which may in turn cause -g/-g0 codegen differences. In the >> given testcase, it's just a -fcompare-debug error, but the test could >> presumably be expanded to trigger actual differences in codegen. > >> The problem is that, when we discard a typedef decl from a lexical >> block, and then inline or clone it, we fail to remap it and its >> underlying type at that moment. We may remap other decls before we even >> get a chance to get to it: if some variable decl uses that type, we'll >> remap the variable before remapping the type, so we've already >> introduced differences. It would get worse if other significant decls >> stood in between the typedef and the variable decl. > >> The problem is further complicated because the decision on whether the >> variable can be nonlocalized depends on whether its type, if needing >> remapping, was already remapped when the time comes to remap the >> variable. So, if we've removed the typedef from its lexical block and >> there's no intervening use of the type, we won't have remapped it yet, >> and the variable will be kept in the local list. I'm not sure whether >> this may have additional implications for codegen. > >> I'm a bit concerned that the problem might be even more serious: >> discarding random variable declarations might change the order of >> remapping of types, and change which variables are regarded as >> nonlocalized, both of which might have implications to codegen (the >> first one certainly would). > >> Now, in C and C++, only local types would have to be remapped in this >> way (global types would reuse the same type AFAIK), and then, if we keep >> local type decls around, we'll remap them before we get to the >> variables, and everything should be fine. I'm concerned, however, that >> this may not hold for other languages, or maybe even in GNU-extended >> versions of C (nested functions referencing local types of the enclosing >> function come to mind). > >> Anyhow, it seems to me that dropping local type decls from lexical >> scopes doesn't buy us much, and even though it is indeed a sledgehammer, >> as richi put it, this fixes the problem, and I can't envision other >> simpler solutions that wouldn't risk running into the problems mentioned >> above, so... > >> Regstrapped on x86_64-linux-gnu and i686-pc-linux-gnu. Ok to install? > > >> One solution I do envision, which might help, would be to try to figure >> out which types are unused, and discard those. Say, scan all variables >> within a lexical scope (including nested blocks), deciding which ones >> can be discarded, and then, as we move out of the nesting, we can >> decide, from last to first, which types are unused, and mark as used >> types refereced from retained variables and other types that are used, >> removing those that, when reached during this backward scan, remain >> marked as unused. Or something along these lines, taking nested >> functions into account, if needed, and anything else I may have missed >> ;-) Ok. Thanks, Richard. > > > -- > 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 > >
for gcc/ChangeLog from Alexandre Oliva <aoliva@redhat.com> PR debug/46583 * tree-ssa-live.c (remove_unused_scope_block_p): Keep type decls. for gcc/testsuite/ChangeLog from Alexandre Oliva <aoliva@redhat.com> PR debug/46583 * g++.dg/debug/pr46583.C: New. Index: gcc/tree-ssa-live.c =================================================================== --- gcc/tree-ssa-live.c.orig 2010-11-21 04:57:04.505193778 -0200 +++ gcc/tree-ssa-live.c 2010-11-21 04:53:31.279647303 -0200 @@ -491,11 +491,16 @@ remove_unused_scope_block_p (tree scope) can be considered dead. We only want to keep around blocks user can breakpoint into and ask about value of optimized out variables. - Similarly we need to keep around types at least until all variables of - all nested blocks are gone. We track no information on whether given - type is used or not. */ + Similarly we need to keep around types at least until all + variables of all nested blocks are gone. We track no + information on whether given type is used or not, so we have + to keep them even when not emitting debug information, + otherwise we may end up remapping variables and their (local) + types in different orders depending on whether debug + information is being generated. */ - else if (debug_info_level == DINFO_LEVEL_NORMAL + else if (TREE_CODE (*t) == TYPE_DECL + || debug_info_level == DINFO_LEVEL_NORMAL || debug_info_level == DINFO_LEVEL_VERBOSE) ; else Index: gcc/testsuite/g++.dg/debug/pr46583.C =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ gcc/testsuite/g++.dg/debug/pr46583.C 2010-11-21 04:56:07.361194389 -0200 @@ -0,0 +1,40 @@ +// PR debug/46583 +// { dg-do compile } +// { dg-options "-O -fno-inline -fipa-cp -fipa-cp-clone -fcompare-debug" } + +template < typename = unsigned long >struct A +{ + unsigned long elems[3]; + unsigned long *begin () + { + return 0; + } +}; + +void +bar (unsigned long *a1, unsigned long, unsigned long *a3, unsigned const &) +{ + *a3 = *a1; +} + +A < >operatorM (A < >a1, unsigned long a2) +{ + typedef A < >G; + G a3; + bar (a1.begin (), a2, a3.begin (), 0); + return a3; +} + +struct B +{ + B (A < >m):n (operatorM (m, 1)) + { + } + A < >n; +}; + +void +foo () +{ + B (A < >()); +}