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]

[PATCH] Fix PR47025


This fixes PR47025, __builtin_va_end is preventing dead store
elimination and __builtin_va_start is an escape point for the
valist.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.

Richard.

2011-09-06  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/47025
	* tree-ssa-alias.c (ref_maybe_used_by_call_p_1): BUILT_IN_VA_END
	uses nothing.
	(call_may_clobber_ref_p_1): BUILT_IN_VA_END is a barrier like
	BUILT_IN_FREE.
	(stmt_kills_ref_p_1): BUILT_IN_VA_END kills what its argument
	definitely points to.
	* tree-ssa-structalias.c (find_func_aliases_for_builtin_call):
	BUILT_IN_VA_START doesn't let its va_list argument escape.
	* tree-ssa-dce.c (propagate_necessity): BUILT_IN_VA_END does
	not make any previous stores necessary.

Index: gcc/tree-ssa-alias.c
===================================================================
*** gcc/tree-ssa-alias.c.orig	2011-09-06 16:24:16.000000000 +0200
--- gcc/tree-ssa-alias.c	2011-09-06 16:28:48.000000000 +0200
*************** ref_maybe_used_by_call_p_1 (gimple call,
*** 1254,1259 ****
--- 1254,1260 ----
  	case BUILT_IN_SINCOSF:
  	case BUILT_IN_SINCOSL:
  	case BUILT_IN_ASSUME_ALIGNED:
+ 	case BUILT_IN_VA_END:
  	  return false;
  	/* __sync_* builtins and some OpenMP builtins act as threading
  	   barriers.  */
*************** call_may_clobber_ref_p_1 (gimple call, a
*** 1518,1523 ****
--- 1519,1525 ----
  	   the call has to serve as a barrier for moving loads and stores
  	   across it.  */
  	case BUILT_IN_FREE:
+ 	case BUILT_IN_VA_END:
  	  {
  	    tree ptr = gimple_call_arg (call, 0);
  	    return ptr_deref_may_alias_ref_p_1 (ptr, ref);
*************** stmt_kills_ref_p_1 (gimple stmt, ao_ref
*** 1763,1772 ****
  			      / BITS_PER_UNIT)))
  		    return true;
  		}
  	    }
  	  default:;
  	  }
- 
      }
    return false;
  }
--- 1765,1787 ----
  			      / BITS_PER_UNIT)))
  		    return true;
  		}
+ 	      break;
+ 	    }
+ 
+ 	  case BUILT_IN_VA_END:
+ 	    {
+ 	      tree ptr = gimple_call_arg (stmt, 0);
+ 	      if (TREE_CODE (ptr) == ADDR_EXPR)
+ 		{
+ 		  tree base = ao_ref_base (ref);
+ 		  if (TREE_OPERAND (ptr, 0) == base)
+ 		    return true;
+ 		}
+ 	      break;
  	    }
+ 
  	  default:;
  	  }
      }
    return false;
  }
Index: gcc/tree-ssa-structalias.c
===================================================================
*** gcc/tree-ssa-structalias.c.orig	2011-09-06 16:23:29.000000000 +0200
--- gcc/tree-ssa-structalias.c	2011-09-06 16:24:18.000000000 +0200
*************** find_func_aliases_for_builtin_call (gimp
*** 4187,4213 ****
  	 mode as well.  */
        case BUILT_IN_VA_START:
  	{
  	  if (in_ipa_mode)
  	    {
- 	      tree valist = gimple_call_arg (t, 0);
- 	      struct constraint_expr rhs, *lhsp;
- 	      unsigned i;
- 	      /* The va_list gets access to pointers in variadic
- 		 arguments.  */
  	      fi = lookup_vi_for_tree (cfun->decl);
- 	      gcc_assert (fi != NULL);
- 	      get_constraint_for (valist, &lhsc);
- 	      do_deref (&lhsc);
  	      rhs = get_function_part_constraint (fi, ~0);
  	      rhs.type = ADDRESSOF;
- 	      FOR_EACH_VEC_ELT (ce_s, lhsc, i, lhsp)
- 		  process_constraint (new_constraint (*lhsp, rhs));
- 	      VEC_free (ce_s, heap, lhsc);
- 	      /* va_list is clobbered.  */
- 	      make_constraint_to (get_call_clobber_vi (t)->id, valist);
- 	      return true;
  	    }
! 	  break;
  	}
        /* va_end doesn't have any effect that matters.  */
        case BUILT_IN_VA_END:
--- 4187,4218 ----
  	 mode as well.  */
        case BUILT_IN_VA_START:
  	{
+ 	  tree valist = gimple_call_arg (t, 0);
+ 	  struct constraint_expr rhs, *lhsp;
+ 	  unsigned i;
+ 	  get_constraint_for (valist, &lhsc);
+ 	  do_deref (&lhsc);
+ 	  /* The va_list gets access to pointers in variadic
+ 	     arguments.  Which we know in the case of IPA analysis
+ 	     and otherwise are just all nonlocal variables.  */
  	  if (in_ipa_mode)
  	    {
  	      fi = lookup_vi_for_tree (cfun->decl);
  	      rhs = get_function_part_constraint (fi, ~0);
  	      rhs.type = ADDRESSOF;
  	    }
! 	  else
! 	    {
! 	      rhs.var = nonlocal_id;
! 	      rhs.type = ADDRESSOF;
! 	      rhs.offset = 0;
! 	    }
! 	  FOR_EACH_VEC_ELT (ce_s, lhsc, i, lhsp)
! 	    process_constraint (new_constraint (*lhsp, rhs));
! 	  VEC_free (ce_s, heap, lhsc);
! 	  /* va_list is clobbered.  */
! 	  make_constraint_to (get_call_clobber_vi (t)->id, valist);
! 	  return true;
  	}
        /* va_end doesn't have any effect that matters.  */
        case BUILT_IN_VA_END:
Index: gcc/tree-ssa-dce.c
===================================================================
*** gcc/tree-ssa-dce.c.orig	2011-09-06 16:23:29.000000000 +0200
--- gcc/tree-ssa-dce.c	2011-09-06 16:24:18.000000000 +0200
*************** propagate_necessity (struct edge_list *e
*** 836,841 ****
--- 836,842 ----
  		      || DECL_FUNCTION_CODE (callee) == BUILT_IN_MALLOC
  		      || DECL_FUNCTION_CODE (callee) == BUILT_IN_CALLOC
  		      || DECL_FUNCTION_CODE (callee) == BUILT_IN_FREE
+ 		      || DECL_FUNCTION_CODE (callee) == BUILT_IN_VA_END
  		      || DECL_FUNCTION_CODE (callee) == BUILT_IN_ALLOCA
  		      || DECL_FUNCTION_CODE (callee) == BUILT_IN_STACK_SAVE
  		      || DECL_FUNCTION_CODE (callee) == BUILT_IN_STACK_RESTORE


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