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: [PR debug/47106] account used vars only once


Hi,
this is variant of patch I am testing now.
Quick testing on the problematic PR shows no problems and we get around w/o
the extra pass.

Honza

Index: cgraphunit.c
===================================================================
*** cgraphunit.c	(revision 170240)
--- cgraphunit.c	(working copy)
*************** cgraph_analyze_function (struct cgraph_n
*** 783,788 ****
--- 783,793 ----
  
    assign_assembler_name_if_neeeded (node->decl);
  
+   /* disregard_inline_limits affects topological order of the early optimization,
+      so we need to compute it ahead of rest of inline parameters.  */
+   node->local.disregard_inline_limits
+     = DECL_DISREGARD_INLINE_LIMITS (node->decl);
+ 
    /* Make sure to gimplify bodies only once.  During analyzing a
       function we lower it, which will require gimplified nested
       functions, so we can end up here with an already gimplified
Index: testsuite/g++.dg/debug/pr47106.C
===================================================================
*** testsuite/g++.dg/debug/pr47106.C	(revision 0)
--- testsuite/g++.dg/debug/pr47106.C	(revision 0)
***************
*** 0 ****
--- 1,37 ----
+ // { dg-do compile }
+ // { dg-options "-O -fpartial-inlining -flto -fconserve-stack -fcompare-debug" }
+ 
+ void end (int, int) __attribute__ ((__noreturn__));
+ 
+ struct S
+ {
+   int i;
+   S *s;
+ };
+ 
+ inline bool f (S *s)
+ {
+   if (!s->s)
+     end (0, 0);
+   return s->s == s;
+ }
+ 
+ inline bool
+ baz (S s1, S)
+ {
+   while (f (&s1));
+ }
+ 
+ inline bool
+ bar (S s1, S s2, S)
+ {
+   baz (s1, s2);
+ }
+ 
+ S getS ();
+ 
+ bool
+ foo ()
+ {
+   bar (getS (), getS (), getS ());
+ }
Index: ipa-inline.c
===================================================================
*** ipa-inline.c	(revision 170240)
--- ipa-inline.c	(working copy)
*************** compute_inline_parameters (struct cgraph
*** 2006,2014 ****
  	  break;
        node->local.can_change_signature = !e;
      }
-   if (node->local.inlinable && !node->local.disregard_inline_limits)
-     node->local.disregard_inline_limits
-       = DECL_DISREGARD_INLINE_LIMITS (node->decl);
    estimate_function_body_sizes (node);
    /* Inlining characteristics are maintained by the cgraph_mark_inline.  */
    node->global.time = inline_summary (node)->self_time;
--- 2006,2011 ----
Index: cfgexpand.c
===================================================================
*** cfgexpand.c	(revision 170240)
--- cfgexpand.c	(working copy)
*************** create_stack_guard (void)
*** 1311,1340 ****
    crtl->stack_protect_guard = guard;
  }
  
- /* A subroutine of expand_used_vars.  Walk down through the BLOCK tree
-    expanding variables.  Those variables that can be put into registers
-    are allocated pseudos; those that can't are put on the stack.
- 
-    TOPLEVEL is true if this is the outermost BLOCK.  */
- 
- static HOST_WIDE_INT
- account_used_vars_for_block (tree block, bool toplevel)
- {
-   tree t;
-   HOST_WIDE_INT size = 0;
- 
-   /* Expand all variables at this level.  */
-   for (t = BLOCK_VARS (block); t ; t = DECL_CHAIN (t))
-     if (var_ann (t) && is_used_p (t))
-       size += expand_one_var (t, toplevel, false);
- 
-   /* Expand all variables at containing levels.  */
-   for (t = BLOCK_SUBBLOCKS (block); t ; t = BLOCK_CHAIN (t))
-     size += account_used_vars_for_block (t, false);
- 
-   return size;
- }
- 
  /* Prepare for expanding variables.  */
  static void
  init_vars_expansion (void)
