This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Copy debug info properly in the inliner
Hi,
here is updated patch. I've changed unexpanded_var_list to contains
only the VAR_DECLs and apparently nothing broke, so things are little
bit easier now.
PS: I just noticed I forgot to replace the code setting TREE_BLOCK. I
am testing patch with the change suggested now, but those should be
equivalent so I might use that one instead if rest looksfine.
Bootstrapped/regtested i686-pc-gnu-linux, OK?
Honza
2005-06-24 Jan Hubicka <jh@suse.cz>
* function.h (struct function): Add saved blocks/unexpanded var list.
* gimple-low.c (record_vars): Insert only VAR_DECLs.
* tree-inline.c (add_lexical_block): Declare; do not clear sublocks.
(remap_decl): Do not declare vars.
(remap_block): Do not care inserting blocks.
(remap_blocks): New function.
(copy_body_r): Update debug info.
(expand_call_inline): Duplicate callee block tree into caller;
copy all the unexpanded_var_list.
(save_body): Save unexpanded_var_list and blocks.
* tree-optimize.c (tree_rest_of_optimization): Restore
blocks/unexpanded_var_list.
Index: function.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/function.h,v
retrieving revision 1.155
diff -c -3 -p -r1.155 function.h
*** function.h 27 Jun 2005 07:40:57 -0000 1.155
--- function.h 27 Jun 2005 16:17:15 -0000
*************** struct function GTY(())
*** 178,183 ****
--- 178,185 ----
inlining */
tree saved_args;
tree saved_static_chain_decl;
+ tree saved_blocks;
+ tree saved_unexpanded_var_list;
/* For function.c. */
Index: gimple-low.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gimple-low.c,v
retrieving revision 2.25
diff -c -3 -p -r2.25 gimple-low.c
*** gimple-low.c 25 Jun 2005 02:00:19 -0000 2.25
--- gimple-low.c 27 Jun 2005 16:17:15 -0000
*************** record_vars (tree vars)
*** 516,526 ****
{
tree var = vars;
/* Nothing to do in this case. */
if (DECL_EXTERNAL (var))
continue;
- if (TREE_CODE (var) == FUNCTION_DECL)
- continue;
/* Record the variable. */
cfun->unexpanded_var_list = tree_cons (NULL_TREE, var,
--- 516,528 ----
{
tree var = vars;
+ /* BIND_EXPRs contains also function/type/constant declarations
+ we don't need to care about. */
+ if (TREE_CODE (var) != VAR_DECL)
+ continue;
/* Nothing to do in this case. */
if (DECL_EXTERNAL (var))
continue;
/* Record the variable. */
cfun->unexpanded_var_list = tree_cons (NULL_TREE, var,
Index: tree-inline.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-inline.c,v
retrieving revision 1.198
diff -c -3 -p -r1.198 tree-inline.c
*** tree-inline.c 25 Jun 2005 02:01:22 -0000 1.198
--- tree-inline.c 27 Jun 2005 16:17:15 -0000
*************** static void declare_inline_vars (tree, t
*** 159,164 ****
--- 159,165 ----
static void remap_save_expr (tree *, void *, int *);
static inline bool inlining_p (inline_data *id);
+ static void add_lexical_block (tree current_block, tree new_block);
/* Insert a tree->tree mapping for ID. Despite the name suggests
that the trees should be variables, it is used for more than that. */
*************** remap_decl (tree decl, inline_data *id)
*** 246,258 ****
}
#endif
- /* If we are inlining and this is a variable (not a label), declare the
- remapped variable in the callers' body. */
- if (inlining_p (id)
- && (TREE_CODE (t) == VAR_DECL
- || TREE_CODE (t) == PARM_DECL))
- declare_inline_vars (id->block, t);
-
/* Remember it, so that if we encounter this local entity
again we can reuse this copy. */
insert_decl_map (id, decl, t);
--- 247,252 ----
*************** remap_block (tree *block, inline_data *i
*** 436,467 ****
BLOCK_VARS (new_block) = remap_decls (BLOCK_VARS (old_block), id);
fn = id->caller;
- #if 1
- /* FIXME! It shouldn't be so hard to manage blocks. Rebuilding them in
- rest_of_compilation is a good start. */
if (id->cloning_p)
/* We're building a clone; DECL_INITIAL is still
error_mark_node, and current_binding_level is the parm
binding level. */
lang_hooks.decls.insert_block (new_block);
- else
- {
- /* Attach this new block after the DECL_INITIAL block for the
- function into which this block is being inlined. In
- rest_of_compilation we will straighten out the BLOCK tree. */
- tree *first_block;
- if (DECL_INITIAL (fn))
- first_block = &BLOCK_CHAIN (DECL_INITIAL (fn));
- else
- first_block = &DECL_INITIAL (fn);
- BLOCK_CHAIN (new_block) = *first_block;
- *first_block = new_block;
- }
- #endif
/* Remember the remapped block. */
insert_decl_map (id, old_block, new_block);
}
static void
copy_statement_list (tree *tp)
{
--- 430,461 ----
BLOCK_VARS (new_block) = remap_decls (BLOCK_VARS (old_block), id);
fn = id->caller;
if (id->cloning_p)
/* We're building a clone; DECL_INITIAL is still
error_mark_node, and current_binding_level is the parm
binding level. */
lang_hooks.decls.insert_block (new_block);
/* Remember the remapped block. */
insert_decl_map (id, old_block, new_block);
}
+ /* Copy the whole block tree and root it in id->block. */
+ static tree
+ remap_blocks (tree block, inline_data *id)
+ {
+ tree t;
+ tree new = block;
+
+ if (!block)
+ return NULL;
+
+ remap_block (&new, id);
+ gcc_assert (new != block);
+ for (t = BLOCK_SUBBLOCKS (block); t ; t = BLOCK_CHAIN (t))
+ add_lexical_block (new, remap_blocks (t, id));
+ return new;
+ }
+
static void
copy_statement_list (tree *tp)
{
*************** copy_body_r (tree *tp, int *walk_subtree
*** 647,655 ****
/* Here is the "usual case". Copy this tree node, and then
tweak some special cases. */
copy_tree_r (tp, walk_subtrees, NULL);
! if (id->block
! && IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (*tp))))
! TREE_BLOCK (*tp) = id->block;
if (TREE_CODE (*tp) == RESX_EXPR && id->eh_region_offset)
TREE_OPERAND (*tp, 0) =
--- 641,663 ----
/* Here is the "usual case". Copy this tree node, and then
tweak some special cases. */
copy_tree_r (tp, walk_subtrees, NULL);
!
! /* If EXPR has block defined, map it to newly constructed block.
! (if set previously by remap_block, when saving blocks are not remapped
! at all)
! When inlining we want EXPRs without block appear in the block
! of function call. */
! if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (*tp))))
! {
! splay_tree_node n;
!
! n = splay_tree_lookup (id->decl_map,
! (splay_tree_key) TREE_BLOCK (*tp));
! if (n)
! TREE_BLOCK (*tp) = (tree)n->value;
! else if (id->block)
! TREE_BLOCK (*tp) = id->block;
! }
if (TREE_CODE (*tp) == RESX_EXPR && id->eh_region_offset)
TREE_OPERAND (*tp, 0) =
*************** add_lexical_block (tree current_block, t
*** 1870,1876 ****
;
*blk_p = new_block;
BLOCK_SUPERCONTEXT (new_block) = current_block;
- BLOCK_SUBBLOCKS (new_block) = NULL_TREE;
}
/* If *TP is a CALL_EXPR, replace it with its inline expansion. */
--- 1878,1883 ----
*************** expand_call_inline (basic_block bb, tree
*** 2032,2037 ****
--- 2039,2049 ----
/* Record the function we are about to inline. */
id->callee = fn;
+ if (DECL_STRUCT_FUNCTION (fn)->saved_blocks)
+ add_lexical_block (id->block, remap_blocks (DECL_STRUCT_FUNCTION (fn)->saved_blocks, id));
+ else if (DECL_INITIAL (fn))
+ add_lexical_block (id->block, remap_blocks (DECL_INITIAL (fn), id));
+
/* Return statements in the function body will be replaced by jumps
to the RET_LABEL. */
*************** expand_call_inline (basic_block bb, tree
*** 2085,2090 ****
--- 2097,2117 ----
copy_body (id, bb->count, bb->frequency, bb, return_block);
id->current_node = old_node;
+ /* Add local vars in this inlined callee to caller. */
+ t_step = id->callee_cfun->unexpanded_var_list;
+ if (id->callee_cfun->saved_unexpanded_var_list)
+ t_step = id->callee_cfun->saved_unexpanded_var_list;
+ for (; t_step; t_step = TREE_CHAIN (t_step))
+ {
+ var = TREE_VALUE (t_step);
+ if (TREE_STATIC (var) && !TREE_ASM_WRITTEN (var))
+ cfun->unexpanded_var_list = tree_cons (NULL_TREE, var,
+ cfun->unexpanded_var_list);
+ else
+ cfun->unexpanded_var_list = tree_cons (NULL_TREE, remap_decl (var, id),
+ cfun->unexpanded_var_list);
+ }
+
/* Clean up. */
splay_tree_delete (id->decl_map);
id->decl_map = st;
*************** expand_call_inline (basic_block bb, tree
*** 2122,2137 ****
/* Declare the 'auto' variables added with this inlined body. */
record_vars (BLOCK_VARS (id->block));
id->block = NULL_TREE;
-
- /* Add local static vars in this inlined callee to caller. */
- for (t_step = id->callee_cfun->unexpanded_var_list;
- t_step;
- t_step = TREE_CHAIN (t_step))
- {
- var = TREE_VALUE (t_step);
- if (TREE_STATIC (var) && !TREE_ASM_WRITTEN (var))
- record_vars (var);
- }
successfully_inlined = TRUE;
egress:
--- 2149,2154 ----
*************** save_body (tree fn, tree *arg_copy, tree
*** 2270,2275 ****
--- 2287,2293 ----
inline_data id;
tree newdecl, *parg;
basic_block fn_entry_block;
+ tree t_step;
memset (&id, 0, sizeof (id));
id.callee = fn;
*************** save_body (tree fn, tree *arg_copy, tree
*** 2308,2313 ****
--- 2326,2345 ----
insert_decl_map (&id, DECL_RESULT (fn), DECL_RESULT (fn));
+ DECL_STRUCT_FUNCTION (fn)->saved_blocks = remap_blocks (DECL_INITIAL (fn), &id);
+ for (t_step = id.callee_cfun->unexpanded_var_list;
+ t_step;
+ t_step = TREE_CHAIN (t_step))
+ {
+ tree var = TREE_VALUE (t_step);
+ if (TREE_STATIC (var) && !TREE_ASM_WRITTEN (var))
+ cfun->saved_unexpanded_var_list = tree_cons (NULL_TREE, var,
+ cfun->saved_unexpanded_var_list);
+ else
+ cfun->saved_unexpanded_var_list = tree_cons (NULL_TREE, remap_decl (var, &id),
+ cfun->saved_unexpanded_var_list);
+ }
+
/* Actually copy the body, including a new (struct function *) and CFG.
EH info is also duplicated so its labels point into the copied
CFG, not the original. */
Index: tree-optimize.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-optimize.c,v
retrieving revision 2.112
diff -c -3 -p -r2.112 tree-optimize.c
*** tree-optimize.c 27 Jun 2005 12:17:20 -0000 2.112
--- tree-optimize.c 27 Jun 2005 16:17:15 -0000
*************** tree_rest_of_compilation (tree fndecl)
*** 841,849 ****
--- 841,853 ----
DECL_ARGUMENTS (fndecl) = cfun->saved_args;
cfun->cfg = cfun->saved_cfg;
cfun->eh = cfun->saved_eh;
+ DECL_INITIAL (fndecl) = cfun->saved_blocks;
+ cfun->unexpanded_var_list = cfun->saved_unexpanded_var_list;
cfun->saved_cfg = NULL;
cfun->saved_eh = NULL;
cfun->saved_args = NULL_TREE;
+ cfun->saved_blocks = NULL_TREE;
+ cfun->saved_unexpanded_var_list = NULL_TREE;
cfun->static_chain_decl = cfun->saved_static_chain_decl;
cfun->saved_static_chain_decl = NULL;
/* When not in unit-at-a-time mode, we must preserve out of line copy