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]

Basic infrastructure for substitution tracking


Hi,
this patch adds basic infrastructure for NONLOCALIZED_VARs.  Without dwarf2out
patches to output them and inliner patches to produce them it does essentially
nothing, but contains all the tricky bits.

Most interesting part is handling in inliner - basically when VAR is getting
replaced by expression, simplify_value is called first to reconstruct (if
possible) simple generic expression that reffers to user vars instead of
temporaries so there is good chance we will be able to work out the value
of exrpession when outputting debug info.

Nested inlining needs a care, since the replacements needs to be updated. Also
when we decide that some variable will be fully substituted, we need to update
debug statements properly, so I am using insert_debug_decl_map whenever I
invent new replacement and relaxed the restriction that insert_debug_decl_map
must map parameter to variable, now it can map to expression. My understanding
is that this is OK, since debug statements can contain quite arbitrary gimple
expressions same way as I do with the subtitutions.

the tree-ssa-live.c code is there to get rid of expressions that no longer makes
sense (i.e. reffer to variables we completely lose track of) so we save some memory
and have better idea how the debug info quality is degrading.

Bootstrapped/regtested x86_64-linux, OK?

Honza

	* tree-pretty-print.c (dump_block_node): Update handling of
	BLOCK_NONLOCALIZED_VARS.
	* tree.h (nonlocalized_var): New struct.
	(BLOCK_NUM_NONLOCALIZED_VARS, BLOCK_NONLOCALIZED_VAR): Update.
	(BLOCK_NONLOCALIZED_VAR_VALUE): New.
	(tree_block): Turn nonlocalized_vars into vector of structures.
	* tree-ssa-live.c (lookup_dead_vars): New function.
	(remove_unused_scope_block_p): Prune nonlocalized vars list.
	(dump_scope_block): Dump nonlocalized vars.
	(remap_decls): Update for handling of nonlocalized vars.
	(simplify_value): New function.
	(declare_nonlocalized_var): New function.
	(remap_decls): Update VALUE_EXPRs.
	(remap_block): Likewise.
	(copy_debug_stmt): No longer insist on replacement being a DECL>
Index: tree-pretty-print.c
===================================================================
*** tree-pretty-print.c	(revision 151901)
--- tree-pretty-print.c	(working copy)
*************** dump_block_node (pretty_printer *buffer,
*** 517,531 ****
        newline_and_indent (buffer, spc + 2);
      }
  
!   if (VEC_length (tree, BLOCK_NONLOCALIZED_VARS (block)) > 0)
      {
        unsigned i;
!       VEC(tree,gc) *nlv = BLOCK_NONLOCALIZED_VARS (block);
  
        pp_string (buffer, "NONLOCALIZED_VARS: ");
!       for (i = 0; VEC_iterate (tree, nlv, i, t); i++)
  	{
! 	  dump_generic_node (buffer, t, 0, flags, false);
  	  pp_string (buffer, " ");
  	}
        newline_and_indent (buffer, spc + 2);
--- 517,532 ----
        newline_and_indent (buffer, spc + 2);
      }
  