--- 1311,1316 ----
*************** estimated_stack_frame_size (struct cgrap
*** 1379,1401 ****
  {
    HOST_WIDE_INT size = 0;
    size_t i;
!   tree var, outer_block = DECL_INITIAL (current_function_decl);
!   unsigned ix;
    tree old_cur_fun_decl = current_function_decl;
  
    current_function_decl = node->decl;
!   push_cfun (DECL_STRUCT_FUNCTION (node->decl));
  
!   init_vars_expansion ();
! 
!   FOR_EACH_LOCAL_DECL (cfun, ix, var)
!     {
!       /* TREE_USED marks local variables that do not appear in lexical
! 	 blocks.  We don't want to expand those that do twice.  */
!       if (TREE_USED (var))
!         size += expand_one_var (var, true, false);
!     }
!   size += account_used_vars_for_block (outer_block, true);
  
    if (stack_vars_num > 0)
      {
--- 1355,1371 ----
  {
    HOST_WIDE_INT size = 0;
    size_t i;
!   tree var;
    tree old_cur_fun_decl = current_function_decl;
+   referenced_var_iterator rvi;
+   struct function *fn = DECL_STRUCT_FUNCTION (node->decl);
  
    current_function_decl = node->decl;
!   push_cfun (fn);
  
!   gcc_checking_assert (gimple_referenced_vars (fn));
!   FOR_EACH_REFERENCED_VAR (fn, var, rvi)
!     size += expand_one_var (var, true, false);
  
    if (stack_vars_num > 0)
      {
Index: tree-inline.c
===================================================================
*** tree-inline.c	(revision 170240)
--- tree-inline.c	(working copy)
*************** remap_decl (tree decl, copy_body_data *i
*** 312,324 ****
  	    walk_tree (&DECL_QUALIFIER (t), copy_tree_body_r, id, NULL);
  	}
  
!       if (cfun && gimple_in_ssa_p (cfun)
! 	  && (TREE_CODE (t) == VAR_DECL
! 	      || TREE_CODE (t) == RESULT_DECL || TREE_CODE (t) == PARM_DECL))
! 	{
! 	  get_var_ann (t);
! 	  add_referenced_var (t);
! 	}
        return t;
      }
  
--- 312,328 ----
  	    walk_tree (&DECL_QUALIFIER (t), copy_tree_body_r, id, NULL);
  	}
  
!       if ((TREE_CODE (t) == VAR_DECL
! 	   || TREE_CODE (t) == RESULT_DECL
! 	   || TREE_CODE (t) == PARM_DECL)
! 	  && id->src_fn && DECL_STRUCT_FUNCTION (id->src_fn)
! 	  && gimple_referenced_vars (DECL_STRUCT_FUNCTION (id->src_fn))
! 	  /* We don't want to mark as referenced VAR_DECLs that were
! 	     not marked as such in the src function.  */
! 	  && (TREE_CODE (decl) != VAR_DECL
! 	      || referenced_var_lookup (DECL_STRUCT_FUNCTION (id->src_fn),
! 					DECL_UID (decl))))
! 	add_referenced_var (t);
        return t;
      }
  
*************** setup_one_parameter (copy_body_data *id,
*** 2547,2556 ****
  
    /* We're actually using the newly-created var.  */
    if (gimple_in_ssa_p (cfun) && TREE_CODE (var) == VAR_DECL)
!     {
!       get_var_ann (var);
!       add_referenced_var (var);
!     }
  
    /* Declare this new variable.  */
    DECL_CHAIN (var) = *vars;
--- 2551,2557 ----
  
    /* We're actually using the newly-created var.  */
    if (gimple_in_ssa_p (cfun) && TREE_CODE (var) == VAR_DECL)
!     add_referenced_var (var);
  
    /* Declare this new variable.  */
    DECL_CHAIN (var) = *vars;
*************** declare_return_variable (copy_body_data 
*** 2857,2866 ****
  
    var = copy_result_decl_to_var (result, id);
    if (gimple_in_ssa_p (cfun))
!     {
!       get_var_ann (var);
!       add_referenced_var (var);
!     }
  
    DECL_SEEN_IN_BIND_EXPR_P (var) = 1;
  
--- 2858,2864 ----
  
    var = copy_result_decl_to_var (result, id);
    if (gimple_in_ssa_p (cfun))
!     add_referenced_var (var);
  
    DECL_SEEN_IN_BIND_EXPR_P (var) = 1;
  
*************** declare_return_variable (copy_body_data 
*** 2896,2905 ****
      {
        tree temp = create_tmp_var (TREE_TYPE (result), "retvalptr");
        if (gimple_in_ssa_p (id->src_cfun))
! 	{
! 	  get_var_ann (temp);
! 	  add_referenced_var (temp);
! 	}
        insert_decl_map (id, result, temp);
        /* When RESULT_DECL is in SSA form, we need to use it's default_def
  	 SSA_NAME.  */
--- 2894,2900 ----
      {
        tree temp = create_tmp_var (TREE_TYPE (result), "retvalptr");
        if (gimple_in_ssa_p (id->src_cfun))
! 	add_referenced_var (temp);
        insert_decl_map (id, result, temp);
        /* When RESULT_DECL is in SSA form, we need to use it's default_def
  	 SSA_NAME.  */
*************** copy_decl_for_dup_finish (copy_body_data
*** 4753,4758 ****
--- 4748,4761 ----
         new function.  */
      DECL_CONTEXT (copy) = id->dst_fn;
  
+   if (TREE_CODE (decl) == VAR_DECL
+       /* C++ clones functions during parsing, before
+ 	 referenced_vars.  */
+       && gimple_referenced_vars (DECL_STRUCT_FUNCTION (id->src_fn))
+       && referenced_var_lookup (DECL_STRUCT_FUNCTION (id->src_fn),
+ 				DECL_UID (decl)))
+     add_referenced_var (copy);
+ 
    return copy;
  }
  
*************** copy_arguments_for_versioning (tree orig
*** 4864,4870 ****
  	   as temporary variable later in function, the uses will be
  	   replaced by local variable.  */
  	tree var = copy_decl_to_var (arg, id);
- 	get_var_ann (var);
  	add_referenced_var (var);
  	insert_decl_map (id, arg, var);
          /* Declare this new variable.  */
--- 4867,4872 ----
Index: passes.c
===================================================================
*** passes.c	(revision 170240)
--- passes.c	(working copy)
*************** init_optimization_passes (void)
*** 729,735 ****
    NEXT_PASS (pass_build_cfg);
    NEXT_PASS (pass_warn_function_return);
    NEXT_PASS (pass_build_cgraph_edges);
-   NEXT_PASS (pass_inline_parameters);
    *p = NULL;
  
    /* Interprocedural optimization passes.  */
--- 729,734 ----
*************** init_optimization_passes (void)
*** 747,758 ****
        NEXT_PASS (pass_build_ssa);
        NEXT_PASS (pass_lower_vector);
        NEXT_PASS (pass_early_warn_uninitialized);
-       /* Note that it is not strictly necessary to schedule an early
- 	 inline pass here.  However, some test cases (e.g.,
- 	 g++.dg/other/p334435.C g++.dg/other/i386-1.C) expect extern
- 	 inline functions to be inlined even at -O0.  This does not
- 	 happen during the first early inline pass.  */
        NEXT_PASS (pass_rebuild_cgraph_edges);
        NEXT_PASS (pass_early_inline);
        NEXT_PASS (pass_all_early_optimizations);
  	{
--- 746,753 ----
        NEXT_PASS (pass_build_ssa);
        NEXT_PASS (pass_lower_vector);
        NEXT_PASS (pass_early_warn_uninitialized);
        NEXT_PASS (pass_rebuild_cgraph_edges);
+       NEXT_PASS (pass_inline_parameters);
        NEXT_PASS (pass_early_inline);
        NEXT_PASS (pass_all_early_optimizations);
  	{


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