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] Make VEC_COND_EXPR a GIMPLE_TERNARY_RHS


On Wed, 31 Aug 2011, Richard Guenther wrote:

> 
> $subject says it all, COND_EXPR to follow.  rhs1 will still be
> a "single" tree, namely a is_gimple_condexpr () operand.  That's
> not easy to change (without forcing it to a separate statement,
> thus making it a is_gimple_val) because it embeds another tree code.
> 
> Bootstrapped and tested on x86_64-unknown-linux-gnu.
> 
> Any serious objections?

None, though the following implements it for both COND_EXPR and
VEC_COND_EXPR.

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

Richard.

2011-08-31  Richard Guenther  <rguenther@suse.de>

	* expr.c (expand_expr_real_2): Move COND_EXPR and VEC_COND_EXPR
	handling here, from ...
	(expand_expr_real_1): ... here.
	* gimple-pretty-print.c (dump_ternary_rhs): Handle COND_EXPR
	and VEC_COND_EXPR.
	* gimple.c (gimple_rhs_class_table): Make COND_EXPR and VEC_COND_EXPR
	a GIMPLE_TERNARY_RHS.
	* tree-cfg.c (verify_gimple_assign_ternary): Handle COND_EXPR
	and VEC_COND_EXPR here ...
	(verify_gimple_assign_single): ... not here.
	* gimple-fold.c (fold_gimple_assign): Move COND_EXPR folding.
	* tree-object-size.c (cond_expr_object_size): Adjust.
	(collect_object_sizes_for): Likewise.
	* tree-scalar-evolution.c (interpret_expr): Don't handle
	ternary RHSs.
	* tree-ssa-forwprop.c (forward_propagate_into_cond): Fix and
	simplify.
	(ssa_forward_propagate_and_combine): Adjust.
	* tree-ssa-loop-im.c (move_computations_stmt): Build the COND_EXPR
	as ternary.
	* tree-ssa-threadedge.c (fold_assignment_stmt): Adjust.
	* tree-vect-loop.c (vect_is_simple_reduction_1): Likewise.
	* tree-vect-stmt.c (vectorizable_condition): Likewise.
	* tree-vrp.c (extract_range_from_cond_expr): Likewise.
	(extract_range_from_assignment): Likewise.

Index: trunk/gcc/expr.c
===================================================================
*** trunk.orig/gcc/expr.c	2011-09-01 12:08:51.000000000 +0200
--- trunk/gcc/expr.c	2011-09-01 12:10:04.000000000 +0200
*************** expand_expr_real_2 (sepops ops, rtx targ
*** 8636,8641 ****
--- 8636,8699 ----
          return temp;
        }
  
+     case COND_EXPR:
+       /* A COND_EXPR with its type being VOID_TYPE represents a
+ 	 conditional jump and is handled in
+ 	 expand_gimple_cond_expr.  */
+       gcc_assert (!VOID_TYPE_P (type));
+ 
+       /* Note that COND_EXPRs whose type is a structure or union
+ 	 are required to be constructed to contain assignments of
+ 	 a temporary variable, so that we can evaluate them here
+ 	 for side effect only.  If type is void, we must do likewise.  */
+ 
+       gcc_assert (!TREE_ADDRESSABLE (type)
+ 		  && !ignore
+ 		  && TREE_TYPE (treeop1) != void_type_node
+ 		  && TREE_TYPE (treeop2) != void_type_node);
+ 
+       /* If we are not to produce a result, we have no target.  Otherwise,
+ 	 if a target was specified use it; it will not be used as an
+ 	 intermediate target unless it is safe.  If no target, use a
+ 	 temporary.  */
+ 
+       if (modifier != EXPAND_STACK_PARM
+ 	  && original_target
+ 	  && safe_from_p (original_target, treeop0, 1)
+ 	  && GET_MODE (original_target) == mode
+ #ifdef HAVE_conditional_move
+ 	  && (! can_conditionally_move_p (mode)
+ 	      || REG_P (original_target))
+ #endif
+ 	  && !MEM_P (original_target))
+ 	temp = original_target;
+       else
+ 	temp = assign_temp (type, 0, 0, 1);
+ 
+       do_pending_stack_adjust ();
+       NO_DEFER_POP;
+       op0 = gen_label_rtx ();
+       op1 = gen_label_rtx ();
+       jumpifnot (treeop0, op0, -1);
+       store_expr (treeop1, temp,
+ 		  modifier == EXPAND_STACK_PARM,
+ 		  false);
+ 
+       emit_jump_insn (gen_jump (op1));
+       emit_barrier ();
+       emit_label (op0);
+       store_expr (treeop2, temp,
+ 		  modifier == EXPAND_STACK_PARM,
+ 		  false);
+ 
+       emit_label (op1);
+       OK_DEFER_POP;
+       return temp;
+ 
+     case VEC_COND_EXPR:
+       target = expand_vec_cond_expr (type, treeop0, treeop1, treeop2, target);
+       return target;
+ 
      default:
        gcc_unreachable ();
      }