!   if (BLOCK_NUM_NONLOCALIZED_VARS (block) > 0)
      {
        unsigned i;
!       VEC(nonlocalized_var,gc) *nlv = BLOCK_NONLOCALIZED_VARS (block);
!       nonlocalized_var *nv;
  
        pp_string (buffer, "NONLOCALIZED_VARS: ");
!       for (i = 0; VEC_iterate (nonlocalized_var, nlv, i, nv); i++)
  	{
! 	  dump_generic_node (buffer, nv->decl, 0, flags, false);
  	  pp_string (buffer, " ");
  	}
        newline_and_indent (buffer, spc + 2);
Index: tree.h
===================================================================
*** tree.h	(revision 151901)
--- tree.h	(working copy)
*************** DEF_VEC_P(tree);
*** 183,188 ****
--- 183,204 ----
  DEF_VEC_ALLOC_P(tree,gc);
  DEF_VEC_ALLOC_P(tree,heap);
  
+ /* Structure holding info about fully optimized out user declaration.
+    DECL points to DECL_ABSTRACT_ORIGIN of the optimized out declaration,
+    VALUE, if non-NULL, contains expression that can be used to compute
+    value originally hold in DECL same vay as in DECL_VALUDE_EXPR.
+    It is used by debug info output.  */
+ 
+ typedef struct GTY(()) nonlocalized_var 
+ {
+   tree decl;
+   tree value;
+ } nonlocalized_var;
+ 
+ DEF_VEC_O(nonlocalized_var);
+ DEF_VEC_ALLOC_O(nonlocalized_var,gc);
+ 
+ 
  /* We have to be able to tell cgraph about the needed-ness of the target
     of an alias.  This requires that the decl have been defined.  Aliases
     that precede their definition have to be queued for later processing.  */
*************** struct varray_head_tag;
*** 1957,1964 ****
  /* In a BLOCK node.  */
  #define BLOCK_VARS(NODE) (BLOCK_CHECK (NODE)->block.vars)
  #define BLOCK_NONLOCALIZED_VARS(NODE) (BLOCK_CHECK (NODE)->block.nonlocalized_vars)
! #define BLOCK_NUM_NONLOCALIZED_VARS(NODE) VEC_length (tree, BLOCK_NONLOCALIZED_VARS (NODE))
! #define BLOCK_NONLOCALIZED_VAR(NODE,N) VEC_index (tree, BLOCK_NONLOCALIZED_VARS (NODE), N)
  #define BLOCK_SUBBLOCKS(NODE) (BLOCK_CHECK (NODE)->block.subblocks)
  #define BLOCK_SUPERCONTEXT(NODE) (BLOCK_CHECK (NODE)->block.supercontext)
  /* Note: when changing this, make sure to find the places
--- 1973,1981 ----
  /* In a BLOCK node.  */
  #define BLOCK_VARS(NODE) (BLOCK_CHECK (NODE)->block.vars)
  #define BLOCK_NONLOCALIZED_VARS(NODE) (BLOCK_CHECK (NODE)->block.nonlocalized_vars)
! #define BLOCK_NUM_NONLOCALIZED_VARS(NODE) VEC_length (nonlocalized_var, BLOCK_NONLOCALIZED_VARS (NODE))
! #define BLOCK_NONLOCALIZED_VAR(NODE,N) VEC_index (nonlocalized_var, BLOCK_NONLOCALIZED_VARS (NODE), N)->decl
! #define BLOCK_NONLOCALIZED_VAR_VALUE(NODE,N) VEC_index (nonlocalized_var, BLOCK_NONLOCALIZED_VARS (NODE), N)->value
  #define BLOCK_SUBBLOCKS(NODE) (BLOCK_CHECK (NODE)->block.subblocks)
  #define BLOCK_SUPERCONTEXT(NODE) (BLOCK_CHECK (NODE)->block.supercontext)
  /* Note: when changing this, make sure to find the places
*************** struct GTY(()) tree_block {
*** 2012,2018 ****
    location_t locus;
  
    tree vars;
!   VEC(tree,gc) *nonlocalized_vars;
  
    tree subblocks;
    tree supercontext;
--- 2029,2035 ----
    location_t locus;
  
    tree vars;
!   VEC(nonlocalized_var,gc) *nonlocalized_vars;
  
    tree subblocks;
    tree supercontext;
Index: tree-ssa-live.c
===================================================================
*** tree-ssa-live.c	(revision 151901)
--- tree-ssa-live.c	(working copy)
*************** mark_scope_block_unused (tree scope)
*** 402,407 ****
--- 402,493 ----
      mark_scope_block_unused (t);
  }
  
+ /* Called via walk_tree. See if expression contains some variable that is
+    no longer used in source function and try to replace them by their
+    VALUE_EXPRs.  If that fails and substitution is no longer useful,
+    return non-NULL_TREE.  */
+ 
+ static tree
+ lookup_dead_vars (tree * tp, int *walk_subtrees, void *data)
+ {
+   bool *fold_p = (bool *)data;
+ 
+   if (TREE_CODE (*tp) == CONSTRUCTOR)
+     {
+       unsigned HOST_WIDE_INT idx;
+       tree value;
+       bool found = false;
+       *walk_subtrees = 0;
+ 
+       FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (*tp), idx, value)
+         {
+ 	  if (value != error_mark_node)
+ 	    {
+               bool fold_field_p = false;
+ 
+               if (walk_tree (&value, lookup_dead_vars, &fold_field_p, NULL))
+ 		value = error_mark_node;
+ 	      if (value != error_mark_node)
+ 		{
+ 	          found = true;
+ 		  if (fold_field_p)
+ 		    {
+ 		      value = fold (value);
+ 		      *fold_p = true;
+ 		    }
+ 		}
+ 	      CONSTRUCTOR_ELT (*tp, idx)->value = value;
+ 	    }
+ 	}
+       if (found)
+         return NULL_TREE;
+       return *tp;
+     }
+ 
+   if (is_gimple_min_invariant (*tp)
+       || TYPE_P (*tp))
+     {
+       *walk_subtrees = 0;
+       return NULL_TREE;
+     }
+   if (DECL_P (*tp))
+     {
+       *walk_subtrees = 0;
+ 
+       if ((TREE_CODE (*tp) == VAR_DECL
+ 	   || TREE_CODE (*tp) == PARM_DECL)
+ 	  && (!var_ann (*tp)
+ 	      || !var_ann (*tp)->used))
+ 	{
+ 	  /* If this is dead variable but we have subtitution for it, go ahead and use it.
+ 	     Watch for recusive cases!  */
+ 	  if (DECL_HAS_VALUE_EXPR_P (*tp))
+ 	    {
+ 	      tree value;
+ 	      tree decl = *tp;
+ 
+ 	      *fold_p = true;
+ 	      DECL_HAS_VALUE_EXPR_P (decl) = 0;
+ 	      value = DECL_VALUE_EXPR (decl);
+ 	      if (value != *tp)
+ 		{
+ 		  *tp = unshare_expr (value);
+ 		  value = walk_tree (tp, lookup_dead_vars, data, NULL);
+ 		}
+ 	      DECL_HAS_VALUE_EXPR_P (decl) = 1;
+ 	      return value;
+ 	    }
+ 
+ 	  /* Function parameters and static vars might survive even if
+ 	     they are unused.  */
+ 	  if (TREE_CODE (*tp) == VAR_DECL
+ 	      && !TREE_STATIC (*tp))
+ 	    return *tp;
+ 	}
+     }
+   return NULL_TREE;
+ }
+ 
  /* Look if the block is dead (by possibly eliminating its dead subblocks)
     and return true if so.  
     Block is declared dead if:
*************** remove_unused_scope_block_p (tree scope)
*** 422,432 ****
--- 508,555 ----
    bool unused = !TREE_USED (scope);
    var_ann_t ann;
    int nsubblocks = 0;
+   unsigned int i;
+ 
+   for (i = 0; i < BLOCK_NUM_NONLOCALIZED_VARS (scope); i++)
+     {
+       bool fold_p = false;
+ 
+       if (BLOCK_NONLOCALIZED_VAR_VALUE (scope, i)
+ 	  && walk_tree (&BLOCK_NONLOCALIZED_VAR_VALUE (scope, i),
+ 			lookup_dead_vars, &fold_p, NULL))
+ 	BLOCK_NONLOCALIZED_VAR_VALUE (scope, i) = NULL_TREE;
+       if (fold_p)
+ 	BLOCK_NONLOCALIZED_VAR_VALUE (scope, i)
+ 	  = fold (BLOCK_NONLOCALIZED_VAR_VALUE (scope, i));
+     }
  
    for (t = &BLOCK_VARS (scope); *t; t = next)
      {
        next = &TREE_CHAIN (*t);
  
+       if ((TREE_CODE (*t) == VAR_DECL || TREE_CODE (*t) == PARM_DECL)
+ 	  && DECL_HAS_VALUE_EXPR_P (*t))
+ 	{
+ 	  tree value = DECL_VALUE_EXPR (*t);
+ 	  bool fold_p = false;
+ 
+ 	  DECL_HAS_VALUE_EXPR_P (*t) = 0;
+ 	  if (walk_tree (&value, lookup_dead_vars, &fold_p, NULL))
+ 	    value = error_mark_node;
+ 	  else if (fold_p)
+ 	    value = fold (value);
+ 	  if (value == error_mark_node)
+ 	    {
+ 	      SET_DECL_VALUE_EXPR (*t, NULL_TREE);
+ 	      DECL_HAS_VALUE_EXPR_P (*t) = 0;
+ 	    }
+ 	  else
+ 	    {
+ 	      SET_DECL_VALUE_EXPR (*t, value);
+ 	      DECL_HAS_VALUE_EXPR_P (*t) = 1;
+ 	    }
+ 	}
+ 
        /* Debug info of nested function refers to the block of the
  	 function.  We might stil call it even if all statements
  	 of function it was nested into was elliminated.
*************** dump_scope_block (FILE *file, int indent
*** 623,628 ****
--- 746,760 ----
  
        fprintf (file, "%*s",indent, "");
        print_generic_decl (file, var, flags);
+       if ((TREE_CODE (var) == VAR_DECL || TREE_CODE (var) == PARM_DECL)
+           && DECL_HAS_VALUE_EXPR_P (var))
+         {
+           fprintf (file, " [value_expr: ");
+ 	  print_generic_expr (file,
+ 	  		      DECL_VALUE_EXPR (var),
+ 			      flags);
+           fprintf (file, " ]");
+         }
        fprintf (file, "%s\n", used ? "" : " (unused)");
      }
    for (i = 0; i < BLOCK_NUM_NONLOCALIZED_VARS (scope); i++)
*************** dump_scope_block (FILE *file, int indent
*** 630,635 ****
--- 762,775 ----
        fprintf (file, "%*s",indent, "");
        print_generic_decl (file, BLOCK_NONLOCALIZED_VAR (scope, i),
        			  flags);
+       if (BLOCK_NONLOCALIZED_VAR_VALUE (scope, i))
+         {
+           fprintf (file, " [value-expr: ");
+ 	  print_generic_expr (file,
+ 	  		      BLOCK_NONLOCALIZED_VAR_VALUE (scope, i),
+ 			      flags);
+           fprintf (file, " ]");
+ 	}
        fprintf (file, " (nonlocalized)\n");
      }
    for (t = BLOCK_SUBBLOCKS (scope); t ; t = BLOCK_CHAIN (t))
Index: tree-inline.c
===================================================================
*** tree-inline.c	(revision 151901)
--- tree-inline.c	(working copy)
*************** insert_debug_decl_map (copy_body_data *i
*** 162,167 ****
    if (!target_for_debug_bind (key))
      return;
  
-   gcc_assert (TREE_CODE (key) == PARM_DECL);
-   gcc_assert (TREE_CODE (value) == VAR_DECL);
  
    if (!id->debug_map)
      id->debug_map = pointer_map_create ();
--- 162,169 ----
    if (!target_for_debug_bind (key))
      return;
  
    if (!id->debug_map)
      id->debug_map = pointer_map_create ();
*************** can_be_nonlocal (tree decl, copy_body_da
*** 529,536 ****
    return true;
  }
  
  static tree
! remap_decls (tree decls, VEC(tree,gc) **nonlocalized_list, copy_body_data *id)
  {
    tree old_var;
    tree new_decls = NULL_TREE;
--- 529,762 ----
    return true;
  }
  
+ /* See if we can turn value into expression that uses user variables
+    and thus can be output in debug information.   Choose variant that has
+    best chance to survive till end of compilation and be represented in
+    debug info.
+ 
+    We look primarily for the most common scenarios: constants, copies and
+    accestors to subobjects.  
+    
+    Dwarf2 has quite limited powers here: the actual value of variable must
+    be either constant or stored in memory.  This we can represent
+    &pointer->firstfield, but not &pointer->secondfield or &local_var.
+    Substitutions can however cascade, so &pointer->secondfield can later
+    optimize into memory reference e.g. by SRA.  */
+ 
+ static tree
+ simplify_value (tree value, tree fn, bool only_address)
+ {
+   tree tmp = value;
+   tree tmp2 = NULL;
+ 
+   /* If we get back to original argument, we are almost always victorious! */
+   if (TREE_CODE (value) == PARM_DECL || TREE_CODE (value) == RESULT_DECL)
+     return value;
+ 
+   /* Addresses of objects are also safe since they do not change. */
+   if (DECL_P (value) && only_address)
+     return value;
+ 
+   /* User variables should survive to debug info.  */
+   if ((DECL_P (value) && !DECL_IGNORED_P (value))
+       && auto_var_in_fn_p (value, fn))
+     return value;
+ 
+   /* Invariants are win.  */
+   if (is_gimple_min_invariant (value))
+     return value;
+ 
+   /* Look into conversions and handled components.  */
+   if (TREE_CODE (value) == NOP_EXPR
+       && (tmp =
+ 	  simplify_value (TREE_OPERAND (value, 0), fn,
+ 				only_address)) != NULL_TREE)
+     return fold_convert (TREE_TYPE (value), tmp);
+ 
+   if (TREE_CODE (value) == VIEW_CONVERT_EXPR
+       && (tmp =
+ 	  simplify_value (TREE_OPERAND (value, 0), fn,
+ 				only_address)) != NULL_TREE)
+     return fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (value), tmp);
+ 
+   if (TREE_CODE (value) == COMPONENT_REF
+       && (tmp =
+ 	  simplify_value (TREE_OPERAND (value, 0), fn,
+ 				only_address)) != NULL_TREE)
+     {
+       if (TREE_OPERAND (value, 2)
+ 	  && (tmp2 =
+ 	      simplify_value (TREE_OPERAND (value, 2), fn,
+ 				    0)) == NULL_TREE)
+ 	return NULL;
+       return fold_build3 (COMPONENT_REF, TREE_TYPE (value), tmp,
+ 			  TREE_OPERAND (value, 1), tmp2);
+     }
+ 
+   if ((TREE_CODE (value) == REALPART_EXPR
+        || TREE_CODE (value) == IMAGPART_EXPR)
+       && (tmp =
+ 	  simplify_value (TREE_OPERAND (value, 0), fn,
+ 				only_address)) != NULL_TREE)
+     return fold_build1 (TREE_CODE (value), TREE_TYPE (value),
+ 			tmp);
+ 
+   if (TREE_CODE (value) == ARRAY_REF
+       && (tmp =
+ 	  simplify_value (TREE_OPERAND (value, 0), fn,
+ 				only_address)) != NULL_TREE
+       && (tmp2 =
+ 	  simplify_value (TREE_OPERAND (value, 1), fn,
+ 				0)) != NULL_TREE)
+     {
+       tree tmp3 = NULL;
+       tree tmp4 = NULL;
+       if (TREE_OPERAND (value, 2)
+ 	  && (tmp3 =
+ 	      simplify_value (TREE_OPERAND (value, 2), fn,
+ 				    0)) == NULL_TREE)
+ 	return NULL;
+       if (TREE_OPERAND (value, 3)
+ 	  && (tmp4 =
+ 	      simplify_value (TREE_OPERAND (value, 3), fn,
+ 				    0)) == NULL_TREE)
+ 	return NULL;
+       return
+ 	fold (build4
+ 	      (ARRAY_REF, TREE_TYPE (value), tmp, tmp2, tmp3, tmp4));
+     }
+ 
+   if (TREE_CODE (value) == BIT_FIELD_REF
+       && (tmp =
+ 	  simplify_value (TREE_OPERAND (value, 0), fn,
+ 				only_address)) != NULL_TREE)
+     return fold (build3 (BIT_FIELD_REF, TREE_TYPE (value), tmp,
+ 			 TREE_OPERAND (value, 1),
+ 			 TREE_OPERAND (value, 2)));
+ 
+   if (TREE_CODE (value) == INDIRECT_REF
+       && (tmp =
+ 	  simplify_value (TREE_OPERAND (value, 0), fn,
+ 				false)) != NULL_TREE)
+     return build_fold_indirect_ref (tmp);
+ 
+   if (TREE_CODE (value) == ADDR_EXPR
+       && (tmp =
+ 	  simplify_value (TREE_OPERAND (value, 0), fn,
+ 				true)) != NULL_TREE)
+     /* Do not use build_fold_addr_expr, because it will set
+        TREE_ADDRESSABLE.  */
+     return fold (build1 (ADDR_EXPR, TREE_TYPE (value), tmp));
+ 
+   if (TREE_CODE (value) == SSA_NAME)
+     {
+       gimple stmt = SSA_NAME_DEF_STMT (value);
+ 
+       /* Early inlining happens on nonoptimized function body.
+          See if we can propagate up to constant or user variable.  */
+       if (gimple_code (stmt) == GIMPLE_ASSIGN)
+ 	{
+ 	  enum tree_code subcode = gimple_assign_rhs_code (stmt);
+ 
+ 	  if (get_gimple_rhs_class (gimple_assign_rhs_code (stmt))
+ 	      == GIMPLE_SINGLE_RHS
+ 	      && (tmp =
+ 		  simplify_value (gimple_assign_rhs1 (stmt), fn,
+ 					only_address)))
+ 	    return tmp;
+ 
+ 	  if (subcode == NOP_EXPR
+ 	      && (tmp =
+ 		  simplify_value (gimple_assign_rhs1 (stmt), fn,
+ 					only_address)))
+ 	    {
+ 	      gcc_assert (get_gimple_rhs_class
+ 			  (gimple_assign_rhs_code (stmt)));
+ 	      return fold_convert (TREE_TYPE (value), tmp);
+ 	    }
+ 
+ 	  if (subcode == ADDR_EXPR
+ 	      && (tmp =
+ 		  simplify_value (gimple_assign_rhs1 (stmt), fn, true)))
+ 	    {
+ 	      gcc_unreachable ();
+ 	      gcc_assert (get_gimple_rhs_class
+ 			  (gimple_assign_rhs_code (stmt)));
+               /* Do not use build_fold_addr_expr, because it will set
+                  TREE_ADDRESSABLE.  */
+               return fold (build1 (ADDR_EXPR, TREE_TYPE (value), tmp));
+ 	    }
+ 	}
+ 
+       /* With priority look deeper in the SSA graph.  Since ealry inlining is done
+          before constant propagation we might easilly miss completely constant
+          user variables otherwise.  */
+       if ((tmp =
+ 	   simplify_value (SSA_NAME_VAR (value), fn,
+ 				 only_address)) != NULL_TREE)
+ 	return tmp;
+       if (!only_address)
+ 	return SSA_NAME_VAR (value);
+     }
+   if (DECL_P (value) && auto_var_in_fn_p (value, fn))
+     return value;
+   return NULL;
+ }
+ 
+ /* Remap VALUE from inlined function to the callee.  */
  static tree
