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][4.5] Move gimplifier predicates


On Fri, 5 Dec 2008, Richard Guenther wrote:

> On Fri, 5 Dec 2008, Diego Novillo wrote:
> 
> > On Thu, Dec 4, 2008 at 12:10, Richard Guenther <rguenther@suse.de> wrote:
> > >
> > > This moves gimplifier predicates to where they belong and makes them
> > > private.  Apart from the uses in walk_gimple_op for which I have no
> > > clue what this monster-function tries to do - Diego, do you remember?
> > 
> > Sure.  It walks the trees in the tuple operand slots.  This is still
> > different than the operand scanner, as it is a pure tree walk.  It's
> > seldom used, but still needed.
> > 
> > > Index: trunk/gcc/gimple.c
> > > ===================================================================
> > > *** trunk.orig/gcc/gimple.c     2008-12-04 11:18:08.000000000 +0100
> > > --- trunk/gcc/gimple.c  2008-12-04 15:00:49.000000000 +0100
> > > *************** walk_gimple_op (gimple stmt, walk_tree_f
> > > *** 1373,1378 ****
> > > --- 1373,1381 ----
> > >    struct pointer_set_t *pset = (wi) ? wi->pset : NULL;
> > >    unsigned i;
> > >    tree ret = NULL_TREE;
> > > +   /* ???  We shouldn't be using these here.  */
> > > +   extern bool is_gimple_formal_tmp_var (tree);
> > > +   extern bool is_gimple_mem_rhs (tree);
> > 
> > Why not?  gimple.c and gimplify.c are joined at the hip after all.
> > It's perfectly fine for walk_gimple_op to want to use these
> > predicates.  The only way I see to get rid of them would be if the
> > functionality they provide is not needed (i.e., wi->val_only).
> >
> > In fact, is_gimple_formal_tmp_var and is_gimple_mem_rhs make more
> > sense to be provided by gimple.c instead of gimplify.c.
> 
> The problem is that the _formal_tmp stuff does only work in the context
> of gimplification.  Which means that these are not predicates that
> you can reliably use from elsewhere which means that they better should
> not be exported.  As is_gimple_mem_rhs calls a _formal_tmp variant the
> same is true for it.
> 
> See the strange places we set DECL_GIMPLE_FORMAL_TEMP_P in gimplify.c
> and how we clean that flag again in pop_gimplify_context (not
> reliably though dependent on what set that flag).
> 
> This patch developed in the course of trying to understand the
> correctness and optimization parts of DECL_GIMPLE_FORMAL_TEMP_P and
> in trying to make DECL_GIMPLE_REG_P handling more general and not
> dependent on is_gimple_reg_type.
> 
> I will just put this patch on hold until I have more convincing
> evidence in this area, but I do not agree with your simple
> rationale ;)

So the following removes DECL_GIMPLE_FORMAL_TEMP_P and instead fixes
the long-standing post-modify fixme and moves the EH related split of
the assignment and call into EH lowering which is IMHO where it belongs.
It fixes some more stuff noticed in intermediate fallouts as well.
It does not remove the temporary decl sharing with poor mans CSE.

Bootstrapped and tested on x86_64-unknown-linux-gnu, ok for 4.5?

As I want to extend the use of DECL_GIMPLE_REG_P this cleanup makes
it easier to see what is going on.

Thanks,
Richard.

2008-12-04  Richard Guenther  <rguenther@suse.de>

	* tree.h (DECL_GIMPLE_FORMAL_TEMP_P): Remove.
	(struct tree_decl_with_vis): Remove gimple_formal_temp member.
	* tree-eh.c (lower_eh_constructs_2): Move LHS assignment to
	a separate statement.
	* gimplify.c (pop_gimplify_context): Remove formal temp handling.
	(lookup_tmp_var): Likewise.
	(is_gimple_formal_tmp_or_call_rhs): Remove.
	(is_gimple_reg_or_call_rhs): Rename to ...
	(is_gimple_reg_rhs_or_call): ... this.
	(is_gimple_mem_or_call_rhs): Rename to ...
	(is_gimple_mem_rhs_or_call): ... this.
	(internal_get_tmp_var): Use is_gimple_reg_rhs_or_call.  Set
	DECL_GIMPLE_REG_P only if is_formal is true.
	(gimplify_compound_lval): Use is_gimple_reg.  Remove workaround
	for non-proper post-modify expression gimplification.
	(gimplify_self_mod_expr): For post-modify expressions gimplify
	the lvalue to a minimal lvalue.
	(rhs_predicate_for): Remove formal temp case.
	(gimplify_modify_expr_rhs): Likewise.
	(gimplify_addr_expr): Use is_gimple_reg.
	(gimplify_expr): Remove formal temp cases.
	(gimple_regimplify_operands): Likewise.
	* tree-ssa-pre.c (get_or_alloc_expr_for): Treat EXC_PTR_EXPR
	and FILTER_EXPR like constants.
	* gimple.c (walk_gimple_op): Fix val_only initialization, use
	is_gimple_reg.
	(is_gimple_formal_tmp_rhs): Remove.
	(is_gimple_reg_rhs): Remove special casing.
	(is_gimple_mem_rhs): Fix.
	(is_gimple_reg): Move DECL_GIMPLE_REG_P handling earlier.
	(is_gimple_formal_tmp_var): Remove.
	(is_gimple_formal_tmp_reg): Likewise.
	(is_gimple_min_lval): Allow invariant component ref parts.
	* gimple.h (is_gimple_formal_tmp_rhs, is_gimple_formal_tmp_var,
	is_gimple_formal_tmp_reg): Remove declarations.
	* tree-cfg.c (verify_expr): Verify that variables with address
	taken do not have DECL_GIMPLE_REG_P set.
	* tree-mudflap.c (mf_build_check_statement_for): Use
	force_gimple_operand instead of gimplify_expr.

	java/
	* java-gimplify.c (java_gimplify_expr): Do not manually gimplify
	the first operand of binary and comaprison expressions.