*************** expand_expr_real_1 (tree exp, rtx target
*** 9878,9941 ****
  
        return op0;
  
-     case COND_EXPR:
-       /* A COND_EXPR with its type being VOID_TYPE represents a
- 	 conditional jump and is handled in
- 	 expand_gimple_cond_expr.  */
-       gcc_assert (!VOID_TYPE_P (type));
- 
-         /* Note that COND_EXPRs whose type is a structure or union
-   	 are required to be constructed to contain assignments of
-   	 a temporary variable, so that we can evaluate them here
-   	 for side effect only.  If type is void, we must do likewise.  */
- 
-         gcc_assert (!TREE_ADDRESSABLE (type)
- 		    && !ignore
- 		    && TREE_TYPE (treeop1) != void_type_node
- 		    && TREE_TYPE (treeop2) != void_type_node);
- 
-        /* If we are not to produce a result, we have no target.  Otherwise,
-  	 if a target was specified use it; it will not be used as an
-  	 intermediate target unless it is safe.  If no target, use a
-  	 temporary.  */
- 
-        if (modifier != EXPAND_STACK_PARM
-  	  && original_target
-  	  && safe_from_p (original_target, treeop0, 1)
-  	  && GET_MODE (original_target) == mode
- #ifdef HAVE_conditional_move
-  	  && (! can_conditionally_move_p (mode)
-  	      || REG_P (original_target))
- #endif
-  	  && !MEM_P (original_target))
-  	temp = original_target;
-        else
-  	temp = assign_temp (type, 0, 0, 1);
- 
-        do_pending_stack_adjust ();
-        NO_DEFER_POP;
-        op0 = gen_label_rtx ();
-        op1 = gen_label_rtx ();
-        jumpifnot (treeop0, op0, -1);
-        store_expr (treeop1, temp,
-  		  modifier == EXPAND_STACK_PARM,
- 		  false);
- 
-        emit_jump_insn (gen_jump (op1));
-        emit_barrier ();
-        emit_label (op0);
-        store_expr (treeop2, temp,
-  		  modifier == EXPAND_STACK_PARM,
- 		  false);
- 
-        emit_label (op1);
-        OK_DEFER_POP;
-        return temp;
- 
-     case VEC_COND_EXPR:
-       target = expand_vec_cond_expr (type, treeop0, treeop1, treeop2, target);
-       return target;
- 
      case MODIFY_EXPR:
        {
  	tree lhs = treeop0;
--- 9936,9941 ----
Index: trunk/gcc/gimple-pretty-print.c
===================================================================
*** trunk.orig/gcc/gimple-pretty-print.c	2011-09-01 12:08:51.000000000 +0200
--- trunk/gcc/gimple-pretty-print.c	2011-09-01 12:10:04.000000000 +0200
*************** dump_ternary_rhs (pretty_printer *buffer
*** 428,433 ****
--- 428,451 ----
        pp_string (buffer, ">");
        break;
  
+     case COND_EXPR:
+       dump_generic_node (buffer, gimple_assign_rhs1 (gs), spc, flags, false);
+       pp_string (buffer, " ? ");
+       dump_generic_node (buffer, gimple_assign_rhs2 (gs), spc, flags, false);
+       pp_string (buffer, " : ");
+       dump_generic_node (buffer, gimple_assign_rhs3 (gs), spc, flags, false);
+       break;
+ 
+     case VEC_COND_EXPR:
+       pp_string (buffer, "VEC_COND_EXPR <");
+       dump_generic_node (buffer, gimple_assign_rhs1 (gs), spc, flags, false);
+       pp_string (buffer, ", ");
+       dump_generic_node (buffer, gimple_assign_rhs2 (gs), spc, flags, false);
+       pp_string (buffer, ", ");
+       dump_generic_node (buffer, gimple_assign_rhs3 (gs), spc, flags, false);
+       pp_string (buffer, ">");
+       break;
+ 
      default:
        gcc_unreachable ();
      }
Index: trunk/gcc/gimple.c
===================================================================
*** trunk.orig/gcc/gimple.c	2011-09-01 12:08:51.000000000 +0200
--- trunk/gcc/gimple.c	2011-09-01 12:10:04.000000000 +0200
*************** get_gimple_rhs_num_ops (enum tree_code c
*** 2611,2629 ****
        || (SYM) == TRUTH_OR_EXPR						    \
        || (SYM) == TRUTH_XOR_EXPR) ? GIMPLE_BINARY_RHS			    \
     : (SYM) == TRUTH_NOT_EXPR ? GIMPLE_UNARY_RHS				    \
!    : ((SYM) == WIDEN_MULT_PLUS_EXPR					    \
        || (SYM) == WIDEN_MULT_MINUS_EXPR					    \
        || (SYM) == DOT_PROD_EXPR						    \
        || (SYM) == REALIGN_LOAD_EXPR					    \
        || (SYM) == FMA_EXPR) ? GIMPLE_TERNARY_RHS			    \
!    : ((SYM) == COND_EXPR						    \
!       || (SYM) == CONSTRUCTOR						    \
        || (SYM) == OBJ_TYPE_REF						    \
        || (SYM) == ASSERT_EXPR						    \
        || (SYM) == ADDR_EXPR						    \
        || (SYM) == WITH_SIZE_EXPR					    \
!       || (SYM) == SSA_NAME						    \
!       || (SYM) == VEC_COND_EXPR) ? GIMPLE_SINGLE_RHS			    \
     : GIMPLE_INVALID_RHS),
  #define END_OF_BASE_TREE_CODES (unsigned char) GIMPLE_INVALID_RHS,
  
--- 2611,2629 ----
        || (SYM) == TRUTH_OR_EXPR						    \
        || (SYM) == TRUTH_XOR_EXPR) ? GIMPLE_BINARY_RHS			    \
     : (SYM) == TRUTH_NOT_EXPR ? GIMPLE_UNARY_RHS				    \
