aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-inline.c
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2013-03-05 09:20:30 +0000
committerRichard Biener <rguenther@suse.de>2013-03-05 09:20:30 +0000
commit8aa3ccbdd01e42876f7430b6ac3d016eb7192ebf (patch)
tree944e306e62bd559731e2480fe1db75db29f8265c /gcc/tree-inline.c
parent0d1cf30d940464982565b8f8b4a38bf6eee77267 (diff)
2013-03-05 Richard Biener <rguenther@suse.de>
PR lto/56515 * tree-inline.c (remap_blocks_to_null): New function. (expand_call_inline): When expanding a call stmt without an associated block inline remap all callee blocks to NULL. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@196452 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-inline.c')
-rw-r--r--gcc/tree-inline.c79
1 files changed, 52 insertions, 27 deletions
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 2a1b6923996..714bcf0fcb0 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -651,6 +651,16 @@ remap_blocks (tree block, copy_body_data *id)
return new_tree;
}
+/* Remap the block tree rooted at BLOCK to nothing. */
+static void
+remap_blocks_to_null (tree block, copy_body_data *id)
+{
+ tree t;
+ insert_decl_map (id, block, NULL_TREE);
+ for (t = BLOCK_SUBBLOCKS (block); t ; t = BLOCK_CHAIN (t))
+ remap_blocks_to_null (t, id);
+}
+
static void
copy_statement_list (tree *tp)
{
@@ -3908,12 +3918,20 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id)
/* Build a block containing code to initialize the arguments, the
actual inline expansion of the body, and a label for the return
statements within the function to jump to. The type of the
- statement expression is the return type of the function call. */
- id->block = make_node (BLOCK);
- BLOCK_ABSTRACT_ORIGIN (id->block) = fn;
- BLOCK_SOURCE_LOCATION (id->block) = input_location;
+ statement expression is the return type of the function call.
+ ??? If the call does not have an associated block then we will
+ remap all callee blocks to NULL, effectively dropping most of
+ its debug information. This should only happen for calls to
+ artificial decls inserted by the compiler itself. We need to
+ either link the inlined blocks into the caller block tree or
+ not refer to them in any way to not break GC for locations. */
if (gimple_block (stmt))
- prepend_lexical_block (gimple_block (stmt), id->block);
+ {
+ id->block = make_node (BLOCK);
+ BLOCK_ABSTRACT_ORIGIN (id->block) = fn;
+ BLOCK_SOURCE_LOCATION (id->block) = input_location;
+ prepend_lexical_block (gimple_block (stmt), id->block);
+ }
/* Local declarations will be replaced by their equivalents in this
map. */
@@ -3942,27 +3960,33 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id)
if (DECL_INITIAL (fn))
{
- tree *var;
-
- prepend_lexical_block (id->block, remap_blocks (DECL_INITIAL (fn), id));
- gcc_checking_assert (BLOCK_SUBBLOCKS (id->block)
- && (BLOCK_CHAIN (BLOCK_SUBBLOCKS (id->block))
- == NULL_TREE));
- /* Move vars for PARM_DECLs from DECL_INITIAL block to id->block,
- otherwise for DWARF DW_TAG_formal_parameter will not be children of
- DW_TAG_inlined_subroutine, but of a DW_TAG_lexical_block
- under it. The parameters can be then evaluated in the debugger,
- but don't show in backtraces. */
- for (var = &BLOCK_VARS (BLOCK_SUBBLOCKS (id->block)); *var; )
- if (TREE_CODE (DECL_ORIGIN (*var)) == PARM_DECL)
- {
- tree v = *var;
- *var = TREE_CHAIN (v);
- TREE_CHAIN (v) = BLOCK_VARS (id->block);
- BLOCK_VARS (id->block) = v;
- }
- else
- var = &TREE_CHAIN (*var);
+ if (gimple_block (stmt))
+ {
+ tree *var;
+
+ prepend_lexical_block (id->block,
+ remap_blocks (DECL_INITIAL (fn), id));
+ gcc_checking_assert (BLOCK_SUBBLOCKS (id->block)
+ && (BLOCK_CHAIN (BLOCK_SUBBLOCKS (id->block))
+ == NULL_TREE));
+ /* Move vars for PARM_DECLs from DECL_INITIAL block to id->block,
+ otherwise for DWARF DW_TAG_formal_parameter will not be children of
+ DW_TAG_inlined_subroutine, but of a DW_TAG_lexical_block
+ under it. The parameters can be then evaluated in the debugger,
+ but don't show in backtraces. */
+ for (var = &BLOCK_VARS (BLOCK_SUBBLOCKS (id->block)); *var; )
+ if (TREE_CODE (DECL_ORIGIN (*var)) == PARM_DECL)
+ {
+ tree v = *var;
+ *var = TREE_CHAIN (v);
+ TREE_CHAIN (v) = BLOCK_VARS (id->block);
+ BLOCK_VARS (id->block) = v;
+ }
+ else
+ var = &TREE_CHAIN (*var);
+ }
+ else
+ remap_blocks_to_null (DECL_INITIAL (fn), id);
}
/* Return statements in the function body will be replaced by jumps
@@ -4106,7 +4130,8 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id)
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) (cg_edge->callee->symbol.decl);
+ if (gimple_block (stmt))
+ (*debug_hooks->outlining_inline_function) (cg_edge->callee->symbol.decl);
/* Update callgraph if needed. */
cgraph_remove_node (cg_edge->callee);