This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]