Index: gcc/java/java-gimplify.c
===================================================================
*** gcc/java/java-gimplify.c	(revision 142487)
--- gcc/java/java-gimplify.c	(working copy)
*************** java_gimplify_expr (tree *expr_p, gimple
*** 95,120 ****
        gcc_unreachable ();
  
      default:
-       /* Java insists on strict left-to-right evaluation of expressions.
- 	 A problem may arise if a variable used in the LHS of a binary
- 	 operation is altered by an assignment to that value in the RHS
- 	 before we've performed the operation.  So, we always copy every
- 	 LHS to a temporary variable.  
- 
- 	 FIXME: Are there any other cases where we should do this?
- 	 Parameter lists, maybe?  Or perhaps that's unnecessary because
- 	 the front end already generates SAVE_EXPRs.  */
- 
-       if (TREE_CODE_CLASS (code) == tcc_binary
- 	  || TREE_CODE_CLASS (code) == tcc_comparison)
- 	{
- 	  enum gimplify_status stat 
- 	    = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
- 			     is_gimple_formal_tmp_var, fb_rvalue);
- 	  if (stat == GS_ERROR)
- 	    return stat;
- 	}
- 
        return GS_UNHANDLED;
      }
  
--- 95,100 ----
Index: gcc/tree.h
===================================================================
*** gcc/tree.h	(revision 142487)
--- gcc/tree.h	(working copy)
*************** struct tree_parm_decl GTY(())
*** 2918,2928 ****
    /* Used to indicate that this DECL has weak linkage.  */
  #define DECL_WEAK(NODE) (DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.weak_flag)
  
- /* Internal to the gimplifier.  Indicates that the value is a formal
-    temporary controlled by the gimplifier.  */
- #define DECL_GIMPLE_FORMAL_TEMP_P(DECL) \
-   DECL_WITH_VIS_CHECK (DECL)->decl_with_vis.gimple_formal_temp
- 
  /* Used to indicate that the DECL is a dllimport.  */
  #define DECL_DLLIMPORT_P(NODE) (DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.dllimport_flag)
  
--- 2918,2923 ----
*************** struct tree_decl_with_vis GTY(())
*** 3034,3040 ****
   unsigned thread_local:1;
   unsigned common_flag:1;
   unsigned in_text_section : 1;
-  unsigned gimple_formal_temp : 1;
   unsigned dllimport_flag : 1;
   unsigned based_on_restrict_p : 1;
   /* Used by C++.  Might become a generic decl flag.  */
--- 3029,3034 ----
*************** struct tree_decl_with_vis GTY(())
*** 3052,3058 ****
  
   /* Belongs to VAR_DECL exclusively.  */
   ENUM_BITFIELD(tls_model) tls_model : 3;
!  /* 12 unused bits. */
  };
  
  /* In a VAR_DECL that's static,
--- 3046,3052 ----
  
   /* Belongs to VAR_DECL exclusively.  */
   ENUM_BITFIELD(tls_model) tls_model : 3;
!  /* 13 unused bits. */
  };
  
  /* In a VAR_DECL that's static,
Index: gcc/tree-eh.c
===================================================================
*** gcc/tree-eh.c	(revision 142487)
--- gcc/tree-eh.c	(working copy)
*************** lower_eh_constructs_2 (struct leh_state 
*** 1823,1828 ****
--- 1823,1847 ----
      {
      case GIMPLE_CALL:
      case GIMPLE_ASSIGN:
+       /* If the stmt can throw use a new temporary for the assignment
+          to a LHS.  This makes sure the old value of the LHS is
+ 	 available on the EH edge.  */
+       if (stmt_could_throw_p (stmt)
+ 	  && gimple_has_lhs (stmt)
+ 	  && !tree_could_throw_p (gimple_get_lhs (stmt))
+ 	  && is_gimple_reg_type (TREE_TYPE (gimple_get_lhs (stmt))))
+ 	{
+ 	  tree lhs = gimple_get_lhs (stmt);
+ 	  tree tmp = create_tmp_var (TREE_TYPE (lhs), NULL);
+ 	  gimple s = gimple_build_assign (lhs, tmp);
+ 	  gimple_set_location (s, gimple_location (stmt));
+ 	  gimple_set_block (s, gimple_block (stmt));
+ 	  gimple_set_lhs (stmt, tmp);
+ 	  if (TREE_CODE (TREE_TYPE (tmp)) == COMPLEX_TYPE
+ 	      || TREE_CODE (TREE_TYPE (tmp)) == VECTOR_TYPE)
+ 	    DECL_GIMPLE_REG_P (tmp) = 1;
+ 	  gsi_insert_after (gsi, s, GSI_SAME_STMT);
+ 	}
        /* Look for things that can throw exceptions, and record them.  */
        if (state->cur_region && stmt_could_throw_p (stmt))
  	{
Index: gcc/gimplify.c
===================================================================
*** gcc/gimplify.c	(revision 142487)
--- gcc/gimplify.c	(working copy)
*************** void
*** 212,227 ****
  pop_gimplify_context (gimple body)
  {
    struct gimplify_ctx *c = gimplify_ctxp;
-   tree t;
  
    gcc_assert (c && (c->bind_expr_stack == NULL
  		    || VEC_empty (gimple, c->bind_expr_stack)));
    VEC_free (gimple, heap, c->bind_expr_stack);
    gimplify_ctxp = c->prev_context;
  
-   for (t = c->temps; t ; t = TREE_CHAIN (t))
-     DECL_GIMPLE_FORMAL_TEMP_P (t) = 0;
- 
    if (body)
      declare_vars (c->temps, body, false);
    else
--- 212,223 ----
*************** lookup_tmp_var (tree val, bool is_formal
*** 607,615 ****
  	}
      }
  
-   if (is_formal)
-     DECL_GIMPLE_FORMAL_TEMP_P (ret) = 1;
- 
    return ret;
  }
  
