aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2009-02-23 14:10:53 +0100
committerJan Hubicka <hubicka@gcc.gnu.org>2009-02-23 13:10:53 +0000
commit61e043223d29e848f24fa5ca8aaeb968e341d6c6 (patch)
treed5fc8eef4ee0352c6b6283866a64b8d5d9ec3bde /gcc
parent791c5e482115ebb266ca3c97881b7ea10f267521 (diff)
downloadgcc-61e043223d29e848f24fa5ca8aaeb968e341d6c6.zip
gcc-61e043223d29e848f24fa5ca8aaeb968e341d6c6.tar.gz
gcc-61e043223d29e848f24fa5ca8aaeb968e341d6c6.tar.bz2
re PR tree-optimization/37709 (inlining causes explosion in debug info)
PR tree-optimization/37709 * tree.c (block_ultimate_origin): Move here from dwarf2out. * tree.h (block_ultimate_origin): Declare. * dwarf2out.c (block_ultimate_origin): Move to tree.c * tree-ssa-live.c (remove_unused_scope_block_p): Eliminate blocks containig no instructions nor live variables nor nested blocks. (dump_scope_block): New function. (remove_unused_locals): Enable removal of dead blocks by default; enable dumping at TDF_DETAILS. From-SVN: r144381
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/dbxout.c2
-rw-r--r--gcc/dwarf2out.c46
-rw-r--r--gcc/tree-ssa-live.c70
-rw-r--r--gcc/tree.c45
-rw-r--r--gcc/tree.h1
6 files changed, 117 insertions, 60 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 1961e74..01968ba 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,16 @@
+2009-02-23 Jan Hubicka <jh@suse.cz>
+
+ PR tree-optimization/37709
+ * tree.c (block_ultimate_origin): Move here from dwarf2out.
+ * tree.h (block_ultimate_origin): Declare.
+ * dwarf2out.c (block_ultimate_origin): Move to tree.c
+ * tree-ssa-live.c (remove_unused_scope_block_p):
+ Eliminate blocks containig no instructions nor live variables nor
+ nested blocks.
+ (dump_scope_block): New function.
+ (remove_unused_locals): Enable removal of dead blocks by default;
+ enable dumping at TDF_DETAILS.
+
2008-02-21 H.J. Lu <hongjiu.lu@intel.com>
* config/i386/i386.c (classify_argument): Don't allow COImode
diff --git a/gcc/dbxout.c b/gcc/dbxout.c
index f4a2792..6cfa55f 100644
--- a/gcc/dbxout.c
+++ b/gcc/dbxout.c
@@ -3593,7 +3593,7 @@ dbxout_block (tree block, int depth, tree args)
while (block)
{
/* Ignore blocks never expanded or otherwise marked as real. */
- if (TREE_USED (block) && TREE_ASM_WRITTEN (block))
+ if (TREE_ASM_WRITTEN (block))
{
int did_output;
int blocknum = BLOCK_NUMBER (block);
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index d3de6e6..2e5f032 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -4947,7 +4947,6 @@ static const char *dwarf_tag_name (unsigned);
static const char *dwarf_attr_name (unsigned);
static const char *dwarf_form_name (unsigned);
static tree decl_ultimate_origin (const_tree);
-static tree block_ultimate_origin (const_tree);
static tree decl_class_context (tree);
static void add_dwarf_attr (dw_die_ref, dw_attr_ref);
static inline enum dw_val_class AT_class (dw_attr_ref);
@@ -5772,51 +5771,6 @@ decl_ultimate_origin (const_tree decl)
return DECL_ABSTRACT_ORIGIN (decl);
}
-/* Determine the "ultimate origin" of a block. The block may be an inlined
- instance of an inlined instance of a block which is local to an inline
- function, so we have to trace all of the way back through the origin chain
- to find out what sort of node actually served as the original seed for the
- given block. */
-
-static tree
-block_ultimate_origin (const_tree block)
-{
- tree immediate_origin = BLOCK_ABSTRACT_ORIGIN (block);
-
- /* output_inline_function sets BLOCK_ABSTRACT_ORIGIN for all the
- nodes in the function to point to themselves; ignore that if
- we're trying to output the abstract instance of this function. */
- if (BLOCK_ABSTRACT (block) && immediate_origin == block)
- return NULL_TREE;
-
- if (immediate_origin == NULL_TREE)
- return NULL_TREE;
- else
- {
- tree ret_val;
- tree lookahead = immediate_origin;
-
- do
- {
- ret_val = lookahead;
- lookahead = (TREE_CODE (ret_val) == BLOCK
- ? BLOCK_ABSTRACT_ORIGIN (ret_val) : NULL);
- }
- while (lookahead != NULL && lookahead != ret_val);
-
- /* The block's abstract origin chain may not be the *ultimate* origin of
- the block. It could lead to a DECL that has an abstract origin set.
- If so, we want that DECL's abstract origin (which is what DECL_ORIGIN
- will give us if it has one). Note that DECL's abstract origins are
- supposed to be the most distant ancestor (or so decl_ultimate_origin
- claims), so we don't need to loop following the DECL origins. */
- if (DECL_P (ret_val))
- return DECL_ORIGIN (ret_val);
-
- return ret_val;
- }
-}
-
/* Get the class to which DECL belongs, if any. In g++, the DECL_CONTEXT
of a virtual function may refer to a base class, so we check the 'this'
parameter. */
diff --git a/gcc/tree-ssa-live.c b/gcc/tree-ssa-live.c
index 8ebf30e..81e65f7 100644
--- a/gcc/tree-ssa-live.c
+++ b/gcc/tree-ssa-live.c
@@ -485,10 +485,13 @@ remove_unused_scope_block_p (tree scope)
next = &TREE_CHAIN (*t);
/* Debug info of nested function refers to the block of the
- function. */
+ function. We might stil call it even if all statements
+ of function it was nested into was elliminated.
+
+ TODO: We can actually look into cgraph to see if function
+ will be output to file. */
if (TREE_CODE (*t) == FUNCTION_DECL)
unused = false;
-
/* Remove everything we don't generate debug info for. */
else if (DECL_IGNORED_P (*t))
{
@@ -506,15 +509,24 @@ remove_unused_scope_block_p (tree scope)
/* When we are not doing full debug info, we however can keep around
only the used variables for cfgexpand's memory packing saving quite
- a lot of memory. */
+ a lot of memory.
+
+ For sake of -g3, we keep around those vars but we don't count this as
+ use of block, so innermost block with no used vars and no instructions
+ 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. */
+
else if (debug_info_level == DINFO_LEVEL_NORMAL
|| debug_info_level == DINFO_LEVEL_VERBOSE
/* Removing declarations before inlining is going to affect
DECL_UID that in turn is going to affect hashtables and
code generation. */
|| !cfun->after_inlining)
- unused = false;
-
+ ;
else
{
*t = TREE_CHAIN (*t);
@@ -537,10 +549,7 @@ remove_unused_scope_block_p (tree scope)
nsubblocks ++;
}
else
- {
- gcc_assert (!BLOCK_VARS (*t));
- *t = BLOCK_CHAIN (*t);
- }
+ *t = BLOCK_CHAIN (*t);
}
else
{
@@ -576,6 +585,38 @@ mark_all_vars_used (tree *expr_p, void *data)
walk_tree (expr_p, mark_all_vars_used_1, data, NULL);
}
+/* Dump scope blocks. */
+
+static void
+dump_scope_block (FILE *file, int indent, tree scope, int flags)
+{
+ tree var, t;
+
+ fprintf (file, "\n%*sScope block #%i %s\n",indent, "" , BLOCK_NUMBER (scope),
+ TREE_USED (scope) ? "" : "(unused)");
+ if (BLOCK_ABSTRACT_ORIGIN (scope) && DECL_P (block_ultimate_origin (scope)))
+ {
+ fprintf (file, "\n%*sOriginating from ",indent + 1, "");
+ print_generic_decl (file, block_ultimate_origin (scope), flags);
+ fprintf (file, "\n");
+ }
+ for (var = BLOCK_VARS (scope); var; var = TREE_CHAIN (var))
+ {
+ bool used = false;
+ var_ann_t ann;
+
+ if ((ann = var_ann (var))
+ && ann->used)
+ used = true;
+
+ fprintf (file, "%*s",indent, "");
+ print_generic_decl (file, var, flags);
+ fprintf (file, "%s\n", used ? "" : " (unused)");
+ }
+ for (t = BLOCK_SUBBLOCKS (scope); t ; t = BLOCK_CHAIN (t))
+ dump_scope_block (file, indent + 2, t, flags);
+}
+
/* Remove local variables that are not referenced in the IL. */
@@ -588,8 +629,7 @@ remove_unused_locals (void)
var_ann_t ann;
bitmap global_unused_vars = NULL;
- if (optimize)
- mark_scope_block_unused (DECL_INITIAL (current_function_decl));
+ mark_scope_block_unused (DECL_INITIAL (current_function_decl));
/* Assume all locals are unused. */
FOR_EACH_REFERENCED_VAR (t, rvi)
@@ -716,8 +756,12 @@ remove_unused_locals (void)
&& !TREE_ADDRESSABLE (t)
&& (optimize || DECL_ARTIFICIAL (t)))
remove_referenced_var (t);
- if (optimize)
- remove_unused_scope_block_p (DECL_INITIAL (current_function_decl));
+ remove_unused_scope_block_p (DECL_INITIAL (current_function_decl));
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "Scope blocks after cleanups:\n");
+ dump_scope_block (dump_file, 0, DECL_INITIAL (current_function_decl), false);
+ }
}
diff --git a/gcc/tree.c b/gcc/tree.c
index 03c54cc..423c868 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -9199,4 +9199,49 @@ build_target_option_node (void)
return t;
}
+/* Determine the "ultimate origin" of a block. The block may be an inlined
+ instance of an inlined instance of a block which is local to an inline
+ function, so we have to trace all of the way back through the origin chain
+ to find out what sort of node actually served as the original seed for the
+ given block. */
+
+tree
+block_ultimate_origin (const_tree block)
+{
+ tree immediate_origin = BLOCK_ABSTRACT_ORIGIN (block);
+
+ /* output_inline_function sets BLOCK_ABSTRACT_ORIGIN for all the
+ nodes in the function to point to themselves; ignore that if
+ we're trying to output the abstract instance of this function. */
+ if (BLOCK_ABSTRACT (block) && immediate_origin == block)
+ return NULL_TREE;
+
+ if (immediate_origin == NULL_TREE)
+ return NULL_TREE;
+ else
+ {
+ tree ret_val;
+ tree lookahead = immediate_origin;
+
+ do
+ {
+ ret_val = lookahead;
+ lookahead = (TREE_CODE (ret_val) == BLOCK
+ ? BLOCK_ABSTRACT_ORIGIN (ret_val) : NULL);
+ }
+ while (lookahead != NULL && lookahead != ret_val);
+
+ /* The block's abstract origin chain may not be the *ultimate* origin of
+ the block. It could lead to a DECL that has an abstract origin set.
+ If so, we want that DECL's abstract origin (which is what DECL_ORIGIN
+ will give us if it has one). Note that DECL's abstract origins are
+ supposed to be the most distant ancestor (or so decl_ultimate_origin
+ claims), so we don't need to loop following the DECL origins. */
+ if (DECL_P (ret_val))
+ return DECL_ORIGIN (ret_val);
+
+ return ret_val;
+ }
+}
+
#include "gt-tree.h"
diff --git a/gcc/tree.h b/gcc/tree.h
index 5a7e765..ae42913 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -5022,6 +5022,7 @@ extern bool gimple_alloca_call_p (const_gimple);
extern bool alloca_call_p (const_tree);
extern bool must_pass_in_stack_var_size (enum machine_mode, const_tree);
extern bool must_pass_in_stack_var_size_or_pad (enum machine_mode, const_tree);
+extern tree block_ultimate_origin (const_tree);
/* In attribs.c. */