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: [PATCH][RFC] Gimplify "into SSA"


On Wed, 27 Apr 2016, Jeff Law wrote:

> On 04/21/2016 06:55 AM, Richard Biener wrote:
> > 
> > The following patch makes us not allocate decls but SSA names for
> > temporaries required during gimplification.  This is basically the
> > same thing as we do when calling the gimplifier on GENERIC expressions
> > from optimization passes (when we are already in SSA).
> > 
> > There are two benefits of doing this.
> > 
> > 1) SSA names are smaller (72 bytes) than VAR_DECLs (144 bytes) and we
> > rewrite them into anonymous SSA names later anyway, leaving up the
> > VAR_DECLs for GC reclaim (but not their UID)
> > 
> > 2) We keep expressions "connected" by having the use->def link via
> > SSA_NAME_DEF_STMT for example allowing match-and-simplify of
> > larger expressions on early GIMPLE
> I like it -- I can't see any significant reason to keep the _DECL nodes for
> these temporaries.  They're not useful for end-user debugging or debugging GCC
> itself.  In fact, I would claim that these temporary _DECL nodes just add
> noise when diffing debugging dumps.
> 
> While GC would reclaim the _DECL nodes, I'm all for avoiding placing work on
> the GC system when it can be easily avoided.

Yeah, it's not a big win here but I hope not breaking up the "big"
expressions we have in GENERIC when gimplifying but instead preserving
them via the SSA use->def link will be the more useful part of the change.

> > Complications arise from the fact that there is no CFG built and thus
> > we have to make sure to not use SSA names where we'd need PHIs.  Or
> > when CFG build may end up separating SSA def and use in a way current
> > into-SSA doesn't fix up (adding of abnormal edges, save-expr placement,
> > gimplification of type sizes, etc.).
> :(

Turns out that OpenMP dependences on seeing decls involves more
fixups ;)

> > As-is the patch has the downside of effectively disabling the
> > lookup_tmp_var () CSE for register typed temporaries and not
> > preserving the "fancy" names we derive from val in
> > create_tmp_from_val (that can be recovered easily though if
> > deemed worthwhile).
> I don't think it's worthwhile.

I've re-instantiated the fancy names with the patch below as it reduces
the testsuite fallout (or rather the requirement to adjust testcases
dump scanning) a bit.

> ISTM this will affect something like the gimple front-end project which would
> need to see the anonymous name and map it back to a suitable type, but I don't
> think that should stop this from moving forward.

Sure.  It's also the "easy" part of handling SSA (SSA without PHIs ;)).

The following is the final patch I am re-testing right now (after
some minor polishing).  I do expect some additional OpenMP fallout
in parts that are not covered by the testsuite - but rather than
mass-replacing gimplify_expr (...) with gimplify_expr (..., false)
I'm appreciating the extra testsuite coverage we'll get from extra
testcases.

Bootstrap and regtest running on x86_64-unknown-linux-gnu.

Richard.

2016-05-03  Richard Biener  <rguenther@suse.de>

	* gimplify.h (get_initialized_tmp_var): Add allow_ssa parameter
	default true.
	(gimplify_arg): Likewise.
	* gimplify.c (gimplify_expr): Add overload with allow_ssa parameter,
	re-writing the result to a decl if required.
	(internal_get_tmp_var): Add allow_ssa parameter
	and override into_ssa with it.
	(get_formal_tmp_var): Adjust.
	(get_initialized_tmp_var): Add allow_ssa parameter.
	(gimplify_arg): Add allow_ssa parameter and avoid generating
	SSA names for the result false.
	(gimplify_call_expr): If the call may return twice do not
	gimplify parameters into SSA.
	(prepare_gimple_addressable): Do not allow an SSA name as
	temporary.
	(gimplify_modify_expr): Adjust assert.  For noreturn calls
	with a SSA name LHS adjust its def.
	(gimplify_save_expr): Do not allow an SSA name as save-expr
	result.
	(gimplify_one_sizepos): Do not allow an SSA name as a sizepos.
	(gimplify_body): Init GIMPLE SSA data structures and gimplify
	into-SSA.
	(gimplify_scan_omp_clauses): Make sure OMP_CLAUSE_SIZE is not
	an SSA name.  Likewise for OMP_CLAUSE_REDUCTION operands.
	(gimplify_omp_for): Likewise for OMP_CLAUSE_DECL.  Likewise
	for OMP_FOR_COND,  OMP_FOR_INCR and OMP_CLAUSE_LINEAR_STEP.
	(optimize_target_teams): Do not allow SSA names for clause operands.
	(gimplify_expr): Likewise for where we mark the result addressable.
	* passes.def (pass_init_datastructures): Remove.
	* tree-into-ssa.c (mark_def_sites): Ignore existing SSA names.
	(rewrite_stmt): Likewise.
	* tree-inline.c (initialize_cfun): Properly transfer SSA state.
	(replace_locals_op): Replace SSA names.
	(copy_gimple_seq_and_replace_locals): Init src_cfun.
	* gimple-low.c (lower_builtin_setjmp): Deal with SSA.
	* cgraph.c (release_function_body): Free CFG annotations only
	when we have a CFG.  Simplify.
	* gimple-fold.c (gimplify_and_update_call_from_tree): Use
	force_gimple_operand instead of get_initialized_tmp_var.
	* tree-pass.h (make_pass_init_datastructures): Remove.
	* tree-ssa.c (execute_init_datastructures): Remove.
	(pass_data_init_datastructures): Likewise.
	(class pass_init_datastructures): Likewise.
	(make_pass_init_datastructures): Likewise.
	* omp-low.c (create_omp_child_function): Init SSA data structures.
	(grid_expand_target_grid_body): Likewise.
	* tree-cfg.c (move_block_to_fn): Double-check the DEF is an SSA
	name before adding it to names_to_release.
	(remove_bb): Always release SSA defs.
	* tree-ssa-ccp.c (get_default_value): Check SSA_NAME_VAR
	before dereferencing it.
	* cgraphunit.c (init_lowered_empty_function): Always
	int SSA data structures.
	* tree-ssanames.c (release_defs): Remove assert that we are in
	SSA form.
	* trans-mem.c (diagnose_tm_1): Handle SSA name function.

	c-family/
	* cilk.c (cilk_gimplify_call_params_in_spawned_fn): Do not
	allow call args to gimplify to SSA names.

	* gcc.dg/pr30172-1.c: Adjust.
	* gcc.dg/pr63743.c: Likewise.
	* gcc.dg/tm/pr51696.c: Likewise.
	* c-c++-common/tm/safe-1.c: Likewise.
	* gcc.dg/tree-prof/val-prof-3.c: Likewise.

Index: gcc/gimplify.c
===================================================================
*** gcc/gimplify.c.orig	2016-05-02 12:21:53.790806675 +0200
--- gcc/gimplify.c	2016-05-03 09:51:35.696738899 +0200
*************** static struct gimplify_omp_ctx *gimplify
*** 185,190 ****
--- 185,192 ----
  /* Forward declaration.  */
  static enum gimplify_status gimplify_compound_expr (tree *, gimple_seq *, bool);
  static hash_map<tree, tree> *oacc_declare_returns;
+ static enum gimplify_status gimplify_expr (tree *, gimple_seq *, gimple_seq *,
+ 					   bool (*) (tree), fallback_t, bool);
  
  /* Shorter alias name for the above function for use in gimplify.c
     only.  */