!    : ((SYM) == COND_EXPR						    \
!       || (SYM) == WIDEN_MULT_PLUS_EXPR					    \
        || (SYM) == WIDEN_MULT_MINUS_EXPR					    \
        || (SYM) == DOT_PROD_EXPR						    \
        || (SYM) == REALIGN_LOAD_EXPR					    \
+       || (SYM) == VEC_COND_EXPR						    \
        || (SYM) == FMA_EXPR) ? GIMPLE_TERNARY_RHS			    \
!    : ((SYM) == CONSTRUCTOR						    \
        || (SYM) == OBJ_TYPE_REF						    \
        || (SYM) == ASSERT_EXPR						    \
        || (SYM) == ADDR_EXPR						    \
        || (SYM) == WITH_SIZE_EXPR					    \
!       || (SYM) == SSA_NAME) ? GIMPLE_SINGLE_RHS				    \
     : GIMPLE_INVALID_RHS),
  #define END_OF_BASE_TREE_CODES (unsigned char) GIMPLE_INVALID_RHS,
  
Index: trunk/gcc/tree-cfg.c
===================================================================
*** trunk.orig/gcc/tree-cfg.c	2011-09-01 12:08:51.000000000 +0200
--- trunk/gcc/tree-cfg.c	2011-09-01 12:10:04.000000000 +0200
*************** verify_gimple_assign_ternary (gimple stm
*** 3761,3767 ****
        return true;
      }
  
!   if (!is_gimple_val (rhs1)
        || !is_gimple_val (rhs2)
        || !is_gimple_val (rhs3))
      {
--- 3761,3768 ----
        return true;
      }
  