--- 603,608 ----
*************** lookup_tmp_var (tree val, bool is_formal
*** 620,651 ****
     gimplify_modify_expr.  */
  
  static bool
! is_gimple_formal_tmp_or_call_rhs (tree t)
  {
!   return TREE_CODE (t) == CALL_EXPR || is_gimple_formal_tmp_rhs (t);
! }
! 
! /* Returns true iff T is a valid RHS for an assignment to a renamed
!    user -- or front-end generated artificial -- variable.  */
! 
! static bool
! is_gimple_reg_or_call_rhs (tree t)
! {
!   /* If the RHS of the MODIFY_EXPR may throw or make a nonlocal goto
!      and the LHS is a user variable, then we need to introduce a formal
!      temporary.  This way the optimizers can determine that the user
!      variable is only modified if evaluation of the RHS does not throw.
! 
!      Don't force a temp of a non-renamable type; the copy could be
!      arbitrarily expensive.  Instead we will generate a VDEF for
!      the assignment.  */
! 
!   if (is_gimple_reg_type (TREE_TYPE (t))
!       && ((TREE_CODE (t) == CALL_EXPR && TREE_SIDE_EFFECTS (t))
! 	  || tree_could_throw_p (t)))
!     return false;
! 
!   return is_gimple_formal_tmp_or_call_rhs (t);
  }
  
  /* Return true if T is a valid memory RHS or a CALL_EXPR.  Note that
--- 613,622 ----
     gimplify_modify_expr.  */
  
  static bool
! is_gimple_reg_rhs_or_call (tree t)
  {
!   return (get_gimple_rhs_class (TREE_CODE (t)) != GIMPLE_INVALID_RHS
! 	  || TREE_CODE (t) == CALL_EXPR);
  }
  
  /* Return true if T is a valid memory RHS or a CALL_EXPR.  Note that
*************** is_gimple_reg_or_call_rhs (tree t)
*** 653,680 ****
     rationale for this in gimplify_modify_expr.  */
  
  static bool
! is_gimple_mem_or_call_rhs (tree t)
  {
    /* If we're dealing with a renamable type, either source or dest must be
       a renamed variable.  */
    if (is_gimple_reg_type (TREE_TYPE (t)))
      return is_gimple_val (t);
    else
!     return is_gimple_formal_tmp_or_call_rhs (t);
  }
  
! 
! /* Returns a formal temporary variable initialized with VAL.  PRE_P is as
!    in gimplify_expr.  Only use this function if:
! 
!    1) The value of the unfactored expression represented by VAL will not
!       change between the initialization and use of the temporary, and
!    2) The temporary will not be otherwise modified.
! 
!    For instance, #1 means that this is inappropriate for SAVE_EXPR temps,
!    and #2 means it is inappropriate for && temps.
! 
!    For other cases, use get_initialized_tmp_var instead.  */
  
  static tree
  internal_get_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p,
--- 624,641 ----
     rationale for this in gimplify_modify_expr.  */
  
  static bool
! is_gimple_mem_rhs_or_call (tree t)
  {
    /* If we're dealing with a renamable type, either source or dest must be
       a renamed variable.  */
    if (is_gimple_reg_type (TREE_TYPE (t)))
      return is_gimple_val (t);
    else
!     return (is_gimple_val (t) || is_gimple_lvalue (t)
! 	    || TREE_CODE (t) == CALL_EXPR);
  }
  
! /* Helper for get_formal_tmp_var and get_initialized_tmp_var.  */
  
  static tree
  internal_get_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p,
*************** internal_get_tmp_var (tree val, gimple_s
*** 684,690 ****
  
    /* Notice that we explicitly allow VAL to be a CALL_EXPR so that we
       can create an INIT_EXPR and convert it into a GIMPLE_CALL below.  */
!   gimplify_expr (&val, pre_p, post_p, is_gimple_formal_tmp_or_call_rhs,
  		 fb_rvalue);
  
    t = lookup_tmp_var (val, is_formal);
--- 645,651 ----
  
    /* Notice that we explicitly allow VAL to be a CALL_EXPR so that we
       can create an INIT_EXPR and convert it into a GIMPLE_CALL below.  */
!   gimplify_expr (&val, pre_p, post_p, is_gimple_reg_rhs_or_call,
  		 fb_rvalue);
  
    t = lookup_tmp_var (val, is_formal);
*************** internal_get_tmp_var (tree val, gimple_s
*** 705,715 ****
  	      SET_DECL_RESTRICT_BASE (t, u);
  	    }
  	}
-     }
  