*************** lookup_tmp_var (tree val, bool is_formal
*** 547,553 ****
  
  static tree
  internal_get_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p,
!                       bool is_formal)
  {
    tree t, mod;
  
--- 549,555 ----
  
  static tree
  internal_get_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p,
!                       bool is_formal, bool allow_ssa)
  {
    tree t, mod;
  
*************** internal_get_tmp_var (tree val, gimple_s
*** 556,564 ****
    gimplify_expr (&val, pre_p, post_p, is_gimple_reg_rhs_or_call,
  		 fb_rvalue);
  
!   if (gimplify_ctxp->into_ssa
        && is_gimple_reg_type (TREE_TYPE (val)))
!     t = make_ssa_name (TYPE_MAIN_VARIANT (TREE_TYPE (val)));
    else
      t = lookup_tmp_var (val, is_formal);
  
--- 558,575 ----
    gimplify_expr (&val, pre_p, post_p, is_gimple_reg_rhs_or_call,
  		 fb_rvalue);
  
!   if (allow_ssa
!       && gimplify_ctxp->into_ssa
        && is_gimple_reg_type (TREE_TYPE (val)))
!     {
!       t = make_ssa_name (TYPE_MAIN_VARIANT (TREE_TYPE (val)));
!       if (! gimple_in_ssa_p (cfun))
! 	{
! 	  const char *name = get_name (val);
! 	  if (name)
! 	    SET_SSA_NAME_VAR_OR_IDENTIFIER (t, create_tmp_var_name (name));
! 	}
!     }
    else
      t = lookup_tmp_var (val, is_formal);
  
*************** internal_get_tmp_var (tree val, gimple_s
*** 588,603 ****
  tree
  get_formal_tmp_var (tree val, gimple_seq *pre_p)
  {
!   return internal_get_tmp_var (val, pre_p, NULL, true);
  }
  
  /* Return a temporary variable initialized with VAL.  PRE_P and POST_P
     are as in gimplify_expr.  */
  
  tree
! get_initialized_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p)
  {
!   return internal_get_tmp_var (val, pre_p, post_p, false);
  }
  
  /* Declare all the variables in VARS in SCOPE.  If DEBUG_INFO is true,
--- 599,615 ----
  tree
  get_formal_tmp_var (tree val, gimple_seq *pre_p)
  {
!   return internal_get_tmp_var (val, pre_p, NULL, true, true);
  }
  
  /* Return a temporary variable initialized with VAL.  PRE_P and POST_P
     are as in gimplify_expr.  */
  
  tree
! get_initialized_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p,
! 			 bool allow_ssa)
  {
!   return internal_get_tmp_var (val, pre_p, post_p, false, allow_ssa);
  }
  
  /* Declare all the variables in VARS in SCOPE.  If DEBUG_INFO is true,
*************** maybe_with_size_expr (tree *expr_p)
*** 2279,2288 ****
  
  /* Helper for gimplify_call_expr.  Gimplify a single argument *ARG_P
     Store any side-effects in PRE_P.  CALL_LOCATION is the location of
!    the CALL_EXPR.  */
  
  enum gimplify_status
! gimplify_arg (tree *arg_p, gimple_seq *pre_p, location_t call_location)
  {
    bool (*test) (tree);
    fallback_t fb;
--- 2291,2302 ----
  
  /* Helper for gimplify_call_expr.  Gimplify a single argument *ARG_P
     Store any side-effects in PRE_P.  CALL_LOCATION is the location of
!    the CALL_EXPR.  If ALLOW_SSA is set the actual parameter may be
!    gimplified to an SSA name.  */
  
  enum gimplify_status
! gimplify_arg (tree *arg_p, gimple_seq *pre_p, location_t call_location,
! 	      bool allow_ssa)
  {
    bool (*test) (tree);
    fallback_t fb;
*************** gimplify_arg (tree *arg_p, gimple_seq *p
*** 2319,2325 ****
       the argument list must occur before the actual call. So, when
       gimplifying arguments, force gimplify_expr to use an internal
       post queue which is then appended to the end of PRE_P.  */
!   return gimplify_expr (arg_p, pre_p, NULL, test, fb);
  }
  
  /* Don't fold inside offloading or taskreg regions: it can break code by
--- 2333,2339 ----
       the argument list must occur before the actual call. So, when
       gimplifying arguments, force gimplify_expr to use an internal
       post queue which is then appended to the end of PRE_P.  */
!   return gimplify_expr (arg_p, pre_p, NULL, test, fb, allow_ssa);
  }
  
  /* Don't fold inside offloading or taskreg regions: it can break code by
*************** gimplify_call_expr (tree *expr_p, gimple
*** 2522,2527 ****
--- 2536,2547 ----
  	}
      }
  
+   /* If the call returns twice then after building the CFG the call
+      argument computations will no longer dominate the call because
+      we add an abnormal incoming edge to the call.  So do not use SSA
+      vars there.  */
+   bool returns_twice = call_expr_flags (*expr_p) & ECF_RETURNS_TWICE;
+ 
    /* Gimplify the function arguments.  */
    if (nargs > 0)
      {
*************** gimplify_call_expr (tree *expr_p, gimple
*** 2536,2542 ****
            if ((i != 1) || !builtin_va_start_p)
              {
                t = gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p,
! 				EXPR_LOCATION (*expr_p));
  
                if (t == GS_ERROR)
                  ret = GS_ERROR;
--- 2556,2562 ----
            if ((i != 1) || !builtin_va_start_p)
              {
                t = gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p,
! 				EXPR_LOCATION (*expr_p), ! returns_twice);
  
                if (t == GS_ERROR)
                  ret = GS_ERROR;
*************** gimplify_call_expr (tree *expr_p, gimple
*** 2553,2559 ****
  	{
  	  enum gimplify_status t;
  	  t = gimplify_arg (&CALL_EXPR_STATIC_CHAIN (*expr_p), pre_p,
! 			    EXPR_LOCATION (*expr_p));
  	  if (t == GS_ERROR)
  	    ret = GS_ERROR;
  	}
--- 2573,2579 ----
  	{
  	  enum gimplify_status t;
  	  t = gimplify_arg (&CALL_EXPR_STATIC_CHAIN (*expr_p), pre_p,
! 			    EXPR_LOCATION (*expr_p), ! returns_twice);
  	  if (t == GS_ERROR)
  	    ret = GS_ERROR;
  	}
*************** prepare_gimple_addressable (tree *expr_p
*** 3316,3322 ****
      expr_p = &TREE_OPERAND (*expr_p, 0);
    if (is_gimple_reg (*expr_p))
      {
!       tree var = get_initialized_tmp_var (*expr_p, seq_p, NULL);
        DECL_GIMPLE_REG_P (var) = 0;
        *expr_p = var;
      }
--- 3336,3343 ----
      expr_p = &TREE_OPERAND (*expr_p, 0);
    if (is_gimple_reg (*expr_p))
      {
!       /* Do not allow an SSA name as the temporary.  */
!       tree var = get_initialized_tmp_var (*expr_p, seq_p, NULL, false);
        DECL_GIMPLE_REG_P (var) = 0;
        *expr_p = var;
      }
*************** gimplify_modify_expr (tree *expr_p, gimp
*** 4848,4853 ****
--- 4869,4879 ----
  	  || TREE_ADDRESSABLE (TREE_TYPE (*to_p))
  	  || TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (*to_p))) != INTEGER_CST)
  	gimple_call_set_lhs (call_stmt, *to_p);
+       else if (TREE_CODE (*to_p) == SSA_NAME)
+ 	/* The above is somewhat premature, avoid ICEing later for a
+ 	   SSA name w/o a definition.  We may have uses in the GIMPLE IL.
+ 	   ???  This doesn't make it a default-def.  */
+ 	SSA_NAME_DEF_STMT (*to_p) = gimple_build_nop ();
        assign = call_stmt;
      }
    else
*************** gimplify_modify_expr (tree *expr_p, gimp
*** 4861,4867 ****
    if (gimplify_ctxp->into_ssa && is_gimple_reg (*to_p))
      {
        /* We should have got an SSA name from the start.  */
!       gcc_assert (TREE_CODE (*to_p) == SSA_NAME);
      }
  
    gimplify_seq_add_stmt (pre_p, assign);
--- 4887,4894 ----
    if (gimplify_ctxp->into_ssa && is_gimple_reg (*to_p))
      {
        /* We should have got an SSA name from the start.  */
!       gcc_assert (TREE_CODE (*to_p) == SSA_NAME
! 		  || ! gimple_in_ssa_p (cfun));
      }
  
    gimplify_seq_add_stmt (pre_p, assign);
*************** gimplify_save_expr (tree *expr_p, gimple
*** 4994,5000 ****
  	  val = NULL;
  	}
        else
! 	val = get_initialized_tmp_var (val, pre_p, post_p);
  
        TREE_OPERAND (*expr_p, 0) = val;
        SAVE_EXPR_RESOLVED_P (*expr_p) = 1;
--- 5021,5029 ----
  	  val = NULL;
  	}
        else
! 	/* The temporary may not be an SSA name as later abnormal and EH
! 	   control flow may invalidate use/def domination.  */
! 	val = get_initialized_tmp_var (val, pre_p, post_p, false);
  
        TREE_OPERAND (*expr_p, 0) = val;
        SAVE_EXPR_RESOLVED_P (*expr_p) = 1;
*************** gimplify_scan_omp_clauses (tree *list_p,
*** 6653,6659 ****
  	    {
  	      tree type = TREE_TYPE (decl);
  	      if (gimplify_expr (&TYPE_MAX_VALUE (TYPE_DOMAIN (type)), pre_p,
! 				 NULL, is_gimple_val, fb_rvalue) == GS_ERROR)
  		{
  		  remove = true;
  		  break;
--- 6682,6689 ----
  	    {
  	      tree type = TREE_TYPE (decl);
  	      if (gimplify_expr (&TYPE_MAX_VALUE (TYPE_DOMAIN (type)), pre_p,
! 				 NULL, is_gimple_val, fb_rvalue, false)
! 		  == GS_ERROR)
  		{
  		  remove = true;
  		  break;
*************** gimplify_scan_omp_clauses (tree *list_p,
*** 6668,6674 ****
  	      if (TREE_CODE (decl) == POINTER_PLUS_EXPR)
  		{
  		  if (gimplify_expr (&TREE_OPERAND (decl, 1), pre_p,
! 				     NULL, is_gimple_val, fb_rvalue)
  		      == GS_ERROR)
  		    {
  		      remove = true;
--- 6698,6704 ----
  	      if (TREE_CODE (decl) == POINTER_PLUS_EXPR)
  		{
  		  if (gimplify_expr (&TREE_OPERAND (decl, 1), pre_p,
! 				     NULL, is_gimple_val, fb_rvalue, false)
  		      == GS_ERROR)
  		    {
  		      remove = true;
*************** gimplify_scan_omp_clauses (tree *list_p,
*** 6865,6871 ****
  		   && TREE_CODE (OMP_CLAUSE_SIZE (c)) != INTEGER_CST)
  	    {
  	      OMP_CLAUSE_SIZE (c)
! 		= get_initialized_tmp_var (OMP_CLAUSE_SIZE (c), pre_p, NULL);
  	      omp_add_variable (ctx, OMP_CLAUSE_SIZE (c),
  				GOVD_FIRSTPRIVATE | GOVD_SEEN);
  	    }
--- 6895,6902 ----
  		   && TREE_CODE (OMP_CLAUSE_SIZE (c)) != INTEGER_CST)
  	    {
  	      OMP_CLAUSE_SIZE (c)
! 		= get_initialized_tmp_var (OMP_CLAUSE_SIZE (c), pre_p, NULL,
! 					   false);
  	      omp_add_variable (ctx, OMP_CLAUSE_SIZE (c),
  				GOVD_FIRSTPRIVATE | GOVD_SEEN);
  	    }
*************** gimplify_omp_for (tree *expr_p, gimple_s
*** 8609,8615 ****
  	    {
  	      TREE_OPERAND (t, 1)
  		= get_initialized_tmp_var (TREE_OPERAND (t, 1),
! 					   pre_p, NULL);
  	      tree c = build_omp_clause (input_location,
  					 OMP_CLAUSE_FIRSTPRIVATE);
  	      OMP_CLAUSE_DECL (c) = TREE_OPERAND (t, 1);
--- 8640,8646 ----
  	    {
  	      TREE_OPERAND (t, 1)
  		= get_initialized_tmp_var (TREE_OPERAND (t, 1),
! 					   pre_p, NULL, false);
  	      tree c = build_omp_clause (input_location,
  					 OMP_CLAUSE_FIRSTPRIVATE);
  	      OMP_CLAUSE_DECL (c) = TREE_OPERAND (t, 1);
*************** gimplify_omp_for (tree *expr_p, gimple_s
*** 8624,8630 ****
  	      TREE_OPERAND (t, 1)
  		= get_initialized_tmp_var (TREE_OPERAND (t, 1),
  					   gimple_seq_empty_p (for_pre_body)
! 					   ? pre_p : &for_pre_body, NULL);
  	      tree c = build_omp_clause (input_location,
  					 OMP_CLAUSE_FIRSTPRIVATE);
  	      OMP_CLAUSE_DECL (c) = TREE_OPERAND (t, 1);
--- 8655,8662 ----
  	      TREE_OPERAND (t, 1)
  		= get_initialized_tmp_var (TREE_OPERAND (t, 1),
  					   gimple_seq_empty_p (for_pre_body)
! 					   ? pre_p : &for_pre_body, NULL,
! 					   false);
  	      tree c = build_omp_clause (input_location,
  					 OMP_CLAUSE_FIRSTPRIVATE);
  	      OMP_CLAUSE_DECL (c) = TREE_OPERAND (t, 1);
*************** gimplify_omp_for (tree *expr_p, gimple_s
*** 8646,8652 ****
  		{
  		  gimple_seq *seq = gimple_seq_empty_p (for_pre_body)
  				    ? pre_p : &for_pre_body;
! 		  *tp = get_initialized_tmp_var (*tp, seq, NULL);
  		  tree c = build_omp_clause (input_location,
  					     OMP_CLAUSE_FIRSTPRIVATE);
  		  OMP_CLAUSE_DECL (c) = *tp;
--- 8678,8684 ----
  		{
  		  gimple_seq *seq = gimple_seq_empty_p (for_pre_body)
  				    ? pre_p : &for_pre_body;
! 		  *tp = get_initialized_tmp_var (*tp, seq, NULL, false);
  		  tree c = build_omp_clause (input_location,
  					     OMP_CLAUSE_FIRSTPRIVATE);
  		  OMP_CLAUSE_DECL (c) = *tp;
*************** gimplify_omp_for (tree *expr_p, gimple_s
*** 8982,8988 ****
  	var = decl;
  
        tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
! 			    is_gimple_val, fb_rvalue);
        ret = MIN (ret, tret);
        if (ret == GS_ERROR)
  	return ret;
--- 9014,9020 ----
  	var = decl;
  
        tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
! 			    is_gimple_val, fb_rvalue, false);
        ret = MIN (ret, tret);
        if (ret == GS_ERROR)
  	return ret;
*************** gimplify_omp_for (tree *expr_p, gimple_s
*** 8993,8999 ****
        gcc_assert (TREE_OPERAND (t, 0) == decl);
  
        tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
! 			    is_gimple_val, fb_rvalue);
        ret = MIN (ret, tret);
  
        /* Handle OMP_FOR_INCR.  */
--- 9025,9031 ----
        gcc_assert (TREE_OPERAND (t, 0) == decl);
  
        tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
! 			    is_gimple_val, fb_rvalue, false);
        ret = MIN (ret, tret);
  
        /* Handle OMP_FOR_INCR.  */
*************** gimplify_omp_for (tree *expr_p, gimple_s
*** 9060,9066 ****
  	    }
  
  	  tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
! 				is_gimple_val, fb_rvalue);
  	  ret = MIN (ret, tret);
  	  if (c)
  	    {
--- 9092,9098 ----
  	    }
  
  	  tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
! 				is_gimple_val, fb_rvalue, false);
  	  ret = MIN (ret, tret);
  	  if (c)
  	    {
*************** gimplify_omp_for (tree *expr_p, gimple_s
*** 9076,9082 ****
  		{
  		  tret = gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c),
  					&for_pre_body, NULL,
! 					is_gimple_val, fb_rvalue);
  		  ret = MIN (ret, tret);
  		}
  	    }
--- 9108,9114 ----
  		{
  		  tret = gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c),
  					&for_pre_body, NULL,
! 					is_gimple_val, fb_rvalue, false);
  		  ret = MIN (ret, tret);
  		}
  	    }
*************** optimize_target_teams (tree target, gimp
*** 9530,9536 ****
  	  }
  	*p = expr;
  	gimplify_omp_ctxp = gimplify_omp_ctxp->outer_context;
! 	if (gimplify_expr (p, pre_p, NULL, is_gimple_val, fb_rvalue)
  	    == GS_ERROR)
  	  {
  	    gimplify_omp_ctxp = target_ctx;
--- 9562,9568 ----
  	  }
  	*p = expr;
  	gimplify_omp_ctxp = gimplify_omp_ctxp->outer_context;
! 	if (gimplify_expr (p, pre_p, NULL, is_gimple_val, fb_rvalue, false)
  	    == GS_ERROR)
  	  {
  	    gimplify_omp_ctxp = target_ctx;
*************** gimplify_expr (tree *expr_p, gimple_seq
*** 10248,10254 ****
  	     required.  */
  	  if (fallback == fb_lvalue)
  	    {
! 	      *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p);
  	      mark_addressable (*expr_p);
  	      ret = GS_OK;
  	    }
--- 10280,10286 ----
  	     required.  */
  	  if (fallback == fb_lvalue)
  	    {
! 	      *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
  	      mark_addressable (*expr_p);
  	      ret = GS_OK;
  	    }
*************** gimplify_expr (tree *expr_p, gimple_seq
*** 10263,10269 ****
  	     required.  */
  	  if (fallback == fb_lvalue)
  	    {
! 	      *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p);
  	      mark_addressable (*expr_p);
  	      ret = GS_OK;
  	    }
--- 10295,10301 ----
  	     required.  */
  	  if (fallback == fb_lvalue)
  	    {
! 	      *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
  	      mark_addressable (*expr_p);
  	      ret = GS_OK;
  	    }
*************** gimplify_expr (tree *expr_p, gimple_seq
*** 10563,10569 ****
  	     required.  */
  	  else if (fallback == fb_lvalue)
  	    {
! 	      *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p);
  	      mark_addressable (*expr_p);
  	      ret = GS_OK;
  	    }
--- 10595,10601 ----
  	     required.  */
  	  else if (fallback == fb_lvalue)
  	    {
! 	      *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
  	      mark_addressable (*expr_p);
  	      ret = GS_OK;
  	    }
*************** gimplify_expr (tree *expr_p, gimple_seq
*** 11261,11266 ****
--- 11293,11327 ----
    return ret;
  }
  
+ /* Like gimplify_expr but make sure the gimplified result is not itself
+    a SSA name (but a decl if it were).  Temporaries required by
+    evaluating *EXPR_P may be still SSA names.  */
+ 
+ static enum gimplify_status
+ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
+ 	       bool (*gimple_test_f) (tree), fallback_t fallback,
+ 	       bool allow_ssa)
+ {
+   bool was_ssa_name_p = TREE_CODE (*expr_p) == SSA_NAME;
+   enum gimplify_status ret = gimplify_expr (expr_p, pre_p, post_p,
+ 					    gimple_test_f, fallback);
+   if (! allow_ssa
+       && TREE_CODE (*expr_p) == SSA_NAME)
+     {
+       tree name = *expr_p;
+       if (was_ssa_name_p)
+ 	*expr_p = get_initialized_tmp_var (*expr_p, pre_p, NULL, false);
+       else
+ 	{
+ 	  /* Avoid the extra copy if possible.  */
+ 	  *expr_p = create_tmp_reg (TREE_TYPE (name));
+ 	  gimple_set_lhs (SSA_NAME_DEF_STMT (name), *expr_p);
+ 	  release_ssa_name (name);
+ 	}
+     }
+   return ret;
+ }
+ 
  /* Look through TYPE for variable-sized objects and gimplify each such
     size that we find.  Add to LIST_P any statements generated.  */
  
*************** gimplify_one_sizepos (tree *expr_p, gimp
*** 11383,11389 ****
  
    *expr_p = unshare_expr (expr);
  
!   gimplify_expr (expr_p, stmt_p, NULL, is_gimple_val, fb_rvalue);
  }
  
  /* Gimplify the body of statements of FNDECL and return a GIMPLE_BIND node
--- 11444,11452 ----
  
    *expr_p = unshare_expr (expr);
  
!   /* SSA names in decl/type fields are a bad idea - they'll get reclaimed
!      if the def vanishes.  */
!   gimplify_expr (expr_p, stmt_p, NULL, is_gimple_val, fb_rvalue, false);
  }
  
  /* Gimplify the body of statements of FNDECL and return a GIMPLE_BIND node
*************** gimplify_body (tree fndecl, bool do_parm
*** 11401,11412 ****
  
    timevar_push (TV_TREE_GIMPLIFY);
  
    /* Initialize for optimize_insn_for_s{ize,peed}_p possibly called during
       gimplification.  */
    default_rtl_profile ();
  
    gcc_assert (gimplify_ctxp == NULL);
!   push_gimplify_context ();
  
    if (flag_openacc || flag_openmp)
      {
--- 11464,11477 ----
  
    timevar_push (TV_TREE_GIMPLIFY);
  
+   init_tree_ssa (cfun);
+ 
    /* Initialize for optimize_insn_for_s{ize,peed}_p possibly called during
       gimplification.  */
    default_rtl_profile ();
  
    gcc_assert (gimplify_ctxp == NULL);
!   push_gimplify_context (true);
  
    if (flag_openacc || flag_openmp)
      {
Index: gcc/passes.def
===================================================================
*** gcc/passes.def.orig	2016-05-02 12:21:53.790806675 +0200
--- gcc/passes.def	2016-05-02 12:22:11.923013123 +0200
*************** along with GCC; see the file COPYING3.
*** 54,60 ****
    NEXT_PASS (pass_build_ssa_passes);
    PUSH_INSERT_PASSES_WITHIN (pass_build_ssa_passes)
        NEXT_PASS (pass_fixup_cfg);
-       NEXT_PASS (pass_init_datastructures);
        NEXT_PASS (pass_build_ssa);
        NEXT_PASS (pass_warn_nonnull_compare);
        NEXT_PASS (pass_ubsan);
--- 54,59 ----
Index: gcc/tree-into-ssa.c
===================================================================
*** gcc/tree-into-ssa.c.orig	2016-05-02 12:21:53.794806720 +0200
--- gcc/tree-into-ssa.c	2016-05-02 12:22:11.923013123 +0200
*************** mark_def_sites (basic_block bb, gimple *
*** 666,671 ****
--- 666,673 ----
    FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_ALL_USES)
      {
        tree sym = USE_FROM_PTR (use_p);
+       if (TREE_CODE (sym) == SSA_NAME)
+ 	continue;
        gcc_checking_assert (DECL_P (sym));
        if (!bitmap_bit_p (kills, DECL_UID (sym)))
  	set_livein_block (sym, bb);
*************** mark_def_sites (basic_block bb, gimple *
*** 676,681 ****
--- 678,685 ----
       each def to the set of killed symbols.  */
    FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_ALL_DEFS)
      {
+       if (TREE_CODE (def) == SSA_NAME)
+ 	continue;
        gcc_checking_assert (DECL_P (def));
        set_def_block (def, bb, false);
        bitmap_set_bit (kills, DECL_UID (def));
*************** rewrite_stmt (gimple_stmt_iterator *si)
*** 1310,1315 ****
--- 1314,1321 ----
  	FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_ALL_USES)
  	  {
  	    tree var = USE_FROM_PTR (use_p);
+ 	    if (TREE_CODE (var) == SSA_NAME)
+ 	      continue;
  	    gcc_checking_assert (DECL_P (var));
  	    SET_USE (use_p, get_reaching_def (var));
  	  }
*************** rewrite_stmt (gimple_stmt_iterator *si)
*** 1323,1328 ****
--- 1329,1336 ----
  	tree name;
  	tree tracked_var;
  
+ 	if (TREE_CODE (var) == SSA_NAME)
+ 	  continue;
  	gcc_checking_assert (DECL_P (var));
  
  	if (gimple_clobber_p (stmt)
Index: gcc/tree-inline.c
===================================================================
*** gcc/tree-inline.c.orig	2016-04-28 15:24:39.691848030 +0200
--- gcc/tree-inline.c	2016-05-02 12:22:11.923013123 +0200
*************** initialize_cfun (tree new_fndecl, tree c
*** 2456,2463 ****
    if (src_cfun->gimple_df)
      {
        init_tree_ssa (cfun);
!       cfun->gimple_df->in_ssa_p = true;
!       init_ssa_operands (cfun);
      }
  }
  
--- 2456,2464 ----
    if (src_cfun->gimple_df)
      {
        init_tree_ssa (cfun);
!       cfun->gimple_df->in_ssa_p = src_cfun->gimple_df->in_ssa_p;
!       if (cfun->gimple_df->in_ssa_p)
! 	init_ssa_operands (cfun);
      }
  }
  
*************** replace_locals_op (tree *tp, int *walk_s
*** 5119,5128 ****
    tree *n;
    tree expr = *tp;
  
    /* Only a local declaration (variable or label).  */
!   if ((TREE_CODE (expr) == VAR_DECL
!        && !TREE_STATIC (expr))
!       || TREE_CODE (expr) == LABEL_DECL)
      {
        /* Lookup the declaration.  */
        n = st->get (expr);
--- 5120,5140 ----
    tree *n;
    tree expr = *tp;
  
+   /* For recursive invocations this is no longer the LHS itself.  */
+   bool is_lhs = wi->is_lhs;
+   wi->is_lhs = false;
+ 
+   if (TREE_CODE (expr) == SSA_NAME)
+     {
+       *tp = remap_ssa_name (*tp, id);
+       *walk_subtrees = 0;
+       if (is_lhs)
+ 	SSA_NAME_DEF_STMT (*tp) = gsi_stmt (wi->gsi);
+     }
    /* Only a local declaration (variable or label).  */
!   else if ((TREE_CODE (expr) == VAR_DECL
! 	    && !TREE_STATIC (expr))
! 	   || TREE_CODE (expr) == LABEL_DECL)
      {
        /* Lookup the declaration.  */
        n = st->get (expr);
*************** copy_gimple_seq_and_replace_locals (gimp
*** 5262,5267 ****
--- 5274,5280 ----
    memset (&id, 0, sizeof (id));
    id.src_fn = current_function_decl;
    id.dst_fn = current_function_decl;
+   id.src_cfun = cfun;
    id.decl_map = new hash_map<tree, tree>;
    id.debug_map = NULL;
  
Index: gcc/gimple-low.c
===================================================================
*** gcc/gimple-low.c.orig	2016-05-02 12:21:53.798806766 +0200
--- gcc/gimple-low.c	2016-05-02 12:22:11.923013123 +0200
*************** lower_builtin_setjmp (gimple_stmt_iterat
*** 740,746 ****
       passed to both __builtin_setjmp_setup and __builtin_setjmp_receiver.  */
    FORCED_LABEL (next_label) = 1;
  
!   dest = gimple_call_lhs (stmt);
  
    /* Build '__builtin_setjmp_setup (BUF, NEXT_LABEL)' and insert.  */
    arg = build_addr (next_label);
--- 740,748 ----
       passed to both __builtin_setjmp_setup and __builtin_setjmp_receiver.  */
    FORCED_LABEL (next_label) = 1;
  
!   tree orig_dest = dest = gimple_call_lhs (stmt);
!   if (orig_dest && TREE_CODE (orig_dest) == SSA_NAME)
!     dest = create_tmp_reg (TREE_TYPE (orig_dest));
  
    /* Build '__builtin_setjmp_setup (BUF, NEXT_LABEL)' and insert.  */
    arg = build_addr (next_label);
*************** lower_builtin_setjmp (gimple_stmt_iterat
*** 789,794 ****
--- 791,803 ----
    g = gimple_build_label (cont_label);
    gsi_insert_before (gsi, g, GSI_SAME_STMT);
  
+   /* Build orig_dest = dest if necessary.  */
+   if (dest != orig_dest)
+     {
+       g = gimple_build_assign (orig_dest, dest);
+       gsi_insert_before (gsi, g, GSI_SAME_STMT);
+     }
+ 
    /* Remove the call to __builtin_setjmp.  */
    gsi_remove (gsi, false);
  }
Index: gcc/cgraph.c
===================================================================
*** gcc/cgraph.c.orig	2016-05-02 12:21:53.802806812 +0200
--- gcc/cgraph.c	2016-05-02 12:22:11.923013123 +0200
*************** release_function_body (tree decl)
*** 1729,1758 ****
    if (fn)
      {
        if (fn->cfg
! 	  || fn->gimple_df)
  	{
! 	  if (fn->cfg
! 	      && loops_for_fn (fn))
! 	    {
! 	      fn->curr_properties &= ~PROP_loops;
! 	      loop_optimizer_finalize (fn);
! 	    }
! 	  if (fn->gimple_df)
! 	    {
! 	      delete_tree_ssa (fn);
! 	      delete_tree_cfg_annotations (fn);
! 	      fn->eh = NULL;
! 	    }
! 	  if (fn->cfg)
! 	    {
! 	      gcc_assert (!dom_info_available_p (fn, CDI_DOMINATORS));
! 	      gcc_assert (!dom_info_available_p (fn, CDI_POST_DOMINATORS));
! 	      clear_edges (fn);
! 	      fn->cfg = NULL;
! 	    }
! 	  if (fn->value_histograms)
! 	    free_histograms (fn);
  	}
        gimple_set_body (decl, NULL);
        /* Struct function hangs a lot of data that would leak if we didn't
           removed all pointers to it.   */
--- 1729,1754 ----
    if (fn)
      {
        if (fn->cfg
! 	  && loops_for_fn (fn))
  	{
! 	  fn->curr_properties &= ~PROP_loops;
! 	  loop_optimizer_finalize (fn);
  	}
+       if (fn->gimple_df)
+ 	{
+ 	  delete_tree_ssa (fn);
+ 	  fn->eh = NULL;
+ 	}
+       if (fn->cfg)
+ 	{
+ 	  gcc_assert (!dom_info_available_p (fn, CDI_DOMINATORS));
+ 	  gcc_assert (!dom_info_available_p (fn, CDI_POST_DOMINATORS));
+ 	  delete_tree_cfg_annotations (fn);
+ 	  clear_edges (fn);
+ 	  fn->cfg = NULL;
+ 	}
+       if (fn->value_histograms)
+ 	free_histograms (fn);
        gimple_set_body (decl, NULL);
        /* Struct function hangs a lot of data that would leak if we didn't
           removed all pointers to it.   */
Index: gcc/gimple-fold.c
===================================================================
*** gcc/gimple-fold.c.orig	2016-05-02 12:21:53.802806812 +0200
--- gcc/gimple-fold.c	2016-05-02 12:22:11.927013168 +0200
*************** gimplify_and_update_call_from_tree (gimp
*** 542,548 ****
      }
    else
      {
!       tree tmp = get_initialized_tmp_var (expr, &stmts, NULL);
        new_stmt = gimple_build_assign (lhs, tmp);
        i = gsi_last (stmts);
        gsi_insert_after_without_update (&i, new_stmt,
--- 542,548 ----
      }
    else
      {
!       tree tmp = force_gimple_operand (expr, &stmts, false, NULL_TREE);
        new_stmt = gimple_build_assign (lhs, tmp);
        i = gsi_last (stmts);
        gsi_insert_after_without_update (&i, new_stmt,
Index: gcc/gimplify.h
===================================================================
*** gcc/gimplify.h.orig	2016-05-02 12:21:53.802806812 +0200
--- gcc/gimplify.h	2016-05-02 12:22:11.927013168 +0200
*************** extern gbind *gimple_current_bind_expr (
*** 57,63 ****
  extern vec<gbind *> gimple_bind_expr_stack (void);
  extern void gimplify_and_add (tree, gimple_seq *);
  extern tree get_formal_tmp_var (tree, gimple_seq *);
! extern tree get_initialized_tmp_var (tree, gimple_seq *, gimple_seq *);
  extern void declare_vars (tree, gimple *, bool);
  extern void gimple_add_tmp_var (tree);
  extern void gimple_add_tmp_var_fn (struct function *, tree);
--- 57,64 ----
  extern vec<gbind *> gimple_bind_expr_stack (void);
  extern void gimplify_and_add (tree, gimple_seq *);
  extern tree get_formal_tmp_var (tree, gimple_seq *);
! extern tree get_initialized_tmp_var (tree, gimple_seq *, gimple_seq *,
! 				     bool = true);
  extern void declare_vars (tree, gimple *, bool);
  extern void gimple_add_tmp_var (tree);
  extern void gimple_add_tmp_var_fn (struct function *, tree);
*************** extern enum gimplify_status gimplify_exp
*** 77,83 ****
  extern void gimplify_type_sizes (tree, gimple_seq *);
  extern void gimplify_one_sizepos (tree *, gimple_seq *);
  extern gbind *gimplify_body (tree, bool);
! extern enum gimplify_status gimplify_arg (tree *, gimple_seq *, location_t);
  extern void gimplify_function_tree (tree);
  extern enum gimplify_status gimplify_va_arg_expr (tree *, gimple_seq *,
  						  gimple_seq *);
--- 78,85 ----
  extern void gimplify_type_sizes (tree, gimple_seq *);
  extern void gimplify_one_sizepos (tree *, gimple_seq *);
  extern gbind *gimplify_body (tree, bool);
! extern enum gimplify_status gimplify_arg (tree *, gimple_seq *, location_t,
! 					  bool = true);
  extern void gimplify_function_tree (tree);
  extern enum gimplify_status gimplify_va_arg_expr (tree *, gimple_seq *,
  						  gimple_seq *);
Index: gcc/tree-pass.h
===================================================================
*** gcc/tree-pass.h.orig	2016-05-02 12:21:53.802806812 +0200
--- gcc/tree-pass.h	2016-05-02 12:22:11.927013168 +0200
*************** extern ipa_opt_pass_d *make_pass_ipa_com
*** 506,512 ****
  
  extern gimple_opt_pass *make_pass_cleanup_cfg_post_optimizing (gcc::context
  							       *ctxt);
- extern gimple_opt_pass *make_pass_init_datastructures (gcc::context *ctxt);
  extern gimple_opt_pass *make_pass_fixup_cfg (gcc::context *ctxt);
  extern gimple_opt_pass *make_pass_backprop (gcc::context *ctxt);
  
--- 506,511 ----
Index: gcc/tree-ssa.c
===================================================================
*** gcc/tree-ssa.c.orig	2016-04-28 15:24:39.691848030 +0200
--- gcc/tree-ssa.c	2016-05-02 12:22:11.927013168 +0200
*************** init_tree_ssa (struct function *fn)
*** 1076,1137 ****
    init_ssanames (fn, 0);
  }
  
- /* Do the actions required to initialize internal data structures used
-    in tree-ssa optimization passes.  */
- 
- static unsigned int
- execute_init_datastructures (void)
- {
-   /* Allocate hash tables, arrays and other structures.  */
-   gcc_assert (!cfun->gimple_df);
-   init_tree_ssa (cfun);
-   return 0;
- }
- 
- namespace {
- 
- const pass_data pass_data_init_datastructures =
- {
-   GIMPLE_PASS, /* type */
-   "*init_datastructures", /* name */
-   OPTGROUP_NONE, /* optinfo_flags */
-   TV_NONE, /* tv_id */
-   PROP_cfg, /* properties_required */
-   0, /* properties_provided */
-   0, /* properties_destroyed */
-   0, /* todo_flags_start */
-   0, /* todo_flags_finish */
- };
- 
- class pass_init_datastructures : public gimple_opt_pass
- {
- public:
-   pass_init_datastructures (gcc::context *ctxt)
-     : gimple_opt_pass (pass_data_init_datastructures, ctxt)
-   {}
- 
-   /* opt_pass methods: */
-   virtual bool gate (function *fun)
-     {
-       /* Do nothing for funcions that was produced already in SSA form.  */
-       return !(fun->curr_properties & PROP_ssa);
-     }
- 
-   virtual unsigned int execute (function *)
-     {
-       return execute_init_datastructures ();
-     }
- 
- }; // class pass_init_datastructures
- 
- } // anon namespace
- 
- gimple_opt_pass *
- make_pass_init_datastructures (gcc::context *ctxt)
- {
-   return new pass_init_datastructures (ctxt);
- }
- 
  /* Deallocate memory associated with SSA data structures for FNDECL.  */
  
  void
--- 1076,1081 ----
Index: gcc/omp-low.c
===================================================================
*** gcc/omp-low.c.orig	2016-05-02 12:21:53.806806857 +0200
--- gcc/omp-low.c	2016-05-02 12:22:11.931013214 +0200
*************** create_omp_child_function (omp_context *
*** 2569,2574 ****
--- 2569,2575 ----
       it afterward.  */
    push_struct_function (decl);
    cfun->function_end_locus = gimple_location (ctx->stmt);
+   init_tree_ssa (cfun);
    pop_cfun ();
  }
  
*************** grid_expand_target_grid_body (struct omp
*** 13673,13678 ****
--- 13674,13680 ----
    DECL_INITIAL (kern_fndecl) = fniniblock;
    push_struct_function (kern_fndecl);
    cfun->function_end_locus = gimple_location (tgt_stmt);
+   init_tree_ssa (cfun);
    pop_cfun ();
  
    tree old_parm_decl = DECL_ARGUMENTS (kern_fndecl);
Index: gcc/testsuite/gcc.dg/pr30172-1.c
===================================================================
*** gcc/testsuite/gcc.dg/pr30172-1.c.orig	2016-05-02 12:21:53.806806857 +0200
--- gcc/testsuite/gcc.dg/pr30172-1.c	2016-05-02 12:22:11.931013214 +0200
*************** _Complex double test5 (double x, double
*** 10,14 ****
  /* { dg-final { scan-tree-dump "COMPLEX_EXPR <x, 1.0e\\+0>" "gimple" } } */
  /* { dg-final { scan-tree-dump "COMPLEX_EXPR <1.0e\\+0, x>" "gimple" } } */
  /* { dg-final { scan-tree-dump "COMPLEX_EXPR <x, y>" "gimple" } } */
! /* { dg-final { scan-tree-dump "D.* = -y;\n.*COMPLEX_EXPR <D.*, x>" "gimple" } } */
! /* { dg-final { scan-tree-dump "D.* = -x;\n.*COMPLEX_EXPR <y, D.*>" "gimple" } } */
--- 10,14 ----
  /* { dg-final { scan-tree-dump "COMPLEX_EXPR <x, 1.0e\\+0>" "gimple" } } */
  /* { dg-final { scan-tree-dump "COMPLEX_EXPR <1.0e\\+0, x>" "gimple" } } */
  /* { dg-final { scan-tree-dump "COMPLEX_EXPR <x, y>" "gimple" } } */
! /* { dg-final { scan-tree-dump " = -y;\n.*COMPLEX_EXPR <\[^,\]*, x>" "gimple" } } */
! /* { dg-final { scan-tree-dump " = -x;\n.*COMPLEX_EXPR <y, " "gimple" } } */
Index: gcc/testsuite/gcc.dg/pr63743.c
===================================================================
*** gcc/testsuite/gcc.dg/pr63743.c.orig	2016-05-02 12:21:53.806806857 +0200
--- gcc/testsuite/gcc.dg/pr63743.c	2016-05-02 12:22:11.931013214 +0200
***************
*** 4,10 ****
  double
  libcall_dep (double x, double y)
  {
!   return x * (x + y);
  }
  
  /* { dg-final { scan-rtl-dump-times "Swap operands" 1 "expand" } } */
--- 4,11 ----
  double
  libcall_dep (double x, double y)
  {
!   double tem = x + y;
!   return x * tem;
  }
  
  /* { dg-final { scan-rtl-dump-times "Swap operands" 1 "expand" } } */
Index: gcc/tree-cfg.c
===================================================================
*** gcc/tree-cfg.c.orig	2016-05-02 12:21:53.810806903 +0200
--- gcc/tree-cfg.c	2016-05-02 12:22:11.935013260 +0200
*************** remove_bb (basic_block bb)
*** 2135,2147 ****
  	    }
  	  else
  	    {
! 	      /* Release SSA definitions if we are in SSA.  Note that we
! 		 may be called when not in SSA.  For example,
! 		 final_cleanup calls this function via
! 		 cleanup_tree_cfg.  */
! 	      if (gimple_in_ssa_p (cfun))
! 		release_defs (stmt);
! 
  	      gsi_remove (&i, true);
  	    }
  
--- 2135,2142 ----
  	    }
  	  else
  	    {
! 	      /* Release SSA definitions.  */
! 	      release_defs (stmt);
  	      gsi_remove (&i, true);
  	    }
  
Index: gcc/tree-ssa-ccp.c
===================================================================
*** gcc/tree-ssa-ccp.c.orig	2016-05-02 12:21:53.810806903 +0200
--- gcc/tree-ssa-ccp.c	2016-05-02 12:22:11.935013260 +0200
*************** get_default_value (tree var)
*** 271,276 ****
--- 271,277 ----
  	 can assume initially that it is UNDEFINED, otherwise we must
  	 consider it VARYING.  */
        if (!virtual_operand_p (var)
+ 	  && SSA_NAME_VAR (var)
  	  && TREE_CODE (SSA_NAME_VAR (var)) == VAR_DECL)
  	val.lattice_val = UNDEFINED;
        else
Index: gcc/cgraphunit.c
===================================================================
*** gcc/cgraphunit.c.orig	2016-05-02 12:21:53.810806903 +0200
--- gcc/cgraphunit.c	2016-05-02 12:22:11.935013260 +0200
*************** init_lowered_empty_function (tree decl,
*** 1428,1437 ****
    allocate_struct_function (decl, false);
    gimple_register_cfg_hooks ();
    init_empty_tree_cfg ();
  
    if (in_ssa)
      {
-       init_tree_ssa (cfun);
        init_ssa_operands (cfun);
        cfun->gimple_df->in_ssa_p = true;
        cfun->curr_properties |= PROP_ssa;
--- 1428,1437 ----
    allocate_struct_function (decl, false);
    gimple_register_cfg_hooks ();
    init_empty_tree_cfg ();
+   init_tree_ssa (cfun);
  
    if (in_ssa)
      {
        init_ssa_operands (cfun);
        cfun->gimple_df->in_ssa_p = true;
        cfun->curr_properties |= PROP_ssa;
Index: gcc/c-family/cilk.c
===================================================================
*** gcc/c-family/cilk.c.orig	2016-05-02 12:21:53.810806903 +0200
--- gcc/c-family/cilk.c	2016-05-02 12:22:11.935013260 +0200
*************** cilk_gimplify_call_params_in_spawned_fn
*** 795,803 ****
      fix_parm_expr = &TREE_OPERAND (*expr_p, 1);
  
    if (TREE_CODE (*fix_parm_expr) == CALL_EXPR)
!     for (ii = 0; ii < call_expr_nargs (*fix_parm_expr); ii++)
!       gimplify_arg (&CALL_EXPR_ARG (*fix_parm_expr, ii), pre_p,
! 		    EXPR_LOCATION (*fix_parm_expr));
  }
  
  
--- 795,807 ----
      fix_parm_expr = &TREE_OPERAND (*expr_p, 1);
  
    if (TREE_CODE (*fix_parm_expr) == CALL_EXPR)
!     {
!       /* Cilk outlining assumes GENERIC bodies, avoid leaking SSA names
!          via parameters.  */
!       for (ii = 0; ii < call_expr_nargs (*fix_parm_expr); ii++)
! 	gimplify_arg (&CALL_EXPR_ARG (*fix_parm_expr, ii), pre_p,
! 		      EXPR_LOCATION (*fix_parm_expr), false);
!     }
  }
  
  
Index: gcc/testsuite/gcc.dg/fold-perm.c
===================================================================
*** gcc/testsuite/gcc.dg/fold-perm.c.orig	2016-05-02 12:21:53.810806903 +0200
--- gcc/testsuite/gcc.dg/fold-perm.c	2016-05-02 12:22:11.935013260 +0200
***************
*** 1,5 ****
  /* { dg-do compile } */
! /* { dg-options "-O -fdump-tree-ccp1" } */
  
  typedef int veci __attribute__ ((vector_size (4 * sizeof (int))));
  
--- 1,5 ----
  /* { dg-do compile } */
! /* { dg-options "-O -fdump-tree-fre1" } */
  
  typedef int veci __attribute__ ((vector_size (4 * sizeof (int))));
  
*************** void fun (veci *f, veci *g, veci *h, vec
*** 14,19 ****
    *f = __builtin_shuffle (*f, *g, n);
  }
  
! /* { dg-final { scan-tree-dump "VEC_PERM_EXPR.*{ 3, 3, 0, 2 }" "ccp1" } } */
! /* { dg-final { scan-tree-dump "VEC_PERM_EXPR.*{ 1, 1, 3, 2 }" "ccp1" } } */
! /* { dg-final { scan-tree-dump-times "VEC_PERM_EXPR" 2 "ccp1" } } */
--- 14,19 ----
    *f = __builtin_shuffle (*f, *g, n);
  }
  
! /* { dg-final { scan-tree-dump "VEC_PERM_EXPR.*{ 3, 3, 0, 2 }" "fre1" } } */
! /* { dg-final { scan-tree-dump "VEC_PERM_EXPR.*{ 1, 1, 3, 2 }" "fre1" } } */
! /* { dg-final { scan-tree-dump-times "VEC_PERM_EXPR" 2 "fre1" } } */
Index: gcc/testsuite/gcc.dg/tree-ssa/forwprop-28.c
===================================================================
*** gcc/testsuite/gcc.dg/tree-ssa/forwprop-28.c.orig	2016-05-02 12:21:53.810806903 +0200
--- gcc/testsuite/gcc.dg/tree-ssa/forwprop-28.c	2016-05-02 12:22:11.935013260 +0200
*************** test_8 (int code)
*** 84,88 ****
     the negated code == 22 compare to code != 22 first.  It turns out if
     we do that we even generate better code on x86 at least.  */
  
! /* { dg-final { scan-tree-dump-times "simplified to if \\\(\[^ ]* <" 4 "forwprop1"} } */
  
--- 84,88 ----
     the negated code == 22 compare to code != 22 first.  It turns out if
     we do that we even generate better code on x86 at least.  */
  
! /* { dg-final { scan-tree-dump-times "simplified to if \\\(\[^ ]* \[<>\]" 4 "forwprop1"} } */
  
Index: gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-43.c
===================================================================
*** gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-43.c.orig	2016-05-02 12:21:53.810806903 +0200
--- gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-43.c	2016-05-02 12:22:11.935013260 +0200
***************
*** 1,6 ****
  /* PR tree-optimization/64193 */
  /* { dg-do compile } */
! /* { dg-options "-O -fdump-tree-fre1-details" } */
  
  double T,T2,E1[5];
  int J;
--- 1,6 ----
  /* PR tree-optimization/64193 */
  /* { dg-do compile } */
! /* { dg-options "-O -fdump-tree-fre1" } */
  
  double T,T2,E1[5];
  int J;
*************** L10:
*** 24,28 ****
  /* We should remove 15 dead loads and some related stmts, fully propagating
     their replacements with exactly 4 loads and 4 stores from/to E remaining.  */
  
! /* { dg-final { scan-tree-dump-times "Removing dead stmt" 19 "fre1" } } */
! /* { dg-final { scan-tree-dump-not "Not changing value number" "fre1" } } */
--- 24,27 ----
  /* We should remove 15 dead loads and some related stmts, fully propagating
     their replacements with exactly 4 loads and 4 stores from/to E remaining.  */
  
! /* { dg-final { scan-tree-dump-times "MEM" 8 "fre1" } } */
Index: gcc/tree-ssanames.c
===================================================================
*** gcc/tree-ssanames.c.orig	2016-04-28 15:24:39.691848030 +0200
--- gcc/tree-ssanames.c	2016-05-02 12:22:11.935013260 +0200
*************** release_defs (gimple *stmt)
*** 742,751 ****
    tree def;
    ssa_op_iter iter;
  
-   /* Make sure that we are in SSA.  Otherwise, operand cache may point
-      to garbage.  */
-   gcc_assert (gimple_in_ssa_p (cfun));
- 
    FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_ALL_DEFS)
      if (TREE_CODE (def) == SSA_NAME)
        release_ssa_name (def);
--- 742,747 ----
Index: gcc/testsuite/gcc.dg/tm/pr51696.c
===================================================================
*** gcc/testsuite/gcc.dg/tm/pr51696.c.orig	2012-01-05 09:54:15.000000000 +0100
--- gcc/testsuite/gcc.dg/tm/pr51696.c	2016-05-02 12:46:36.535700245 +0200
*************** static void (*compare)();
*** 10,14 ****
  __attribute__((transaction_safe))
  static void func () {
    listPtr->compare(); /* { dg-error "unsafe indirect function call" } */
!   compare(); /* { dg-error "unsafe function call" } */
  }
--- 10,14 ----
  __attribute__((transaction_safe))
  static void func () {
    listPtr->compare(); /* { dg-error "unsafe indirect function call" } */
!   compare(); /* { dg-error "unsafe indirect function call" } */
  }
Index: gcc/trans-mem.c
===================================================================
*** gcc/trans-mem.c.orig	2016-02-11 09:20:42.949807781 +0100
--- gcc/trans-mem.c	2016-05-02 12:46:22.107535747 +0200
*************** diagnose_tm_1 (gimple_stmt_iterator *gsi
*** 726,732 ****
  				"atomic transaction", fn);
  		    else
  		      {
! 			if (!DECL_P (fn) || DECL_NAME (fn))
  			  error_at (gimple_location (stmt),
  				    "unsafe function call %qE within "
  				    "atomic transaction", fn);
--- 726,733 ----
  				"atomic transaction", fn);
  		    else
  		      {
! 			if ((!DECL_P (fn) || DECL_NAME (fn))
! 			    && TREE_CODE (fn) != SSA_NAME)
  			  error_at (gimple_location (stmt),
  				    "unsafe function call %qE within "
  				    "atomic transaction", fn);
*************** diagnose_tm_1 (gimple_stmt_iterator *gsi
*** 744,750 ****
  				"%<transaction_safe%> function", fn);
  		    else
  		      {
! 			if (!DECL_P (fn) || DECL_NAME (fn))
  			  error_at (gimple_location (stmt),
  				    "unsafe function call %qE within "
  				    "%<transaction_safe%> function", fn);
--- 745,752 ----
  				"%<transaction_safe%> function", fn);
  		    else
  		      {
! 			if ((!DECL_P (fn) || DECL_NAME (fn))
! 			    && TREE_CODE (fn) != SSA_NAME)
  			  error_at (gimple_location (stmt),
  				    "unsafe function call %qE within "
  				    "%<transaction_safe%> function", fn);
Index: gcc/testsuite/c-c++-common/tm/safe-1.c
===================================================================
*** gcc/testsuite/c-c++-common/tm/safe-1.c.orig	2011-11-08 12:17:10.000000000 +0100
--- gcc/testsuite/c-c++-common/tm/safe-1.c	2016-05-03 09:13:15.922846597 +0200
*************** foo(void)
*** 35,43 ****
    /* tu(); */
  
    (*ps)();
!   (*pc)();		/* { dg-error "unsafe function call" } */
!   (*pi)();		/* { dg-error "unsafe function call" } */
!   (*pu)();		/* { dg-error "unsafe function call" } */
  
    asm("");		/* { dg-error "asm not allowed" } */
    asm("" : "=g"(i));	/* { dg-error "asm not allowed" } */
--- 35,43 ----
    /* tu(); */
  
    (*ps)();
!   (*pc)();		/* { dg-error "unsafe indirect function call" } */
!   (*pi)();		/* { dg-error "unsafe indirect function call" } */
!   (*pu)();		/* { dg-error "unsafe indirect function call" } */
  
    asm("");		/* { dg-error "asm not allowed" } */
    asm("" : "=g"(i));	/* { dg-error "asm not allowed" } */
*************** bar(void)
*** 57,66 ****
    tm();
  
    (*ps)();
!   (*pc)();		/* { dg-error "unsafe function call" } */
!   (*pi)();		/* { dg-error "unsafe function call" } */
    (*pm)();
!   (*pu)();		/* { dg-error "unsafe function call" } */
  
    asm("");		/* { dg-error "asm not allowed" } */
    asm("" : "=g"(i));	/* { dg-error "asm not allowed" } */
--- 57,66 ----
    tm();
  
    (*ps)();
!   (*pc)();		/* { dg-error "unsafe indirect function call" } */
!   (*pi)();		/* { dg-error "unsafe indirect function call" } */
    (*pm)();
!   (*pu)();		/* { dg-error "unsafe indirect function call" } */
  
    asm("");		/* { dg-error "asm not allowed" } */
    asm("" : "=g"(i));	/* { dg-error "asm not allowed" } */
Index: gcc/testsuite/gcc.dg/tree-prof/val-prof-3.c
===================================================================
*** gcc/testsuite/gcc.dg/tree-prof/val-prof-3.c.orig	2015-06-09 15:45:27.624348709 +0200
--- gcc/testsuite/gcc.dg/tree-prof/val-prof-3.c	2016-05-03 10:00:53.795043278 +0200
*************** main ()
*** 27,31 ****
  /* { dg-final-use { scan-ipa-dump "Mod subtract transformation on insn" "profile" } } */
  /* This is part of code checking that n is greater than the divisor so we are sure that it
     didn't get optimized out.  */
! /* { dg-final-use { scan-tree-dump "if \\(n_\[0-9\]* \\>" "optimized"} } */
  /* { dg-final-use { scan-tree-dump-not "Invalid sum" "optimized"} } */
--- 27,31 ----
  /* { dg-final-use { scan-ipa-dump "Mod subtract transformation on insn" "profile" } } */
  /* This is part of code checking that n is greater than the divisor so we are sure that it
     didn't get optimized out.  */
! /* { dg-final-use { scan-tree-dump "if \\(_\[0-9\]* \\< n_\[0-9\]*" "optimized"} } */
  /* { dg-final-use { scan-tree-dump-not "Invalid sum" "optimized"} } */


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