! remap_value (tree value, copy_body_data *id)
! {
!   if (!value)
!     return NULL;
!   walk_tree (&value, copy_tree_body_r, id, NULL);
!   /* Replacing declarations might've introduced new simplifiable
!      expressions.  */
!   return simplify_value (fold (value), id->src_fn, false);
! }
! 
! /* DECL is not going to be copied into function body.  Declare it in NONLOCALIZED_LIST
!    and if possible note it being replaced by value.  */
! static void
! declare_nonlocalized_var (VEC(nonlocalized_var,gc) **nonlocalized_list,
! 			  tree decl, tree value, copy_body_data *id,
! 			  bool newly_nonlocal_p)
! {
!   nonlocalized_var var;
!   tree origin_var = DECL_ORIGIN (decl);
! 
!   if (debug_info_level <= DINFO_LEVEL_TERSE)
!     value = NULL_TREE;
!   if (TREE_READONLY (decl) && !TREE_THIS_VOLATILE (decl) && DECL_INITIAL (decl)
!       && TREE_CODE (decl) == VAR_DECL)
!     value = NULL_TREE;
!   if (value && newly_nonlocal_p)
!     value = simplify_value (value, id->src_fn, false);
!   if (value)
!     {
!      if (!useless_type_conversion_p (TREE_TYPE (origin_var), TREE_TYPE (value)))
!        {
!          if (fold_convertible_p (TREE_TYPE (origin_var), value))
! 	   value = fold_build1 (NOP_EXPR, TREE_TYPE (value), value);
! 	 else gcc_unreachable ();
! 	   value = NULL;
! 	}
!     }
!   var.decl = origin_var;
!   var.value = value;
!   if (newly_nonlocal_p && TREE_CODE (decl) == PARM_DECL
!       && value
!       && !pointer_map_contains (id->decl_map, decl))
!     insert_decl_map (id, decl, value);
!   if (debug_info_level > DINFO_LEVEL_TERSE
!       && !DECL_IGNORED_P (decl))
!     VEC_safe_push (nonlocalized_var, gc, *nonlocalized_list, &var);
!   insert_debug_decl_map (id, decl, value);
! }
! 
! 
! static tree
! remap_decls (tree decls, VEC(nonlocalized_var,gc) **nonlocalized_list, copy_body_data *id)
  {
    tree old_var;
    tree new_decls = NULL_TREE;
*************** remap_decls (tree decls, VEC(tree,gc) **
*** 539,544 ****
    for (old_var = decls; old_var; old_var = TREE_CHAIN (old_var))
      {
        tree new_var;
-       tree origin_var = DECL_ORIGIN (old_var);
  
        if (can_be_nonlocal (old_var, id))
  	{
--- 765,771 ----
    for (old_var = decls; old_var; old_var = TREE_CHAIN (old_var))
      {
        tree new_var;
  
        if (can_be_nonlocal (old_var, id))
  	{
*************** remap_decls (tree decls, VEC(tree,gc) **
*** 551,557 ****
  	  if ((!optimize || debug_info_level > DINFO_LEVEL_TERSE)
  	      && !DECL_IGNORED_P (old_var)
  	      && nonlocalized_list)
! 	    VEC_safe_push (tree, gc, *nonlocalized_list, origin_var);
  	  continue;
  	}
  
--- 777,789 ----
  	  if ((!optimize || debug_info_level > DINFO_LEVEL_TERSE)
  	      && !DECL_IGNORED_P (old_var)
  	      && nonlocalized_list)
! 	    {
! 	      tree value = NULL;
! 	      if ((TREE_CODE (old_var) == VAR_DECL || TREE_CODE (old_var) == PARM_DECL)
! 	          && DECL_HAS_VALUE_EXPR_P (old_var))
! 		value = remap_value (old_var, id);
! 	      declare_nonlocalized_var (nonlocalized_list, old_var, value, id, true);
! 	    }
  	  continue;
  	}
  
*************** remap_decls (tree decls, VEC(tree,gc) **
*** 569,575 ****
  	  if ((!optimize || debug_info_level > DINFO_LEVEL_TERSE)
  	      && !DECL_IGNORED_P (old_var)
  	      && nonlocalized_list)
! 	    VEC_safe_push (tree, gc, *nonlocalized_list, origin_var);
  	}
        else
  	{
--- 801,813 ----
  	  if ((!optimize || debug_info_level > DINFO_LEVEL_TERSE)
  	      && !DECL_IGNORED_P (old_var)
  	      && nonlocalized_list)
! 	    {
! 	      tree value = NULL;
! 	      if ((TREE_CODE (old_var) == VAR_DECL || TREE_CODE (old_var) == PARM_DECL)
! 	          && DECL_HAS_VALUE_EXPR_P (old_var))
! 		value = remap_value (old_var, id);
! 	      declare_nonlocalized_var (nonlocalized_list, old_var, value, id, true);
! 	    }
  	}
        else
  	{
*************** remap_block (tree *block, copy_body_data
*** 591,596 ****
--- 829,835 ----
    tree old_block;
    tree new_block;
    tree fn;
+   unsigned int i;
  
    /* Make the new block.  */
    old_block = *block;
*************** remap_block (tree *block, copy_body_data
*** 598,605 ****
    TREE_USED (new_block) = TREE_USED (old_block);
    BLOCK_ABSTRACT_ORIGIN (new_block) = old_block;
    BLOCK_SOURCE_LOCATION (new_block) = BLOCK_SOURCE_LOCATION (old_block);
!   BLOCK_NONLOCALIZED_VARS (new_block)
!     = VEC_copy (tree, gc, BLOCK_NONLOCALIZED_VARS (old_block));
    *block = new_block;
  
    /* Remap its variables.  */
--- 837,849 ----
    TREE_USED (new_block) = TREE_USED (old_block);
    BLOCK_ABSTRACT_ORIGIN (new_block) = old_block;
    BLOCK_SOURCE_LOCATION (new_block) = BLOCK_SOURCE_LOCATION (old_block);
!   for (i = 0; i < BLOCK_NUM_NONLOCALIZED_VARS (old_block); i++)
!     {
!       tree value = remap_value (BLOCK_NONLOCALIZED_VAR_VALUE (old_block, i), id);
!       declare_nonlocalized_var (&BLOCK_NONLOCALIZED_VARS (new_block),
! 				BLOCK_NONLOCALIZED_VAR (old_block, i),
! 				value, id, false);
!     }
    *block = new_block;
  
    /* Remap its variables.  */
*************** copy_debug_stmt (gimple stmt, copy_body_
*** 2143,2149 ****
    if (TREE_CODE (t) == PARM_DECL && id->debug_map
        && (n = (tree *) pointer_map_contains (id->debug_map, t)))
      {
-       gcc_assert (TREE_CODE (*n) == VAR_DECL);
        t = *n;
      }
    else
--- 2387,2393 ----
    if (TREE_CODE (t) == PARM_DECL && id->debug_map
        && (n = (tree *) pointer_map_contains (id->debug_map, t)))
      {
        t = *n;
      }
    else


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