!   if (TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE
!       || TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE)
!     DECL_GIMPLE_REG_P (t) = 1;
  
    mod = build2 (INIT_EXPR, TREE_TYPE (t), t, unshare_expr (val));
  
--- 666,676 ----
  	      SET_DECL_RESTRICT_BASE (t, u);
  	    }
  	}
  
!       if (TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE
! 	  || TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE)
! 	DECL_GIMPLE_REG_P (t) = 1;
!     }
  
    mod = build2 (INIT_EXPR, TREE_TYPE (t), t, unshare_expr (val));
  
*************** internal_get_tmp_var (tree val, gimple_s
*** 733,741 ****
    return t;
  }
  
! /* Returns a formal temporary variable initialized with VAL.  PRE_P
!    points to a sequence where side-effects needed to compute VAL should be
!    stored.  */
  
  tree
  get_formal_tmp_var (tree val, gimple_seq *pre_p)
--- 694,710 ----
    return t;
  }
  
! /* Returns a formal temporary variable initialized with VAL.  PRE_P is as
!    in gimplify_expr.  Only use this function if:
! 
!    1) The value of the unfactored expression represented by VAL will not
!       change between the initialization and use of the temporary, and
!    2) The temporary will not be otherwise modified.
! 
!    For instance, #1 means that this is inappropriate for SAVE_EXPR temps,
!    and #2 means it is inappropriate for && temps.
! 
!    For other cases, use get_initialized_tmp_var instead.  */
  
  tree
  get_formal_tmp_var (tree val, gimple_seq *pre_p)
*************** gimplify_compound_lval (tree *expr_p, gi
*** 2001,2007 ****
  		{
  		  TREE_OPERAND (t, 2) = low;
  		  tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
! 					post_p, is_gimple_formal_tmp_reg,
  					fb_rvalue);
  		  ret = MIN (ret, tret);
  		}
--- 1970,1976 ----
  		{
  		  TREE_OPERAND (t, 2) = low;
  		  tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
! 					post_p, is_gimple_reg,
  					fb_rvalue);
  		  ret = MIN (ret, tret);
  		}
*************** gimplify_compound_lval (tree *expr_p, gi
*** 2021,2027 ****
  		{
  		  TREE_OPERAND (t, 3) = elmt_size;
  		  tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p,
! 					post_p, is_gimple_formal_tmp_reg,
  					fb_rvalue);
  		  ret = MIN (ret, tret);
  		}
--- 1990,1996 ----
  		{
  		  TREE_OPERAND (t, 3) = elmt_size;
  		  tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p,
! 					post_p, is_gimple_reg,
  					fb_rvalue);
  		  ret = MIN (ret, tret);
  		}
*************** gimplify_compound_lval (tree *expr_p, gi
*** 2044,2050 ****
  		{
  		  TREE_OPERAND (t, 2) = offset;
  		  tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
! 					post_p, is_gimple_formal_tmp_reg,
  					fb_rvalue);
  		  ret = MIN (ret, tret);
  		}
--- 2013,2019 ----
  		{
  		  TREE_OPERAND (t, 2) = offset;
  		  tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p,
! 					post_p, is_gimple_reg,
  					fb_rvalue);
  		  ret = MIN (ret, tret);
  		}
