diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f94c25f202fd..d9439885c26f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,20 @@ +2005-01-03 Daniel Berlin + + Fix PR debug/17924 + Fix PR debug/19191 + * dwarf2out.c (block_ultimate_origin): Follow decl origin if origin + is a decl. + * gimple-low.c (mark_blocks_with_used_vars): New function. + (mark_blocks_with_used_subblocks): Ditto. + (mark_used_blocks): Ditto. + (pass_mark_used_blocks): New pass. + * tree-inline.c: Include debug.h. + (expand_call_inline): Call outlining_inline_function here. + * tree-optimize.c (init_tree_optimization_passes): Add + pass_mark_used_blocks. + * tree-pass.h (pass_mark_used_blocks): New. + * Makefile.in (tree-inline.o): Add debug.h dependency. + 2005-01-03 Geoffrey Keating * config/darwin.c (darwin_handle_weak_import_attribute): Permit diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 79b13fbea840..a772ccd048b4 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -1594,7 +1594,7 @@ tree-inline.o : tree-inline.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(TREE_H) $(RTL_H) $(EXPR_H) $(FLAGS_H) $(PARAMS_H) input.h insn-config.h \ $(INTEGRATE_H) $(VARRAY_H) $(HASHTAB_H) $(SPLAY_TREE_H) toplev.h \ langhooks.h $(C_COMMON_H) tree-inline.h $(CGRAPH_H) intl.h function.h \ - pointer-set.h $(TREE_GIMPLE_H) + pointer-set.h $(TREE_GIMPLE_H) debug.h print-tree.o : print-tree.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ $(GGC_H) langhooks.h real.h stor-layout.o : stor-layout.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 26174ec1c51b..0ad5ce300465 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -4632,6 +4632,15 @@ block_ultimate_origin (tree 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; } diff --git a/gcc/gimple-low.c b/gcc/gimple-low.c index c6f6f7611e2a..ee57d9beda0e 100644 --- a/gcc/gimple-low.c +++ b/gcc/gimple-low.c @@ -540,3 +540,87 @@ struct tree_opt_pass pass_remove_useless_vars = TODO_dump_func, /* todo_flags_finish */ 0 /* letter */ }; + +/* Mark BLOCK used if it has a used variable in it, then recurse over it's + subblocks. */ + +static void +mark_blocks_with_used_vars (tree block) +{ + tree var; + tree subblock; + + if (!TREE_USED (block)) + { + for (var = BLOCK_VARS (block); + var; + var = TREE_CHAIN (var)) + { + if (TREE_USED (var)) + { + TREE_USED (block) = true; + break; + } + } + } + for (subblock = BLOCK_SUBBLOCKS (block); + subblock; + subblock = BLOCK_CHAIN (subblock)) + mark_blocks_with_used_vars (subblock); +} + +/* Mark BLOCK used if any of it's subblocks have the USED bit set, or it's + abstract origin is used. */ + +static bool +mark_blocks_with_used_subblocks (tree block) +{ + tree subblock; + + /* The block may have no variables, but still be used, if it's abstract + origin is used. This occurs when we inline functions with no parameters + that call functions with no parameters or local vars (such as + dwarf2/dwarf-die7.c). You end up with a block that has an abstract + origin, no variables, and nothing in the subblocks is used. However, the + block is really used, because it's abstract origin was used. */ + + if (BLOCK_ABSTRACT_ORIGIN (block)) + { + if (TREE_USED (BLOCK_ABSTRACT_ORIGIN (block))) + TREE_USED (block) = true; + } + + for (subblock = BLOCK_SUBBLOCKS (block); + subblock; + subblock = BLOCK_CHAIN (subblock)) + TREE_USED (block) |= mark_blocks_with_used_subblocks (subblock); + return TREE_USED (block); +} + +/* Mark the used attribute on blocks correctly. */ + +static void +mark_used_blocks (void) +{ + + mark_blocks_with_used_vars (DECL_INITIAL (current_function_decl)); + mark_blocks_with_used_subblocks (DECL_INITIAL (current_function_decl)); +} + + +struct tree_opt_pass pass_mark_used_blocks = +{ + "blocks", /* name */ + NULL, /* gate */ + mark_used_blocks, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + 0, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_dump_func, /* todo_flags_finish */ + 0 /* letter */ +}; diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 8f3e161d2922..b6ad39940e05 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -43,6 +43,7 @@ Boston, MA 02111-1307, USA. */ #include "tree-mudflap.h" #include "function.h" #include "diagnostic.h" +#include "debug.h" /* I'm not real happy about this, but we need to handle gimple and non-gimple trees. */ @@ -1640,6 +1641,12 @@ expand_call_inline (tree *tp, int *walk_subtrees, void *data) The easiest solution is to simply recalculate TREE_SIDE_EFFECTS for the toplevel expression. */ recalculate_side_effects (expr); + + /* Output the inlining info for this abstract function, since it has been + inlined. If we don't do this now, we can lose the information about the + variables in the function when the blocks get blown away as soon as we + remove the cgraph node. */ + (*debug_hooks->outlining_inline_function) (edge->callee->decl); /* Update callgraph if needed. */ cgraph_remove_node (edge->callee); diff --git a/gcc/tree-optimize.c b/gcc/tree-optimize.c index eae39df90aac..85cfb3a87df4 100644 --- a/gcc/tree-optimize.c +++ b/gcc/tree-optimize.c @@ -399,6 +399,7 @@ init_tree_optimization_passes (void) NEXT_PASS (pass_del_ssa); NEXT_PASS (pass_nrv); NEXT_PASS (pass_remove_useless_vars); + NEXT_PASS (pass_mark_used_blocks); NEXT_PASS (pass_cleanup_cfg_post_optimizing); *p = NULL; diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h index f9270476859f..4468fe5d6c5e 100644 --- a/gcc/tree-pass.h +++ b/gcc/tree-pass.h @@ -158,6 +158,7 @@ extern struct tree_opt_pass pass_redundant_phi; extern struct tree_opt_pass pass_dse; extern struct tree_opt_pass pass_nrv; extern struct tree_opt_pass pass_remove_useless_vars; +extern struct tree_opt_pass pass_mark_used_blocks; extern struct tree_opt_pass pass_rename_ssa_copies; extern struct tree_opt_pass pass_expand; extern struct tree_opt_pass pass_rest_of_compilation;