From patchwork Thu Jan 6 10:11:16 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [PR,debug/47106] account used vars only once From: Alexandre Oliva X-Patchwork-Id: 77699 Message-Id: To: gcc-patches@gcc.gnu.org Date: Thu, 06 Jan 2011 08:11:16 -0200 This -fcompare-debug failure occurs because we remove variables from the lexical blocks in the compilation without debug info, but we account the stack space they won't use in the compilation with debug info, which leads to different inlining decisions when stack-growth limits are set. It turns out that the use of TREE_USED in the stack frame size estimation functions seems to be misguided: we initially set it for all local decls that don't appear in lexical blocks (not shown in patch), then account the size of all LOCAL_DECLs that have it set (which means accounting only those that don't appear in lexical blocks), set it on all LOCAL_DECLs, and then account the size of decls in lexical blocks if they have TREE_USED (which means accounting only those that are in LOCAL_DECLs, not accounting those that aren't). I fixed it so that we leave TREE_USED alone after initialization: we account variables that aren't in lexical blocks while looping over LOCAL_DECLs, and then account all variables in lexical blocks, as long as they are actually used, which avoids accounting declarations retained only for purposes of debug information generation. I suppose restoring the assignment and test of TREE_USED would also work, but AFAICT it would just waste CPU cycles. This was regstrapped on x86_{32,64}-linux-gnu. I also bootstrapped it with BOOT_CFLAGS='-O2 -g -fpartial-inlining -flto -fconserve-stack', and regstrapping succeeded except for gfortran.dg/realloc_on_assign_2.exe at all torture levels: stage3 f951 fails to compile it, although a non-bootstrap f951 does, on both x86_{32,64}. From that I concluded that stage[23]s are miscompiled with these BOOT_CFLAGS above, even before my patch, but I haven't debugged or investigated that any further. Ok to install? for gcc/ChangeLog from Alexandre Oliva PR debug/47106 * cfgexpand.c (account_used_vars_for_block): Only account vars that are annotated as used. (estimated_stack_frame_size): Don't set TREE_USED. Index: gcc/cfgexpand.c =================================================================== --- gcc/cfgexpand.c.orig 2010-12-30 18:05:43.930553884 -0200 +++ gcc/cfgexpand.c 2011-01-04 02:39:50.745382341 -0200 @@ -1325,7 +1325,7 @@ account_used_vars_for_block (tree block, /* Expand all variables at this level. */ for (t = BLOCK_VARS (block); t ; t = DECL_CHAIN (t)) - if (TREE_USED (t)) + if (var_ann (t) && var_ann (t)->used) size += expand_one_var (t, toplevel, false); /* Expand all variables at containing levels. */ @@ -1389,9 +1389,10 @@ estimated_stack_frame_size (tree decl) FOR_EACH_LOCAL_DECL (cfun, ix, var) { + /* TREE_USED marks local variables that do not appear in lexical + blocks. We don't want to expand those that do twice. */ if (TREE_USED (var)) size += expand_one_var (var, true, false); - TREE_USED (var) = 1; } size += account_used_vars_for_block (outer_block, true);