*************** gimplify_compound_lval (tree *expr_p, gi
*** 2067,2085 ****
  
        if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
  	{
! 	  /* Gimplify the dimension.
! 	     Temporary fix for gcc.c-torture/execute/20040313-1.c.
! 	     Gimplify non-constant array indices into a temporary
! 	     variable.
! 	     FIXME - The real fix is to gimplify post-modify
! 	     expressions into a minimal gimple lvalue.  However, that
! 	     exposes bugs in alias analysis.  The alias analyzer does
! 	     not handle &PTR->FIELD very well.  Will fix after the
! 	     branch is merged into mainline (dnovillo 2004-05-03).  */
  	  if (!is_gimple_min_invariant (TREE_OPERAND (t, 1)))
  	    {
  	      tret = gimplify_expr (&TREE_OPERAND (t, 1), pre_p, post_p,
! 				    is_gimple_formal_tmp_reg, fb_rvalue);
  	      ret = MIN (ret, tret);
  	    }
  	}
--- 2036,2046 ----
  
        if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
  	{
! 	  /* Gimplify the dimension.  */
  	  if (!is_gimple_min_invariant (TREE_OPERAND (t, 1)))
  	    {
  	      tret = gimplify_expr (&TREE_OPERAND (t, 1), pre_p, post_p,
! 				    is_gimple_val, fb_rvalue);
  	      ret = MIN (ret, tret);
  	    }
  	}
*************** gimplify_self_mod_expr (tree *expr_p, gi
*** 2171,2179 ****
    rhs = TREE_OPERAND (*expr_p, 1);
  
    /* For postfix operator, we evaluate the LHS to an rvalue and then use
!      that as the result value and in the postqueue operation.  */
    if (postfix)
      {
        ret = gimplify_expr (&lhs, pre_p, post_p, is_gimple_val, fb_rvalue);
        if (ret == GS_ERROR)
  	return ret;
--- 2132,2149 ----
    rhs = TREE_OPERAND (*expr_p, 1);
  
    /* For postfix operator, we evaluate the LHS to an rvalue and then use
!      that as the result value and in the postqueue operation.  We also
!      make sure to make lvalue a minimal lval, see
!      gcc.c-torture/execute/20040313-1.c for an example where this matters.  */
    if (postfix)
      {
+       if (!is_gimple_min_lval (lvalue))
+ 	{
+ 	  mark_addressable (lvalue);
+ 	  lvalue = build_fold_addr_expr (lvalue);
+ 	  gimplify_expr (&lvalue, pre_p, post_p, is_gimple_val, fb_rvalue);
+ 	  lvalue = build_fold_indirect_ref (lvalue);
+ 	}
        ret = gimplify_expr (&lhs, pre_p, post_p, is_gimple_val, fb_rvalue);
        if (ret == GS_ERROR)
  	return ret;
*************** gimplify_init_ctor_eval (tree object, VE
*** 3445,3456 ****
  gimple_predicate
  rhs_predicate_for (tree lhs)
  {
!   if (is_gimple_formal_tmp_var (lhs))
!     return is_gimple_formal_tmp_or_call_rhs;
!   else if (is_gimple_reg (lhs))
!     return is_gimple_reg_or_call_rhs;
    else
!     return is_gimple_mem_or_call_rhs;
  }
  
  
--- 3415,3424 ----
  gimple_predicate
  rhs_predicate_for (tree lhs)
  {
!   if (is_gimple_reg (lhs))
!     return is_gimple_reg_rhs_or_call;
    else
!     return is_gimple_mem_rhs_or_call;
  }
  
  
*************** gimplify_modify_expr_rhs (tree *expr_p, 
*** 4031,4041 ****
  		     || (DECL_P (*to_p) && DECL_REGISTER (*to_p)))
  	      /* Don't force regs into memory.  */
  	      use_target = false;
- 	    else if (TREE_CODE (*to_p) == VAR_DECL
- 		     && DECL_GIMPLE_FORMAL_TEMP_P (*to_p))
- 	      /* Don't use the original target if it's a formal temp; we
- 		 don't want to take their addresses.  */
- 	      use_target = false;
  	    else if (TREE_CODE (*expr_p) == INIT_EXPR)
  	      /* It's OK to use the target directly if it's being
  		 initialized. */
--- 3999,4004 ----
*************** gimplify_addr_expr (tree *expr_p, gimple
*** 4535,4541 ****
  	 This mostly happens if the frontend passed us something that
  	 it could not mark addressable yet, like a fortran
  	 pass-by-reference parameter (int) floatvar.  */
!       if (is_gimple_formal_tmp_var (TREE_OPERAND (expr, 0)))
  	TREE_OPERAND (expr, 0)
  	  = get_initialized_tmp_var (TREE_OPERAND (expr, 0), pre_p, post_p);
  
--- 4498,4504 ----
  	 This mostly happens if the frontend passed us something that
  	 it could not mark addressable yet, like a fortran
  	 pass-by-reference parameter (int) floatvar.  */
!       if (is_gimple_reg (TREE_OPERAND (expr, 0)))
  	TREE_OPERAND (expr, 0)
  	  = get_initialized_tmp_var (TREE_OPERAND (expr, 0), pre_p, post_p);
  
*************** gimplify_expr (tree *expr_p, gimple_seq 
*** 6178,6193 ****
    if (gimple_test_f == is_gimple_reg)
      gcc_assert (fallback & (fb_rvalue | fb_lvalue));
    else if (gimple_test_f == is_gimple_val
-            || gimple_test_f == is_gimple_formal_tmp_rhs
-            || gimple_test_f == is_gimple_formal_tmp_or_call_rhs
-            || gimple_test_f == is_gimple_formal_tmp_reg
-            || gimple_test_f == is_gimple_formal_tmp_var
             || gimple_test_f == is_gimple_call_addr
             || gimple_test_f == is_gimple_condexpr
             || gimple_test_f == is_gimple_mem_rhs
!            || gimple_test_f == is_gimple_mem_or_call_rhs
             || gimple_test_f == is_gimple_reg_rhs
!            || gimple_test_f == is_gimple_reg_or_call_rhs
             || gimple_test_f == is_gimple_asm_val)
      gcc_assert (fallback & fb_rvalue);
    else if (gimple_test_f == is_gimple_min_lval
--- 6141,6152 ----
    if (gimple_test_f == is_gimple_reg)
      gcc_assert (fallback & (fb_rvalue | fb_lvalue));
    else if (gimple_test_f == is_gimple_val
             || gimple_test_f == is_gimple_call_addr
             || gimple_test_f == is_gimple_condexpr
             || gimple_test_f == is_gimple_mem_rhs
!            || gimple_test_f == is_gimple_mem_rhs_or_call
             || gimple_test_f == is_gimple_reg_rhs
!            || gimple_test_f == is_gimple_reg_rhs_or_call
             || gimple_test_f == is_gimple_asm_val)
      gcc_assert (fallback & fb_rvalue);
    else if (gimple_test_f == is_gimple_min_lval
*************** gimplify_expr (tree *expr_p, gimple_seq 
*** 6986,6992 ****
        gimplify_expr (&tmp, pre_p, post_p, is_gimple_reg, fb_rvalue);
        *expr_p = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (tmp)), tmp);
      }
!   else if ((fallback & fb_rvalue) && is_gimple_formal_tmp_or_call_rhs (*expr_p))
      {
        /* An rvalue will do.  Assign the gimplified expression into a
  	 new temporary TMP and replace the original expression with
--- 6945,6951 ----
        gimplify_expr (&tmp, pre_p, post_p, is_gimple_reg, fb_rvalue);
        *expr_p = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (tmp)), tmp);
      }
!   else if ((fallback & fb_rvalue) && is_gimple_reg_rhs_or_call (*expr_p))
      {
        /* An rvalue will do.  Assign the gimplified expression into a
  	 new temporary TMP and replace the original expression with
*************** gimplify_expr (tree *expr_p, gimple_seq 
*** 7001,7009 ****
  	*expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p);
        else
  	*expr_p = get_formal_tmp_var (*expr_p, pre_p);
- 
-       if (TREE_CODE (*expr_p) != SSA_NAME)
- 	DECL_GIMPLE_FORMAL_TEMP_P (*expr_p) = 1;
      }
    else
      {
--- 6960,6965 ----
*************** gimple_regimplify_operands (gimple stmt,
*** 7449,7455 ****
        lhs = gimple_get_lhs (stmt);
        /* If regimplification of the LHS changed it in a way that requires
  	 a simple RHS, create temporary.  */
!       if (orig_lhs != lhs && !is_gimple_formal_tmp_var (lhs))
  	{
  	  bool need_temp = false;
  
--- 7405,7411 ----
        lhs = gimple_get_lhs (stmt);
        /* If regimplification of the LHS changed it in a way that requires
  	 a simple RHS, create temporary.  */
!       if (orig_lhs != lhs && !is_gimple_reg (lhs))
  	{
  	  bool need_temp = false;
  
*************** gimple_regimplify_operands (gimple stmt,
*** 7498,7504 ****
  	    {
  	      tree temp = create_tmp_var (TREE_TYPE (lhs), NULL);
  
- 	      DECL_GIMPLE_FORMAL_TEMP_P (temp) = 1;
  	      if (TREE_CODE (TREE_TYPE (lhs)) == COMPLEX_TYPE
  		  || TREE_CODE (TREE_TYPE (lhs)) == VECTOR_TYPE)
  		DECL_GIMPLE_REG_P (temp) = 1;
--- 7454,7459 ----
Index: gcc/tree-ssa-pre.c
===================================================================
*** gcc/tree-ssa-pre.c	(revision 142487)
--- gcc/tree-ssa-pre.c	(working copy)
*************** get_or_alloc_expr_for (tree t)
*** 1044,1050 ****
  {
    if (TREE_CODE (t) == SSA_NAME)
      return get_or_alloc_expr_for_name (t);
!   else if (is_gimple_min_invariant (t))
      return get_or_alloc_expr_for_constant (t);
    else
      {
--- 1044,1052 ----
  {
    if (TREE_CODE (t) == SSA_NAME)
      return get_or_alloc_expr_for_name (t);
!   else if (is_gimple_min_invariant (t)
! 	   || TREE_CODE (t) == EXC_PTR_EXPR
! 	   || TREE_CODE (t) == FILTER_EXPR)
      return get_or_alloc_expr_for_constant (t);
    else
      {
Index: gcc/tree-mudflap.c
===================================================================
*** gcc/tree-mudflap.c	(revision 142487)
--- gcc/tree-mudflap.c	(working copy)
*************** mf_build_check_statement_for (tree base,
*** 503,509 ****
    tree mf_elem;
    tree mf_limit;
    gimple g;
!   gimple_seq seq;
  
    /* We first need to split the current basic block, and start altering
       the CFG.  This allows us to insert the statements we're about to
--- 503,509 ----
    tree mf_elem;
    tree mf_limit;
    gimple g;
!   gimple_seq seq, stmts;
  
    /* We first need to split the current basic block, and start altering
       the CFG.  This allows us to insert the statements we're about to
*************** mf_build_check_statement_for (tree base,
*** 553,566 ****
    /* Build: __mf_base = (uintptr_t) <base address expression>.  */
    seq = gimple_seq_alloc ();
    t = fold_convert (mf_uintptr_type, unshare_expr (base));
!   gimplify_expr (&t, &seq, &seq, is_gimple_reg_rhs, fb_rvalue);
    g = gimple_build_assign (mf_base, t);
    gimple_set_location (g, location);
    gimple_seq_add_stmt (&seq, g);
  
    /* Build: __mf_limit = (uintptr_t) <limit address expression>.  */
    t = fold_convert (mf_uintptr_type, unshare_expr (limit));
!   gimplify_expr (&t, &seq, &seq, is_gimple_reg_rhs, fb_rvalue);
    g = gimple_build_assign (mf_limit, t);
    gimple_set_location (g, location);
    gimple_seq_add_stmt (&seq, g);
--- 553,568 ----
    /* Build: __mf_base = (uintptr_t) <base address expression>.  */
    seq = gimple_seq_alloc ();
    t = fold_convert (mf_uintptr_type, unshare_expr (base));
!   t = force_gimple_operand (t, &stmts, false, NULL_TREE);
!   gimple_seq_add_seq (&seq, stmts);
    g = gimple_build_assign (mf_base, t);
    gimple_set_location (g, location);
    gimple_seq_add_stmt (&seq, g);
  
    /* Build: __mf_limit = (uintptr_t) <limit address expression>.  */
    t = fold_convert (mf_uintptr_type, unshare_expr (limit));
!   t = force_gimple_operand (t, &stmts, false, NULL_TREE);
!   gimple_seq_add_seq (&seq, stmts);
    g = gimple_build_assign (mf_limit, t);
    gimple_set_location (g, location);
    gimple_seq_add_stmt (&seq, g);
*************** mf_build_check_statement_for (tree base,
*** 577,583 ****
                TREE_TYPE (TREE_TYPE (mf_cache_array_decl)),
                mf_cache_array_decl, t, NULL_TREE, NULL_TREE);
    t = build1 (ADDR_EXPR, mf_cache_structptr_type, t);
!   gimplify_expr (&t, &seq, &seq, is_gimple_reg_rhs, fb_rvalue);
    g = gimple_build_assign (mf_elem, t);
    gimple_set_location (g, location);
    gimple_seq_add_stmt (&seq, g);
--- 579,586 ----
                TREE_TYPE (TREE_TYPE (mf_cache_array_decl)),
                mf_cache_array_decl, t, NULL_TREE, NULL_TREE);
    t = build1 (ADDR_EXPR, mf_cache_structptr_type, t);
!   t = force_gimple_operand (t, &stmts, false, NULL_TREE);
!   gimple_seq_add_seq (&seq, stmts);
    g = gimple_build_assign (mf_elem, t);
    gimple_set_location (g, location);
    gimple_seq_add_stmt (&seq, g);
*************** mf_build_check_statement_for (tree base,
*** 622,628 ****
       result of the evaluation of 't' in a temporary variable which we
       can use as the condition for the conditional jump.  */
    t = build2 (TRUTH_OR_EXPR, boolean_type_node, t, u);
!   gimplify_expr (&t, &seq, &seq, is_gimple_reg_rhs, fb_rvalue);
    cond = create_tmp_var (boolean_type_node, "__mf_unlikely_cond");
    g = gimple_build_assign  (cond, t);
    gimple_set_location (g, location);
--- 625,632 ----
       result of the evaluation of 't' in a temporary variable which we
       can use as the condition for the conditional jump.  */
    t = build2 (TRUTH_OR_EXPR, boolean_type_node, t, u);
!   t = force_gimple_operand (t, &stmts, false, NULL_TREE);
!   gimple_seq_add_seq (&seq, stmts);
    cond = create_tmp_var (boolean_type_node, "__mf_unlikely_cond");
    g = gimple_build_assign  (cond, t);
    gimple_set_location (g, location);
*************** mf_build_check_statement_for (tree base,
*** 663,669 ****
    v = fold_build2 (PLUS_EXPR, integer_type_node,
  		   fold_build2 (MINUS_EXPR, mf_uintptr_type, mf_limit, mf_base),
  		   integer_one_node);
!   gimplify_expr (&v, &seq, &seq, is_gimple_mem_rhs, fb_rvalue);
    g = gimple_build_call (mf_check_fndecl, 4, mf_base, v, dirflag, u);
    gimple_seq_add_stmt (&seq, g);
  
--- 667,674 ----
    v = fold_build2 (PLUS_EXPR, integer_type_node,
  		   fold_build2 (MINUS_EXPR, mf_uintptr_type, mf_limit, mf_base),
  		   integer_one_node);
!   v = force_gimple_operand (v, &stmts, true, NULL_TREE);
!   gimple_seq_add_seq (&seq, stmts);
    g = gimple_build_call (mf_check_fndecl, 4, mf_base, v, dirflag, u);
    gimple_seq_add_stmt (&seq, g);
  
Index: gcc/gimple.c
===================================================================
*** gcc/gimple.c	(revision 142487)
--- gcc/gimple.c	(working copy)
*************** walk_gimple_op (gimple stmt, walk_tree_f
*** 1380,1386 ****
        /* Walk the RHS operands.  A formal temporary LHS may use a
  	 COMPONENT_REF RHS.  */
        if (wi)
! 	wi->val_only = !is_gimple_formal_tmp_var (gimple_assign_lhs (stmt));
  
        for (i = 1; i < gimple_num_ops (stmt); i++)
  	{
--- 1380,1387 ----
        /* Walk the RHS operands.  A formal temporary LHS may use a
  	 COMPONENT_REF RHS.  */
        if (wi)
! 	wi->val_only = !is_gimple_reg (gimple_assign_lhs (stmt))
!                        || !gimple_assign_single_p (stmt);
  
        for (i = 1; i < gimple_num_ops (stmt); i++)
  	{
*************** is_gimple_operand (const_tree op)
*** 2559,2595 ****
    return op && get_gimple_rhs_class (TREE_CODE (op)) == GIMPLE_SINGLE_RHS;
  }
  
- 
- /* Return true if T is a GIMPLE RHS for an assignment to a temporary.  */
- 
- bool
- is_gimple_formal_tmp_rhs (tree t)
- {
-   if (is_gimple_lvalue (t) || is_gimple_val (t))
-     return true;
- 
-   return get_gimple_rhs_class (TREE_CODE (t)) != GIMPLE_INVALID_RHS;
- }
- 
  /* Returns true iff T is a valid RHS for an assignment to a renamed
     user -- or front-end generated artificial -- variable.  */
  
  bool
  is_gimple_reg_rhs (tree t)
  {
!   /* If the RHS of the MODIFY_EXPR may throw or make a nonlocal goto
!      and the LHS is a user variable, then we need to introduce a formal
!      temporary.  This way the optimizers can determine that the user
!      variable is only modified if evaluation of the RHS does not throw.
! 
!      Don't force a temp of a non-renamable type; the copy could be
!      arbitrarily expensive.  Instead we will generate a VDEF for
!      the assignment.  */
! 
!   if (is_gimple_reg_type (TREE_TYPE (t)) && tree_could_throw_p (t))
!     return false;
! 
!   return is_gimple_formal_tmp_rhs (t);
  }
  
  /* Returns true iff T is a valid RHS for an assignment to an un-renamed
--- 2560,2572 ----
    return op && get_gimple_rhs_class (TREE_CODE (op)) == GIMPLE_SINGLE_RHS;
  }
  
  /* Returns true iff T is a valid RHS for an assignment to a renamed
     user -- or front-end generated artificial -- variable.  */
  
  bool
  is_gimple_reg_rhs (tree t)
  {
!   return get_gimple_rhs_class (TREE_CODE (t)) != GIMPLE_INVALID_RHS;
  }
  
  /* Returns true iff T is a valid RHS for an assignment to an un-renamed
*************** is_gimple_mem_rhs (tree t)
*** 2603,2609 ****
    if (is_gimple_reg_type (TREE_TYPE (t)))
      return is_gimple_val (t);
    else
!     return is_gimple_formal_tmp_rhs (t);
  }
  
  /*  Return true if T is a valid LHS for a GIMPLE assignment expression.  */
--- 2580,2586 ----
    if (is_gimple_reg_type (TREE_TYPE (t)))
      return is_gimple_val (t);
    else
!     return is_gimple_val (t) || is_gimple_lvalue (t);
  }
  
  /*  Return true if T is a valid LHS for a GIMPLE assignment expression.  */
*************** is_gimple_reg (tree t)
*** 2895,2900 ****
--- 2872,2883 ----
    if (!is_gimple_variable (t))
      return false;
  
+   /* Complex and vector values must have been put into SSA-like form.
+      That is, no assignments to the individual components.  */
+   if (TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE
+       || TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE)
+     return DECL_GIMPLE_REG_P (t);
+ 
    if (!is_gimple_reg_type (TREE_TYPE (t)))
      return false;
  
*************** is_gimple_reg (tree t)
*** 2921,2965 ****
    if (TREE_CODE (t) == VAR_DECL && DECL_HARD_REGISTER (t))
      return false;
  
-   /* Complex and vector values must have been put into SSA-like form.
-      That is, no assignments to the individual components.  */
-   if (TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE
-       || TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE)
-     return DECL_GIMPLE_REG_P (t);
- 
    return true;
  }
  
  
- /* Returns true if T is a GIMPLE formal temporary variable.  */
- 
- bool
- is_gimple_formal_tmp_var (tree t)
- {
-   if (TREE_CODE (t) == SSA_NAME)
-     return true;
- 
-   return TREE_CODE (t) == VAR_DECL && DECL_GIMPLE_FORMAL_TEMP_P (t);
- }
- 
- /* Returns true if T is a GIMPLE formal temporary register variable.  */
- 
- bool
- is_gimple_formal_tmp_reg (tree t)
- {
-   /* The intent of this is to get hold of a value that won't change.
-      An SSA_NAME qualifies no matter if its of a user variable or not.  */
-   if (TREE_CODE (t) == SSA_NAME)
-     return true;
- 
-   /* We don't know the lifetime characteristics of user variables.  */
-   if (!is_gimple_formal_tmp_var (t))
-     return false;
- 
-   /* Finally, it must be capable of being placed in a register.  */
-   return is_gimple_reg (t);
- }
- 
  /* Return true if T is a GIMPLE variable whose address is not needed.  */
  
  bool
--- 2904,2913 ----
*************** is_gimple_asm_val (tree t)
*** 3006,3011 ****
--- 2954,2961 ----
  bool
  is_gimple_min_lval (tree t)
  {
+   if (!(t = CONST_CAST_TREE (strip_invariant_refs (t))))
+     return false;
    return (is_gimple_id (t) || TREE_CODE (t) == INDIRECT_REF);
  }
  
Index: gcc/gimple.h
===================================================================
*** gcc/gimple.h	(revision 142487)
--- gcc/gimple.h	(working copy)
*************** extern bool is_gimple_stmt (tree);
*** 857,866 ****
  extern bool is_gimple_reg_type (tree);
  /* Returns true iff T is a scalar register variable.  */
  extern bool is_gimple_reg (tree);
- /* Returns true if T is a GIMPLE temporary variable, false otherwise.  */
- extern bool is_gimple_formal_tmp_var (tree);
- /* Returns true if T is a GIMPLE temporary register variable.  */
- extern bool is_gimple_formal_tmp_reg (tree);
  /* Returns true iff T is any sort of variable.  */
  extern bool is_gimple_variable (tree);
  /* Returns true iff T is any sort of symbol.  */
--- 857,862 ----
*************** extern bool is_gimple_asm_val (tree);
*** 892,898 ****
  /* Returns true iff T is a valid rhs for a MODIFY_EXPR where the LHS is a
     GIMPLE temporary, a renamed user variable, or something else,
     respectively.  */
- extern bool is_gimple_formal_tmp_rhs (tree);
  extern bool is_gimple_reg_rhs (tree);
  extern bool is_gimple_mem_rhs (tree);
  
--- 888,893 ----
Index: gcc/tree-cfg.c
===================================================================
*** gcc/tree-cfg.c	(revision 142487)
--- gcc/tree-cfg.c	(working copy)
*************** verify_expr (tree *tp, int *walk_subtree
*** 2871,2876 ****
--- 2871,2881 ----
  	    error ("address taken, but ADDRESSABLE bit not set");
  	    return x;
  	  }
+ 	if (DECL_GIMPLE_REG_P (x))
+ 	  {
+ 	    error ("DECL_GIMPLE_REG_P set on a variable with address taken");
+ 	    return x;
+ 	  }
  
  	break;
        }


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