This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Make VEC_COND_EXPR a GIMPLE_TERNARY_RHS
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 1 Sep 2011 13:42:16 +0200 (CEST)
- Subject: Re: [PATCH] Make VEC_COND_EXPR a GIMPLE_TERNARY_RHS
- References: <alpine.LNX.2.00.1108311529270.2130@zhemvz.fhfr.qr>
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),