!   if (((rhs_code == VEC_COND_EXPR || rhs_code == COND_EXPR)
!        ? !is_gimple_condexpr (rhs1) : !is_gimple_val (rhs1))
        || !is_gimple_val (rhs2)
        || !is_gimple_val (rhs3))
      {
*************** verify_gimple_assign_ternary (gimple stm
*** 3804,3809 ****
--- 3805,3823 ----
  	}
        break;
  
+     case COND_EXPR:
+     case VEC_COND_EXPR:
+       if (!useless_type_conversion_p (lhs_type, rhs2_type)
+ 	  || !useless_type_conversion_p (lhs_type, rhs3_type))
+ 	{
+ 	  error ("type mismatch in conditional expression");
+ 	  debug_generic_expr (lhs_type);
+ 	  debug_generic_expr (rhs2_type);
+ 	  debug_generic_expr (rhs3_type);
+ 	  return true;
+ 	}
+       break;
+ 
      case DOT_PROD_EXPR:
      case REALIGN_LOAD_EXPR:
        /* FIXME.  */
*************** verify_gimple_assign_single (gimple stmt
*** 3920,3945 ****
  	}
        return res;
  
-     case COND_EXPR:
-       if (!is_gimple_reg (lhs)
- 	  || (!is_gimple_reg (TREE_OPERAND (rhs1, 0))
- 	      && !COMPARISON_CLASS_P (TREE_OPERAND (rhs1, 0)))
- 	  || (!is_gimple_reg (TREE_OPERAND (rhs1, 1))
- 	      && !is_gimple_min_invariant (TREE_OPERAND (rhs1, 1)))
- 	  || (!is_gimple_reg (TREE_OPERAND (rhs1, 2))
- 	      && !is_gimple_min_invariant (TREE_OPERAND (rhs1, 2))))
- 	{
- 	  error ("invalid COND_EXPR in gimple assignment");
- 	  debug_generic_stmt (rhs1);
- 	  return true;
- 	}
-       return res;
- 
      case CONSTRUCTOR:
      case OBJ_TYPE_REF:
      case ASSERT_EXPR:
      case WITH_SIZE_EXPR:
-     case VEC_COND_EXPR:
        /* FIXME.  */
        return res;
  
--- 3934,3943 ----
Index: trunk/gcc/gimple-fold.c
===================================================================
*** trunk.orig/gcc/gimple-fold.c	2011-09-01 12:08:51.000000000 +0200
--- trunk/gcc/gimple-fold.c	2011-09-01 12:10:04.000000000 +0200
*************** fold_gimple_assign (gimple_stmt_iterator
*** 294,335 ****
        {
          tree rhs = gimple_assign_rhs1 (stmt);
  
!         /* Try to fold a conditional expression.  */
!         if (TREE_CODE (rhs) == COND_EXPR)
!           {
! 	    tree op0 = COND_EXPR_COND (rhs);
! 	    tree tem;
! 	    bool set = false;
! 	    location_t cond_loc = EXPR_LOCATION (rhs);
! 
! 	    if (COMPARISON_CLASS_P (op0))
! 	      {
! 		fold_defer_overflow_warnings ();
! 		tem = fold_binary_loc (cond_loc,
! 				   TREE_CODE (op0), TREE_TYPE (op0),
! 				   TREE_OPERAND (op0, 0),
! 				   TREE_OPERAND (op0, 1));
! 		/* This is actually a conditional expression, not a GIMPLE
! 		   conditional statement, however, the valid_gimple_rhs_p
! 		   test still applies.  */
! 		set = (tem && is_gimple_condexpr (tem)
! 		       && valid_gimple_rhs_p (tem));
! 		fold_undefer_overflow_warnings (set, stmt, 0);
! 	      }
! 	    else if (is_gimple_min_invariant (op0))
! 	      {
! 		tem = op0;
! 		set = true;
! 	      }
! 	    else
! 	      return NULL_TREE;
! 
! 	    if (set)
! 	      result = fold_build3_loc (cond_loc, COND_EXPR, TREE_TYPE (rhs), tem,
! 				    COND_EXPR_THEN (rhs), COND_EXPR_ELSE (rhs));
!           }
! 
! 	else if (REFERENCE_CLASS_P (rhs))
  	  return maybe_fold_reference (rhs, false);
  
  	else if (TREE_CODE (rhs) == ADDR_EXPR)
--- 294,300 ----
        {
          tree rhs = gimple_assign_rhs1 (stmt);
  
! 	if (REFERENCE_CLASS_P (rhs))
  	  return maybe_fold_reference (rhs, false);
  
  	else if (TREE_CODE (rhs) == ADDR_EXPR)
*************** fold_gimple_assign (gimple_stmt_iterator
*** 469,479 ****
        break;
  
      case GIMPLE_TERNARY_RHS:
!       result = fold_ternary_loc (loc, subcode,
! 				 TREE_TYPE (gimple_assign_lhs (stmt)),
! 				 gimple_assign_rhs1 (stmt),
! 				 gimple_assign_rhs2 (stmt),
! 				 gimple_assign_rhs3 (stmt));
  
        if (result)
          {
--- 434,482 ----
        break;
  
      case GIMPLE_TERNARY_RHS:
!       /* Try to fold a conditional expression.  */
!       if (gimple_assign_rhs_code (stmt) == COND_EXPR)
! 	{
! 	  tree op0 = gimple_assign_rhs1 (stmt);
! 	  tree tem;
! 	  bool set = false;
! 	  location_t cond_loc = gimple_location (stmt);
! 
! 	  if (COMPARISON_CLASS_P (op0))
! 	    {
! 	      fold_defer_overflow_warnings ();
! 	      tem = fold_binary_loc (cond_loc,
! 				     TREE_CODE (op0), TREE_TYPE (op0),
! 				     TREE_OPERAND (op0, 0),
! 				     TREE_OPERAND (op0, 1));
! 	      /* This is actually a conditional expression, not a GIMPLE
! 		 conditional statement, however, the valid_gimple_rhs_p
! 		 test still applies.  */
! 	      set = (tem && is_gimple_condexpr (tem)
! 		     && valid_gimple_rhs_p (tem));
! 	      fold_undefer_overflow_warnings (set, stmt, 0);
! 	    }
! 	  else if (is_gimple_min_invariant (op0))
! 	    {
! 	      tem = op0;
! 	      set = true;
! 	    }
! 	  else
! 	    return NULL_TREE;
! 
! 	  if (set)
! 	    result = fold_build3_loc (cond_loc, COND_EXPR,
! 				      TREE_TYPE (gimple_assign_lhs (stmt)), tem,
! 				      gimple_assign_rhs2 (stmt),
! 				      gimple_assign_rhs3 (stmt));
! 	}
! 
!       if (!result)
! 	result = fold_ternary_loc (loc, subcode,
! 				   TREE_TYPE (gimple_assign_lhs (stmt)),
! 				   gimple_assign_rhs1 (stmt),
! 				   gimple_assign_rhs2 (stmt),
! 				   gimple_assign_rhs3 (stmt));
  
        if (result)
          {
Index: trunk/gcc/tree-object-size.c
===================================================================
*** trunk.orig/gcc/tree-object-size.c	2011-09-01 12:08:51.000000000 +0200
--- trunk/gcc/tree-object-size.c	2011-09-01 12:10:04.000000000 +0200
*************** static void expr_object_size (struct obj
*** 53,59 ****
  static bool merge_object_sizes (struct object_size_info *, tree, tree,
  				unsigned HOST_WIDE_INT);
  static bool plus_stmt_object_size (struct object_size_info *, tree, gimple);
! static bool cond_expr_object_size (struct object_size_info *, tree, tree);
  static unsigned int compute_object_sizes (void);
  static void init_offset_limit (void);
  static void check_for_plus_in_loops (struct object_size_info *, tree);
--- 53,59 ----
  static bool merge_object_sizes (struct object_size_info *, tree, tree,
  				unsigned HOST_WIDE_INT);
  static bool plus_stmt_object_size (struct object_size_info *, tree, gimple);
! static bool cond_expr_object_size (struct object_size_info *, tree, gimple);
  static unsigned int compute_object_sizes (void);
  static void init_offset_limit (void);
  static void check_for_plus_in_loops (struct object_size_info *, tree);
*************** plus_stmt_object_size (struct object_siz
*** 827,851 ****
  }
  
  
! /* Compute object_sizes for VAR, defined to VALUE, which is
     a COND_EXPR.  Return true if the object size might need reexamination
     later.  */
  
  static bool
! cond_expr_object_size (struct object_size_info *osi, tree var, tree value)
  {
    tree then_, else_;
    int object_size_type = osi->object_size_type;
    unsigned int varno = SSA_NAME_VERSION (var);
    bool reexamine = false;
  
!   gcc_assert (TREE_CODE (value) == COND_EXPR);
  
    if (object_sizes[object_size_type][varno] == unknown[object_size_type])
      return false;
  
!   then_ = COND_EXPR_THEN (value);
!   else_ = COND_EXPR_ELSE (value);
  
    if (TREE_CODE (then_) == SSA_NAME)
      reexamine |= merge_object_sizes (osi, var, then_, 0);
--- 827,851 ----
  }
  
  
! /* Compute object_sizes for VAR, defined at STMT, which is
     a COND_EXPR.  Return true if the object size might need reexamination
     later.  */
  
  static bool
! cond_expr_object_size (struct object_size_info *osi, tree var, gimple stmt)
  {
    tree then_, else_;
    int object_size_type = osi->object_size_type;
    unsigned int varno = SSA_NAME_VERSION (var);
    bool reexamine = false;
  
!   gcc_assert (gimple_assign_rhs_code (stmt) == COND_EXPR);
  
    if (object_sizes[object_size_type][varno] == unknown[object_size_type])
      return false;
  
!   then_ = gimple_assign_rhs2 (stmt);
!   else_ = gimple_assign_rhs3 (stmt);
  
    if (TREE_CODE (then_) == SSA_NAME)
      reexamine |= merge_object_sizes (osi, var, then_, 0);
*************** collect_object_sizes_for (struct object_
*** 932,945 ****
  	    || (gimple_assign_rhs_code (stmt) == ADDR_EXPR
  		&& TREE_CODE (TREE_OPERAND (rhs, 0)) == MEM_REF))
            reexamine = plus_stmt_object_size (osi, var, stmt);
          else if (gimple_assign_single_p (stmt)
                   || gimple_assign_unary_nop_p (stmt))
            {
              if (TREE_CODE (rhs) == SSA_NAME
                  && POINTER_TYPE_P (TREE_TYPE (rhs)))
                reexamine = merge_object_sizes (osi, var, rhs, 0);
-             else if (TREE_CODE (rhs) == COND_EXPR)
-               reexamine = cond_expr_object_size (osi, var, rhs);
              else
                expr_object_size (osi, var, rhs);
            }
--- 932,945 ----
  	    || (gimple_assign_rhs_code (stmt) == ADDR_EXPR
  		&& TREE_CODE (TREE_OPERAND (rhs, 0)) == MEM_REF))
            reexamine = plus_stmt_object_size (osi, var, stmt);
+ 	else if (gimple_assign_rhs_code (stmt) == COND_EXPR)
+ 	  reexamine = cond_expr_object_size (osi, var, stmt);
          else if (gimple_assign_single_p (stmt)
                   || gimple_assign_unary_nop_p (stmt))
            {
              if (TREE_CODE (rhs) == SSA_NAME
                  && POINTER_TYPE_P (TREE_TYPE (rhs)))
                reexamine = merge_object_sizes (osi, var, rhs, 0);
              else
                expr_object_size (osi, var, rhs);
            }
*************** collect_object_sizes_for (struct object_
*** 956,963 ****
              if (TREE_CODE (arg) == SSA_NAME
                  && POINTER_TYPE_P (TREE_TYPE (arg)))
                reexamine = merge_object_sizes (osi, var, arg, 0);
-             else if (TREE_CODE (arg) == COND_EXPR)
-               reexamine = cond_expr_object_size (osi, var, arg);
              else
                expr_object_size (osi, var, arg);
            }
--- 956,961 ----
Index: trunk/gcc/tree-scalar-evolution.c
===================================================================
*** trunk.orig/gcc/tree-scalar-evolution.c	2011-09-01 12:08:51.000000000 +0200
--- trunk/gcc/tree-scalar-evolution.c	2011-09-01 12:10:04.000000000 +0200
*************** interpret_expr (struct loop *loop, gimpl
*** 1796,1802 ****
    if (automatically_generated_chrec_p (expr))
      return expr;
  
!   if (TREE_CODE (expr) == POLYNOMIAL_CHREC)
      return chrec_dont_know;
  
    extract_ops_from_tree (expr, &code, &op0, &op1);
--- 1796,1803 ----
    if (automatically_generated_chrec_p (expr))
      return expr;
  
!   if (TREE_CODE (expr) == POLYNOMIAL_CHREC
!       || get_gimple_rhs_class (TREE_CODE (expr)) == GIMPLE_TERNARY_RHS)
      return chrec_dont_know;
  
    extract_ops_from_tree (expr, &code, &op0, &op1);
Index: trunk/gcc/tree-ssa-forwprop.c
===================================================================
*** trunk.orig/gcc/tree-ssa-forwprop.c	2011-09-01 12:08:51.000000000 +0200
--- trunk/gcc/tree-ssa-forwprop.c	2011-09-01 12:17:17.000000000 +0200
*************** forward_propagate_into_gimple_cond (gimp
*** 540,551 ****
  
  /* Propagate from the ssa name definition statements of COND_EXPR
     in the rhs of statement STMT into the conditional if that simplifies it.
!    Returns zero if no statement was changed, one if there were
!    changes and two if cfg_cleanup needs to run.
  
!    This must be kept in sync with forward_propagate_into_gimple_cond.  */
! 
! static int
  forward_propagate_into_cond (gimple_stmt_iterator *gsi_p)
  {
    gimple stmt = gsi_stmt (*gsi_p);
--- 540,548 ----
  
  /* Propagate from the ssa name definition statements of COND_EXPR
     in the rhs of statement STMT into the conditional if that simplifies it.
!    Returns true zero if the stmt was changed.  */
  
! static bool
  forward_propagate_into_cond (gimple_stmt_iterator *gsi_p)
  {
    gimple stmt = gsi_stmt (*gsi_p);
*************** forward_propagate_into_cond (gimple_stmt
*** 560,574 ****
  					       TREE_OPERAND (cond, 1));
    else if (TREE_CODE (cond) == SSA_NAME)
      {
!       tree name = cond, rhs0;
        gimple def_stmt = get_prop_source_stmt (name, true, NULL);
        if (!def_stmt || !can_propagate_from (def_stmt))
  	return 0;
  
!       rhs0 = gimple_assign_rhs1 (def_stmt);
!       tmp = combine_cond_expr_cond (stmt, NE_EXPR, boolean_type_node, rhs0,
! 				    build_int_cst (TREE_TYPE (rhs0), 0),
! 				    false);
      }
  
    if (tmp)
--- 557,573 ----
  					       TREE_OPERAND (cond, 1));
    else if (TREE_CODE (cond) == SSA_NAME)
      {
!       tree name = cond;
        gimple def_stmt = get_prop_source_stmt (name, true, NULL);
        if (!def_stmt || !can_propagate_from (def_stmt))
  	return 0;
  
!       if (TREE_CODE_CLASS (gimple_assign_rhs_code (def_stmt)) == tcc_comparison)
! 	tmp = fold_build2_loc (gimple_location (def_stmt),
! 			       gimple_assign_rhs_code (def_stmt),
! 			       boolean_type_node,
! 			       gimple_assign_rhs1 (def_stmt),
! 			       gimple_assign_rhs2 (def_stmt));
      }
  
    if (tmp)
*************** forward_propagate_into_cond (gimple_stmt
*** 582,592 ****
  	  fprintf (dump_file, "'\n");
  	}
  
!       gimple_assign_set_rhs_from_tree (gsi_p, unshare_expr (tmp));
        stmt = gsi_stmt (*gsi_p);
        update_stmt (stmt);
  
!       return is_gimple_min_invariant (tmp) ? 2 : 1;
      }
  
    return 0;
--- 581,596 ----
  	  fprintf (dump_file, "'\n");
  	}
  
!       if (integer_onep (tmp))
! 	gimple_assign_set_rhs_from_tree (gsi_p, gimple_assign_rhs2 (stmt));
!       else if (integer_zerop (tmp))
! 	gimple_assign_set_rhs_from_tree (gsi_p, gimple_assign_rhs3 (stmt));
!       else
! 	gimple_assign_set_rhs1 (stmt, unshare_expr (tmp));
        stmt = gsi_stmt (*gsi_p);
        update_stmt (stmt);
  
!       return true;
      }
  
    return 0;
*************** ssa_forward_propagate_and_combine (void)
*** 2436,2447 ****
  		else if (code == COND_EXPR)
  		  {
  		    /* In this case the entire COND_EXPR is in rhs1. */
! 		    int did_something;
! 		    did_something = forward_propagate_into_cond (&gsi);
  		    stmt = gsi_stmt (gsi);
- 		    if (did_something == 2)
- 		      cfg_changed = true;
- 		    changed = did_something != 0;
  		  }
  		else if (TREE_CODE_CLASS (code) == tcc_comparison)
  		  {
--- 2440,2447 ----
  		else if (code == COND_EXPR)
  		  {
  		    /* In this case the entire COND_EXPR is in rhs1. */
! 		    changed |= forward_propagate_into_cond (&gsi);
  		    stmt = gsi_stmt (gsi);
  		  }
  		else if (TREE_CODE_CLASS (code) == tcc_comparison)
  		  {
Index: trunk/gcc/tree-ssa-loop-im.c
===================================================================
*** trunk.orig/gcc/tree-ssa-loop-im.c	2011-09-01 12:08:51.000000000 +0200
--- trunk/gcc/tree-ssa-loop-im.c	2011-09-01 12:10:04.000000000 +0200
*************** move_computations_stmt (struct dom_walk_
*** 1251,1261 ****
  	  gcc_assert (arg0 && arg1);
  	  t = build2 (gimple_cond_code (cond), boolean_type_node,
  		      gimple_cond_lhs (cond), gimple_cond_rhs (cond));
! 	  t = build3 (COND_EXPR, TREE_TYPE (gimple_phi_result (stmt)),
! 		      t, arg0, arg1);
! 	  new_stmt = gimple_build_assign_with_ops (COND_EXPR,
! 						   gimple_phi_result (stmt),
! 						   t, NULL_TREE);
  	  SSA_NAME_DEF_STMT (gimple_phi_result (stmt)) = new_stmt;
  	  *((unsigned int *)(dw_data->global_data)) |= TODO_cleanup_cfg;
  	}
--- 1251,1259 ----
  	  gcc_assert (arg0 && arg1);
  	  t = build2 (gimple_cond_code (cond), boolean_type_node,
  		      gimple_cond_lhs (cond), gimple_cond_rhs (cond));
! 	  new_stmt = gimple_build_assign_with_ops3 (COND_EXPR,
! 						    gimple_phi_result (stmt),
! 						    t, arg0, arg1);
  	  SSA_NAME_DEF_STMT (gimple_phi_result (stmt)) = new_stmt;
  	  *((unsigned int *)(dw_data->global_data)) |= TODO_cleanup_cfg;
  	}
Index: trunk/gcc/tree-ssa-threadedge.c
===================================================================
*** trunk.orig/gcc/tree-ssa-threadedge.c	2011-09-01 12:08:51.000000000 +0200
--- trunk/gcc/tree-ssa-threadedge.c	2011-09-01 12:10:04.000000000 +0200
*************** fold_assignment_stmt (gimple stmt)
*** 225,248 ****
    switch (get_gimple_rhs_class (subcode))
      {
      case GIMPLE_SINGLE_RHS:
!       {
!         tree rhs = gimple_assign_rhs1 (stmt);
! 
!         if (TREE_CODE (rhs) == COND_EXPR)
!           {
!             /* Sadly, we have to handle conditional assignments specially
!                here, because fold expects all the operands of an expression
!                to be folded before the expression itself is folded, but we
!                can't just substitute the folded condition here.  */
!             tree cond = fold (COND_EXPR_COND (rhs));
!             if (cond == boolean_true_node)
!               rhs = COND_EXPR_THEN (rhs);
!             else if (cond == boolean_false_node)
!               rhs = COND_EXPR_ELSE (rhs);
!           }
! 
!         return fold (rhs);
!       }
  
      case GIMPLE_UNARY_RHS:
        {
--- 225,231 ----
    switch (get_gimple_rhs_class (subcode))
      {
      case GIMPLE_SINGLE_RHS:
!       return fold (gimple_assign_rhs1 (stmt));
  
      case GIMPLE_UNARY_RHS:
        {
*************** fold_assignment_stmt (gimple stmt)
*** 265,270 ****
--- 248,261 ----
          tree op0 = gimple_assign_rhs1 (stmt);
          tree op1 = gimple_assign_rhs2 (stmt);
          tree op2 = gimple_assign_rhs3 (stmt);
+ 
+ 	/* Sadly, we have to handle conditional assignments specially
+ 	   here, because fold expects all the operands of an expression
+ 	   to be folded before the expression itself is folded, but we
+ 	   can't just substitute the folded condition here.  */
+         if (gimple_assign_rhs_code (stmt) == COND_EXPR)
+ 	  op0 = fold (op0);
+ 
          return fold_ternary (subcode, TREE_TYPE (lhs), op0, op1, op2);
        }
  
Index: trunk/gcc/tree-vect-loop.c
===================================================================
*** trunk.orig/gcc/tree-vect-loop.c	2011-09-01 12:08:51.000000000 +0200
--- trunk/gcc/tree-vect-loop.c	2011-09-01 12:10:04.000000000 +0200
*************** vect_is_simple_reduction_1 (loop_vec_inf
*** 2126,2140 ****
            return NULL;
          }
  
!       op3 = TREE_OPERAND (gimple_assign_rhs1 (def_stmt), 0);
        if (COMPARISON_CLASS_P (op3))
          {
            op4 = TREE_OPERAND (op3, 1);
            op3 = TREE_OPERAND (op3, 0);
          }
  
!       op1 = TREE_OPERAND (gimple_assign_rhs1 (def_stmt), 1);
!       op2 = TREE_OPERAND (gimple_assign_rhs1 (def_stmt), 2);
  
        if (TREE_CODE (op1) != SSA_NAME && TREE_CODE (op2) != SSA_NAME)
          {
--- 2126,2140 ----
            return NULL;
          }
  
!       op3 = gimple_assign_rhs1 (def_stmt);
        if (COMPARISON_CLASS_P (op3))
          {
            op4 = TREE_OPERAND (op3, 1);
            op3 = TREE_OPERAND (op3, 0);
          }
  
!       op1 = gimple_assign_rhs2 (def_stmt);
!       op2 = gimple_assign_rhs3 (def_stmt);
  
        if (TREE_CODE (op1) != SSA_NAME && TREE_CODE (op2) != SSA_NAME)
          {
Index: trunk/gcc/tree-vect-stmts.c
===================================================================
*** trunk.orig/gcc/tree-vect-stmts.c	2011-09-01 12:08:51.000000000 +0200
--- trunk/gcc/tree-vect-stmts.c	2011-09-01 12:10:04.000000000 +0200
*************** vectorizable_condition (gimple stmt, gim
*** 4740,4746 ****
  {
    tree scalar_dest = NULL_TREE;
    tree vec_dest = NULL_TREE;
-   tree op = NULL_TREE;
    tree cond_expr, then_clause, else_clause;
    stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
    tree vectype = STMT_VINFO_VECTYPE (stmt_info);
--- 4740,4745 ----
*************** vectorizable_condition (gimple stmt, gim
*** 4794,4804 ****
    if (code != COND_EXPR)
      return false;
  
!   gcc_assert (gimple_assign_single_p (stmt));
!   op = gimple_assign_rhs1 (stmt);
!   cond_expr = TREE_OPERAND (op, 0);
!   then_clause = TREE_OPERAND (op, 1);
!   else_clause = TREE_OPERAND (op, 2);
  
    if (!vect_is_simple_cond (cond_expr, loop_vinfo))
      return false;
--- 4793,4801 ----
    if (code != COND_EXPR)
      return false;
  
!   cond_expr = gimple_assign_rhs1 (stmt);
!   then_clause = gimple_assign_rhs2 (stmt);
!   else_clause = gimple_assign_rhs3 (stmt);
  
    if (!vect_is_simple_cond (cond_expr, loop_vinfo))
      return false;
*************** vectorizable_condition (gimple stmt, gim
*** 4839,4845 ****
    if (!vec_stmt)
      {
        STMT_VINFO_TYPE (stmt_info) = condition_vec_info_type;
!       return expand_vec_cond_expr_p (TREE_TYPE (op), vec_mode);
      }
  
    /* Transform */
--- 4836,4843 ----
    if (!vec_stmt)
      {
        STMT_VINFO_TYPE (stmt_info) = condition_vec_info_type;
!       return expand_vec_cond_expr_p (TREE_TYPE (gimple_assign_lhs (stmt)),
! 				     vec_mode);
      }
  
    /* Transform */
Index: trunk/gcc/tree-vrp.c
===================================================================
*** trunk.orig/gcc/tree-vrp.c	2011-09-01 12:08:51.000000000 +0200
--- trunk/gcc/tree-vrp.c	2011-09-01 12:10:04.000000000 +0200
*************** extract_range_from_unary_expr (value_ran
*** 3190,3200 ****
  }
  
  
! /* Extract range information from a conditional expression EXPR based on
     the ranges of each of its operands and the expression code.  */
  
  static void
! extract_range_from_cond_expr (value_range_t *vr, tree expr)
  {
    tree op0, op1;
    value_range_t vr0 = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };
--- 3190,3200 ----
  }
  
  
! /* Extract range information from a conditional expression STMT based on
     the ranges of each of its operands and the expression code.  */
  
  static void
! extract_range_from_cond_expr (value_range_t *vr, gimple stmt)
  {
    tree op0, op1;
    value_range_t vr0 = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };
*************** extract_range_from_cond_expr (value_rang
*** 3202,3208 ****
  
    /* Get value ranges for each operand.  For constant operands, create
       a new value range with the operand to simplify processing.  */
!   op0 = COND_EXPR_THEN (expr);
    if (TREE_CODE (op0) == SSA_NAME)
      vr0 = *(get_value_range (op0));
    else if (is_gimple_min_invariant (op0))
--- 3202,3208 ----
  
    /* Get value ranges for each operand.  For constant operands, create
       a new value range with the operand to simplify processing.  */
!   op0 = gimple_assign_rhs2 (stmt);
    if (TREE_CODE (op0) == SSA_NAME)
      vr0 = *(get_value_range (op0));
    else if (is_gimple_min_invariant (op0))
*************** extract_range_from_cond_expr (value_rang
*** 3210,3216 ****
    else
      set_value_range_to_varying (&vr0);
  
!   op1 = COND_EXPR_ELSE (expr);
    if (TREE_CODE (op1) == SSA_NAME)
      vr1 = *(get_value_range (op1));
    else if (is_gimple_min_invariant (op1))
--- 3210,3216 ----
    else
      set_value_range_to_varying (&vr0);
  
!   op1 = gimple_assign_rhs3 (stmt);
    if (TREE_CODE (op1) == SSA_NAME)
      vr1 = *(get_value_range (op1));
    else if (is_gimple_min_invariant (op1))
*************** extract_range_from_assignment (value_ran
*** 3302,3308 ****
  				   gimple_expr_type (stmt),
  				   gimple_assign_rhs1 (stmt));
    else if (code == COND_EXPR)
!     extract_range_from_cond_expr (vr, gimple_assign_rhs1 (stmt));
    else if (TREE_CODE_CLASS (code) == tcc_comparison)
      extract_range_from_comparison (vr, gimple_assign_rhs_code (stmt),
  				   gimple_expr_type (stmt),
--- 3302,3308 ----
  				   gimple_expr_type (stmt),
  				   gimple_assign_rhs1 (stmt));
    else if (code == COND_EXPR)
!     extract_range_from_cond_expr (vr, stmt);
    else if (TREE_CODE_CLASS (code) == tcc_comparison)
      extract_range_from_comparison (vr, gimple_assign_rhs_code (stmt),
  				   gimple_expr_type (stmt),


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