+2005-01-03 Daniel Berlin <dberlin@dberlin.org>
+
+ 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 <geoffk@apple.com>
* config/darwin.c (darwin_handle_weak_import_attribute): Permit
$(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) \
? 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;
}
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 */
+};
#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. */
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);
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;
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;