This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Force predicates into separate GIMPLE_ASSIGNs
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 30 Aug 2010 16:40:27 +0200 (CEST)
- Subject: [PATCH] Force predicates into separate GIMPLE_ASSIGNs
This is a more complete patch to transition GIMPLE to require
gimple vals for GIMPLE_COND and COND_EXPR predicates. That
unifies code-paths in several optimization passes and makes
the value-numberer able to track the predicate computations
(and PRE to mark jump-threading opportunities by PHI node
insertion for partially redundant predicates ...).
There is still a lot of fallout, mostly in poorly maintained
passes which accumulated a lot of hacks (autopar - ick).
Also some passes do not like separating predicates too much
(like the vectorizer, which can't vectorize pred = A CMP B, sth
that needs some re-org).
The patch bootstraps on x86_64-unknown-linux-gnu if you disable
-Werror (there is one uninitialized variable warning in ira-color.c),
testing shows issues with autopar (ICEs) and the vectorizer mostly.
I'm not sure what to do about this at this point, given that
stage1 is nearing its end and I still have some MEM_REF-related
IL changes pending. So this will probably be postponed for 4.7
(and eventually split up to tackle the simpler COND_EXPR part
separately).
Richard.
2010-08-30 Richard Guenther <rguenther@suse.de>
* gimplify.c (gimplify_pure_cond_expr): Require is_gimple_val
for the predicate.
(gimplify_cond_expr): Likewise.
...
Index: trunk/gcc/cfgloopmanip.c
===================================================================
*** trunk.orig/gcc/cfgloopmanip.c 2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/cfgloopmanip.c 2010-08-30 14:32:23.000000000 +0200
*************** create_empty_if_region_on_edge (edge ent
*** 547,553 ****
simple_cond =
force_gimple_operand_gsi (&gsi, condition, true, NULL,
false, GSI_NEW_STMT);
! cond_stmt = gimple_build_cond_from_tree (simple_cond, NULL_TREE, NULL_TREE);
gsi = gsi_last_bb (cond_bb);
gsi_insert_after (&gsi, cond_stmt, GSI_NEW_STMT);
--- 547,553 ----
simple_cond =
force_gimple_operand_gsi (&gsi, condition, true, NULL,
false, GSI_NEW_STMT);
! cond_stmt = gimple_build_cond (simple_cond, NULL_TREE, NULL_TREE);
gsi = gsi_last_bb (cond_bb);
gsi_insert_after (&gsi, cond_stmt, GSI_NEW_STMT);
*************** create_empty_loop_on_edge (edge entry_ed
*** 681,693 ****
iv_before, iv_after);
/* Insert loop exit condition. */
! cond_expr = gimple_build_cond
! (LT_EXPR, *iv_before, upper_bound, NULL_TREE, NULL_TREE);
!
! exit_test = gimple_cond_lhs (cond_expr);
exit_test = force_gimple_operand_gsi (&gsi, exit_test, true, NULL,
false, GSI_NEW_STMT);
! gimple_cond_set_lhs (cond_expr, exit_test);
gsi = gsi_last_bb (exit_e->src);
gsi_insert_after (&gsi, cond_expr, GSI_NEW_STMT);
--- 681,691 ----
iv_before, iv_after);
/* Insert loop exit condition. */
! exit_test = fold_build2 (LT_EXPR, boolean_type_node, *iv_before, upper_bound);
exit_test = force_gimple_operand_gsi (&gsi, exit_test, true, NULL,
false, GSI_NEW_STMT);
! cond_expr = gimple_build_cond (exit_test, NULL_TREE, NULL_TREE);
!
gsi = gsi_last_bb (exit_e->src);
gsi_insert_after (&gsi, cond_expr, GSI_NEW_STMT);
Index: trunk/gcc/gimple.c
===================================================================
*** trunk.orig/gcc/gimple.c 2010-08-25 14:47:45.000000000 +0200
--- trunk/gcc/gimple.c 2010-08-30 15:11:34.000000000 +0200
*************** gimplify_assign (tree dst, tree src, gim
*** 417,499 ****
/* Build a GIMPLE_COND statement.
! PRED is the condition used to compare LHS and the RHS.
T_LABEL is the label to jump to if the condition is true.
F_LABEL is the label to jump to otherwise. */
gimple
! gimple_build_cond (enum tree_code pred_code, tree lhs, tree rhs,
! tree t_label, tree f_label)
{
gimple p;
! gcc_assert (TREE_CODE_CLASS (pred_code) == tcc_comparison);
! p = gimple_build_with_ops (GIMPLE_COND, pred_code, 4);
! gimple_cond_set_lhs (p, lhs);
! gimple_cond_set_rhs (p, rhs);
gimple_cond_set_true_label (p, t_label);
gimple_cond_set_false_label (p, f_label);
return p;
}
!
! /* Extract operands for a GIMPLE_COND statement out of COND_EXPR tree COND. */
void
! gimple_cond_get_ops_from_tree (tree cond, enum tree_code *code_p,
! tree *lhs_p, tree *rhs_p)
{
! location_t loc = EXPR_LOCATION (cond);
! gcc_assert (TREE_CODE_CLASS (TREE_CODE (cond)) == tcc_comparison
! || TREE_CODE (cond) == TRUTH_NOT_EXPR
! || is_gimple_min_invariant (cond)
! || SSA_VAR_P (cond));
!
! extract_ops_from_tree (cond, code_p, lhs_p, rhs_p);
!
! /* Canonicalize conditionals of the form 'if (!VAL)'. */
! if (*code_p == TRUTH_NOT_EXPR)
! {
! *code_p = EQ_EXPR;
! gcc_assert (*lhs_p && *rhs_p == NULL_TREE);
! *rhs_p = fold_convert_loc (loc, TREE_TYPE (*lhs_p), integer_zero_node);
! }
! /* Canonicalize conditionals of the form 'if (VAL)' */
! else if (TREE_CODE_CLASS (*code_p) != tcc_comparison)
{
! *code_p = NE_EXPR;
! gcc_assert (*lhs_p && *rhs_p == NULL_TREE);
! *rhs_p = fold_convert_loc (loc, TREE_TYPE (*lhs_p), integer_zero_node);
}
}
! /* Build a GIMPLE_COND statement from the conditional expression tree
! COND. T_LABEL and F_LABEL are as in gimple_build_cond. */
! gimple
! gimple_build_cond_from_tree (tree cond, tree t_label, tree f_label)
{
enum tree_code code;
tree lhs, rhs;
!
! gimple_cond_get_ops_from_tree (cond, &code, &lhs, &rhs);
! return gimple_build_cond (code, lhs, rhs, t_label, f_label);
}
! /* Set code, lhs, and rhs of a GIMPLE_COND from a suitable
! boolean expression tree COND. */
void
! gimple_cond_set_condition_from_tree (gimple stmt, tree cond)
{
! enum tree_code code;
! tree lhs, rhs;
!
! gimple_cond_get_ops_from_tree (cond, &code, &lhs, &rhs);
! gimple_cond_set_condition (stmt, code, lhs, rhs);
}
/* Build a GIMPLE_LABEL statement for LABEL. */
gimple
--- 417,550 ----
/* Build a GIMPLE_COND statement.
! PRED is the boolean predicate.
T_LABEL is the label to jump to if the condition is true.
F_LABEL is the label to jump to otherwise. */
gimple
! gimple_build_cond (tree pred, tree t_label, tree f_label)
{
gimple p;
! gcc_assert (is_gimple_val (pred));
! p = gimple_build_with_ops (GIMPLE_COND, ERROR_MARK, 3);
! gimple_cond_set_pred (p, pred);
gimple_cond_set_true_label (p, t_label);
gimple_cond_set_false_label (p, f_label);
return p;
}
! /* From a SSA name predicate PRED extract a comparison
! *LHS *CODE *RHS that defines it. */
void
! gimple_pred_extract_comparison (tree pred, enum tree_code *code,
! tree *lhs, tree *rhs)
{
! restart:
! if (TREE_CODE (pred) == SSA_NAME)
{
! gimple def_stmt = SSA_NAME_DEF_STMT (pred);
! if (is_gimple_assign (def_stmt))
! {
! enum tree_code def_code = gimple_assign_rhs_code (def_stmt);
! if (def_code == SSA_NAME)
! {
! pred = gimple_assign_rhs1 (def_stmt);
! goto restart;
! }
! else if (def_code == TRUTH_NOT_EXPR)
! {
! *code = EQ_EXPR;
! *lhs = gimple_assign_rhs1 (def_stmt);
! *rhs = boolean_false_node;
! return;
! }
! else if (TREE_CODE_CLASS (def_code) == tcc_comparison)
! {
! *code = def_code;
! *lhs = gimple_assign_rhs1 (def_stmt);
! *rhs = gimple_assign_rhs2 (def_stmt);
! return;
! }
! else if (CONVERT_EXPR_CODE_P (def_code))
! {
! *code = NE_EXPR;
! *lhs = gimple_assign_rhs1 (def_stmt);
! *rhs = build_int_cst (TREE_TYPE (*lhs), 0);
! return;
! }
! }
}
+
+ *code = NE_EXPR;
+ *lhs = pred;
+ *rhs = boolean_false_node;
}
+ /* From the gimple conditional statement COND extract a comparison
+ *LHS *CODE *RHS that defines its predicate. */
! void
! gimple_cond_extract_comparison (gimple cond, enum tree_code *code,
! tree *lhs, tree *rhs)
! {
! gimple_pred_extract_comparison (gimple_cond_pred (cond), code, lhs, rhs);
! }
! /* From the gimple conditional statement COND extract a comparison
! that defines its predicate and return it as a tree. */
!
! tree
! gimple_cond_to_tree (gimple cond)
{
enum tree_code code;
tree lhs, rhs;
! gimple_cond_extract_comparison (cond, &code, &lhs, &rhs);
! return fold_build2_loc (gimple_location (cond),
! code, boolean_type_node, lhs, rhs);
}
! /* Update the gimple conditional statement at GSI to use the
! predicate computed by the comparison LHS CODE RHS. */
void
! gimple_update_cond_from_comparison (gimple_stmt_iterator gsi,
! enum tree_code code, tree lhs, tree rhs)
{
! gimple cond = gsi_stmt (gsi);
! tree pred = gimple_cond_pred (cond);
! gimple pred_stmt;
! if (TREE_CODE (pred) == SSA_NAME
! && has_single_use (pred))
! {
! gimple def_stmt = SSA_NAME_DEF_STMT (pred);
! if (is_gimple_assign (def_stmt)
! && (TREE_CODE_CLASS (gimple_assign_rhs_code (def_stmt))
! == tcc_comparison))
! {
! gimple_assign_set_rhs_code (def_stmt, code);
! gimple_assign_set_rhs1 (def_stmt, lhs);
! gimple_assign_set_rhs2 (def_stmt, rhs);
! return;
! }
! /* Else at least re-use the SSA name. */
! }
! else
! {
! if (TREE_CODE (pred) == SSA_NAME)
! pred = SSA_NAME_VAR (pred);
! else
! pred = create_tmp_reg (boolean_type_node, NULL);
! if (gimple_in_ssa_p (cfun))
! pred = make_ssa_name (pred, NULL);
! }
! pred_stmt = gimple_build_assign_with_ops (code, pred, lhs, rhs);
! gsi_insert_before (&gsi, pred_stmt, GSI_SAME_STMT);
! gimple_cond_set_pred (cond, pred);
}
+
/* Build a GIMPLE_LABEL statement for LABEL. */
gimple
*************** is_gimple_lvalue (tree t)
*** 2590,2595 ****
--- 2641,2648 ----
bool
is_gimple_condexpr (tree t)
{
+ /* ??? This is not the predicate for use of conditionals in valid
+ gimple statements - but it is used in all sort of code. */
return (is_gimple_val (t) || (COMPARISON_CLASS_P (t)
&& !tree_could_trap_p (t)
&& is_gimple_val (TREE_OPERAND (t, 0))
Index: trunk/gcc/gimple.h
===================================================================
*** trunk.orig/gcc/gimple.h 2010-08-25 11:22:16.000000000 +0200
--- trunk/gcc/gimple.h 2010-08-30 15:11:53.000000000 +0200
*************** gimple gimple_build_call_vec (tree, VEC(
*** 821,827 ****
gimple gimple_build_call (tree, unsigned, ...);
gimple gimple_build_call_from_tree (tree);
gimple gimplify_assign (tree, tree, gimple_seq *);
! gimple gimple_build_cond (enum tree_code, tree, tree, tree, tree);
gimple gimple_build_label (tree label);
gimple gimple_build_goto (tree dest);
gimple gimple_build_nop (void);
--- 821,832 ----
gimple gimple_build_call (tree, unsigned, ...);
gimple gimple_build_call_from_tree (tree);
gimple gimplify_assign (tree, tree, gimple_seq *);
! gimple gimple_build_cond (tree, tree, tree);
! void gimple_pred_extract_comparison (tree, enum tree_code *, tree *, tree *);
! void gimple_cond_extract_comparison (gimple, enum tree_code *, tree *, tree *);
! tree gimple_cond_to_tree (gimple);
! void gimple_update_cond_from_comparison (gimple_stmt_iterator, enum tree_code,
! tree, tree);
gimple gimple_build_label (tree label);
gimple gimple_build_goto (tree dest);
gimple gimple_build_nop (void);
*************** void gimple_set_lhs (gimple, tree);
*** 880,888 ****
void gimple_replace_lhs (gimple, tree);
gimple gimple_copy (gimple);
void gimple_set_modified (gimple, bool);
- void gimple_cond_get_ops_from_tree (tree, enum tree_code *, tree *, tree *);
- gimple gimple_build_cond_from_tree (tree, tree, tree);
- void gimple_cond_set_condition_from_tree (gimple, tree);
bool gimple_has_side_effects (const_gimple);
bool gimple_rhs_has_side_effects (const_gimple);
bool gimple_could_trap_p (gimple);
--- 885,890 ----
*************** gimple_has_lhs (gimple stmt)
*** 2347,2441 ****
}
! /* Return the code of the predicate computed by conditional statement GS. */
!
! static inline enum tree_code
! gimple_cond_code (const_gimple gs)
! {
! GIMPLE_CHECK (gs, GIMPLE_COND);
! return (enum tree_code) gs->gsbase.subcode;
! }
!
!
! /* Set CODE to be the predicate code for the conditional statement GS. */
!
! static inline void
! gimple_cond_set_code (gimple gs, enum tree_code code)
! {
! GIMPLE_CHECK (gs, GIMPLE_COND);
! gs->gsbase.subcode = code;
! }
!
!
! /* Return the LHS of the predicate computed by conditional statement GS. */
static inline tree
! gimple_cond_lhs (const_gimple gs)
{
GIMPLE_CHECK (gs, GIMPLE_COND);
return gimple_op (gs, 0);
}
! /* Return the pointer to the LHS of the predicate computed by conditional
! statement GS. */
static inline tree *
! gimple_cond_lhs_ptr (const_gimple gs)
{
GIMPLE_CHECK (gs, GIMPLE_COND);
return gimple_op_ptr (gs, 0);
}
! /* Set LHS to be the LHS operand of the predicate computed by
! conditional statement GS. */
static inline void
! gimple_cond_set_lhs (gimple gs, tree lhs)
{
GIMPLE_CHECK (gs, GIMPLE_COND);
! gimple_set_op (gs, 0, lhs);
}
! /* Return the RHS operand of the predicate computed by conditional GS. */
static inline tree
! gimple_cond_rhs (const_gimple gs)
{
GIMPLE_CHECK (gs, GIMPLE_COND);
return gimple_op (gs, 1);
}
- /* Return the pointer to the RHS operand of the predicate computed by
- conditional GS. */
-
- static inline tree *
- gimple_cond_rhs_ptr (const_gimple gs)
- {
- GIMPLE_CHECK (gs, GIMPLE_COND);
- return gimple_op_ptr (gs, 1);
- }
-
-
- /* Set RHS to be the RHS operand of the predicate computed by
- conditional statement GS. */
! static inline void
! gimple_cond_set_rhs (gimple gs, tree rhs)
! {
! GIMPLE_CHECK (gs, GIMPLE_COND);
! gimple_set_op (gs, 1, rhs);
! }
!
!
! /* Return the label used by conditional statement GS when its
predicate evaluates to true. */
! static inline tree
! gimple_cond_true_label (const_gimple gs)
{
GIMPLE_CHECK (gs, GIMPLE_COND);
! return gimple_op (gs, 2);
}
--- 2349,2401 ----
}
! /* Return the predicate used by conditional statement GS. */
static inline tree
! gimple_cond_pred (const_gimple gs)
{
GIMPLE_CHECK (gs, GIMPLE_COND);
return gimple_op (gs, 0);
}
! /* Return the pointer to the predicate used by conditional statement GS. */
static inline tree *
! gimple_cond_pred_ptr (const_gimple gs)
{
GIMPLE_CHECK (gs, GIMPLE_COND);
return gimple_op_ptr (gs, 0);
}
! /* Set the predicate of the conditional statement GS to PRED. */
static inline void
! gimple_cond_set_pred (gimple gs, tree pred)
{
GIMPLE_CHECK (gs, GIMPLE_COND);
! gimple_set_op (gs, 0, pred);
}
! /* Return the label used by conditional statement GS when its
! predicate evaluates to true. */
static inline tree
! gimple_cond_true_label (const_gimple gs)
{
GIMPLE_CHECK (gs, GIMPLE_COND);
return gimple_op (gs, 1);
}
! /* Return a pointer to the label used by conditional statement GS when its
predicate evaluates to true. */
! static inline tree *
! gimple_cond_true_label_ptr (const_gimple gs)
{
GIMPLE_CHECK (gs, GIMPLE_COND);
! return gimple_op_ptr (gs, 1);
}
*************** static inline void
*** 2446,2452 ****
gimple_cond_set_true_label (gimple gs, tree label)
{
GIMPLE_CHECK (gs, GIMPLE_COND);
! gimple_set_op (gs, 2, label);
}
--- 2406,2412 ----
gimple_cond_set_true_label (gimple gs, tree label)
{
GIMPLE_CHECK (gs, GIMPLE_COND);
! gimple_set_op (gs, 1, label);
}
*************** static inline void
*** 2457,2463 ****
gimple_cond_set_false_label (gimple gs, tree label)
{
GIMPLE_CHECK (gs, GIMPLE_COND);
! gimple_set_op (gs, 3, label);
}
--- 2417,2423 ----
gimple_cond_set_false_label (gimple gs, tree label)
{
GIMPLE_CHECK (gs, GIMPLE_COND);
! gimple_set_op (gs, 2, label);
}
*************** static inline tree
*** 2468,2474 ****
gimple_cond_false_label (const_gimple gs)
{
GIMPLE_CHECK (gs, GIMPLE_COND);
! return gimple_op (gs, 3);
}
--- 2428,2445 ----
gimple_cond_false_label (const_gimple gs)
{
GIMPLE_CHECK (gs, GIMPLE_COND);
! return gimple_op (gs, 2);
! }
!
!
! /* Return a pointer to the label used by conditional statement GS when its
! predicate evaluates to false. */
!
! static inline tree *
! gimple_cond_false_label_ptr (const_gimple gs)
! {
! GIMPLE_CHECK (gs, GIMPLE_COND);
! return gimple_op_ptr (gs, 2);
}
*************** gimple_cond_false_label (const_gimple gs
*** 2477,2485 ****
static inline void
gimple_cond_make_false (gimple gs)
{
! gimple_cond_set_lhs (gs, boolean_true_node);
! gimple_cond_set_rhs (gs, boolean_false_node);
! gs->gsbase.subcode = EQ_EXPR;
}
--- 2448,2454 ----
static inline void
gimple_cond_make_false (gimple gs)
{
! gimple_cond_set_pred (gs, boolean_false_node);
}
*************** gimple_cond_make_false (gimple gs)
*** 2488,2496 ****
static inline void
gimple_cond_make_true (gimple gs)
{
! gimple_cond_set_lhs (gs, boolean_true_node);
! gimple_cond_set_rhs (gs, boolean_true_node);
! gs->gsbase.subcode = EQ_EXPR;
}
/* Check if conditional statemente GS is of the form 'if (1 == 1)',
--- 2457,2463 ----
static inline void
gimple_cond_make_true (gimple gs)
{
! gimple_cond_set_pred (gs, boolean_true_node);
}
/* Check if conditional statemente GS is of the form 'if (1 == 1)',
*************** gimple_cond_make_true (gimple gs)
*** 2499,2521 ****
static inline bool
gimple_cond_true_p (const_gimple gs)
{
! tree lhs = gimple_cond_lhs (gs);
! tree rhs = gimple_cond_rhs (gs);
! enum tree_code code = gimple_cond_code (gs);
!
! if (lhs != boolean_true_node && lhs != boolean_false_node)
! return false;
!
! if (rhs != boolean_true_node && rhs != boolean_false_node)
! return false;
!
! if (code == NE_EXPR && lhs != rhs)
! return true;
!
! if (code == EQ_EXPR && lhs == rhs)
! return true;
!
! return false;
}
/* Check if conditional statement GS is of the form 'if (1 != 1)',
--- 2466,2472 ----
static inline bool
gimple_cond_true_p (const_gimple gs)
{
! return integer_nonzerop (gimple_cond_pred (gs));
}
/* Check if conditional statement GS is of the form 'if (1 != 1)',
*************** gimple_cond_true_p (const_gimple gs)
*** 2524,2573 ****
static inline bool
gimple_cond_false_p (const_gimple gs)
{
! tree lhs = gimple_cond_lhs (gs);
! tree rhs = gimple_cond_rhs (gs);
! enum tree_code code = gimple_cond_code (gs);
!
! if (lhs != boolean_true_node && lhs != boolean_false_node)
! return false;
!
! if (rhs != boolean_true_node && rhs != boolean_false_node)
! return false;
!
! if (code == NE_EXPR && lhs == rhs)
! return true;
!
! if (code == EQ_EXPR && lhs != rhs)
! return true;
!
! return false;
! }
!
! /* Check if conditional statement GS is of the form 'if (var != 0)' or
! 'if (var == 1)' */
!
! static inline bool
! gimple_cond_single_var_p (gimple gs)
! {
! if (gimple_cond_code (gs) == NE_EXPR
! && gimple_cond_rhs (gs) == boolean_false_node)
! return true;
!
! if (gimple_cond_code (gs) == EQ_EXPR
! && gimple_cond_rhs (gs) == boolean_true_node)
! return true;
!
! return false;
! }
!
! /* Set the code, LHS and RHS of GIMPLE_COND STMT from CODE, LHS and RHS. */
!
! static inline void
! gimple_cond_set_condition (gimple stmt, enum tree_code code, tree lhs, tree rhs)
! {
! gimple_cond_set_code (stmt, code);
! gimple_cond_set_lhs (stmt, lhs);
! gimple_cond_set_rhs (stmt, rhs);
}
/* Return the LABEL_DECL node used by GIMPLE_LABEL statement GS. */
--- 2475,2481 ----
static inline bool
gimple_cond_false_p (const_gimple gs)
{
! return integer_zerop (gimple_cond_pred (gs));
}
/* Return the LABEL_DECL node used by GIMPLE_LABEL statement GS. */
Index: trunk/gcc/gimplify.c
===================================================================
*** trunk.orig/gcc/gimplify.c 2010-08-25 16:49:48.000000000 +0200
--- trunk/gcc/gimplify.c 2010-08-30 14:32:23.000000000 +0200
*************** gimplify_pure_cond_expr (tree *expr_p, g
*** 2859,2865 ****
TREE_SET_CODE (cond, TRUTH_AND_EXPR);
else if (code == TRUTH_ORIF_EXPR)
TREE_SET_CODE (cond, TRUTH_OR_EXPR);
! ret = gimplify_expr (&cond, pre_p, NULL, is_gimple_condexpr, fb_rvalue);
COND_EXPR_COND (*expr_p) = cond;
tret = gimplify_expr (&COND_EXPR_THEN (expr), pre_p, NULL,
--- 2859,2865 ----
TREE_SET_CODE (cond, TRUTH_AND_EXPR);
else if (code == TRUTH_ORIF_EXPR)
TREE_SET_CODE (cond, TRUTH_OR_EXPR);
! ret = gimplify_expr (&cond, pre_p, NULL, is_gimple_val, fb_rvalue);
COND_EXPR_COND (*expr_p) = cond;
tret = gimplify_expr (&COND_EXPR_THEN (expr), pre_p, NULL,
*************** gimplify_cond_expr (tree *expr_p, gimple
*** 2914,2925 ****
tree expr = *expr_p;
tree type = TREE_TYPE (expr);
location_t loc = EXPR_LOCATION (expr);
! tree tmp, arm1, arm2;
enum gimplify_status ret;
tree label_true, label_false, label_cont;
bool have_then_clause_p, have_else_clause_p;
gimple gimple_cond;
- enum tree_code pred_code;
gimple_seq seq = NULL;
/* If this COND_EXPR has a value, copy the values into a temporary within
--- 2914,2924 ----
tree expr = *expr_p;
tree type = TREE_TYPE (expr);
location_t loc = EXPR_LOCATION (expr);
! tree tmp;
enum gimplify_status ret;
tree label_true, label_false, label_cont;
bool have_then_clause_p, have_else_clause_p;
gimple gimple_cond;
gimple_seq seq = NULL;
/* If this COND_EXPR has a value, copy the values into a temporary within
*************** gimplify_cond_expr (tree *expr_p, gimple
*** 3013,3019 ****
/* Now do the normal gimplification. */
/* Gimplify condition. */
! ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, NULL, is_gimple_condexpr,
fb_rvalue);
if (ret == GS_ERROR)
return GS_ERROR;
--- 3012,3018 ----
/* Now do the normal gimplification. */
/* Gimplify condition. */
! ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, NULL, is_gimple_val,
fb_rvalue);
if (ret == GS_ERROR)
return GS_ERROR;
*************** gimplify_cond_expr (tree *expr_p, gimple
*** 3059,3068 ****
else
label_false = create_artificial_label (UNKNOWN_LOCATION);
! gimple_cond_get_ops_from_tree (COND_EXPR_COND (expr), &pred_code, &arm1,
! &arm2);
!
! gimple_cond = gimple_build_cond (pred_code, arm1, arm2, label_true,
label_false);
gimplify_seq_add_stmt (&seq, gimple_cond);
--- 3058,3064 ----
else
label_false = create_artificial_label (UNKNOWN_LOCATION);
! gimple_cond = gimple_build_cond (COND_EXPR_COND (expr), label_true,
label_false);
gimplify_seq_add_stmt (&seq, gimple_cond);
*************** gimplify_init_ctor_eval_range (tree obje
*** 3427,3434 ****
gimplify_seq_add_stmt (pre_p, gimple_build_assign (cref, value));
/* We exit the loop when the index var is equal to the upper bound. */
gimplify_seq_add_stmt (pre_p,
! gimple_build_cond (EQ_EXPR, var, upper,
loop_exit_label, fall_thru_label));
gimplify_seq_add_stmt (pre_p, gimple_build_label (fall_thru_label));
--- 3423,3433 ----
gimplify_seq_add_stmt (pre_p, gimple_build_assign (cref, value));
/* We exit the loop when the index var is equal to the upper bound. */
+ tmp = get_initialized_tmp_var (fold_build2 (EQ_EXPR,
+ boolean_type_node,
+ var, upper), pre_p, NULL);
gimplify_seq_add_stmt (pre_p,
! gimple_build_cond (tmp,
loop_exit_label, fall_thru_label));
gimplify_seq_add_stmt (pre_p, gimple_build_label (fall_thru_label));
*************** gimplify_expr (tree *expr_p, gimple_seq
*** 6565,6571 ****
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
--- 6564,6569 ----
*************** gimple_regimplify_operands (gimple stmt,
*** 7831,7839 ****
switch (gimple_code (stmt))
{
case GIMPLE_COND:
! gimplify_expr (gimple_cond_lhs_ptr (stmt), &pre, NULL,
! is_gimple_val, fb_rvalue);
! gimplify_expr (gimple_cond_rhs_ptr (stmt), &pre, NULL,
is_gimple_val, fb_rvalue);
break;
case GIMPLE_SWITCH:
--- 7829,7835 ----
switch (gimple_code (stmt))
{
case GIMPLE_COND:
! gimplify_expr (gimple_cond_pred_ptr (stmt), &pre, NULL,
is_gimple_val, fb_rvalue);
break;
case GIMPLE_SWITCH:
Index: trunk/gcc/lambda-code.c
===================================================================
*** trunk.orig/gcc/lambda-code.c 2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/lambda-code.c 2010-08-30 14:32:23.000000000 +0200
*************** gcc_loop_to_lambda_loop (struct loop *lo
*** 1262,1267 ****
--- 1262,1268 ----
int stepint;
int extra = 0;
tree lboundvar, uboundvar, uboundresult;
+ enum tree_code test_code;
/* Find out induction var and exit condition. */
inductionvar = find_induction_var_from_exit_cond (loop);
*************** gcc_loop_to_lambda_loop (struct loop *lo
*** 1392,1399 ****
}
/* One part of the test may be a loop invariant tree. */
VEC_reserve (tree, heap, *invariants, 1);
! test_lhs = gimple_cond_lhs (exit_cond);
! test_rhs = gimple_cond_rhs (exit_cond);
if (TREE_CODE (test_rhs) == SSA_NAME
&& invariant_in_loop_and_outer_loops (loop, test_rhs))
--- 1393,1399 ----
}
/* One part of the test may be a loop invariant tree. */
VEC_reserve (tree, heap, *invariants, 1);
! gimple_cond_extract_comparison (exit_cond, &test_code, &test_lhs, &test_rhs);
if (TREE_CODE (test_rhs) == SSA_NAME
&& invariant_in_loop_and_outer_loops (loop, test_rhs))
*************** gcc_loop_to_lambda_loop (struct loop *lo
*** 1417,1429 ****
/* We might have some leftover. */
! if (gimple_cond_code (exit_cond) == LT_EXPR)
extra = -1 * stepint;
! else if (gimple_cond_code (exit_cond) == NE_EXPR)
extra = -1 * stepint;
! else if (gimple_cond_code (exit_cond) == GT_EXPR)
extra = -1 * stepint;
! else if (gimple_cond_code (exit_cond) == EQ_EXPR)
extra = 1 * stepint;
ubound = gcc_tree_to_linear_expression (depth, uboundvar,
--- 1417,1429 ----
/* We might have some leftover. */
! if (test_code == LT_EXPR)
extra = -1 * stepint;
! else if (test_code == NE_EXPR)
extra = -1 * stepint;
! else if (test_code == GT_EXPR)
extra = -1 * stepint;
! else if (test_code == EQ_EXPR)
extra = 1 * stepint;
ubound = gcc_tree_to_linear_expression (depth, uboundvar,
*************** find_induction_var_from_exit_cond (struc
*** 1458,1469 ****
gimple expr = get_loop_exit_condition (loop);
tree ivarop;
tree test_lhs, test_rhs;
if (expr == NULL)
return NULL_TREE;
if (gimple_code (expr) != GIMPLE_COND)
return NULL_TREE;
! test_lhs = gimple_cond_lhs (expr);
! test_rhs = gimple_cond_rhs (expr);
/* Find the side that is invariant in this loop. The ivar must be the other
side. */
--- 1458,1469 ----
gimple expr = get_loop_exit_condition (loop);
tree ivarop;
tree test_lhs, test_rhs;
+ enum tree_code test_code;
if (expr == NULL)
return NULL_TREE;
if (gimple_code (expr) != GIMPLE_COND)
return NULL_TREE;
! gimple_cond_extract_comparison (expr, &test_code, &test_lhs, &test_rhs);
/* Find the side that is invariant in this loop. The ivar must be the other
side. */
*************** lambda_loopnest_to_gcc_loopnest (struct
*** 1826,1832 ****
if (exit->flags & EDGE_FALSE_VALUE)
testtype = swap_tree_comparison (testtype);
! gimple_cond_set_condition (exitcond, testtype, newupperbound, ivvarinced);
update_stmt (exitcond);
VEC_replace (tree, new_ivs, i, ivvar);
--- 1826,1833 ----
if (exit->flags & EDGE_FALSE_VALUE)
testtype = swap_tree_comparison (testtype);
! gimple_update_cond_from_comparison (gsi_for_stmt (exitcond), testtype,
! newupperbound, ivvarinced);
update_stmt (exitcond);
VEC_replace (tree, new_ivs, i, ivvar);
*************** perfect_nest_p (struct loop *loop)
*** 2018,2023 ****
--- 2019,2026 ----
for (bsi = gsi_start_bb (bbs[i]); !gsi_end_p (bsi); gsi_next (&bsi))
{
gimple stmt = gsi_stmt (bsi);
+ use_operand_p use;
+ gimple use_stmt;
if (gimple_code (stmt) == GIMPLE_COND
&& exit_cond != stmt)
*************** perfect_nest_p (struct loop *loop)
*** 2028,2033 ****
--- 2031,2043 ----
|| stmt_is_bumper_for_loop (loop, stmt))
continue;
+ if (is_gimple_assign (stmt)
+ && TREE_CODE (gimple_assign_lhs (stmt)) == SSA_NAME
+ && single_imm_use (gimple_assign_lhs (stmt),
+ &use, &use_stmt)
+ && use_stmt == exit_cond)
+ continue;
+
non_perfectly_nested:
free (bbs);
return false;
*************** perfect_nestify (struct loop *loop,
*** 2469,2476 ****
bodybb = create_empty_bb (EXIT_BLOCK_PTR->prev_bb);
latchbb = create_empty_bb (EXIT_BLOCK_PTR->prev_bb);
make_edge (headerbb, bodybb, EDGE_FALLTHRU);
! cond_stmt = gimple_build_cond (NE_EXPR, integer_one_node, integer_zero_node,
! NULL_TREE, NULL_TREE);
bsi = gsi_start_bb (bodybb);
gsi_insert_after (&bsi, cond_stmt, GSI_NEW_STMT);
e = make_edge (bodybb, olddest, EDGE_FALSE_VALUE);
--- 2479,2485 ----
bodybb = create_empty_bb (EXIT_BLOCK_PTR->prev_bb);
latchbb = create_empty_bb (EXIT_BLOCK_PTR->prev_bb);
make_edge (headerbb, bodybb, EDGE_FALLTHRU);
! cond_stmt = gimple_build_cond (boolean_false_node, NULL_TREE, NULL_TREE);
bsi = gsi_start_bb (bodybb);
gsi_insert_after (&bsi, cond_stmt, GSI_NEW_STMT);
e = make_edge (bodybb, olddest, EDGE_FALSE_VALUE);
*************** perfect_nestify (struct loop *loop,
*** 2516,2522 ****
else
gsi_insert_before (&bsi, stmt, GSI_SAME_STMT);
update_stmt (stmt);
! gimple_cond_set_condition (exit_condition, GE_EXPR, uboundvar, ivvarinced);
update_stmt (exit_condition);
replacements = htab_create_ggc (20, tree_map_hash,
tree_map_eq, NULL);
--- 2525,2532 ----
else
gsi_insert_before (&bsi, stmt, GSI_SAME_STMT);
update_stmt (stmt);
! gimple_update_cond_from_comparison (gsi_for_stmt (exit_condition),
! GE_EXPR, uboundvar, ivvarinced);
update_stmt (exit_condition);
replacements = htab_create_ggc (20, tree_map_hash,
tree_map_eq, NULL);
Index: trunk/gcc/omp-low.c
===================================================================
*** trunk.orig/gcc/omp-low.c 2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/omp-low.c 2010-08-30 14:32:23.000000000 +0200
*************** lower_lastprivate_clauses (tree clauses,
*** 2543,2558 ****
if (predicate)
{
gimple stmt;
! tree label_true, arm1, arm2;
label = create_artificial_label (UNKNOWN_LOCATION);
label_true = create_artificial_label (UNKNOWN_LOCATION);
! arm1 = TREE_OPERAND (predicate, 0);
! arm2 = TREE_OPERAND (predicate, 1);
! gimplify_expr (&arm1, stmt_list, NULL, is_gimple_val, fb_rvalue);
! gimplify_expr (&arm2, stmt_list, NULL, is_gimple_val, fb_rvalue);
! stmt = gimple_build_cond (TREE_CODE (predicate), arm1, arm2,
! label_true, label);
gimple_seq_add_stmt (stmt_list, stmt);
gimple_seq_add_stmt (stmt_list, gimple_build_label (label_true));
}
--- 2543,2554 ----
if (predicate)
{
gimple stmt;
! tree label_true;
label = create_artificial_label (UNKNOWN_LOCATION);
label_true = create_artificial_label (UNKNOWN_LOCATION);
! gimplify_expr (&predicate, stmt_list, NULL, is_gimple_val, fb_rvalue);
! stmt = gimple_build_cond (predicate, label_true, label);
gimple_seq_add_stmt (stmt_list, stmt);
gimple_seq_add_stmt (stmt_list, gimple_build_label (label_true));
}
*************** lower_send_shared_vars (gimple_seq *ilis
*** 2893,2903 ****
static gimple
gimple_build_cond_empty (tree cond)
{
! enum tree_code pred_code;
! tree lhs, rhs;
!
! gimple_cond_get_ops_from_tree (cond, &pred_code, &lhs, &rhs);
! return gimple_build_cond (pred_code, lhs, rhs, NULL_TREE, NULL_TREE);
}
--- 2889,2895 ----
static gimple
gimple_build_cond_empty (tree cond)
{
! return gimple_build_cond (cond, NULL_TREE, NULL_TREE);
}
*************** expand_omp_for_generic (struct omp_regio
*** 3867,3874 ****
if (TREE_TYPE (t) != boolean_type_node)
t = fold_build2 (NE_EXPR, boolean_type_node,
t, build_int_cst (TREE_TYPE (t), 0));
! t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
! true, GSI_SAME_STMT);
gsi_insert_after (&gsi, gimple_build_cond_empty (t), GSI_SAME_STMT);
/* Remove the GIMPLE_OMP_FOR statement. */
--- 3859,3865 ----
if (TREE_TYPE (t) != boolean_type_node)
t = fold_build2 (NE_EXPR, boolean_type_node,
t, build_int_cst (TREE_TYPE (t), 0));
! t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, true, GSI_SAME_STMT);
gsi_insert_after (&gsi, gimple_build_cond_empty (t), GSI_SAME_STMT);
/* Remove the GIMPLE_OMP_FOR statement. */
*************** expand_omp_for_generic (struct omp_regio
*** 3953,3959 ****
stmt = gimple_build_assign (vback, t);
gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
! t = build2 (fd->loop.cond_code, boolean_type_node, vback, iend);
stmt = gimple_build_cond_empty (t);
gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
--- 3944,3953 ----
stmt = gimple_build_assign (vback, t);
gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
! t = force_gimple_operand_gsi (&gsi, build2 (fd->loop.cond_code,
! boolean_type_node, vback,
! iend), true, NULL_TREE,
! true, GSI_SAME_STMT);
stmt = gimple_build_cond_empty (t);
gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
*************** expand_omp_for_generic (struct omp_regio
*** 4005,4012 ****
t = fd->loops[i].n2;
t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
false, GSI_CONTINUE_LINKING);
! t = fold_build2 (fd->loops[i].cond_code, boolean_type_node,
! fd->loops[i].v, t);
stmt = gimple_build_cond_empty (t);
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
e = make_edge (bb, l1_bb, EDGE_TRUE_VALUE);
--- 3999,4009 ----
t = fd->loops[i].n2;
t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
false, GSI_CONTINUE_LINKING);
! t = force_gimple_operand_gsi
! (&gsi, fold_build2 (fd->loops[i].cond_code,
! boolean_type_node,
! fd->loops[i].v, t), true,
! NULL_TREE, false, GSI_CONTINUE_LINKING);
stmt = gimple_build_cond_empty (t);
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
e = make_edge (bb, l1_bb, EDGE_TRUE_VALUE);
*************** expand_omp_for_generic (struct omp_regio
*** 4027,4034 ****
t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
false, GSI_CONTINUE_LINKING);
if (TREE_TYPE (t) != boolean_type_node)
! t = fold_build2 (NE_EXPR, boolean_type_node,
! t, build_int_cst (TREE_TYPE (t), 0));
stmt = gimple_build_cond_empty (t);
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
}
--- 4024,4035 ----
t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
false, GSI_CONTINUE_LINKING);
if (TREE_TYPE (t) != boolean_type_node)
! t = force_gimple_operand_gsi (&gsi, fold_build2 (NE_EXPR,
! boolean_type_node,
! t, build_int_cst
! (TREE_TYPE (t), 0)),
! true, NULL_TREE, false,
! GSI_CONTINUE_LINKING);
stmt = gimple_build_cond_empty (t);
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
}
*************** expand_omp_for_static_nochunk (struct om
*** 4200,4206 ****
t = fold_build2 (MIN_EXPR, itype, t, n);
e0 = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, true, GSI_SAME_STMT);
! t = build2 (GE_EXPR, boolean_type_node, s0, e0);
gsi_insert_before (&gsi, gimple_build_cond_empty (t), GSI_SAME_STMT);
/* Remove the GIMPLE_OMP_FOR statement. */
--- 4201,4209 ----
t = fold_build2 (MIN_EXPR, itype, t, n);
e0 = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, true, GSI_SAME_STMT);
! t = force_gimple_operand_gsi (&gsi, build2 (GE_EXPR,
! boolean_type_node, s0, e0),
! true, NULL_TREE, true, GSI_SAME_STMT);
gsi_insert_before (&gsi, gimple_build_cond_empty (t), GSI_SAME_STMT);
/* Remove the GIMPLE_OMP_FOR statement. */
*************** expand_omp_for_static_nochunk (struct om
*** 4249,4255 ****
stmt = gimple_build_assign (vback, t);
gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
! t = build2 (fd->loop.cond_code, boolean_type_node, vback, e);
gsi_insert_before (&gsi, gimple_build_cond_empty (t), GSI_SAME_STMT);
/* Remove the GIMPLE_OMP_CONTINUE statement. */
--- 4252,4260 ----
stmt = gimple_build_assign (vback, t);
gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
! t = force_gimple_operand_gsi (&gsi, build2 (fd->loop.cond_code,
! boolean_type_node, vback, e),
! true, NULL_TREE, true, GSI_SAME_STMT);
gsi_insert_before (&gsi, gimple_build_cond_empty (t), GSI_SAME_STMT);
/* Remove the GIMPLE_OMP_CONTINUE statement. */
*************** expand_omp_for_static_chunk (struct omp_
*** 4432,4438 ****
e0 = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
false, GSI_CONTINUE_LINKING);
! t = build2 (LT_EXPR, boolean_type_node, s0, n);
gsi_insert_after (&si, gimple_build_cond_empty (t), GSI_CONTINUE_LINKING);
/* Setup code for sequential iteration goes in SEQ_START_BB. */
--- 4437,4444 ----
e0 = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
false, GSI_CONTINUE_LINKING);
! t = force_gimple_operand_gsi (&si, build2 (LT_EXPR, boolean_type_node, s0, n),
! true, NULL_TREE, false, GSI_CONTINUE_LINKING);
gsi_insert_after (&si, gimple_build_cond_empty (t), GSI_CONTINUE_LINKING);
/* Setup code for sequential iteration goes in SEQ_START_BB. */
*************** expand_omp_for_static_chunk (struct omp_
*** 4476,4482 ****
stmt = gimple_build_assign (v_back, t);
gsi_insert_before (&si, stmt, GSI_SAME_STMT);
! t = build2 (fd->loop.cond_code, boolean_type_node, v_back, e);
gsi_insert_before (&si, gimple_build_cond_empty (t), GSI_SAME_STMT);
/* Remove GIMPLE_OMP_CONTINUE. */
--- 4482,4490 ----
stmt = gimple_build_assign (v_back, t);
gsi_insert_before (&si, stmt, GSI_SAME_STMT);
! t = force_gimple_operand_gsi (&si, build2 (fd->loop.cond_code,
! boolean_type_node, v_back, e),
! true, NULL_TREE, true, GSI_SAME_STMT);
gsi_insert_before (&si, gimple_build_cond_empty (t), GSI_SAME_STMT);
/* Remove GIMPLE_OMP_CONTINUE. */
*************** expand_omp_atomic_pipeline (basic_block
*** 5049,5055 ****
tree addr, tree loaded_val, tree stored_val,
int index)
{
! tree loadedi, storedi, initial, new_storedi, old_vali;
tree type, itype, cmpxchg, iaddr;
gimple_stmt_iterator si;
basic_block loop_header = single_succ (load_bb);
--- 5057,5063 ----
tree addr, tree loaded_val, tree stored_val,
int index)
{
! tree loadedi, storedi, initial, new_storedi, old_vali, t;
tree type, itype, cmpxchg, iaddr;
gimple_stmt_iterator si;
basic_block loop_header = single_succ (load_bb);
*************** expand_omp_atomic_pipeline (basic_block
*** 5178,5186 ****
/* Note that we always perform the comparison as an integer, even for
floating point. This allows the atomic operation to properly
succeed even with NaNs and -0.0. */
! stmt = gimple_build_cond_empty
! (build2 (NE_EXPR, boolean_type_node,
! new_storedi, old_vali));
gsi_insert_before (&si, stmt, GSI_SAME_STMT);
/* Update cfg. */
--- 5186,5195 ----
/* Note that we always perform the comparison as an integer, even for
floating point. This allows the atomic operation to properly
succeed even with NaNs and -0.0. */
! t = force_gimple_operand_gsi (&si, build2 (NE_EXPR, boolean_type_node,
! new_storedi, old_vali),
! true, NULL_TREE, true, GSI_SAME_STMT);
! stmt = gimple_build_cond_empty (t);
gsi_insert_before (&si, stmt, GSI_SAME_STMT);
/* Update cfg. */
*************** lower_omp_single_simple (gimple single_s
*** 5680,5689 ****
gimple_call_set_lhs (call, lhs);
gimple_seq_add_stmt (pre_p, call);
! cond = gimple_build_cond (EQ_EXPR, lhs,
! fold_convert_loc (loc, TREE_TYPE (lhs),
! boolean_true_node),
! tlabel, flabel);
gimple_seq_add_stmt (pre_p, cond);
gimple_seq_add_stmt (pre_p, gimple_build_label (tlabel));
gimple_seq_add_seq (pre_p, gimple_omp_body (single_stmt));
--- 5689,5695 ----
gimple_call_set_lhs (call, lhs);
gimple_seq_add_stmt (pre_p, call);
! cond = gimple_build_cond (lhs, tlabel, flabel);
gimple_seq_add_stmt (pre_p, cond);
gimple_seq_add_stmt (pre_p, gimple_build_label (tlabel));
gimple_seq_add_seq (pre_p, gimple_omp_body (single_stmt));
*************** lower_omp_1 (gimple_stmt_iterator *gsi_p
*** 6594,6603 ****
{
case GIMPLE_COND:
if ((ctx || task_shared_vars)
! && (walk_tree (gimple_cond_lhs_ptr (stmt), lower_omp_regimplify_p,
! ctx ? NULL : &wi, NULL)
! || walk_tree (gimple_cond_rhs_ptr (stmt), lower_omp_regimplify_p,
! ctx ? NULL : &wi, NULL)))
gimple_regimplify_operands (stmt, gsi_p);
break;
case GIMPLE_CATCH:
--- 6600,6607 ----
{
case GIMPLE_COND:
if ((ctx || task_shared_vars)
! && (walk_tree (gimple_cond_pred_ptr (stmt), lower_omp_regimplify_p,
! ctx ? NULL : &wi, NULL)))
gimple_regimplify_operands (stmt, gsi_p);
break;
case GIMPLE_CATCH:
Index: trunk/gcc/tree-call-cdce.c
===================================================================
*** trunk.orig/gcc/tree-call-cdce.c 2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/tree-call-cdce.c 2010-08-30 14:32:23.000000000 +0200
*************** gen_one_condition (tree arg, int lbub,
*** 348,354 ****
tempcn = make_ssa_name (tempc, stmt2);
gimple_assign_set_lhs (stmt2, tempcn);
! stmt3 = gimple_build_cond_from_tree (tempcn, NULL_TREE, NULL_TREE);
VEC_quick_push (gimple, conds, stmt1);
VEC_quick_push (gimple, conds, stmt2);
VEC_quick_push (gimple, conds, stmt3);
--- 348,354 ----
tempcn = make_ssa_name (tempc, stmt2);
gimple_assign_set_lhs (stmt2, tempcn);
! stmt3 = gimple_build_cond (tempcn, NULL_TREE, NULL_TREE);
VEC_quick_push (gimple, conds, stmt1);
VEC_quick_push (gimple, conds, stmt2);
VEC_quick_push (gimple, conds, stmt3);
*************** gen_conditions_for_pow_int_base (tree ba
*** 453,459 ****
tree base_var, int_type;
tree temp, tempn;
tree cst0;
! gimple stmt1, stmt2;
int bit_sz, max_exp;
inp_domain exp_domain;
--- 453,459 ----
tree base_var, int_type;
tree temp, tempn;
tree cst0;
! gimple stmt1, stmt2, stmt3;
int bit_sz, max_exp;
inp_domain exp_domain;
*************** gen_conditions_for_pow_int_base (tree ba
*** 510,519 ****
stmt1 = gimple_build_assign (temp, base_val0);
tempn = make_ssa_name (temp, stmt1);
gimple_assign_set_lhs (stmt1, tempn);
! stmt2 = gimple_build_cond (LE_EXPR, tempn, cst0, NULL_TREE, NULL_TREE);
VEC_quick_push (gimple, conds, stmt1);
VEC_quick_push (gimple, conds, stmt2);
(*nconds)++;
}
--- 510,525 ----
stmt1 = gimple_build_assign (temp, base_val0);
tempn = make_ssa_name (temp, stmt1);
gimple_assign_set_lhs (stmt1, tempn);
! temp = create_tmp_var (boolean_type_node, NULL);
! stmt2 = gimple_build_assign (temp, fold_build2 (LE_EXPR, boolean_type_node,
! tempn, cst0));
! tempn = make_ssa_name (temp, stmt2);
! gimple_assign_set_lhs (stmt2, tempn);
! stmt3 = gimple_build_cond (tempn, NULL_TREE, NULL_TREE);
VEC_quick_push (gimple, conds, stmt1);
VEC_quick_push (gimple, conds, stmt2);
+ VEC_quick_push (gimple, conds, stmt3);
(*nconds)++;
}
Index: trunk/gcc/tree-cfg.c
===================================================================
*** trunk.orig/gcc/tree-cfg.c 2010-08-27 11:03:47.000000000 +0200
--- trunk/gcc/tree-cfg.c 2010-08-30 14:32:23.000000000 +0200
*************** create_bb (void *h, void *e, basic_block
*** 470,514 ****
Edge creation
---------------------------------------------------------------------------*/
- /* Fold COND_EXPR_COND of each COND_EXPR. */
-
- void
- fold_cond_expr_cond (void)
- {
- basic_block bb;
-
- FOR_EACH_BB (bb)
- {
- gimple stmt = last_stmt (bb);
-
- if (stmt && gimple_code (stmt) == GIMPLE_COND)
- {
- location_t loc = gimple_location (stmt);
- tree cond;
- bool zerop, onep;
-
- fold_defer_overflow_warnings ();
- cond = fold_binary_loc (loc, gimple_cond_code (stmt), boolean_type_node,
- gimple_cond_lhs (stmt), gimple_cond_rhs (stmt));
- if (cond)
- {
- zerop = integer_zerop (cond);
- onep = integer_onep (cond);
- }
- else
- zerop = onep = false;
-
- fold_undefer_overflow_warnings (zerop || onep,
- stmt,
- WARN_STRICT_OVERFLOW_CONDITIONAL);
- if (zerop)
- gimple_cond_make_false (stmt);
- else if (onep)
- gimple_cond_make_true (stmt);
- }
- }
- }
-
/* Join all the blocks in the flowgraph. */
static void
--- 470,475 ----
*************** make_edges (void)
*** 690,698 ****
if (root_omp_region)
free_omp_regions ();
-
- /* Fold COND_EXPR_COND of each COND_EXPR. */
- fold_cond_expr_cond ();
}
/* Trivial hash function for a location_t. ITEM is a pointer to
--- 651,656 ----
*************** verify_expr (tree *tp, int *walk_subtree
*** 2748,2754 ****
error ("non-integral used in condition");
return x;
}
! if (!is_gimple_condexpr (x))
{
error ("invalid conditional operand");
return x;
--- 2706,2712 ----
error ("non-integral used in condition");
return x;
}
! if (!is_gimple_val (x))
{
error ("invalid conditional operand");
return x;
*************** verify_types_in_gimple_stmt (gimple stmt
*** 4066,4076 ****
return verify_gimple_call (stmt);
case GIMPLE_COND:
- if (TREE_CODE_CLASS (gimple_cond_code (stmt)) != tcc_comparison)
- {
- error ("invalid comparison code in gimple cond");
- return true;
- }
if (!(!gimple_cond_true_label (stmt)
|| TREE_CODE (gimple_cond_true_label (stmt)) == LABEL_DECL)
|| !(!gimple_cond_false_label (stmt)
--- 4024,4029 ----
*************** verify_types_in_gimple_stmt (gimple stmt
*** 4079,4088 ****
error ("invalid labels in gimple cond");
return true;
}
!
! return verify_gimple_comparison (boolean_type_node,
! gimple_cond_lhs (stmt),
! gimple_cond_rhs (stmt));
case GIMPLE_GOTO:
return verify_gimple_goto (stmt);
--- 4032,4049 ----
error ("invalid labels in gimple cond");
return true;
}
! if (!is_gimple_val (gimple_cond_pred (stmt)))
! {
! error ("invalid predicate in gimple cond");
! return true;
! }
! if (!INTEGRAL_TYPE_P (TREE_TYPE (gimple_cond_pred (stmt))))
! {
! error ("invalid predicate type in gimple cond");
! debug_generic_stmt (TREE_TYPE (gimple_cond_pred (stmt)));
! return true;
! }
! return false;
case GIMPLE_GOTO:
return verify_gimple_goto (stmt);
*************** gimple_duplicate_sese_region (edge entry
*** 5483,5491 ****
*/
bool
! gimple_duplicate_sese_tail (edge entry ATTRIBUTE_UNUSED, edge exit ATTRIBUTE_UNUSED,
! basic_block *region ATTRIBUTE_UNUSED, unsigned n_region ATTRIBUTE_UNUSED,
! basic_block *region_copy ATTRIBUTE_UNUSED)
{
unsigned i;
bool free_region_copy = false;
--- 5444,5452 ----
*/
bool
! gimple_duplicate_sese_tail (edge entry, edge exit,
! basic_block *region, unsigned n_region,
! basic_block *region_copy)
{
unsigned i;
bool free_region_copy = false;
*************** gimple_duplicate_sese_tail (edge entry A
*** 5500,5510 ****
gimple cond_stmt;
edge sorig, snew;
basic_block exit_bb;
- basic_block iters_bb;
tree new_rhs;
gimple_stmt_iterator psi;
gimple phi;
tree def;
gcc_assert (EDGE_COUNT (exit->src->succs) == 2);
exits[0] = exit;
--- 5461,5472 ----
gimple cond_stmt;
edge sorig, snew;
basic_block exit_bb;
tree new_rhs;
gimple_stmt_iterator psi;
gimple phi;
tree def;
+ enum tree_code code;
+ tree lhs, rhs;
gcc_assert (EDGE_COUNT (exit->src->succs) == 2);
exits[0] = exit;
*************** gimple_duplicate_sese_tail (edge entry A
*** 5590,5617 ****
peel out the last iteration). If the body is executed after
the condition, moving the condition to the entry requires
decrementing one iteration. */
if (exits[1]->dest == orig_loop->latch)
! new_rhs = gimple_cond_rhs (cond_stmt);
else
! {
! new_rhs = fold_build2 (MINUS_EXPR, TREE_TYPE (gimple_cond_rhs (cond_stmt)),
! gimple_cond_rhs (cond_stmt),
! build_int_cst (TREE_TYPE (gimple_cond_rhs (cond_stmt)), 1));
!
! if (TREE_CODE (gimple_cond_rhs (cond_stmt)) == SSA_NAME)
! {
! iters_bb = gimple_bb (SSA_NAME_DEF_STMT (gimple_cond_rhs (cond_stmt)));
! for (gsi1 = gsi_start_bb (iters_bb); !gsi_end_p (gsi1); gsi_next (&gsi1))
! if (gsi_stmt (gsi1) == SSA_NAME_DEF_STMT (gimple_cond_rhs (cond_stmt)))
! break;
!
! new_rhs = force_gimple_operand_gsi (&gsi1, new_rhs, true,
! NULL_TREE,false,GSI_CONTINUE_LINKING);
! }
! }
! gimple_cond_set_rhs (cond_stmt, unshare_expr (new_rhs));
! gimple_cond_set_lhs (cond_stmt, unshare_expr (gimple_cond_lhs (cond_stmt)));
gsi_insert_after (&gsi, cond_stmt, GSI_NEW_STMT);
sorig = single_succ_edge (switch_bb);
sorig->flags = exits[1]->flags;
--- 5552,5578 ----
peel out the last iteration). If the body is executed after
the condition, moving the condition to the entry requires
decrementing one iteration. */
+ gimple_cond_extract_comparison (cond_stmt, &code, &lhs, &rhs);
if (exits[1]->dest == orig_loop->latch)
! new_rhs = rhs;
else
! {
! new_rhs = fold_build2 (MINUS_EXPR, TREE_TYPE (rhs),
! rhs,
! build_int_cst (TREE_TYPE (rhs), 1));
!
! if (TREE_CODE (rhs) == SSA_NAME)
! {
! gsi1 = gsi_for_stmt (SSA_NAME_DEF_STMT (rhs));
! new_rhs = force_gimple_operand_gsi (&gsi1, new_rhs, true,
! NULL_TREE, false,
! GSI_CONTINUE_LINKING);
! }
! }
gsi_insert_after (&gsi, cond_stmt, GSI_NEW_STMT);
+ gimple_update_cond_from_comparison (gsi, code, unshare_expr (lhs),
+ unshare_expr (new_rhs));
+ update_stmt (cond_stmt);
sorig = single_succ_edge (switch_bb);
sorig->flags = exits[1]->flags;
*************** gimple_lv_add_condition_to_bb (basic_blo
*** 7203,7214 ****
tree cond_expr = (tree) cond_e;
edge e0;
/* Build new conditional expr */
! new_cond_expr = gimple_build_cond_from_tree (cond_expr,
! NULL_TREE, NULL_TREE);
/* Add new cond in cond_bb. */
- gsi = gsi_last_bb (cond_bb);
gsi_insert_after (&gsi, new_cond_expr, GSI_NEW_STMT);
/* Adjust edges appropriately to connect new head with first head
--- 7164,7177 ----
tree cond_expr = (tree) cond_e;
edge e0;
+ gsi = gsi_last_bb (cond_bb);
+
/* Build new conditional expr */
! cond_expr = force_gimple_operand_gsi (&gsi, cond_expr, true, NULL,
! false, GSI_NEW_STMT);
! new_cond_expr = gimple_build_cond (cond_expr, NULL_TREE, NULL_TREE);
/* Add new cond in cond_bb. */
gsi_insert_after (&gsi, new_cond_expr, GSI_NEW_STMT);
/* Adjust edges appropriately to connect new head with first head
Index: trunk/gcc/tree-complex.c
===================================================================
*** trunk.orig/gcc/tree-complex.c 2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/tree-complex.c 2010-08-30 14:32:23.000000000 +0200
*************** init_dont_simulate_again (void)
*** 234,244 ****
op1 = gimple_assign_rhs2 (stmt);
break;
- case GIMPLE_COND:
- op0 = gimple_cond_lhs (stmt);
- op1 = gimple_cond_rhs (stmt);
- break;
-
default:
break;
}
--- 234,239 ----
*************** expand_complex_div_wide (gimple_stmt_ite
*** 1118,1124 ****
{
edge e;
gimple stmt;
! tree cond, tmp;
tmp = create_tmp_var (boolean_type_node, NULL);
stmt = gimple_build_assign (tmp, compare);
--- 1113,1119 ----
{
edge e;
gimple stmt;
! tree tmp;
tmp = create_tmp_var (boolean_type_node, NULL);
stmt = gimple_build_assign (tmp, compare);
*************** expand_complex_div_wide (gimple_stmt_ite
*** 1127,1138 ****
tmp = make_ssa_name (tmp, stmt);
gimple_assign_set_lhs (stmt, tmp);
}
-
gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
! cond = fold_build2_loc (gimple_location (stmt),
! EQ_EXPR, boolean_type_node, tmp, boolean_true_node);
! stmt = gimple_build_cond_from_tree (cond, NULL_TREE, NULL_TREE);
gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
/* Split the original block, and create the TRUE and FALSE blocks. */
--- 1122,1130 ----
tmp = make_ssa_name (tmp, stmt);
gimple_assign_set_lhs (stmt, tmp);
}
gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
! stmt = gimple_build_cond (tmp, NULL_TREE, NULL_TREE);
gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
/* Split the original block, and create the TRUE and FALSE blocks. */
*************** expand_complex_comparison (gimple_stmt_i
*** 1386,1397 ****
stmt = gsi_stmt (*gsi);
break;
- case GIMPLE_COND:
- gimple_cond_set_code (stmt, EQ_EXPR);
- gimple_cond_set_lhs (stmt, cc);
- gimple_cond_set_rhs (stmt, boolean_true_node);
- break;
-
default:
gcc_unreachable ();
}
--- 1378,1383 ----
*************** expand_complex_operations_1 (gimple_stmt
*** 1412,1418 ****
enum tree_code code;
lhs = gimple_get_lhs (stmt);
! if (!lhs && gimple_code (stmt) != GIMPLE_COND)
return;
type = TREE_TYPE (gimple_op (stmt, 0));
--- 1398,1404 ----
enum tree_code code;
lhs = gimple_get_lhs (stmt);
! if (!lhs)
return;
type = TREE_TYPE (gimple_op (stmt, 0));
*************** expand_complex_operations_1 (gimple_stmt
*** 1449,1459 ****
{
tree rhs;
- /* GIMPLE_COND may also fallthru here, but we do not need to
- do anything with it. */
- if (gimple_code (stmt) == GIMPLE_COND)
- return;
-
if (TREE_CODE (type) == COMPLEX_TYPE)
expand_complex_move (gsi, type);
else if (is_gimple_assign (stmt)
--- 1435,1440 ----
*************** expand_complex_operations_1 (gimple_stmt
*** 1476,1492 ****
/* Extract the components of the two complex values. Make sure and
handle the common case of the same value used twice specially. */
! if (is_gimple_assign (stmt))
! {
! ac = gimple_assign_rhs1 (stmt);
! bc = (gimple_num_ops (stmt) > 2) ? gimple_assign_rhs2 (stmt) : NULL;
! }
! /* GIMPLE_CALL can not get here. */
! else
! {
! ac = gimple_cond_lhs (stmt);
! bc = gimple_cond_rhs (stmt);
! }
ar = extract_component (gsi, ac, false, true);
ai = extract_component (gsi, ac, true, true);
--- 1457,1464 ----
/* Extract the components of the two complex values. Make sure and
handle the common case of the same value used twice specially. */
! ac = gimple_assign_rhs1 (stmt);
! bc = (gimple_num_ops (stmt) > 2) ? gimple_assign_rhs2 (stmt) : NULL;
ar = extract_component (gsi, ac, false, true);
ai = extract_component (gsi, ac, true, true);
Index: trunk/gcc/tree-switch-conversion.c
===================================================================
*** trunk.orig/gcc/tree-switch-conversion.c 2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/tree-switch-conversion.c 2010-08-30 14:32:23.000000000 +0200
*************** gen_inbound_check (gimple swtch)
*** 680,686 ****
tree cast;
gimple cast_assign, minus_assign;
tree ulb, minus;
! tree bound;
gimple cond_stmt;
--- 680,686 ----
tree cast;
gimple cast_assign, minus_assign;
tree ulb, minus;
! tree bound, cond;
gimple cond_stmt;
*************** gen_inbound_check (gimple swtch)
*** 724,730 ****
update_stmt (minus_assign);
bound = fold_convert_loc (loc, utype, info.range_size);
! cond_stmt = gimple_build_cond (LE_EXPR, tmp_u_2, bound, NULL_TREE, NULL_TREE);
gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT);
update_stmt (cond_stmt);
--- 724,732 ----
update_stmt (minus_assign);
bound = fold_convert_loc (loc, utype, info.range_size);
! cond = fold_build2 (LE_EXPR, boolean_type_node, tmp_u_2, bound);
! cond = force_gimple_operand_gsi (&gsi, cond, true, NULL, true, GSI_SAME_STMT);
! cond_stmt = gimple_build_cond (cond, NULL_TREE, NULL_TREE);
gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT);
update_stmt (cond_stmt);
Index: trunk/gcc/cfgexpand.c
===================================================================
*** trunk.orig/gcc/cfgexpand.c 2010-08-25 16:49:48.000000000 +0200
--- trunk/gcc/cfgexpand.c 2010-08-30 14:32:23.000000000 +0200
*************** expand_gimple_cond (basic_block bb, gimp
*** 1607,1615 ****
enum tree_code code;
tree op0, op1;
! code = gimple_cond_code (stmt);
! op0 = gimple_cond_lhs (stmt);
! op1 = gimple_cond_rhs (stmt);
/* We're sometimes presented with such code:
D.123_1 = x < y;
if (D.123_1 != 0)
--- 1607,1615 ----
enum tree_code code;
tree op0, op1;
! code = NE_EXPR;
! op0 = gimple_cond_pred (stmt);
! op1 = boolean_false_node;
/* We're sometimes presented with such code:
D.123_1 = x < y;
if (D.123_1 != 0)
*************** expand_gimple_cond (basic_block bb, gimp
*** 1618,1625 ****
be cleaned up by combine. But some pattern matchers like if-conversion
work better when there's only one compare, so make up for this
here as special exception if TER would have made the same change. */
! if (gimple_cond_single_var_p (stmt)
! && SA.values
&& TREE_CODE (op0) == SSA_NAME
&& bitmap_bit_p (SA.values, SSA_NAME_VERSION (op0)))
{
--- 1618,1624 ----
be cleaned up by combine. But some pattern matchers like if-conversion
work better when there's only one compare, so make up for this
here as special exception if TER would have made the same change. */
! if (SA.values
&& TREE_CODE (op0) == SSA_NAME
&& bitmap_bit_p (SA.values, SSA_NAME_VERSION (op0)))
{
Index: trunk/gcc/gimple-fold.c
===================================================================
*** trunk.orig/gcc/gimple-fold.c 2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/gimple-fold.c 2010-08-30 14:32:23.000000000 +0200
*************** fold_gimple_assign (gimple_stmt_iterator
*** 571,605 ****
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 (TREE_CODE (rhs) == TARGET_MEM_REF)
--- 571,583 ----
if (TREE_CODE (rhs) == COND_EXPR)
{
tree op0 = COND_EXPR_COND (rhs);
location_t cond_loc = EXPR_LOCATION (rhs);
! if (!is_gimple_min_invariant (op0))
return NULL_TREE;
! result = fold_build3_loc (cond_loc, COND_EXPR, TREE_TYPE (rhs), op0,
! COND_EXPR_THEN (rhs), COND_EXPR_ELSE (rhs));
}
else if (TREE_CODE (rhs) == TARGET_MEM_REF)
*************** fold_gimple_assign (gimple_stmt_iterator
*** 783,800 ****
static bool
fold_gimple_cond (gimple stmt)
{
! tree result = fold_binary_loc (gimple_location (stmt),
! gimple_cond_code (stmt),
! boolean_type_node,
! gimple_cond_lhs (stmt),
! gimple_cond_rhs (stmt));
if (result)
{
STRIP_USELESS_TYPE_CONVERSION (result);
! if (is_gimple_condexpr (result) && valid_gimple_rhs_p (result))
{
! gimple_cond_set_condition_from_tree (stmt, result);
return true;
}
}
--- 761,778 ----
static bool
fold_gimple_cond (gimple stmt)
{
! enum tree_code code;
! tree lhs, rhs, result;
+ gimple_cond_extract_comparison (stmt, &code, &lhs, &rhs);
+ result = fold_binary_loc (gimple_location (stmt), code,
+ boolean_type_node, lhs, rhs);
if (result)
{
STRIP_USELESS_TYPE_CONVERSION (result);
! if (is_gimple_val (result))
{
! gimple_cond_set_pred (stmt, result);
return true;
}
}
Index: trunk/gcc/gimple-pretty-print.c
===================================================================
*** trunk.orig/gcc/gimple-pretty-print.c 2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/gimple-pretty-print.c 2010-08-30 14:32:23.000000000 +0200
*************** static void
*** 674,692 ****
dump_gimple_cond (pretty_printer *buffer, gimple gs, int spc, int flags)
{
if (flags & TDF_RAW)
! dump_gimple_fmt (buffer, spc, flags, "%G <%s, %T, %T, %T, %T>", gs,
! tree_code_name [gimple_cond_code (gs)],
! gimple_cond_lhs (gs), gimple_cond_rhs (gs),
gimple_cond_true_label (gs), gimple_cond_false_label (gs));
else
{
if (!(flags & TDF_RHS_ONLY))
pp_string (buffer, "if (");
! dump_generic_node (buffer, gimple_cond_lhs (gs), spc, flags, false);
! pp_space (buffer);
! pp_string (buffer, op_symbol_code (gimple_cond_code (gs)));
! pp_space (buffer);
! dump_generic_node (buffer, gimple_cond_rhs (gs), spc, flags, false);
if (!(flags & TDF_RHS_ONLY))
{
pp_character (buffer, ')');
--- 674,687 ----
dump_gimple_cond (pretty_printer *buffer, gimple gs, int spc, int flags)
{
if (flags & TDF_RAW)
! dump_gimple_fmt (buffer, spc, flags, "%G <%T, %T, %T>", gs,
! gimple_cond_pred (gs),
gimple_cond_true_label (gs), gimple_cond_false_label (gs));
else
{
if (!(flags & TDF_RHS_ONLY))
pp_string (buffer, "if (");
! dump_generic_node (buffer, gimple_cond_pred (gs), spc, flags, false);
if (!(flags & TDF_RHS_ONLY))
{
pp_character (buffer, ')');
Index: trunk/gcc/graphite-scop-detection.c
===================================================================
*** trunk.orig/gcc/graphite-scop-detection.c 2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/graphite-scop-detection.c 2010-08-30 14:32:23.000000000 +0200
*************** stmt_has_simple_data_refs_p (loop_p oute
*** 305,314 ****
static bool
stmt_simple_for_scop_p (basic_block scop_entry, loop_p outermost_loop,
! gimple stmt, basic_block bb)
{
- loop_p loop = bb->loop_father;
-
gcc_assert (scop_entry);
/* GIMPLE_ASM and GIMPLE_CALL may embed arbitrary side effects.
--- 305,312 ----
static bool
stmt_simple_for_scop_p (basic_block scop_entry, loop_p outermost_loop,
! gimple stmt, basic_block bb ATTRIBUTE_UNUSED)
{
gcc_assert (scop_entry);
/* GIMPLE_ASM and GIMPLE_CALL may embed arbitrary side effects.
*************** stmt_simple_for_scop_p (basic_block scop
*** 333,364 ****
return true;
case GIMPLE_COND:
! {
! tree op;
! ssa_op_iter op_iter;
! enum tree_code code = gimple_cond_code (stmt);
!
! /* We can handle all binary comparisons. Inequalities are
! also supported as they can be represented with union of
! polyhedra. */
! if (!(code == LT_EXPR
! || code == GT_EXPR
! || code == LE_EXPR
! || code == GE_EXPR
! || code == EQ_EXPR
! || code == NE_EXPR))
! return false;
!
! FOR_EACH_SSA_TREE_OPERAND (op, stmt, op_iter, SSA_OP_ALL_USES)
! if (!graphite_can_represent_expr (scop_entry, loop, outermost_loop,
! op)
! /* We can not handle REAL_TYPE. Failed for pr39260. */
! || TREE_CODE (TREE_TYPE (op)) == REAL_TYPE)
! return false;
!
! return true;
! }
!
case GIMPLE_ASSIGN:
case GIMPLE_CALL:
return true;
--- 331,338 ----
return true;
case GIMPLE_COND:
! /* ??? We tested for handled comparisons here but I cannot see
! a test for comparisons in assignment rhs. */
case GIMPLE_ASSIGN:
case GIMPLE_CALL:
return true;
Index: trunk/gcc/graphite-sese-to-poly.c
===================================================================
*** trunk.orig/gcc/graphite-sese-to-poly.c 2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/graphite-sese-to-poly.c 2010-08-30 14:32:23.000000000 +0200
*************** find_params_in_bb (sese region, gimple_b
*** 962,972 ****
/* Find parameters in conditional statements. */
FOR_EACH_VEC_ELT (gimple, GBB_CONDITIONS (gbb), i, stmt)
{
! tree lhs = scalar_evolution_in_region (region, loop,
! gimple_cond_lhs (stmt));
! tree rhs = scalar_evolution_in_region (region, loop,
! gimple_cond_rhs (stmt));
!
scan_tree_for_params (region, lhs, NULL, one);
scan_tree_for_params (region, rhs, NULL, one);
}
--- 962,972 ----
/* Find parameters in conditional statements. */
FOR_EACH_VEC_ELT (gimple, GBB_CONDITIONS (gbb), i, stmt)
{
! enum tree_code code;
! tree lhs, rhs;
! gimple_cond_extract_comparison (stmt, &code, &lhs, &rhs);
! lhs = scalar_evolution_in_region (region, loop, lhs);
! rhs = scalar_evolution_in_region (region, loop, rhs);
scan_tree_for_params (region, lhs, NULL, one);
scan_tree_for_params (region, rhs, NULL, one);
}
*************** add_condition_to_domain (ppl_Pointset_Po
*** 1258,1266 ****
ppl_Linear_Expression_t left, right;
ppl_Constraint_t cstr;
enum ppl_enum_Constraint_Type type;
! left = create_linear_expr_from_tree (pbb, gimple_cond_lhs (stmt));
! right = create_linear_expr_from_tree (pbb, gimple_cond_rhs (stmt));
/* If we have < or > expressions convert them to <= or >= by adding 1 to
the left or the right side of the expression. */
--- 1258,1270 ----
ppl_Linear_Expression_t left, right;
ppl_Constraint_t cstr;
enum ppl_enum_Constraint_Type type;
+ enum tree_code dummy_code;
+ tree lhs, rhs;
+
+ gimple_cond_extract_comparison (stmt, &dummy_code, &lhs, &rhs);
! left = create_linear_expr_from_tree (pbb, lhs);
! right = create_linear_expr_from_tree (pbb, rhs);
/* If we have < or > expressions convert them to <= or >= by adding 1 to
the left or the right side of the expression. */
*************** add_conditions_to_domain (poly_bb_p pbb)
*** 1340,1346 ****
{
case GIMPLE_COND:
{
! enum tree_code code = gimple_cond_code (stmt);
/* The conditions for ELSE-branches are inverted. */
if (!VEC_index (gimple, GBB_CONDITION_CASES (gbb), i))
--- 1344,1353 ----
{
case GIMPLE_COND:
{
! enum tree_code code;
! tree lhs, rhs;
!
! gimple_cond_extract_comparison (stmt, &code, &lhs, &rhs);
/* The conditions for ELSE-branches are inverted. */
if (!VEC_index (gimple, GBB_CONDITION_CASES (gbb), i))
Index: trunk/gcc/predict.c
===================================================================
*** trunk.orig/gcc/predict.c 2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/predict.c 2010-08-30 14:32:23.000000000 +0200
*************** tree_predict_by_opcode (basic_block bb)
*** 1358,1366 ****
FOR_EACH_EDGE (then_edge, ei, bb->succs)
if (then_edge->flags & EDGE_TRUE_VALUE)
break;
! op0 = gimple_cond_lhs (stmt);
! op1 = gimple_cond_rhs (stmt);
! cmp = gimple_cond_code (stmt);
type = TREE_TYPE (op0);
visited = BITMAP_ALLOC (NULL);
val = expr_expected_value_1 (boolean_type_node, op0, cmp, op1, visited);
--- 1358,1364 ----
FOR_EACH_EDGE (then_edge, ei, bb->succs)
if (then_edge->flags & EDGE_TRUE_VALUE)
break;
! gimple_cond_extract_comparison (stmt, &cmp, &op0, &op1);
type = TREE_TYPE (op0);
visited = BITMAP_ALLOC (NULL);
val = expr_expected_value_1 (boolean_type_node, op0, cmp, op1, visited);
Index: trunk/gcc/sese.c
===================================================================
*** trunk.orig/gcc/sese.c 2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/sese.c 2010-08-30 14:32:23.000000000 +0200
*************** set_ifsese_condition (ifsese if_region,
*** 772,778 ****
gsi = gsi_last_bb (bb);
condition = force_gimple_operand_gsi (&gsi, condition, true, NULL,
false, GSI_NEW_STMT);
! cond_stmt = gimple_build_cond_from_tree (condition, NULL_TREE, NULL_TREE);
gsi = gsi_last_bb (bb);
gsi_insert_after (&gsi, cond_stmt, GSI_NEW_STMT);
}
--- 772,778 ----
gsi = gsi_last_bb (bb);
condition = force_gimple_operand_gsi (&gsi, condition, true, NULL,
false, GSI_NEW_STMT);
! cond_stmt = gimple_build_cond (condition, NULL_TREE, NULL_TREE);
gsi = gsi_last_bb (bb);
gsi_insert_after (&gsi, cond_stmt, GSI_NEW_STMT);
}
Index: trunk/gcc/tree-cfgcleanup.c
===================================================================
*** trunk.orig/gcc/tree-cfgcleanup.c 2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/tree-cfgcleanup.c 2010-08-30 14:32:23.000000000 +0200
*************** cleanup_control_expr_graph (basic_block
*** 87,131 ****
edge e;
edge_iterator ei;
bool warned;
- location_t loc;
fold_defer_overflow_warnings ();
- loc = gimple_location (stmt);
switch (gimple_code (stmt))
{
case GIMPLE_COND:
{
! tree lhs = gimple_cond_lhs (stmt);
! tree rhs = gimple_cond_rhs (stmt);
/* For conditions try harder and lookup single-argument
PHI nodes. Only do so from the same basic-block though
as other basic-blocks may be dead already. */
! if (TREE_CODE (lhs) == SSA_NAME
! && !name_registered_for_update_p (lhs))
{
! gimple def_stmt = SSA_NAME_DEF_STMT (lhs);
if (gimple_code (def_stmt) == GIMPLE_PHI
&& gimple_phi_num_args (def_stmt) == 1
&& gimple_bb (def_stmt) == gimple_bb (stmt)
&& (TREE_CODE (PHI_ARG_DEF (def_stmt, 0)) != SSA_NAME
|| !name_registered_for_update_p (PHI_ARG_DEF (def_stmt,
0))))
! lhs = PHI_ARG_DEF (def_stmt, 0);
}
- if (TREE_CODE (rhs) == SSA_NAME
- && !name_registered_for_update_p (rhs))
- {
- gimple def_stmt = SSA_NAME_DEF_STMT (rhs);
- if (gimple_code (def_stmt) == GIMPLE_PHI
- && gimple_phi_num_args (def_stmt) == 1
- && gimple_bb (def_stmt) == gimple_bb (stmt)
- && (TREE_CODE (PHI_ARG_DEF (def_stmt, 0)) != SSA_NAME
- || !name_registered_for_update_p (PHI_ARG_DEF (def_stmt,
- 0))))
- rhs = PHI_ARG_DEF (def_stmt, 0);
- }
- val = fold_binary_loc (loc, gimple_cond_code (stmt),
- boolean_type_node, lhs, rhs);
break;
}
--- 87,114 ----
edge e;
edge_iterator ei;
bool warned;
fold_defer_overflow_warnings ();
switch (gimple_code (stmt))
{
case GIMPLE_COND:
{
! val = gimple_cond_pred (stmt);
/* For conditions try harder and lookup single-argument
PHI nodes. Only do so from the same basic-block though
as other basic-blocks may be dead already. */
! if (TREE_CODE (val) == SSA_NAME
! && !name_registered_for_update_p (val))
{
! gimple def_stmt = SSA_NAME_DEF_STMT (val);
if (gimple_code (def_stmt) == GIMPLE_PHI
&& gimple_phi_num_args (def_stmt) == 1
&& gimple_bb (def_stmt) == gimple_bb (stmt)
&& (TREE_CODE (PHI_ARG_DEF (def_stmt, 0)) != SSA_NAME
|| !name_registered_for_update_p (PHI_ARG_DEF (def_stmt,
0))))
! val = PHI_ARG_DEF (def_stmt, 0);
}
break;
}
Index: trunk/gcc/tree-flow.h
===================================================================
*** trunk.orig/gcc/tree-flow.h 2010-08-29 16:30:26.000000000 +0200
--- trunk/gcc/tree-flow.h 2010-08-30 14:32:23.000000000 +0200
*************** extern tree gimplify_build3 (gimple_stmt
*** 461,467 ****
tree, tree, tree, tree);
extern void init_empty_tree_cfg (void);
extern void init_empty_tree_cfg_for_function (struct function *);
- extern void fold_cond_expr_cond (void);
extern void make_abnormal_goto_edges (basic_block, bool);
extern void replace_uses_by (tree, tree);
extern void start_recording_case_labels (void);
--- 461,466 ----
Index: trunk/gcc/tree-if-conv.c
===================================================================
*** trunk.orig/gcc/tree-if-conv.c 2010-08-25 11:22:16.000000000 +0200
--- trunk/gcc/tree-if-conv.c 2010-08-30 14:32:23.000000000 +0200
*************** predicate_bbs (loop_p loop)
*** 918,927 ****
tree c2;
edge true_edge, false_edge;
location_t loc = gimple_location (stmt);
! tree c = fold_build2_loc (loc, gimple_cond_code (stmt),
! boolean_type_node,
! gimple_cond_lhs (stmt),
! gimple_cond_rhs (stmt));
/* Add new condition into destination's predicate list. */
extract_true_false_edges_from_block (gimple_bb (stmt),
--- 918,924 ----
tree c2;
edge true_edge, false_edge;
location_t loc = gimple_location (stmt);
! tree c = gimple_cond_pred (stmt);
/* Add new condition into destination's predicate list. */
extract_true_false_edges_from_block (gimple_bb (stmt),
Index: trunk/gcc/tree-inline.c
===================================================================
*** trunk.orig/gcc/tree-inline.c 2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/tree-inline.c 2010-08-30 14:32:23.000000000 +0200
*************** estimate_num_insns (gimple stmt, eni_wei
*** 3451,3459 ****
break;
case GIMPLE_COND:
! cost = 1 + estimate_operator_cost (gimple_cond_code (stmt), weights,
! gimple_op (stmt, 0),
! gimple_op (stmt, 1));
break;
case GIMPLE_SWITCH:
--- 3451,3457 ----
break;
case GIMPLE_COND:
! cost = 1;
break;
case GIMPLE_SWITCH:
*************** optimize_inline_calls (tree fn)
*** 4226,4232 ****
/* Renumber the lexical scoping (non-code) blocks consecutively. */
number_blocks (fn);
- fold_cond_expr_cond ();
delete_unreachable_blocks_update_callgraph (&id);
#ifdef ENABLE_CHECKING
verify_cgraph_node (id.dst_node);
--- 4224,4229 ----
*************** tree_function_versioning (tree old_decl,
*** 5166,5172 ****
fold_marked_statements (0, id.statements_to_fold);
pointer_set_destroy (id.statements_to_fold);
- fold_cond_expr_cond ();
delete_unreachable_blocks_update_callgraph (&id);
if (id.dst_node->analyzed)
cgraph_rebuild_references ();
--- 5163,5168 ----
Index: trunk/gcc/tree-optimize.c
===================================================================
*** trunk.orig/gcc/tree-optimize.c 2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/tree-optimize.c 2010-08-30 14:32:23.000000000 +0200
*************** struct gimple_opt_pass pass_cleanup_cfg
*** 189,195 ****
static unsigned int
execute_cleanup_cfg_post_optimizing (void)
{
- fold_cond_expr_cond ();
cleanup_tree_cfg ();
cleanup_dead_labels ();
group_case_labels ();
--- 189,194 ----
Index: trunk/gcc/tree-ssa-ccp.c
===================================================================
*** trunk.orig/gcc/tree-ssa-ccp.c 2010-08-25 16:49:48.000000000 +0200
--- trunk/gcc/tree-ssa-ccp.c 2010-08-30 14:32:23.000000000 +0200
*************** ccp_fold (gimple stmt)
*** 1292,1302 ****
case GIMPLE_COND:
{
! /* Handle comparison operators that can appear in GIMPLE form. */
! tree op0 = valueize_op (gimple_cond_lhs (stmt));
! tree op1 = valueize_op (gimple_cond_rhs (stmt));
! enum tree_code code = gimple_cond_code (stmt);
! return fold_binary_loc (loc, code, boolean_type_node, op0, op1);
}
case GIMPLE_SWITCH:
--- 1292,1299 ----
case GIMPLE_COND:
{
! /* Return the constant predicate. */
! return valueize_op (gimple_cond_pred (stmt));
}
case GIMPLE_SWITCH:
*************** bit_value_binop_1 (enum tree_code code,
*** 1827,1832 ****
--- 1824,1833 ----
if (double_int_negative_p (r1mask) || double_int_negative_p (r2mask))
break;
+ /* Signedness is determined by the first operand, not the result. */
+ uns = (TREE_CODE (r1type) == INTEGER_TYPE
+ && TYPE_IS_SIZETYPE (r1type) ? 0 : TYPE_UNSIGNED (r1type));
+
/* If we know the most significant bits we know the values
value ranges by means of treating varying bits as zero
or one. Do a cross comparison of the max/min pairs. */
*************** evaluate_stmt (gimple stmt)
*** 2042,2064 ****
|| POINTER_TYPE_P (TREE_TYPE (rhs1)))
{
tree rhs2 = gimple_assign_rhs2 (stmt);
! val = bit_value_binop (subcode,
! TREE_TYPE (rhs1), rhs1, rhs2);
}
break;
default:;
}
}
- else if (code == GIMPLE_COND)
- {
- enum tree_code code = gimple_cond_code (stmt);
- tree rhs1 = gimple_cond_lhs (stmt);
- tree rhs2 = gimple_cond_rhs (stmt);
- if (INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
- || POINTER_TYPE_P (TREE_TYPE (rhs1)))
- val = bit_value_binop (code, TREE_TYPE (rhs1), rhs1, rhs2);
- }
else if (code == GIMPLE_CALL
&& (fndecl = gimple_call_fndecl (stmt))
&& DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
--- 2043,2056 ----
|| POINTER_TYPE_P (TREE_TYPE (rhs1)))
{
tree rhs2 = gimple_assign_rhs2 (stmt);
! val = bit_value_binop (subcode, gimple_expr_type (stmt),
! rhs1, rhs2);
}
break;
default:;
}
}
else if (code == GIMPLE_CALL
&& (fndecl = gimple_call_fndecl (stmt))
&& DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
*************** ccp_fold_stmt (gimple_stmt_iterator *gsi
*** 2132,2146 ****
|| !double_int_zero_p (val.mask))
return false;
- if (dump_file)
- {
- fprintf (dump_file, "Folding predicate ");
- print_gimple_expr (dump_file, stmt, 0, 0);
- fprintf (dump_file, " to ");
- print_generic_expr (dump_file, val.value, 0);
- fprintf (dump_file, "\n");
- }
-
if (integer_zerop (val.value))
gimple_cond_make_false (stmt);
else
--- 2124,2129 ----
Index: trunk/gcc/tree-ssa-copy.c
===================================================================
*** trunk.orig/gcc/tree-ssa-copy.c 2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/tree-ssa-copy.c 2010-08-30 14:32:23.000000000 +0200
*************** propagate_tree_value_into_stmt (gimple_s
*** 247,258 ****
}
else if (gimple_code (stmt) == GIMPLE_COND)
{
! tree lhs = NULL_TREE;
! tree rhs = fold_convert (TREE_TYPE (val), integer_zero_node);
! propagate_tree_value (&lhs, val);
! gimple_cond_set_code (stmt, NE_EXPR);
! gimple_cond_set_lhs (stmt, lhs);
! gimple_cond_set_rhs (stmt, rhs);
}
else if (is_gimple_call (stmt)
&& gimple_call_lhs (stmt) != NULL_TREE)
--- 247,255 ----
}
else if (gimple_code (stmt) == GIMPLE_COND)
{
! tree pred = NULL_TREE;
! propagate_tree_value (&pred, val);
! gimple_cond_set_pred (stmt, pred);
}
else if (is_gimple_call (stmt)
&& gimple_call_lhs (stmt) != NULL_TREE)
*************** copy_prop_visit_assignment (gimple stmt,
*** 412,434 ****
tree lhs, rhs;
lhs = gimple_assign_lhs (stmt);
- rhs = valueize_val (gimple_assign_rhs1 (stmt));
! if (TREE_CODE (lhs) == SSA_NAME)
{
! /* Straight copy between two SSA names. First, make sure that
! we can propagate the RHS into uses of LHS. */
! if (!may_propagate_copy (lhs, rhs))
return SSA_PROP_VARYING;
-
- *result_p = lhs;
- if (set_copy_of_val (*result_p, rhs))
- return SSA_PROP_INTERESTING;
- else
- return SSA_PROP_NOT_INTERESTING;
}
! return SSA_PROP_VARYING;
}
--- 409,442 ----
tree lhs, rhs;
lhs = gimple_assign_lhs (stmt);
! if (gimple_assign_single_p (stmt)
! && (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
! || is_gimple_min_invariant (gimple_assign_rhs1 (stmt))))
! rhs = valueize_val (gimple_assign_rhs1 (stmt));
! else if (TREE_CODE_CLASS (gimple_assign_rhs_code (stmt)) == tcc_comparison)
{
! tree op0 = valueize_val (gimple_assign_rhs1 (stmt));
! tree op1 = valueize_val (gimple_assign_rhs2 (stmt));
! rhs = fold_binary (gimple_assign_rhs_code (stmt),
! boolean_type_node, op0, op1);
! if (!rhs
! || TREE_CODE (rhs) != INTEGER_CST)
return SSA_PROP_VARYING;
}
+ else
+ return SSA_PROP_VARYING;
! /* Straight copy between two SSA names. First, make sure that
! we can propagate the RHS into uses of LHS. */
! if (!may_propagate_copy (lhs, rhs))
! return SSA_PROP_VARYING;
!
! *result_p = lhs;
! if (set_copy_of_val (*result_p, rhs))
! return SSA_PROP_INTERESTING;
! else
! return SSA_PROP_NOT_INTERESTING;
}
*************** static enum ssa_prop_result
*** 440,479 ****
copy_prop_visit_cond_stmt (gimple stmt, edge *taken_edge_p)
{
enum ssa_prop_result retval = SSA_PROP_VARYING;
! location_t loc = gimple_location (stmt);
!
! tree op0 = gimple_cond_lhs (stmt);
! tree op1 = gimple_cond_rhs (stmt);
! /* The only conditionals that we may be able to compute statically
! are predicates involving two SSA_NAMEs. */
! if (TREE_CODE (op0) == SSA_NAME && TREE_CODE (op1) == SSA_NAME)
{
! op0 = valueize_val (op0);
! op1 = valueize_val (op1);
! /* See if we can determine the predicate's value. */
! if (dump_file && (dump_flags & TDF_DETAILS))
! {
! fprintf (dump_file, "Trying to determine truth value of ");
! fprintf (dump_file, "predicate ");
! print_gimple_stmt (dump_file, stmt, 0, 0);
! }
!
! /* We can fold COND and get a useful result only when we have
! the same SSA_NAME on both sides of a comparison operator. */
! if (op0 == op1)
! {
! tree folded_cond = fold_binary_loc (loc, gimple_cond_code (stmt),
! boolean_type_node, op0, op1);
! if (folded_cond)
! {
! basic_block bb = gimple_bb (stmt);
! *taken_edge_p = find_taken_edge (bb, folded_cond);
! if (*taken_edge_p)
! retval = SSA_PROP_INTERESTING;
! }
! }
}
if (dump_file && (dump_flags & TDF_DETAILS) && *taken_edge_p)
--- 448,469 ----
copy_prop_visit_cond_stmt (gimple stmt, edge *taken_edge_p)
{
enum ssa_prop_result retval = SSA_PROP_VARYING;
! tree pred = valueize_val (gimple_cond_pred (stmt));
! /* See if we can determine the predicate's value. */
! if (dump_file && (dump_flags & TDF_DETAILS))
{
! fprintf (dump_file, "Trying to determine truth value of ");
! fprintf (dump_file, "predicate ");
! print_gimple_stmt (dump_file, stmt, 0, 0);
! }
! if (TREE_CODE (pred) == INTEGER_CST)
! {
! basic_block bb = gimple_bb (stmt);
! *taken_edge_p = find_taken_edge (bb, pred);
! if (*taken_edge_p)
! retval = SSA_PROP_INTERESTING;
}
if (dump_file && (dump_flags & TDF_DETAILS) && *taken_edge_p)
*************** copy_prop_visit_stmt (gimple stmt, edge
*** 506,515 ****
fprintf (dump_file, "\n");
}
! if (gimple_assign_single_p (stmt)
! && TREE_CODE (gimple_assign_lhs (stmt)) == SSA_NAME
! && (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
! || is_gimple_min_invariant (gimple_assign_rhs1 (stmt))))
{
/* If the statement is a copy assignment, evaluate its RHS to
see if the lattice value of its output has changed. */
--- 496,503 ----
fprintf (dump_file, "\n");
}
! if (is_gimple_assign (stmt)
! && TREE_CODE (gimple_assign_lhs (stmt)) == SSA_NAME)
{
/* If the statement is a copy assignment, evaluate its RHS to
see if the lattice value of its output has changed. */
Index: trunk/gcc/tree-ssa-dom.c
===================================================================
*** trunk.orig/gcc/tree-ssa-dom.c 2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/tree-ssa-dom.c 2010-08-30 14:32:23.000000000 +0200
*************** DEF_VEC_ALLOC_O(cond_equivalence,heap);
*** 96,106 ****
struct edge_info
{
- /* If this edge creates a simple equivalence, the LHS and RHS of
- the equivalence will be stored here. */
- tree lhs;
- tree rhs;
-
/* Traversing an edge may also indicate one or more particular conditions
are true or false. */
VEC(cond_equivalence, heap) *cond_equivalences;
--- 96,101 ----
*************** initialize_hash_element (gimple stmt, tr
*** 244,253 ****
else if (code == GIMPLE_COND)
{
expr->type = boolean_type_node;
! expr->kind = EXPR_BINARY;
! expr->ops.binary.op = gimple_cond_code (stmt);
! expr->ops.binary.opnd0 = gimple_cond_lhs (stmt);
! expr->ops.binary.opnd1 = gimple_cond_rhs (stmt);
}
else if (code == GIMPLE_CALL)
{
--- 239,246 ----
else if (code == GIMPLE_COND)
{
expr->type = boolean_type_node;
! expr->kind = EXPR_SINGLE;
! expr->ops.single.rhs = gimple_cond_pred (stmt);
}
else if (code == GIMPLE_CALL)
{
*************** canonicalize_comparison (gimple condstmt
*** 817,828 ****
tree op1;
enum tree_code code;
! gcc_assert (gimple_code (condstmt) == GIMPLE_COND);
! op0 = gimple_cond_lhs (condstmt);
! op1 = gimple_cond_rhs (condstmt);
!
! code = gimple_cond_code (condstmt);
/* If it would be profitable to swap the operands, then do so to
canonicalize the statement, enabling better optimization.
--- 810,819 ----
tree op1;
enum tree_code code;
! op0 = gimple_assign_rhs1 (condstmt);
! op1 = gimple_assign_rhs2 (condstmt);
! code = gimple_assign_rhs_code (condstmt);
/* If it would be profitable to swap the operands, then do so to
canonicalize the statement, enabling better optimization.
*************** canonicalize_comparison (gimple condstmt
*** 841,849 ****
{
code = swap_tree_comparison (code);
! gimple_cond_set_code (condstmt, code);
! gimple_cond_set_lhs (condstmt, op1);
! gimple_cond_set_rhs (condstmt, op0);
update_stmt (condstmt);
}
--- 832,840 ----
{
code = swap_tree_comparison (code);
! gimple_assign_set_rhs_code (condstmt, code);
! gimple_assign_set_rhs1 (condstmt, op1);
! gimple_assign_set_rhs2 (condstmt, op0);
update_stmt (condstmt);
}
*************** dom_thread_across_edge (struct dom_walk_
*** 933,942 ****
{
if (! walk_data->global_data)
{
! gimple dummy_cond =
! gimple_build_cond (NE_EXPR,
! integer_zero_node, integer_zero_node,
! NULL, NULL);
walk_data->global_data = dummy_cond;
}
--- 924,930 ----
{
if (! walk_data->global_data)
{
! gimple dummy_cond = gimple_build_cond (boolean_false_node, NULL, NULL);
walk_data->global_data = dummy_cond;
}
*************** record_equivalences_from_incoming_edge (
*** 1057,1072 ****
if (edge_info)
{
- tree lhs = edge_info->lhs;
- tree rhs = edge_info->rhs;
cond_equivalence *eq;
- if (lhs)
- record_equality (lhs, rhs);
-
for (i = 0; VEC_iterate (cond_equivalence,
edge_info->cond_equivalences, i, eq); ++i)
! record_cond (eq);
}
}
}
--- 1045,1061 ----
if (edge_info)
{
cond_equivalence *eq;
for (i = 0; VEC_iterate (cond_equivalence,
edge_info->cond_equivalences, i, eq); ++i)
! {
! if (eq->cond.ops.binary.op == EQ_EXPR
! && eq->value == boolean_true_node)
! record_equality (eq->cond.ops.binary.opnd0,
! eq->cond.ops.binary.opnd1);
! record_cond (eq);
! }
}
}
}
*************** static void
*** 1491,1497 ****
record_edge_info (basic_block bb)
{
gimple_stmt_iterator gsi = gsi_last_bb (bb);
- struct edge_info *edge_info;
if (! gsi_end_p (gsi))
{
--- 1480,1485 ----
*************** record_edge_info (basic_block bb)
*** 1501,1506 ****
--- 1489,1495 ----
if (gimple_code (stmt) == GIMPLE_SWITCH)
{
tree index = gimple_switch_index (stmt);
+ struct edge_info *edge_info;
if (TREE_CODE (index) == SSA_NAME)
{
*************** record_edge_info (basic_block bb)
*** 1532,1539 ****
tree x = fold_convert_loc (loc, TREE_TYPE (index),
CASE_LOW (label));
edge_info = allocate_edge_info (e);
! edge_info->lhs = index;
! edge_info->rhs = x;
}
}
free (info);
--- 1521,1528 ----
tree x = fold_convert_loc (loc, TREE_TYPE (index),
CASE_LOW (label));
edge_info = allocate_edge_info (e);
! build_and_record_new_cond (EQ_EXPR, index, x,
! &edge_info->cond_equivalences);
}
}
free (info);
*************** record_edge_info (basic_block bb)
*** 1543,1619 ****
/* A COND_EXPR may create equivalences too. */
if (gimple_code (stmt) == GIMPLE_COND)
{
edge true_edge;
edge false_edge;
! tree op0 = gimple_cond_lhs (stmt);
! tree op1 = gimple_cond_rhs (stmt);
! enum tree_code code = gimple_cond_code (stmt);
!
extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
! /* Special case comparing booleans against a constant as we
! know the value of OP0 on both arms of the branch. i.e., we
! can record an equivalence for OP0 rather than COND. */
! if ((code == EQ_EXPR || code == NE_EXPR)
! && TREE_CODE (op0) == SSA_NAME
! && TREE_CODE (TREE_TYPE (op0)) == BOOLEAN_TYPE
! && is_gimple_min_invariant (op1))
! {
! if (code == EQ_EXPR)
! {
! edge_info = allocate_edge_info (true_edge);
! edge_info->lhs = op0;
! edge_info->rhs = (integer_zerop (op1)
! ? boolean_false_node
! : boolean_true_node);
!
! edge_info = allocate_edge_info (false_edge);
! edge_info->lhs = op0;
! edge_info->rhs = (integer_zerop (op1)
! ? boolean_true_node
! : boolean_false_node);
! }
! else
! {
! edge_info = allocate_edge_info (true_edge);
! edge_info->lhs = op0;
! edge_info->rhs = (integer_zerop (op1)
! ? boolean_true_node
! : boolean_false_node);
!
! edge_info = allocate_edge_info (false_edge);
! edge_info->lhs = op0;
! edge_info->rhs = (integer_zerop (op1)
! ? boolean_false_node
! : boolean_true_node);
! }
! }
! else if (is_gimple_min_invariant (op0)
! && (TREE_CODE (op1) == SSA_NAME
! || is_gimple_min_invariant (op1)))
{
tree cond = build2 (code, boolean_type_node, op0, op1);
tree inverted = invert_truthvalue_loc (loc, cond);
- struct edge_info *edge_info;
-
- edge_info = allocate_edge_info (true_edge);
- record_conditions (edge_info, cond, inverted);
! if (code == EQ_EXPR)
! {
! edge_info->lhs = op1;
! edge_info->rhs = op0;
! }
!
! edge_info = allocate_edge_info (false_edge);
! record_conditions (edge_info, inverted, cond);
!
! if (TREE_CODE (inverted) == EQ_EXPR)
! {
! edge_info->lhs = op1;
! edge_info->rhs = op0;
! }
}
else if (TREE_CODE (op0) == SSA_NAME
--- 1532,1558 ----
/* A COND_EXPR may create equivalences too. */
if (gimple_code (stmt) == GIMPLE_COND)
{
+ struct edge_info *t_edge_info = NULL, *f_edge_info = NULL;
edge true_edge;
edge false_edge;
+ enum tree_code code;
+ tree op0, op1;
! gimple_cond_extract_comparison (stmt, &code, &op0, &op1);
extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
! t_edge_info = allocate_edge_info (true_edge);
! f_edge_info = allocate_edge_info (false_edge);
!
! if (is_gimple_min_invariant (op0)
! && (TREE_CODE (op1) == SSA_NAME
! || is_gimple_min_invariant (op1)))
{
tree cond = build2 (code, boolean_type_node, op0, op1);
tree inverted = invert_truthvalue_loc (loc, cond);
! record_conditions (t_edge_info, cond, inverted);
! record_conditions (f_edge_info, inverted, cond);
}
else if (TREE_CODE (op0) == SSA_NAME
*************** record_edge_info (basic_block bb)
*** 1622,1647 ****
{
tree cond = build2 (code, boolean_type_node, op0, op1);
tree inverted = invert_truthvalue_loc (loc, cond);
- struct edge_info *edge_info;
! edge_info = allocate_edge_info (true_edge);
! record_conditions (edge_info, cond, inverted);
!
! if (code == EQ_EXPR)
! {
! edge_info->lhs = op0;
! edge_info->rhs = op1;
! }
!
! edge_info = allocate_edge_info (false_edge);
! record_conditions (edge_info, inverted, cond);
!
! if (TREE_CODE (inverted) == EQ_EXPR)
! {
! edge_info->lhs = op0;
! edge_info->rhs = op1;
! }
}
}
/* ??? TRUTH_NOT_EXPR can create an equivalence too. */
--- 1561,1587 ----
{
tree cond = build2 (code, boolean_type_node, op0, op1);
tree inverted = invert_truthvalue_loc (loc, cond);
! record_conditions (t_edge_info, cond, inverted);
! record_conditions (f_edge_info, inverted, cond);
}
+
+ /* Record equivalences for the predicate itself. */
+ if (op0 != gimple_cond_pred (stmt))
+ {
+ build_and_record_new_cond (EQ_EXPR, gimple_cond_pred (stmt),
+ boolean_true_node,
+ &t_edge_info->cond_equivalences);
+ build_and_record_new_cond (NE_EXPR, gimple_cond_pred (stmt),
+ boolean_false_node,
+ &t_edge_info->cond_equivalences);
+ build_and_record_new_cond (EQ_EXPR, gimple_cond_pred (stmt),
+ boolean_false_node,
+ &f_edge_info->cond_equivalences);
+ build_and_record_new_cond (NE_EXPR, gimple_cond_pred (stmt),
+ boolean_true_node,
+ &f_edge_info->cond_equivalences);
+ }
}
/* ??? TRUTH_NOT_EXPR can create an equivalence too. */
*************** dom_opt_leave_block (struct dom_walk_dat
*** 1724,1741 ****
if (edge_info)
{
cond_equivalence *eq;
- tree lhs = edge_info->lhs;
- tree rhs = edge_info->rhs;
-
- /* If we have a simple NAME = VALUE equivalence, record it. */
- if (lhs && TREE_CODE (lhs) == SSA_NAME)
- record_const_or_copy (lhs, rhs);
/* If we have 0 = COND or 1 = COND equivalences, record them
into our expression hash tables. */
for (i = 0; VEC_iterate (cond_equivalence,
edge_info->cond_equivalences, i, eq); ++i)
! record_cond (eq);
}
dom_thread_across_edge (walk_data, true_edge);
--- 1664,1683 ----
if (edge_info)
{
cond_equivalence *eq;
/* If we have 0 = COND or 1 = COND equivalences, record them
into our expression hash tables. */
for (i = 0; VEC_iterate (cond_equivalence,
edge_info->cond_equivalences, i, eq); ++i)
! {
! /* If we have a simple NAME = VAL equivalence, record it. */
! if (eq->cond.ops.binary.op == EQ_EXPR
! && eq->value == boolean_true_node
! && TREE_CODE (eq->cond.ops.binary.opnd0) == SSA_NAME)
! record_const_or_copy (eq->cond.ops.binary.opnd0,
! eq->cond.ops.binary.opnd1);
! record_cond (eq);
! }
}
dom_thread_across_edge (walk_data, true_edge);
*************** dom_opt_leave_block (struct dom_walk_dat
*** 1759,1776 ****
if (edge_info)
{
cond_equivalence *eq;
- tree lhs = edge_info->lhs;
- tree rhs = edge_info->rhs;
-
- /* If we have a simple NAME = VALUE equivalence, record it. */
- if (lhs && TREE_CODE (lhs) == SSA_NAME)
- record_const_or_copy (lhs, rhs);
/* If we have 0 = COND or 1 = COND equivalences, record them
into our expression hash tables. */
for (i = 0; VEC_iterate (cond_equivalence,
edge_info->cond_equivalences, i, eq); ++i)
! record_cond (eq);
}
/* Now thread the edge. */
--- 1701,1720 ----
if (edge_info)
{
cond_equivalence *eq;
/* If we have 0 = COND or 1 = COND equivalences, record them
into our expression hash tables. */
for (i = 0; VEC_iterate (cond_equivalence,
edge_info->cond_equivalences, i, eq); ++i)
! {
! /* If we have a simple NAME = VAL equivalence, record it. */
! if (eq->cond.ops.binary.op == EQ_EXPR
! && eq->value == boolean_true_node
! && TREE_CODE (eq->cond.ops.binary.opnd0) == SSA_NAME)
! record_const_or_copy (eq->cond.ops.binary.opnd0,
! eq->cond.ops.binary.opnd1);
! record_cond (eq);
! }
}
/* Now thread the edge. */
*************** optimize_stmt (basic_block bb, gimple_st
*** 2094,2102 ****
old_stmt = stmt = gsi_stmt (si);
- if (gimple_code (stmt) == GIMPLE_COND)
- canonicalize_comparison (stmt);
-
update_stmt_if_modified (stmt);
opt_stats.num_stmts++;
--- 2038,2043 ----
*************** optimize_stmt (basic_block bb, gimple_st
*** 2147,2152 ****
--- 2088,2097 ----
modified_p = true;
}
+ if (is_gimple_assign (stmt)
+ && TREE_CODE_CLASS (gimple_assign_rhs_code (stmt)) == tcc_comparison)
+ canonicalize_comparison (stmt);
+
/* Check for redundant computations. Do this optimization only
for assignments that have no volatile ops and conditionals. */
may_optimize_p = (!gimple_has_volatile_ops (stmt)
*************** optimize_stmt (basic_block bb, gimple_st
*** 2216,2224 ****
update_stmt_if_modified (stmt);
if (gimple_code (stmt) == GIMPLE_COND)
! val = fold_binary_loc (gimple_location (stmt),
! gimple_cond_code (stmt), boolean_type_node,
! gimple_cond_lhs (stmt), gimple_cond_rhs (stmt));
else if (gimple_code (stmt) == GIMPLE_SWITCH)
val = gimple_switch_index (stmt);
--- 2161,2167 ----
update_stmt_if_modified (stmt);
if (gimple_code (stmt) == GIMPLE_COND)
! val = gimple_cond_pred (stmt);
else if (gimple_code (stmt) == GIMPLE_SWITCH)
val = gimple_switch_index (stmt);
*************** propagate_rhs_into_lhs (gimple stmt, tre
*** 2652,2662 ****
tree val;
if (gimple_code (use_stmt) == GIMPLE_COND)
! val = fold_binary_loc (gimple_location (use_stmt),
! gimple_cond_code (use_stmt),
! boolean_type_node,
! gimple_cond_lhs (use_stmt),
! gimple_cond_rhs (use_stmt));
else if (gimple_code (use_stmt) == GIMPLE_SWITCH)
val = gimple_switch_index (use_stmt);
else
--- 2595,2601 ----
tree val;
if (gimple_code (use_stmt) == GIMPLE_COND)
! val = gimple_cond_pred (use_stmt);
else if (gimple_code (use_stmt) == GIMPLE_SWITCH)
val = gimple_switch_index (use_stmt);
else
Index: trunk/gcc/tree-ssa-forwprop.c
===================================================================
*** trunk.orig/gcc/tree-ssa-forwprop.c 2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/tree-ssa-forwprop.c 2010-08-30 14:32:23.000000000 +0200
*************** combine_cond_expr_cond (location_t loc,
*** 387,492 ****
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_cond. */
static int
forward_propagate_into_gimple_cond (gimple stmt)
{
! int did_something = 0;
! location_t loc = gimple_location (stmt);
!
! do {
! tree tmp = NULL_TREE;
! tree name = NULL_TREE, rhs0 = NULL_TREE, rhs1 = NULL_TREE;
! gimple def_stmt;
! bool single_use0_p = false, single_use1_p = false;
! enum tree_code code = gimple_cond_code (stmt);
!
! /* We can do tree combining on SSA_NAME and comparison expressions. */
! if (TREE_CODE_CLASS (gimple_cond_code (stmt)) == tcc_comparison)
! {
! /* For comparisons use the first operand, that is likely to
! simplify comparisons against constants. */
! if (TREE_CODE (gimple_cond_lhs (stmt)) == SSA_NAME)
! {
! name = gimple_cond_lhs (stmt);
! def_stmt = get_prop_source_stmt (name, false, &single_use0_p);
! if (def_stmt && can_propagate_from (def_stmt))
! {
! tree op1 = gimple_cond_rhs (stmt);
! rhs0 = rhs_to_tree (TREE_TYPE (op1), def_stmt);
! tmp = combine_cond_expr_cond (loc, code, boolean_type_node,
! rhs0, op1, !single_use0_p);
! }
! }
! /* If that wasn't successful, try the second operand. */
! if (tmp == NULL_TREE
! && TREE_CODE (gimple_cond_rhs (stmt)) == SSA_NAME)
! {
! tree op0 = gimple_cond_lhs (stmt);
! name = gimple_cond_rhs (stmt);
! def_stmt = get_prop_source_stmt (name, false, &single_use1_p);
! if (!def_stmt || !can_propagate_from (def_stmt))
! return did_something;
!
! rhs1 = rhs_to_tree (TREE_TYPE (op0), def_stmt);
! tmp = combine_cond_expr_cond (loc, code, boolean_type_node, op0,
! rhs1, !single_use1_p);
! }
! /* If that wasn't successful either, try both operands. */
! if (tmp == NULL_TREE
! && rhs0 != NULL_TREE
! && rhs1 != NULL_TREE)
! tmp = combine_cond_expr_cond (loc, code, boolean_type_node, rhs0,
! fold_convert_loc (loc,
! TREE_TYPE (rhs0),
! rhs1),
! !(single_use0_p && single_use1_p));
! }
!
! if (tmp)
! {
! if (dump_file && tmp)
! {
! tree cond = build2 (gimple_cond_code (stmt),
! boolean_type_node,
! gimple_cond_lhs (stmt),
! gimple_cond_rhs (stmt));
! fprintf (dump_file, " Replaced '");
! print_generic_expr (dump_file, cond, 0);
! fprintf (dump_file, "' with '");
! print_generic_expr (dump_file, tmp, 0);
! fprintf (dump_file, "'\n");
! }
!
! gimple_cond_set_condition_from_tree (stmt, unshare_expr (tmp));
! update_stmt (stmt);
! /* Remove defining statements. */
! remove_prop_source_from_use (name, NULL);
! if (is_gimple_min_invariant (tmp))
! did_something = 2;
! else if (did_something == 0)
! did_something = 1;
! /* Continue combining. */
! continue;
! }
! break;
! } while (1);
! return did_something;
}
/* 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)
--- 387,450 ----
Returns zero if no statement was changed, one if there were
changes and two if cfg_cleanup needs to run.
! This does simple constant propagation into the predicate. */
static int
forward_propagate_into_gimple_cond (gimple stmt)
{
! tree cond = gimple_cond_pred (stmt);
! gimple def_stmt;
! if (TREE_CODE (cond) != SSA_NAME)
! return 0;
! def_stmt = SSA_NAME_DEF_STMT (cond);
! /* Forward propagate constants. */
! if (gimple_assign_single_p (def_stmt))
! {
! cond = gimple_assign_rhs1 (def_stmt);
! if (integer_nonzerop (cond))
! {
! gimple_cond_make_true (stmt);
! update_stmt (stmt);
! return 2;
! }
! else if (integer_zerop (cond))
! {
! gimple_cond_make_false (stmt);
! update_stmt (stmt);
! return 2;
! }
! }
! /* We can forward propagate !pred into the condition by
! switching edges. */
! if (is_gimple_assign (def_stmt)
! && gimple_assign_rhs_code (def_stmt) == TRUTH_NOT_EXPR)
! {
! edge_iterator ei;
! edge e;
! gimple_cond_set_pred (stmt, gimple_assign_rhs1 (def_stmt));
! FOR_EACH_EDGE (e, ei, gimple_bb (stmt)->succs)
! {
! if (e->flags & EDGE_TRUE_VALUE)
! e->flags = (e->flags & ~EDGE_TRUE_VALUE) | EDGE_FALSE_VALUE;
! else
! e->flags = (e->flags & ~EDGE_FALSE_VALUE) | EDGE_TRUE_VALUE;
! }
! update_stmt (stmt);
! return 1;
! }
! return 0;
}
/* 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. */
static int
forward_propagate_into_cond (gimple_stmt_iterator *gsi_p)
*************** forward_propagate_into_cond (gimple_stmt
*** 497,569 ****
do {
tree tmp = NULL_TREE;
! tree cond = gimple_assign_rhs1 (stmt);
tree name, rhs0 = NULL_TREE, rhs1 = NULL_TREE;
gimple def_stmt;
bool single_use0_p = false, single_use1_p = false;
/* We can do tree combining on SSA_NAME and comparison expressions. */
! if (COMPARISON_CLASS_P (cond)
! && TREE_CODE (TREE_OPERAND (cond, 0)) == SSA_NAME)
{
/* For comparisons use the first operand, that is likely to
simplify comparisons against constants. */
! name = TREE_OPERAND (cond, 0);
def_stmt = get_prop_source_stmt (name, false, &single_use0_p);
if (def_stmt && can_propagate_from (def_stmt))
{
! tree op1 = TREE_OPERAND (cond, 1);
! rhs0 = rhs_to_tree (TREE_TYPE (op1), def_stmt);
! tmp = combine_cond_expr_cond (loc, TREE_CODE (cond),
! boolean_type_node,
! rhs0, op1, !single_use0_p);
}
/* If that wasn't successful, try the second operand. */
if (tmp == NULL_TREE
! && TREE_CODE (TREE_OPERAND (cond, 1)) == SSA_NAME)
{
! tree op0 = TREE_OPERAND (cond, 0);
! name = TREE_OPERAND (cond, 1);
def_stmt = get_prop_source_stmt (name, false, &single_use1_p);
if (!def_stmt || !can_propagate_from (def_stmt))
return did_something;
! rhs1 = rhs_to_tree (TREE_TYPE (op0), def_stmt);
! tmp = combine_cond_expr_cond (loc, TREE_CODE (cond),
! boolean_type_node,
! op0, rhs1, !single_use1_p);
}
/* If that wasn't successful either, try both operands. */
if (tmp == NULL_TREE
&& rhs0 != NULL_TREE
&& rhs1 != NULL_TREE)
! tmp = combine_cond_expr_cond (loc, TREE_CODE (cond),
! boolean_type_node,
rhs0,
fold_convert_loc (loc,
TREE_TYPE (rhs0),
rhs1),
!(single_use0_p && single_use1_p));
}
- else if (TREE_CODE (cond) == SSA_NAME)
- {
- name = cond;
- def_stmt = get_prop_source_stmt (name, true, NULL);
- if (def_stmt || !can_propagate_from (def_stmt))
- return did_something;
-
- rhs0 = gimple_assign_rhs1 (def_stmt);
- tmp = combine_cond_expr_cond (loc, NE_EXPR, boolean_type_node, rhs0,
- build_int_cst (TREE_TYPE (rhs0), 0),
- false);
- }
if (tmp)
{
if (dump_file && tmp)
{
fprintf (dump_file, " Replaced '");
! print_generic_expr (dump_file, cond, 0);
fprintf (dump_file, "' with '");
print_generic_expr (dump_file, tmp, 0);
fprintf (dump_file, "'\n");
--- 455,514 ----
do {
tree tmp = NULL_TREE;
! enum tree_code code = gimple_assign_rhs_code (stmt);
! tree cond_lhs = gimple_assign_rhs1 (stmt);
! tree cond_rhs = gimple_assign_rhs2 (stmt);
! tree type = TREE_TYPE (gimple_assign_lhs (stmt));
tree name, rhs0 = NULL_TREE, rhs1 = NULL_TREE;
gimple def_stmt;
bool single_use0_p = false, single_use1_p = false;
/* We can do tree combining on SSA_NAME and comparison expressions. */
! if (TREE_CODE (cond_lhs) == SSA_NAME)
{
/* For comparisons use the first operand, that is likely to
simplify comparisons against constants. */
! name = cond_lhs;
def_stmt = get_prop_source_stmt (name, false, &single_use0_p);
if (def_stmt && can_propagate_from (def_stmt))
{
! rhs0 = rhs_to_tree (TREE_TYPE (cond_rhs), def_stmt);
! tmp = combine_cond_expr_cond (loc, code, type,
! rhs0, cond_rhs, !single_use0_p);
}
/* If that wasn't successful, try the second operand. */
if (tmp == NULL_TREE
! && TREE_CODE (cond_rhs) == SSA_NAME)
{
! name = cond_rhs;
def_stmt = get_prop_source_stmt (name, false, &single_use1_p);
if (!def_stmt || !can_propagate_from (def_stmt))
return did_something;
! rhs1 = rhs_to_tree (TREE_TYPE (cond_lhs), def_stmt);
! tmp = combine_cond_expr_cond (loc, code, type,
! cond_lhs, rhs1, !single_use1_p);
}
/* If that wasn't successful either, try both operands. */
if (tmp == NULL_TREE
&& rhs0 != NULL_TREE
&& rhs1 != NULL_TREE)
! tmp = combine_cond_expr_cond (loc, code, type,
rhs0,
fold_convert_loc (loc,
TREE_TYPE (rhs0),
rhs1),
!(single_use0_p && single_use1_p));
}
if (tmp)
{
if (dump_file && tmp)
{
fprintf (dump_file, " Replaced '");
! print_generic_expr (dump_file, cond_lhs, 0);
! fprintf (dump_file, " %s ", op_symbol_code (code));
! print_generic_expr (dump_file, cond_rhs, 0);
fprintf (dump_file, "' with '");
print_generic_expr (dump_file, tmp, 0);
fprintf (dump_file, "'\n");
*************** forward_propagate_into_cond (gimple_stmt
*** 581,588 ****
else if (did_something == 0)
did_something = 1;
! /* Continue combining. */
! continue;
}
break;
--- 526,534 ----
else if (did_something == 0)
did_something = 1;
! /* Continue combining if we can. */
! if (TREE_CODE_CLASS (gimple_assign_rhs_code (stmt)) == tcc_comparison)
! continue;
}
break;
*************** tree_ssa_forward_propagate_single_use_va
*** 1729,1751 ****
simplify_not_neg_expr (&gsi);
gsi_next (&gsi);
}
! else if (gimple_assign_rhs_code (stmt) == COND_EXPR)
! {
/* In this case the entire COND_EXPR is in rhs1. */
int did_something;
fold_defer_overflow_warnings ();
did_something = forward_propagate_into_cond (&gsi);
stmt = gsi_stmt (gsi);
- if (did_something == 2)
- cfg_changed = true;
fold_undefer_overflow_warnings (!TREE_NO_WARNING (rhs)
&& did_something, stmt, WARN_STRICT_OVERFLOW_CONDITIONAL);
! gsi_next (&gsi);
! }
! else if (TREE_CODE_CLASS (gimple_assign_rhs_code (stmt))
! == tcc_comparison)
! {
! if (forward_propagate_comparison (stmt))
{
release_defs (stmt);
todoflags |= TODO_remove_unused_locals;
--- 1675,1693 ----
simplify_not_neg_expr (&gsi);
gsi_next (&gsi);
}
! else if (TREE_CODE_CLASS (gimple_assign_rhs_code (stmt))
! == tcc_comparison)
! {
/* In this case the entire COND_EXPR is in rhs1. */
int did_something;
fold_defer_overflow_warnings ();
did_something = forward_propagate_into_cond (&gsi);
stmt = gsi_stmt (gsi);
fold_undefer_overflow_warnings (!TREE_NO_WARNING (rhs)
&& did_something, stmt, WARN_STRICT_OVERFLOW_CONDITIONAL);
! if ((TREE_CODE_CLASS (gimple_assign_rhs_code (stmt))
! == tcc_comparison)
! && forward_propagate_comparison (stmt))
{
release_defs (stmt);
todoflags |= TODO_remove_unused_locals;
Index: trunk/gcc/tree-ssa-ifcombine.c
===================================================================
*** trunk.orig/gcc/tree-ssa-ifcombine.c 2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/tree-ssa-ifcombine.c 2010-08-30 14:32:23.000000000 +0200
*************** static bool
*** 171,183 ****
recognize_single_bit_test (gimple cond, tree *name, tree *bit)
{
gimple stmt;
/* Get at the definition of the result of the bit test. */
! if (gimple_cond_code (cond) != NE_EXPR
! || TREE_CODE (gimple_cond_lhs (cond)) != SSA_NAME
! || !integer_zerop (gimple_cond_rhs (cond)))
return false;
! stmt = SSA_NAME_DEF_STMT (gimple_cond_lhs (cond));
if (!is_gimple_assign (stmt))
return false;
--- 171,187 ----
recognize_single_bit_test (gimple cond, tree *name, tree *bit)
{
gimple stmt;
+ enum tree_code code;
+ tree lhs, rhs;
+
+ gimple_cond_extract_comparison (cond, &code, &lhs, &rhs);
/* Get at the definition of the result of the bit test. */
! if (code != NE_EXPR
! || TREE_CODE (lhs) != SSA_NAME
! || !integer_zerop (rhs))
return false;
! stmt = SSA_NAME_DEF_STMT (lhs);
if (!is_gimple_assign (stmt))
return false;
*************** static bool
*** 279,291 ****
recognize_bits_test (gimple cond, tree *name, tree *bits)
{
gimple stmt;
/* Get at the definition of the result of the bit test. */
! if (gimple_cond_code (cond) != NE_EXPR
! || TREE_CODE (gimple_cond_lhs (cond)) != SSA_NAME
! || !integer_zerop (gimple_cond_rhs (cond)))
return false;
! stmt = SSA_NAME_DEF_STMT (gimple_cond_lhs (cond));
if (!is_gimple_assign (stmt)
|| gimple_assign_rhs_code (stmt) != BIT_AND_EXPR)
return false;
--- 283,299 ----
recognize_bits_test (gimple cond, tree *name, tree *bits)
{
gimple stmt;
+ enum tree_code code;
+ tree lhs, rhs;
+
+ gimple_cond_extract_comparison (cond, &code, &lhs, &rhs);
/* Get at the definition of the result of the bit test. */
! if (code != NE_EXPR
! || TREE_CODE (lhs) != SSA_NAME
! || !integer_zerop (rhs))
return false;
! stmt = SSA_NAME_DEF_STMT (lhs);
if (!is_gimple_assign (stmt)
|| gimple_assign_rhs_code (stmt) != BIT_AND_EXPR)
return false;
*************** ifcombine_ifandif (basic_block inner_con
*** 340,353 ****
t2 = force_gimple_operand_gsi (&gsi, t2, true, NULL_TREE,
true, GSI_SAME_STMT);
t = fold_build2 (EQ_EXPR, boolean_type_node, t2, t);
! t = canonicalize_cond_expr_cond (t);
! if (!t)
! return false;
! gimple_cond_set_condition_from_tree (inner_cond, t);
update_stmt (inner_cond);
/* Leave CFG optimization to cfg_cleanup. */
! gimple_cond_set_condition_from_tree (outer_cond, boolean_true_node);
update_stmt (outer_cond);
if (dump_file)
--- 348,360 ----
t2 = force_gimple_operand_gsi (&gsi, t2, true, NULL_TREE,
true, GSI_SAME_STMT);
t = fold_build2 (EQ_EXPR, boolean_type_node, t2, t);
! t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
! true, GSI_SAME_STMT);
! gimple_cond_set_pred (inner_cond, t);
update_stmt (inner_cond);
/* Leave CFG optimization to cfg_cleanup. */
! gimple_cond_make_true (outer_cond);
update_stmt (outer_cond);
if (dump_file)
*************** ifcombine_ifandif (basic_block inner_con
*** 365,390 ****
}
/* See if we have two comparisons that we can merge into one. */
! else if (TREE_CODE_CLASS (gimple_cond_code (inner_cond)) == tcc_comparison
! && TREE_CODE_CLASS (gimple_cond_code (outer_cond)) == tcc_comparison)
{
tree t;
! if (!(t = maybe_fold_and_comparisons (gimple_cond_code (inner_cond),
! gimple_cond_lhs (inner_cond),
! gimple_cond_rhs (inner_cond),
! gimple_cond_code (outer_cond),
! gimple_cond_lhs (outer_cond),
! gimple_cond_rhs (outer_cond))))
return false;
t = canonicalize_cond_expr_cond (t);
if (!t)
return false;
! gimple_cond_set_condition_from_tree (inner_cond, t);
update_stmt (inner_cond);
/* Leave CFG optimization to cfg_cleanup. */
! gimple_cond_set_condition_from_tree (outer_cond, boolean_true_node);
update_stmt (outer_cond);
if (dump_file)
--- 372,400 ----
}
/* See if we have two comparisons that we can merge into one. */
! else
{
+ enum tree_code code1, code2;
+ tree lhs1, lhs2, rhs1, rhs2;
tree t;
+ gimple_stmt_iterator gsi;
+
+ gimple_cond_extract_comparison (inner_cond, &code1, &lhs1, &rhs1);
+ gimple_cond_extract_comparison (outer_cond, &code2, &lhs2, &rhs2);
! if (!(t = maybe_fold_and_comparisons (code1, lhs1, rhs1,
! code2, lhs2, rhs2)))
return false;
t = canonicalize_cond_expr_cond (t);
if (!t)
return false;
! gsi = gsi_for_stmt (inner_cond);
! t = force_gimple_operand_gsi (&gsi, t, true, NULL, true, GSI_SAME_STMT);
! gimple_cond_set_pred (inner_cond, t);
update_stmt (inner_cond);
/* Leave CFG optimization to cfg_cleanup. */
! gimple_cond_make_true (outer_cond);
update_stmt (outer_cond);
if (dump_file)
*************** ifcombine_iforif (basic_block inner_cond
*** 486,499 ****
true, GSI_SAME_STMT);
t = fold_build2 (NE_EXPR, boolean_type_node, t,
build_int_cst (TREE_TYPE (t), 0));
! t = canonicalize_cond_expr_cond (t);
! if (!t)
! return false;
! gimple_cond_set_condition_from_tree (inner_cond, t);
update_stmt (inner_cond);
/* Leave CFG optimization to cfg_cleanup. */
! gimple_cond_set_condition_from_tree (outer_cond, boolean_false_node);
update_stmt (outer_cond);
if (dump_file)
--- 496,508 ----
true, GSI_SAME_STMT);
t = fold_build2 (NE_EXPR, boolean_type_node, t,
build_int_cst (TREE_TYPE (t), 0));
! t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
! true, GSI_SAME_STMT);
! gimple_cond_set_pred (inner_cond, t);
update_stmt (inner_cond);
/* Leave CFG optimization to cfg_cleanup. */
! gimple_cond_make_false (outer_cond);
update_stmt (outer_cond);
if (dump_file)
*************** ifcombine_iforif (basic_block inner_cond
*** 513,538 ****
/* See if we have two comparisons that we can merge into one.
This happens for C++ operator overloading where for example
GE_EXPR is implemented as GT_EXPR || EQ_EXPR. */
! else if (TREE_CODE_CLASS (gimple_cond_code (inner_cond)) == tcc_comparison
! && TREE_CODE_CLASS (gimple_cond_code (outer_cond)) == tcc_comparison)
{
tree t;
! if (!(t = maybe_fold_or_comparisons (gimple_cond_code (inner_cond),
! gimple_cond_lhs (inner_cond),
! gimple_cond_rhs (inner_cond),
! gimple_cond_code (outer_cond),
! gimple_cond_lhs (outer_cond),
! gimple_cond_rhs (outer_cond))))
return false;
t = canonicalize_cond_expr_cond (t);
if (!t)
return false;
! gimple_cond_set_condition_from_tree (inner_cond, t);
update_stmt (inner_cond);
/* Leave CFG optimization to cfg_cleanup. */
! gimple_cond_set_condition_from_tree (outer_cond, boolean_false_node);
update_stmt (outer_cond);
if (dump_file)
--- 522,550 ----
/* See if we have two comparisons that we can merge into one.
This happens for C++ operator overloading where for example
GE_EXPR is implemented as GT_EXPR || EQ_EXPR. */
! else
{
+ enum tree_code code1, code2;
+ tree lhs1, lhs2, rhs1, rhs2;
tree t;
+ gimple_stmt_iterator gsi;
! gimple_cond_extract_comparison (inner_cond, &code1, &lhs1, &rhs1);
! gimple_cond_extract_comparison (outer_cond, &code2, &lhs2, &rhs2);
!
! if (!(t = maybe_fold_or_comparisons (code1, lhs1, rhs1,
! code2, lhs2, rhs2)))
return false;
t = canonicalize_cond_expr_cond (t);
if (!t)
return false;
! gsi = gsi_for_stmt (inner_cond);
! t = force_gimple_operand_gsi (&gsi, t, true, NULL, true, GSI_SAME_STMT);
! gimple_cond_set_pred (inner_cond, t);
update_stmt (inner_cond);
/* Leave CFG optimization to cfg_cleanup. */
! gimple_cond_make_false (outer_cond);
update_stmt (outer_cond);
if (dump_file)
Index: trunk/gcc/tree-ssa-loop-im.c
===================================================================
*** trunk.orig/gcc/tree-ssa-loop-im.c 2010-08-25 16:49:48.000000000 +0200
--- trunk/gcc/tree-ssa-loop-im.c 2010-08-30 14:32:23.000000000 +0200
*************** rewrite_bittest (gimple_stmt_iterator *b
*** 956,967 ****
/* Verify that the single use of lhs is a comparison against zero. */
if (TREE_CODE (lhs) != SSA_NAME
|| !single_imm_use (lhs, &use, &use_stmt)
! || gimple_code (use_stmt) != GIMPLE_COND)
return stmt;
! if (gimple_cond_lhs (use_stmt) != lhs
! || (gimple_cond_code (use_stmt) != NE_EXPR
! && gimple_cond_code (use_stmt) != EQ_EXPR)
! || !integer_zerop (gimple_cond_rhs (use_stmt)))
return stmt;
/* Get at the operands of the shift. The rhs is TMP1 & 1. */
--- 956,967 ----
/* Verify that the single use of lhs is a comparison against zero. */
if (TREE_CODE (lhs) != SSA_NAME
|| !single_imm_use (lhs, &use, &use_stmt)
! || gimple_code (use_stmt) != GIMPLE_ASSIGN)
return stmt;
! if ((gimple_assign_rhs_code (use_stmt) != NE_EXPR
! && gimple_assign_rhs_code (use_stmt) != EQ_EXPR)
! || gimple_assign_rhs1 (use_stmt) != lhs
! || !integer_zerop (gimple_assign_rhs2 (use_stmt)))
return stmt;
/* Get at the operands of the shift. The rhs is TMP1 & 1. */
*************** rewrite_bittest (gimple_stmt_iterator *b
*** 1013,1019 ****
/* Replace the SSA_NAME we compare against zero. Adjust
the type of zero accordingly. */
SET_USE (use, name);
! gimple_cond_set_rhs (use_stmt, build_int_cst_type (TREE_TYPE (name), 0));
/* Don't use gsi_replace here, none of the new assignments sets
the variable originally set in stmt. Move bsi to stmt1, and
--- 1013,1020 ----
/* Replace the SSA_NAME we compare against zero. Adjust
the type of zero accordingly. */
SET_USE (use, name);
! gimple_assign_set_rhs2 (use_stmt,
! build_int_cst_type (TREE_TYPE (name), 0));
/* Don't use gsi_replace here, none of the new assignments sets
the variable originally set in stmt. Move bsi to stmt1, and
*************** move_computations_stmt (struct dom_walk_
*** 1250,1259 ****
edges of COND. */
extract_true_false_args_from_phi (dom, stmt, &arg0, &arg1);
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);
--- 1251,1258 ----
edges of COND. */
extract_true_false_args_from_phi (dom, stmt, &arg0, &arg1);
gcc_assert (arg0 && arg1);
t = build3 (COND_EXPR, TREE_TYPE (gimple_phi_result (stmt)),
! gimple_cond_pred (cond), arg0, arg1);
new_stmt = gimple_build_assign_with_ops (COND_EXPR,
gimple_phi_result (stmt),
t, NULL_TREE);
Index: trunk/gcc/tree-ssa-loop-ivcanon.c
===================================================================
*** trunk.orig/gcc/tree-ssa-loop-ivcanon.c 2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/tree-ssa-loop-ivcanon.c 2010-08-30 14:32:23.000000000 +0200
*************** create_canonical_iv (struct loop *loop,
*** 74,80 ****
tree type, var;
gimple cond;
gimple_stmt_iterator incr_at;
! enum tree_code cmp;
if (dump_file && (dump_flags & TDF_DETAILS))
{
--- 74,80 ----
tree type, var;
gimple cond;
gimple_stmt_iterator incr_at;
! tree cmp;
if (dump_file && (dump_flags & TDF_DETAILS))
{
*************** create_canonical_iv (struct loop *loop,
*** 103,112 ****
NULL_TREE, loop,
&incr_at, false, NULL, &var);
! cmp = (exit->flags & EDGE_TRUE_VALUE) ? EQ_EXPR : NE_EXPR;
! gimple_cond_set_code (cond, cmp);
! gimple_cond_set_lhs (cond, var);
! gimple_cond_set_rhs (cond, build_int_cst (type, 0));
update_stmt (cond);
}
--- 103,114 ----
NULL_TREE, loop,
&incr_at, false, NULL, &var);
! cmp = fold_build2 ((exit->flags & EDGE_TRUE_VALUE) ? EQ_EXPR : NE_EXPR,
! boolean_type_node, var, build_int_cst (type, 0));
! incr_at = gsi_for_stmt (cond);
! cmp = force_gimple_operand_gsi (&incr_at, cmp, true, NULL,
! true, GSI_SAME_STMT);
! gimple_cond_set_pred (cond, cmp);
update_stmt (cond);
}
*************** tree_estimate_loop_size (struct loop *lo
*** 266,273 ****
}
/* Conditionals. */
else if (gimple_code (stmt) == GIMPLE_COND
! && constant_after_peeling (gimple_cond_lhs (stmt), stmt, loop)
! && constant_after_peeling (gimple_cond_rhs (stmt), stmt, loop))
{
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, " Constant conditional.\n");
--- 268,275 ----
}
/* Conditionals. */
else if (gimple_code (stmt) == GIMPLE_COND
! && constant_after_peeling (gimple_cond_pred (stmt),
! stmt, loop))
{
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, " Constant conditional.\n");
Index: trunk/gcc/tree-ssa-loop-ivopts.c
===================================================================
*** trunk.orig/gcc/tree-ssa-loop-ivopts.c 2010-08-29 16:30:58.000000000 +0200
--- trunk/gcc/tree-ssa-loop-ivopts.c 2010-08-30 14:32:23.000000000 +0200
*************** extract_cond_operands (struct ivopts_dat
*** 1299,1314 ****
struct iv *iv0 = &const_iv, *iv1 = &const_iv, *tmp_iv;
bool ret = false;
! if (gimple_code (stmt) == GIMPLE_COND)
! {
! op0 = gimple_cond_lhs_ptr (stmt);
! op1 = gimple_cond_rhs_ptr (stmt);
! }
! else
! {
! op0 = gimple_assign_rhs1_ptr (stmt);
! op1 = gimple_assign_rhs2_ptr (stmt);
! }
zero = integer_zero_node;
const_iv.step = integer_zero_node;
--- 1299,1306 ----
struct iv *iv0 = &const_iv, *iv1 = &const_iv, *tmp_iv;
bool ret = false;
! op0 = gimple_assign_rhs1_ptr (stmt);
! op1 = gimple_assign_rhs2_ptr (stmt);
zero = integer_zero_node;
const_iv.step = integer_zero_node;
*************** find_interesting_uses_stmt (struct ivopt
*** 1826,1832 ****
if (gimple_code (stmt) == GIMPLE_COND)
{
! find_interesting_uses_cond (data, stmt);
return;
}
--- 1818,1824 ----
if (gimple_code (stmt) == GIMPLE_COND)
{
! find_interesting_uses_op (data, gimple_cond_pred (stmt));
return;
}
*************** rewrite_use_compare (struct ivopts_data
*** 6071,6079 ****
loop_preheader_edge (data->current_loop),
stmts);
! gimple_cond_set_lhs (use->stmt, var);
! gimple_cond_set_code (use->stmt, compare);
! gimple_cond_set_rhs (use->stmt, op);
return;
}
--- 6063,6071 ----
loop_preheader_edge (data->current_loop),
stmts);
! gimple_assign_set_rhs1 (use->stmt, var);
! gimple_assign_set_rhs_code (use->stmt, compare);
! gimple_assign_set_rhs2 (use->stmt, op);
return;
}
Index: trunk/gcc/tree-ssa-loop-manip.c
===================================================================
*** trunk.orig/gcc/tree-ssa-loop-manip.c 2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/tree-ssa-loop-manip.c 2010-08-30 14:32:23.000000000 +0200
*************** tree_transform_and_unroll_loop (struct l
*** 958,966 ****
REG_BR_PROB_BASE - exit->probability);
bsi = gsi_last_bb (exit_bb);
! exit_if = gimple_build_cond (EQ_EXPR, integer_zero_node,
! integer_zero_node,
! NULL_TREE, NULL_TREE);
gsi_insert_after (&bsi, exit_if, GSI_NEW_STMT);
new_exit = make_edge (exit_bb, rest, EDGE_FALSE_VALUE | irr);
--- 958,964 ----
REG_BR_PROB_BASE - exit->probability);
bsi = gsi_last_bb (exit_bb);
! exit_if = gimple_build_cond (boolean_true_node, NULL_TREE, NULL_TREE);
gsi_insert_after (&bsi, exit_if, GSI_NEW_STMT);
new_exit = make_edge (exit_bb, rest, EDGE_FALSE_VALUE | irr);
*************** tree_transform_and_unroll_loop (struct l
*** 1085,1093 ****
exit_if = gsi_stmt (bsi);
create_iv (exit_base, exit_step, NULL_TREE, loop,
&bsi, false, &ctr_before, &ctr_after);
! gimple_cond_set_code (exit_if, exit_cmp);
! gimple_cond_set_lhs (exit_if, ctr_after);
! gimple_cond_set_rhs (exit_if, exit_bound);
update_stmt (exit_if);
#ifdef ENABLE_CHECKING
--- 1083,1090 ----
exit_if = gsi_stmt (bsi);
create_iv (exit_base, exit_step, NULL_TREE, loop,
&bsi, false, &ctr_before, &ctr_after);
! gimple_update_cond_from_comparison (gsi_for_stmt (exit_if),
! exit_cmp, ctr_after, exit_bound);
update_stmt (exit_if);
#ifdef ENABLE_CHECKING
*************** canonicalize_loop_ivs (struct loop *loop
*** 1233,1241 ****
te->flags = EDGE_FALSE_VALUE;
fe->flags = EDGE_TRUE_VALUE;
}
! gimple_cond_set_code (stmt, LT_EXPR);
! gimple_cond_set_lhs (stmt, var_before);
! gimple_cond_set_rhs (stmt, *nit);
update_stmt (stmt);
return var_before;
--- 1230,1237 ----
te->flags = EDGE_FALSE_VALUE;
fe->flags = EDGE_TRUE_VALUE;
}
! gimple_update_cond_from_comparison (gsi_for_stmt (stmt),
! LT_EXPR, var_before, *nit);
update_stmt (stmt);
return var_before;
Index: trunk/gcc/tree-ssa-loop-niter.c
===================================================================
*** trunk.orig/gcc/tree-ssa-loop-niter.c 2010-08-29 16:30:26.000000000 +0200
--- trunk/gcc/tree-ssa-loop-niter.c 2010-08-30 14:32:23.000000000 +0200
*************** bound_difference (struct loop *loop, tre
*** 431,439 ****
continue;
cond = last_stmt (e->src);
! c0 = gimple_cond_lhs (cond);
! cmp = gimple_cond_code (cond);
! c1 = gimple_cond_rhs (cond);
if (e->flags & EDGE_FALSE_VALUE)
cmp = invert_tree_comparison (cmp, false);
--- 431,437 ----
continue;
cond = last_stmt (e->src);
! gimple_cond_extract_comparison (cond, &cmp, &c0, &c1);
if (e->flags & EDGE_FALSE_VALUE)
cmp = invert_tree_comparison (cmp, false);
*************** simplify_using_initial_conditions (struc
*** 1661,1672 ****
continue;
stmt = last_stmt (e->src);
! cond = fold_build2 (gimple_cond_code (stmt),
! boolean_type_node,
! gimple_cond_lhs (stmt),
! gimple_cond_rhs (stmt));
! if (e->flags & EDGE_FALSE_VALUE)
! cond = invert_truthvalue (cond);
expr = tree_simplify_using_condition (cond, expr);
++cnt;
}
--- 1659,1674 ----
continue;
stmt = last_stmt (e->src);
! cond = gimple_cond_pred (stmt);
! if (TREE_CODE (cond) == SSA_NAME)
! {
! enum tree_code code;
! tree lhs, rhs;
! gimple_cond_extract_comparison (stmt, &code, &lhs, &rhs);
! cond = fold_build2 (code, boolean_type_node, lhs, rhs);
! if (e->flags & EDGE_FALSE_VALUE)
! cond = invert_truthvalue (cond);
! }
expr = tree_simplify_using_condition (cond, expr);
++cnt;
}
*************** number_of_iterations_exit (struct loop *
*** 1791,1797 ****
return false;
/* We want the condition for staying inside loop. */
! code = gimple_cond_code (stmt);
if (exit->flags & EDGE_TRUE_VALUE)
code = invert_tree_comparison (code, false);
--- 1793,1799 ----
return false;
/* We want the condition for staying inside loop. */
! gimple_cond_extract_comparison (stmt, &code, &op0, &op1);
if (exit->flags & EDGE_TRUE_VALUE)
code = invert_tree_comparison (code, false);
*************** number_of_iterations_exit (struct loop *
*** 1808,1815 ****
return false;
}
- op0 = gimple_cond_lhs (stmt);
- op1 = gimple_cond_rhs (stmt);
type = TREE_TYPE (op0);
if (TREE_CODE (type) != INTEGER_TYPE
--- 1810,1815 ----
*************** loop_niter_by_eval (struct loop *loop, e
*** 2169,2175 ****
if (!cond || gimple_code (cond) != GIMPLE_COND)
return chrec_dont_know;
! cmp = gimple_cond_code (cond);
if (exit->flags & EDGE_TRUE_VALUE)
cmp = invert_tree_comparison (cmp, false);
--- 2169,2175 ----
if (!cond || gimple_code (cond) != GIMPLE_COND)
return chrec_dont_know;
! gimple_cond_extract_comparison (cond, &cmp, &op[0], &op[1]);
if (exit->flags & EDGE_TRUE_VALUE)
cmp = invert_tree_comparison (cmp, false);
*************** loop_niter_by_eval (struct loop *loop, e
*** 2181,2188 ****
case GE_EXPR:
case LT_EXPR:
case LE_EXPR:
- op[0] = gimple_cond_lhs (cond);
- op[1] = gimple_cond_rhs (cond);
break;
default:
--- 2181,2186 ----
Index: trunk/gcc/tree-ssa-loop-unswitch.c
===================================================================
*** trunk.orig/gcc/tree-ssa-loop-unswitch.c 2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/tree-ssa-loop-unswitch.c 2010-08-30 14:32:23.000000000 +0200
*************** static tree
*** 120,126 ****
tree_may_unswitch_on (basic_block bb, struct loop *loop)
{
gimple stmt, def;
! tree cond, use;
basic_block def_bb;
ssa_op_iter iter;
--- 120,126 ----
tree_may_unswitch_on (basic_block bb, struct loop *loop)
{
gimple stmt, def;
! tree use;
basic_block def_bb;
ssa_op_iter iter;
*************** tree_may_unswitch_on (basic_block bb, st
*** 145,154 ****
return NULL_TREE;
}
! cond = build2 (gimple_cond_code (stmt), boolean_type_node,
! gimple_cond_lhs (stmt), gimple_cond_rhs (stmt));
!
! return cond;
}
/* Simplifies COND using checks in front of the entry of the LOOP. Just very
--- 145,151 ----
return NULL_TREE;
}
! return gimple_cond_pred (stmt);
}
/* Simplifies COND using checks in front of the entry of the LOOP. Just very
*************** simplify_using_entry_checks (struct loop
*** 166,176 ****
stmt = last_stmt (e->src);
if (stmt
&& gimple_code (stmt) == GIMPLE_COND
! && gimple_cond_code (stmt) == TREE_CODE (cond)
! && operand_equal_p (gimple_cond_lhs (stmt),
! TREE_OPERAND (cond, 0), 0)
! && operand_equal_p (gimple_cond_rhs (stmt),
! TREE_OPERAND (cond, 1), 0))
return (e->flags & EDGE_TRUE_VALUE
? boolean_true_node
: boolean_false_node);
--- 163,169 ----
stmt = last_stmt (e->src);
if (stmt
&& gimple_code (stmt) == GIMPLE_COND
! && operand_equal_p (gimple_cond_pred (stmt), cond, 0))
return (e->flags & EDGE_TRUE_VALUE
? boolean_true_node
: boolean_false_node);
*************** tree_unswitch_single_loop (struct loop *
*** 229,241 ****
if (integer_nonzerop (cond))
{
/* Remove false path. */
! gimple_cond_set_condition_from_tree (stmt, boolean_true_node);
changed = true;
}
else if (integer_zerop (cond))
{
/* Remove true path. */
! gimple_cond_set_condition_from_tree (stmt, boolean_false_node);
changed = true;
}
/* Do not unswitch too much. */
--- 222,234 ----
if (integer_nonzerop (cond))
{
/* Remove false path. */
! gimple_cond_make_true (stmt);
changed = true;
}
else if (integer_zerop (cond))
{
/* Remove true path. */
! gimple_cond_make_false (stmt);
changed = true;
}
/* Do not unswitch too much. */
Index: trunk/gcc/tree-ssa-phiopt.c
===================================================================
*** trunk.orig/gcc/tree-ssa-phiopt.c 2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/tree-ssa-phiopt.c 2010-08-30 14:32:23.000000000 +0200
*************** replace_phi_edge_with_variable (basic_bl
*** 401,406 ****
--- 401,408 ----
basic_block bb = gimple_bb (phi);
basic_block block_to_remove;
gimple_stmt_iterator gsi;
+ gimple cond;
+ tree name;
/* Change the PHI argument to new. */
SET_USE (PHI_ARG_DEF_PTR (phi, e->dest_idx), new_tree);
*************** replace_phi_edge_with_variable (basic_bl
*** 429,435 ****
--- 431,448 ----
/* Eliminate the COND_EXPR at the end of COND_BLOCK. */
gsi = gsi_last_bb (cond_block);
+ cond = gsi_stmt (gsi);
+ if (TREE_CODE (name = gimple_cond_pred (cond)) != SSA_NAME
+ || !has_single_use (name)
+ || gimple_has_side_effects (SSA_NAME_DEF_STMT (name)))
+ name = NULL_TREE;
gsi_remove (&gsi, true);
+ if (name)
+ {
+ gsi = gsi_for_stmt (SSA_NAME_DEF_STMT (name));
+ gsi_remove (&gsi, true);
+ release_defs (SSA_NAME_DEF_STMT (name));
+ }
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file,
*************** conditional_replacement (basic_block con
*** 496,503 ****
/* To handle special cases like floating point comparison, it is easier and
less error-prone to build a tree and gimplify it on the fly though it is
less efficient. */
! cond = fold_build2 (gimple_cond_code (stmt), boolean_type_node,
! gimple_cond_lhs (stmt), gimple_cond_rhs (stmt));
/* We need to know which is the true edge and which is the false
edge so that we know when to invert the condition below. */
--- 509,515 ----
/* To handle special cases like floating point comparison, it is easier and
less error-prone to build a tree and gimplify it on the fly though it is
less efficient. */
! cond = gimple_cond_to_tree (stmt);
/* We need to know which is the true edge and which is the false
edge so that we know when to invert the condition below. */
*************** value_replacement (basic_block cond_bb,
*** 555,560 ****
--- 567,573 ----
gimple cond;
edge true_edge, false_edge;
enum tree_code code;
+ tree lhs, rhs;
/* If the type says honor signed zeros we cannot do this
optimization. */
*************** value_replacement (basic_block cond_bb,
*** 565,571 ****
return false;
cond = last_stmt (cond_bb);
! code = gimple_cond_code (cond);
/* This transformation is only valid for equality comparisons. */
if (code != NE_EXPR && code != EQ_EXPR)
--- 578,584 ----
return false;
cond = last_stmt (cond_bb);
! gimple_cond_extract_comparison (cond, &code, &lhs, &rhs);
/* This transformation is only valid for equality comparisons. */
if (code != NE_EXPR && code != EQ_EXPR)
*************** value_replacement (basic_block cond_bb,
*** 586,595 ****
We now need to verify that the two arguments in the PHI node match
the two arguments to the equality comparison. */
! if ((operand_equal_for_phi_arg_p (arg0, gimple_cond_lhs (cond))
! && operand_equal_for_phi_arg_p (arg1, gimple_cond_rhs (cond)))
! || (operand_equal_for_phi_arg_p (arg1, gimple_cond_lhs (cond))
! && operand_equal_for_phi_arg_p (arg0, gimple_cond_rhs (cond))))
{
edge e;
tree arg;
--- 599,608 ----
We now need to verify that the two arguments in the PHI node match
the two arguments to the equality comparison. */
! if ((operand_equal_for_phi_arg_p (arg0, lhs)
! && operand_equal_for_phi_arg_p (arg1, rhs))
! || (operand_equal_for_phi_arg_p (arg1, lhs)
! && operand_equal_for_phi_arg_p (arg0, rhs)))
{
edge e;
tree arg;
*************** minmax_replacement (basic_block cond_bb,
*** 638,643 ****
--- 651,657 ----
enum tree_code cmp, minmax, ass_code;
tree smaller, larger, arg_true, arg_false;
gimple_stmt_iterator gsi, gsi_from;
+ tree lhs, rhs;
type = TREE_TYPE (PHI_RESULT (phi));
*************** minmax_replacement (basic_block cond_bb,
*** 646,665 ****
return false;
cond = last_stmt (cond_bb);
! cmp = gimple_cond_code (cond);
result = PHI_RESULT (phi);
/* This transformation is only valid for order comparisons. Record which
operand is smaller/larger if the result of the comparison is true. */
if (cmp == LT_EXPR || cmp == LE_EXPR)
{
! smaller = gimple_cond_lhs (cond);
! larger = gimple_cond_rhs (cond);
}
else if (cmp == GT_EXPR || cmp == GE_EXPR)
{
! smaller = gimple_cond_rhs (cond);
! larger = gimple_cond_lhs (cond);
}
else
return false;
--- 660,679 ----
return false;
cond = last_stmt (cond_bb);
! gimple_cond_extract_comparison (cond, &cmp, &lhs, &rhs);
result = PHI_RESULT (phi);
/* This transformation is only valid for order comparisons. Record which
operand is smaller/larger if the result of the comparison is true. */
if (cmp == LT_EXPR || cmp == LE_EXPR)
{
! smaller = lhs;
! larger = rhs;
}
else if (cmp == GT_EXPR || cmp == GE_EXPR)
{
! smaller = rhs;
! larger = lhs;
}
else
return false;
*************** abs_replacement (basic_block cond_bb, ba
*** 886,892 ****
edge true_edge, false_edge;
gimple assign;
edge e;
! tree rhs, lhs;
bool negate;
enum tree_code cond_code;
--- 900,906 ----
edge true_edge, false_edge;
gimple assign;
edge e;
! tree rhs, lhs, cond_lhs, cond_rhs;
bool negate;
enum tree_code cond_code;
*************** abs_replacement (basic_block cond_bb, ba
*** 926,943 ****
result = PHI_RESULT (phi);
/* Only relationals comparing arg[01] against zero are interesting. */
! cond_code = gimple_cond_code (cond);
if (cond_code != GT_EXPR && cond_code != GE_EXPR
&& cond_code != LT_EXPR && cond_code != LE_EXPR)
return false;
/* Make sure the conditional is arg[01] OP y. */
! if (gimple_cond_lhs (cond) != rhs)
return false;
! if (FLOAT_TYPE_P (TREE_TYPE (gimple_cond_rhs (cond)))
! ? real_zerop (gimple_cond_rhs (cond))
! : integer_zerop (gimple_cond_rhs (cond)))
;
else
return false;
--- 940,956 ----
result = PHI_RESULT (phi);
/* Only relationals comparing arg[01] against zero are interesting. */
! gimple_cond_extract_comparison (cond, &cond_code, &cond_lhs, &cond_rhs);
if (cond_code != GT_EXPR && cond_code != GE_EXPR
&& cond_code != LT_EXPR && cond_code != LE_EXPR)
return false;
/* Make sure the conditional is arg[01] OP y. */
! if (cond_lhs != rhs)
return false;
! if (FLOAT_TYPE_P (TREE_TYPE (cond_rhs))
! ? real_zerop (cond_rhs) : integer_zerop (cond_rhs))
;
else
return false;
Index: trunk/gcc/tree-ssa-pre.c
===================================================================
*** trunk.orig/gcc/tree-ssa-pre.c 2010-08-25 16:49:48.000000000 +0200
--- trunk/gcc/tree-ssa-pre.c 2010-08-30 14:32:23.000000000 +0200
*************** insert_into_preds_of_block (basic_block
*** 3343,3348 ****
--- 3343,3361 ----
}
}
+ /* Make sure we are not inserting PHI nodes for predicates.
+ Those are all marking jump threading opportunities and just
+ will move predicate computations away from jumps and complicate
+ late analysis of uninitialized uses. */
+ if (expr->kind == NARY
+ && truth_value_p (expr->u.nary->opcode))
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "Skipping insertion of phi for partial "
+ "redundancy: Looks like a predicate\n");
+ nophi = true;
+ }
+
/* Make the necessary insertions. */
FOR_EACH_EDGE (pred, ei, block->preds)
{
*************** eliminate (void)
*** 4339,4357 ****
available value-numbers. */
else if (gimple_code (stmt) == GIMPLE_COND)
{
! tree op0 = gimple_cond_lhs (stmt);
! tree op1 = gimple_cond_rhs (stmt);
! tree result;
!
! if (TREE_CODE (op0) == SSA_NAME)
! op0 = VN_INFO (op0)->valnum;
! if (TREE_CODE (op1) == SSA_NAME)
! op1 = VN_INFO (op1)->valnum;
! result = fold_binary (gimple_cond_code (stmt), boolean_type_node,
! op0, op1);
! if (result && TREE_CODE (result) == INTEGER_CST)
{
! if (integer_zerop (result))
gimple_cond_make_false (stmt);
else
gimple_cond_make_true (stmt);
--- 4352,4364 ----
available value-numbers. */
else if (gimple_code (stmt) == GIMPLE_COND)
{
! tree pred = gimple_cond_pred (stmt);
!
! if (TREE_CODE (pred) == SSA_NAME)
! pred = VN_INFO (pred)->valnum;
! if (TREE_CODE (pred) == INTEGER_CST)
{
! if (integer_zerop (pred))
gimple_cond_make_false (stmt);
else
gimple_cond_make_true (stmt);
Index: trunk/gcc/tree-ssa-threadedge.c
===================================================================
*** trunk.orig/gcc/tree-ssa-threadedge.c 2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/tree-ssa-threadedge.c 2010-08-30 14:32:23.000000000 +0200
*************** record_temporary_equivalence (tree x, tr
*** 162,168 ****
{
tree prev_x = SSA_NAME_VALUE (x);
! if (TREE_CODE (y) == SSA_NAME)
{
tree tmp = SSA_NAME_VALUE (y);
y = tmp ? tmp : y;
--- 162,168 ----
{
tree prev_x = SSA_NAME_VALUE (x);
! if (y && TREE_CODE (y) == SSA_NAME)
{
tree tmp = SSA_NAME_VALUE (y);
y = tmp ? tmp : y;
*************** record_temporary_equivalences_from_stmts
*** 457,550 ****
static tree
simplify_control_stmt_condition (edge e,
gimple stmt,
- gimple dummy_cond,
tree (*simplify) (gimple, gimple),
bool handle_dominating_asserts)
{
tree cond, cached_lhs;
enum gimple_code code = gimple_code (stmt);
- /* For comparisons, we have to update both operands, then try
- to simplify the comparison. */
- if (code == GIMPLE_COND)
- {
- tree op0, op1;
- enum tree_code cond_code;
-
- op0 = gimple_cond_lhs (stmt);
- op1 = gimple_cond_rhs (stmt);
- cond_code = gimple_cond_code (stmt);
-
- /* Get the current value of both operands. */
- if (TREE_CODE (op0) == SSA_NAME)
- {
- tree tmp = SSA_NAME_VALUE (op0);
- if (tmp)
- op0 = tmp;
- }
-
- if (TREE_CODE (op1) == SSA_NAME)
- {
- tree tmp = SSA_NAME_VALUE (op1);
- if (tmp)
- op1 = tmp;
- }
-
- if (handle_dominating_asserts)
- {
- /* Now see if the operand was consumed by an ASSERT_EXPR
- which dominates E->src. If so, we want to replace the
- operand with the LHS of the ASSERT_EXPR. */
- if (TREE_CODE (op0) == SSA_NAME)
- op0 = lhs_of_dominating_assert (op0, e->src, stmt);
-
- if (TREE_CODE (op1) == SSA_NAME)
- op1 = lhs_of_dominating_assert (op1, e->src, stmt);
- }
-
- /* We may need to canonicalize the comparison. For
- example, op0 might be a constant while op1 is an
- SSA_NAME. Failure to canonicalize will cause us to
- miss threading opportunities. */
- if (tree_swap_operands_p (op0, op1, false))
- {
- tree tmp;
- cond_code = swap_tree_comparison (cond_code);
- tmp = op0;
- op0 = op1;
- op1 = tmp;
- }
-
- /* Stuff the operator and operands into our dummy conditional
- expression. */
- gimple_cond_set_code (dummy_cond, cond_code);
- gimple_cond_set_lhs (dummy_cond, op0);
- gimple_cond_set_rhs (dummy_cond, op1);
-
- /* We absolutely do not care about any type conversions
- we only care about a zero/nonzero value. */
- fold_defer_overflow_warnings ();
-
- cached_lhs = fold_binary (cond_code, boolean_type_node, op0, op1);
- if (cached_lhs)
- while (CONVERT_EXPR_P (cached_lhs))
- cached_lhs = TREE_OPERAND (cached_lhs, 0);
-
- fold_undefer_overflow_warnings ((cached_lhs
- && is_gimple_min_invariant (cached_lhs)),
- stmt, WARN_STRICT_OVERFLOW_CONDITIONAL);
-
- /* If we have not simplified the condition down to an invariant,
- then use the pass specific callback to simplify the condition. */
- if (!cached_lhs
- || !is_gimple_min_invariant (cached_lhs))
- cached_lhs = (*simplify) (dummy_cond, stmt);
-
- return cached_lhs;
- }
-
if (code == GIMPLE_SWITCH)
cond = gimple_switch_index (stmt);
else if (code == GIMPLE_GOTO)
cond = gimple_goto_dest (stmt);
else
--- 457,472 ----
static tree
simplify_control_stmt_condition (edge e,
gimple stmt,
tree (*simplify) (gimple, gimple),
bool handle_dominating_asserts)
{
tree cond, cached_lhs;
enum gimple_code code = gimple_code (stmt);
if (code == GIMPLE_SWITCH)
cond = gimple_switch_index (stmt);
+ else if (code == GIMPLE_COND)
+ cond = gimple_cond_pred (stmt);
else if (code == GIMPLE_GOTO)
cond = gimple_goto_dest (stmt);
else
*************** simplify_control_stmt_condition (edge e,
*** 610,616 ****
SIMPLIFY is a pass-specific function used to simplify statements. */
void
! thread_across_edge (gimple dummy_cond,
edge e,
bool handle_dominating_asserts,
VEC(tree, heap) **stack,
--- 532,538 ----
SIMPLIFY is a pass-specific function used to simplify statements. */
void
! thread_across_edge (gimple dummy_cond ATTRIBUTE_UNUSED,
edge e,
bool handle_dominating_asserts,
VEC(tree, heap) **stack,
*************** thread_across_edge (gimple dummy_cond,
*** 628,642 ****
use_operand_p use_p;
gimple last = gsi_stmt (gsi_last_bb (e->dest));
! FOR_EACH_SSA_USE_OPERAND (use_p, last, iter, SSA_OP_USE | SSA_OP_VUSE)
{
! tree use = USE_FROM_PTR (use_p);
!
! if (TREE_CODE (use) == SSA_NAME
! && gimple_code (SSA_NAME_DEF_STMT (use)) != GIMPLE_PHI
! && gimple_bb (SSA_NAME_DEF_STMT (use)) == e->dest)
goto fail;
}
}
stmt_count = 0;
--- 550,583 ----
use_operand_p use_p;
gimple last = gsi_stmt (gsi_last_bb (e->dest));
! if (gimple_code (last) == GIMPLE_COND)
{
! enum tree_code code;
! tree op0, op1;
! gimple_cond_extract_comparison (last, &code, &op0, &op1);
! if (TREE_CODE (op0) == SSA_NAME
! && gimple_code (SSA_NAME_DEF_STMT (op0)) != GIMPLE_PHI
! && gimple_bb (SSA_NAME_DEF_STMT (op0)) == e->dest)
goto fail;
+ if (TREE_CODE (op1) == SSA_NAME
+ && gimple_code (SSA_NAME_DEF_STMT (op1)) != GIMPLE_PHI
+ && gimple_bb (SSA_NAME_DEF_STMT (op1)) == e->dest)
+ goto fail;
+ /* Reset any previously known value for the predicate. */
+ if (TREE_CODE (gimple_cond_pred (last)) == SSA_NAME)
+ record_temporary_equivalence (gimple_cond_pred (last),
+ NULL_TREE, stack);
}
+ else
+ FOR_EACH_SSA_USE_OPERAND (use_p, last, iter, SSA_OP_USE | SSA_OP_VUSE)
+ {
+ tree use = USE_FROM_PTR (use_p);
+
+ if (TREE_CODE (use) == SSA_NAME
+ && gimple_code (SSA_NAME_DEF_STMT (use)) != GIMPLE_PHI
+ && gimple_bb (SSA_NAME_DEF_STMT (use)) == e->dest)
+ goto fail;
+ }
}
stmt_count = 0;
*************** thread_across_edge (gimple dummy_cond,
*** 660,666 ****
tree cond;
/* Extract and simplify the condition. */
! cond = simplify_control_stmt_condition (e, stmt, dummy_cond, simplify, handle_dominating_asserts);
if (cond && is_gimple_min_invariant (cond))
{
--- 601,608 ----
tree cond;
/* Extract and simplify the condition. */
! cond = simplify_control_stmt_condition (e, stmt, simplify,
! handle_dominating_asserts);
if (cond && is_gimple_min_invariant (cond))
{
Index: trunk/gcc/tree-ssa-uncprop.c
===================================================================
*** trunk.orig/gcc/tree-ssa-uncprop.c 2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/tree-ssa-uncprop.c 2010-08-30 14:32:23.000000000 +0200
*************** associate_equivalences_with_edges (void)
*** 81,96 ****
edge true_edge;
edge false_edge;
struct edge_equivalency *equivalency;
! enum tree_code code = gimple_cond_code (stmt);
extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
/* Equality tests may create one or two equivalences. */
if (code == EQ_EXPR || code == NE_EXPR)
{
- tree op0 = gimple_cond_lhs (stmt);
- tree op1 = gimple_cond_rhs (stmt);
-
/* Special case comparing booleans against a constant as we
know the value of OP0 on both arms of the branch. i.e., we
can record an equivalence for OP0 rather than COND. */
--- 81,95 ----
edge true_edge;
edge false_edge;
struct edge_equivalency *equivalency;
! enum tree_code code;
! tree op0, op1;
+ gimple_cond_extract_comparison (stmt, &code, &op0, &op1);
extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
/* Equality tests may create one or two equivalences. */
if (code == EQ_EXPR || code == NE_EXPR)
{
/* Special case comparing booleans against a constant as we
know the value of OP0 on both arms of the branch. i.e., we
can record an equivalence for OP0 rather than COND. */
Index: trunk/gcc/tree-ssa-uninit.c
===================================================================
*** trunk.orig/gcc/tree-ssa-uninit.c 2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/tree-ssa-uninit.c 2010-08-30 14:32:23.000000000 +0200
*************** use_pred_not_overlap_with_undef_path_pre
*** 887,895 ****
cond = the_pred->cond;
invert = the_pred->invert;
! cond_lhs = gimple_cond_lhs (cond);
! cond_rhs = gimple_cond_rhs (cond);
! cmp_code = gimple_cond_code (cond);
if (cond_lhs != NULL_TREE && TREE_CODE (cond_lhs) == SSA_NAME
&& cond_rhs != NULL_TREE && is_gimple_constant (cond_rhs))
--- 887,893 ----
cond = the_pred->cond;
invert = the_pred->invert;
! gimple_cond_extract_comparison (cond, &cmp_code, &cond_lhs, &cond_rhs);
if (cond_lhs != NULL_TREE && TREE_CODE (cond_lhs) == SSA_NAME
&& cond_rhs != NULL_TREE && is_gimple_constant (cond_rhs))
*************** normalize_cond_1 (gimple cond,
*** 1012,1017 ****
--- 1010,1017 ----
enum tree_code cur_cond_code;
tree rhs1, rhs2;
+ /* ??? If we would start to PRE predicates we could unwind to
+ PHI nodes here. */
gc = gimple_code (cond);
if (gc != GIMPLE_ASSIGN)
{
*************** normalize_cond (gimple cond, norm_cond_t
*** 1066,1086 ****
norm_cond->invert = false;
norm_cond->conds = NULL;
gcc_assert (gimple_code (cond) == GIMPLE_COND);
! cond_code = gimple_cond_code (cond);
if (invert)
cond_code = invert_tree_comparison (cond_code, false);
if (cond_code == NE_EXPR)
{
! if (integer_zerop (gimple_cond_rhs (cond))
! && (TREE_CODE (gimple_cond_lhs (cond)) == SSA_NAME))
normalize_cond_1 (
! SSA_NAME_DEF_STMT (gimple_cond_lhs (cond)),
! norm_cond, ERROR_MARK);
! else if (integer_zerop (gimple_cond_lhs (cond))
! && (TREE_CODE (gimple_cond_rhs (cond)) == SSA_NAME))
! normalize_cond_1 (
! SSA_NAME_DEF_STMT (gimple_cond_rhs (cond)),
norm_cond, ERROR_MARK);
else
{
--- 1066,1082 ----
norm_cond->invert = false;
norm_cond->conds = NULL;
gcc_assert (gimple_code (cond) == GIMPLE_COND);
! /* All GIMPLE_CONDs are pred != false. */
! cond_code = NE_EXPR;
if (invert)
cond_code = invert_tree_comparison (cond_code, false);
+ /* ??? It's not clear why we can't handle EQ_EXPR here but also not how. */
if (cond_code == NE_EXPR)
{
! if (TREE_CODE (gimple_cond_pred (cond)) == SSA_NAME)
normalize_cond_1 (
! SSA_NAME_DEF_STMT (gimple_cond_pred (cond)),
norm_cond, ERROR_MARK);
else
{
*************** is_gcond_subset_of (gimple cond1, bool i
*** 1126,1143 ****
gc1 = gimple_code (cond1);
gc2 = gimple_code (cond2);
! if ((gc1 != GIMPLE_ASSIGN && gc1 != GIMPLE_COND)
! || (gc2 != GIMPLE_ASSIGN && gc2 != GIMPLE_COND))
return cond1 == cond2;
! cond1_code = ((gc1 == GIMPLE_ASSIGN)
! ? gimple_assign_rhs_code (cond1)
! : gimple_cond_code (cond1));
!
! cond2_code = ((gc2 == GIMPLE_ASSIGN)
! ? gimple_assign_rhs_code (cond2)
! : gimple_cond_code (cond2));
if (TREE_CODE_CLASS (cond1_code) != tcc_comparison
|| TREE_CODE_CLASS (cond2_code) != tcc_comparison)
--- 1122,1144 ----
gc1 = gimple_code (cond1);
gc2 = gimple_code (cond2);
+ if (gc1 == GIMPLE_COND)
+ {
+ if (TREE_CODE (gimple_cond_pred (cond1)) == SSA_NAME)
+ cond1 = SSA_NAME_DEF_STMT (gimple_cond_pred (cond1));
+ }
+ if (gc2 == GIMPLE_COND)
+ {
+ if (TREE_CODE (gimple_cond_pred (cond2)) == SSA_NAME)
+ cond2 = SSA_NAME_DEF_STMT (gimple_cond_pred (cond2));
+ }
! if (gc1 != GIMPLE_ASSIGN
! || gc2 != GIMPLE_ASSIGN)
return cond1 == cond2;
! cond1_code = gimple_assign_rhs_code (cond1);
! cond2_code = gimple_assign_rhs_code (cond2);
if (TREE_CODE_CLASS (cond1_code) != tcc_comparison
|| TREE_CODE_CLASS (cond2_code) != tcc_comparison)
*************** is_gcond_subset_of (gimple cond1, bool i
*** 1148,1165 ****
if (invert2)
cond2_code = invert_tree_comparison (cond2_code, false);
! cond1_lhs = ((gc1 == GIMPLE_ASSIGN)
! ? gimple_assign_rhs1 (cond1)
! : gimple_cond_lhs (cond1));
! cond1_rhs = ((gc1 == GIMPLE_ASSIGN)
! ? gimple_assign_rhs2 (cond1)
! : gimple_cond_rhs (cond1));
! cond2_lhs = ((gc2 == GIMPLE_ASSIGN)
! ? gimple_assign_rhs1 (cond2)
! : gimple_cond_lhs (cond2));
! cond2_rhs = ((gc2 == GIMPLE_ASSIGN)
! ? gimple_assign_rhs2 (cond2)
! : gimple_cond_rhs (cond2));
/* Assuming const operands have been swapped to the
rhs at this point of the analysis. */
--- 1149,1158 ----
if (invert2)
cond2_code = invert_tree_comparison (cond2_code, false);
! cond1_lhs = gimple_assign_rhs1 (cond1);
! cond1_rhs = gimple_assign_rhs2 (cond1);
! cond2_lhs = gimple_assign_rhs1 (cond2);
! cond2_rhs = gimple_assign_rhs2 (cond2);
/* Assuming const operands have been swapped to the
rhs at this point of the analysis. */
*************** is_pred_expr_subset_of (use_pred_info_t
*** 1383,1390 ****
cond1 = expr1->cond;
cond2 = expr2->cond;
! code1 = gimple_cond_code (cond1);
! code2 = gimple_cond_code (cond2);
if (expr1->invert)
code1 = invert_tree_comparison (code1, false);
--- 1376,1383 ----
cond1 = expr1->cond;
cond2 = expr2->cond;
! code1 = NE_EXPR;
! code2 = NE_EXPR;
if (expr1->invert)
code1 = invert_tree_comparison (code1, false);
*************** is_pred_expr_subset_of (use_pred_info_t
*** 1392,1399 ****
code2 = invert_tree_comparison (code2, false);
/* Fast path -- match exactly */
! if ((gimple_cond_lhs (cond1) == gimple_cond_lhs (cond2))
! && (gimple_cond_rhs (cond1) == gimple_cond_rhs (cond2))
&& (code1 == code2))
return true;
--- 1385,1391 ----
code2 = invert_tree_comparison (code2, false);
/* Fast path -- match exactly */
! if ((gimple_cond_pred (cond1) == gimple_cond_pred (cond2))
&& (code1 == code2))
return true;
Index: trunk/gcc/tree-vect-loop-manip.c
===================================================================
*** trunk.orig/gcc/tree-vect-loop-manip.c 2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/tree-vect-loop-manip.c 2010-08-30 14:32:23.000000000 +0200
*************** slpeel_make_loop_iterate_ntimes (struct
*** 767,772 ****
--- 767,773 ----
tree step = build_int_cst (TREE_TYPE (niters), 1);
LOC loop_loc;
enum tree_code code;
+ tree cmp;
orig_cond = get_loop_exit_condition (loop);
gcc_assert (orig_cond);
*************** slpeel_make_loop_iterate_ntimes (struct
*** 783,790 ****
true, GSI_SAME_STMT);
code = (exit_edge->flags & EDGE_TRUE_VALUE) ? GE_EXPR : LT_EXPR;
! cond_stmt = gimple_build_cond (code, indx_after_incr, niters, NULL_TREE,
! NULL_TREE);
gsi_insert_before (&loop_cond_gsi, cond_stmt, GSI_SAME_STMT);
--- 784,793 ----
true, GSI_SAME_STMT);
code = (exit_edge->flags & EDGE_TRUE_VALUE) ? GE_EXPR : LT_EXPR;
! cmp = fold_build2 (code, boolean_type_node, indx_after_incr, niters);
! cmp = force_gimple_operand_gsi (&loop_cond_gsi, cmp, true, NULL, true,
! GSI_SAME_STMT);
! cond_stmt = gimple_build_cond (cmp, NULL_TREE, NULL_TREE);
gsi_insert_before (&loop_cond_gsi, cond_stmt, GSI_SAME_STMT);
*************** slpeel_add_loop_guard (basic_block guard
*** 947,955 ****
cond = force_gimple_operand (cond, &gimplify_stmt_list, true, NULL_TREE);
if (gimplify_stmt_list)
gimple_seq_add_seq (&cond_expr_stmt_list, gimplify_stmt_list);
! cond_stmt = gimple_build_cond (NE_EXPR,
! cond, build_int_cst (TREE_TYPE (cond), 0),
! NULL_TREE, NULL_TREE);
if (cond_expr_stmt_list)
gsi_insert_seq_after (&gsi, cond_expr_stmt_list, GSI_NEW_STMT);
--- 950,956 ----
cond = force_gimple_operand (cond, &gimplify_stmt_list, true, NULL_TREE);
if (gimplify_stmt_list)
gimple_seq_add_seq (&cond_expr_stmt_list, gimplify_stmt_list);
! cond_stmt = gimple_build_cond (cond, NULL_TREE, NULL_TREE);
if (cond_expr_stmt_list)
gsi_insert_seq_after (&gsi, cond_expr_stmt_list, GSI_NEW_STMT);
*************** set_prologue_iterations (basic_block bb_
*** 1077,1085 ****
cost_pre_condition =
force_gimple_operand (cost_pre_condition, &gimplify_stmt_list,
true, NULL_TREE);
! cond_stmt = gimple_build_cond (NE_EXPR, cost_pre_condition,
! build_int_cst (TREE_TYPE (cost_pre_condition),
! 0), NULL_TREE, NULL_TREE);
gsi = gsi_last_bb (cond_bb);
if (gimplify_stmt_list)
--- 1078,1084 ----
cost_pre_condition =
force_gimple_operand (cost_pre_condition, &gimplify_stmt_list,
true, NULL_TREE);
! cond_stmt = gimple_build_cond (cost_pre_condition, NULL_TREE, NULL_TREE);
gsi = gsi_last_bb (cond_bb);
if (gimplify_stmt_list)
Index: trunk/gcc/cgraphunit.c
===================================================================
*** trunk.orig/gcc/cgraphunit.c 2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/cgraphunit.c 2010-08-30 14:32:23.000000000 +0200
*************** assemble_thunk (struct cgraph_node *node
*** 1397,1415 ****
if (TREE_CODE (TREE_TYPE (restmp)) == POINTER_TYPE)
{
gimple stmt;
/* If the return type is a pointer, we need to
protect against NULL. We know there will be an
adjustment, because that's why we're emitting a
thunk. */
then_bb = create_basic_block (NULL, (void *) 0, bb);
return_bb = create_basic_block (NULL, (void *) 0, then_bb);
else_bb = create_basic_block (NULL, (void *) 0, else_bb);
remove_edge (single_succ_edge (bb));
true_label = gimple_block_label (then_bb);
! stmt = gimple_build_cond (NE_EXPR, restmp,
! fold_convert (TREE_TYPE (restmp),
! integer_zero_node),
! NULL_TREE, NULL_TREE);
gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
make_edge (bb, then_bb, EDGE_TRUE_VALUE);
make_edge (bb, else_bb, EDGE_FALSE_VALUE);
--- 1397,1421 ----
if (TREE_CODE (TREE_TYPE (restmp)) == POINTER_TYPE)
{
gimple stmt;
+ tree ctmp;
/* If the return type is a pointer, we need to
protect against NULL. We know there will be an
adjustment, because that's why we're emitting a
thunk. */
+ ctmp = create_tmp_var_raw (boolean_type_node, NULL);
then_bb = create_basic_block (NULL, (void *) 0, bb);
return_bb = create_basic_block (NULL, (void *) 0, then_bb);
else_bb = create_basic_block (NULL, (void *) 0, else_bb);
remove_edge (single_succ_edge (bb));
true_label = gimple_block_label (then_bb);
! stmt = gimple_build_assign_with_ops (NE_EXPR, ctmp, restmp,
! fold_convert
! (TREE_TYPE (restmp),
! integer_zero_node));
! ctmp = make_ssa_name (ctmp, stmt);
! gimple_assign_set_lhs (stmt, ctmp);
! gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
! stmt = gimple_build_cond (ctmp, NULL_TREE, NULL_TREE);
gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
make_edge (bb, then_bb, EDGE_TRUE_VALUE);
make_edge (bb, else_bb, EDGE_FALSE_VALUE);
Index: trunk/gcc/ipa-prop.c
===================================================================
*** trunk.orig/gcc/ipa-prop.c 2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/ipa-prop.c 2010-08-30 14:32:23.000000000 +0200
*************** compute_complex_ancestor_jump_func (stru
*** 458,463 ****
--- 458,465 ----
basic_block phi_bb, assign_bb, cond_bb;
tree tmp, parm, expr;
int index, i;
+ enum tree_code code;
+ tree lhs, rhs;
if (gimple_phi_num_args (phi) != 2
|| !integer_zerop (PHI_ARG_DEF (phi, 1)))
*************** compute_complex_ancestor_jump_func (stru
*** 500,511 ****
cond_bb = single_pred (assign_bb);
cond = last_stmt (cond_bb);
if (!cond
! || gimple_code (cond) != GIMPLE_COND
! || gimple_cond_code (cond) != NE_EXPR
! || gimple_cond_lhs (cond) != parm
! || !integer_zerop (gimple_cond_rhs (cond)))
return;
-
phi_bb = gimple_bb (phi);
for (i = 0; i < 2; i++)
--- 502,514 ----
cond_bb = single_pred (assign_bb);
cond = last_stmt (cond_bb);
if (!cond
! || gimple_code (cond) != GIMPLE_COND)
! return;
! gimple_cond_extract_comparison (cond, &code, &lhs, &rhs);
! if (code != NE_EXPR
! || lhs != parm
! || !integer_zerop (rhs))
return;
phi_bb = gimple_bb (phi);
for (i = 0; i < 2; i++)
*************** ipa_analyze_indirect_call_uses (struct c
*** 1052,1057 ****
--- 1055,1062 ----
gimple branch;
int index;
basic_block bb, virt_bb, join;
+ enum tree_code code;
+ tree rhs;
if (SSA_NAME_IS_DEFAULT_DEF (target))
{
*************** ipa_analyze_indirect_call_uses (struct c
*** 1117,1127 ****
if (!branch || gimple_code (branch) != GIMPLE_COND)
return;
! if (gimple_cond_code (branch) != NE_EXPR
! || !integer_zerop (gimple_cond_rhs (branch)))
return;
- cond = gimple_cond_lhs (branch);
if (!ipa_is_ssa_with_stmt_def (cond))
return;
--- 1122,1132 ----
if (!branch || gimple_code (branch) != GIMPLE_COND)
return;
! gimple_cond_extract_comparison (branch, &code, &cond, &rhs);
! if (code != NE_EXPR
! || !integer_zerop (rhs))
return;
if (!ipa_is_ssa_with_stmt_def (cond))
return;
Index: trunk/gcc/ipa-struct-reorg.c
===================================================================
*** trunk.orig/gcc/ipa-struct-reorg.c 2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/ipa-struct-reorg.c 2010-08-30 14:32:23.000000000 +0200
*************** along with GCC; see the file COPYING3.
*** 56,61 ****
--- 56,63 ----
#include "tree-dump.h"
#include "gimple.h"
+ #if 0
+
/* This optimization implements structure peeling.
For example, given a structure type:
*************** reorg_structs (void)
*** 4023,4037 ****
free_data_structs ();
}
/* Struct-reorg optimization entry point function. */
static unsigned int
reorg_structs_drive (void)
{
/* IPA struct-reorg is completely broken - its analysis phase is
! non-conservative (which is not the only reason it is broken). */
if (0)
! reorg_structs ();
return 0;
}
--- 4025,4041 ----
free_data_structs ();
}
+ #endif
+
/* Struct-reorg optimization entry point function. */
static unsigned int
reorg_structs_drive (void)
{
/* IPA struct-reorg is completely broken - its analysis phase is
! non-conservative (which is not the only reason it is broken).
if (0)
! reorg_structs (); */
return 0;
}
Index: trunk/gcc/tree-mudflap.c
===================================================================
*** trunk.orig/gcc/tree-mudflap.c 2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/tree-mudflap.c 2010-08-30 14:32:23.000000000 +0200
*************** mf_build_check_statement_for (tree base,
*** 641,648 ****
/* Build the conditional jump. 'cond' is just a temporary so we can
simply build a void COND_EXPR. We do need labels in both arms though. */
! g = gimple_build_cond (NE_EXPR, cond, boolean_false_node, NULL_TREE,
! NULL_TREE);
gimple_set_location (g, location);
gimple_seq_add_stmt (&seq, g);
--- 641,647 ----
/* Build the conditional jump. 'cond' is just a temporary so we can
simply build a void COND_EXPR. We do need labels in both arms though. */
! g = gimple_build_cond (cond, NULL_TREE, NULL_TREE);
gimple_set_location (g, location);
gimple_seq_add_stmt (&seq, g);
Index: trunk/gcc/tree-parloops.c
===================================================================
*** trunk.orig/gcc/tree-parloops.c 2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/tree-parloops.c 2010-08-30 14:32:23.000000000 +0200
*************** transform_to_exit_first_loop (struct loo
*** 1294,1307 ****
gimple phi, nphi, cond_stmt, stmt, cond_nit;
gimple_stmt_iterator gsi;
tree nit_1;
split_block_after_labels (loop->header);
orig_header = single_succ (loop->header);
hpred = single_succ_edge (loop->header);
cond_stmt = last_stmt (exit->src);
! control = gimple_cond_lhs (cond_stmt);
! gcc_assert (gimple_cond_rhs (cond_stmt) == nit);
/* Make sure that we have phi nodes on exit for all loop header phis
(create_parallel_loop requires that). */
--- 1294,1309 ----
gimple phi, nphi, cond_stmt, stmt, cond_nit;
gimple_stmt_iterator gsi;
tree nit_1;
+ enum tree_code code;
+ tree rhs;
split_block_after_labels (loop->header);
orig_header = single_succ (loop->header);
hpred = single_succ_edge (loop->header);
cond_stmt = last_stmt (exit->src);
! gimple_cond_extract_comparison (cond_stmt, &code, &control, &rhs);
! gcc_assert (rhs == nit);
/* Make sure that we have phi nodes on exit for all loop header phis
(create_parallel_loop requires that). */
*************** transform_to_exit_first_loop (struct loo
*** 1317,1323 ****
if (res == control)
{
! gimple_cond_set_lhs (cond_stmt, t);
update_stmt (cond_stmt);
control = t;
}
--- 1319,1326 ----
if (res == control)
{
! gimple_update_cond_from_comparison (gsi_for_stmt (cond_stmt),
! code, t, rhs);
update_stmt (cond_stmt);
control = t;
}
*************** transform_to_exit_first_loop (struct loo
*** 1379,1385 ****
according to the rhs of the exit condition. */
gsi = gsi_after_labels (ex_bb);
cond_nit = last_stmt (exit->src);
! nit_1 = gimple_cond_rhs (cond_nit);
nit_1 = force_gimple_operand_gsi (&gsi,
fold_convert (TREE_TYPE (control_name), nit_1),
false, NULL_TREE, false, GSI_SAME_STMT);
--- 1382,1388 ----
according to the rhs of the exit condition. */
gsi = gsi_after_labels (ex_bb);
cond_nit = last_stmt (exit->src);
! gimple_cond_extract_comparison (cond_nit, &code, &rhs, &nit_1);
nit_1 = force_gimple_operand_gsi (&gsi,
fold_convert (TREE_TYPE (control_name), nit_1),
false, NULL_TREE, false, GSI_SAME_STMT);
*************** create_parallel_loop (struct loop *loop,
*** 1404,1409 ****
--- 1407,1414 ----
gimple stmt, for_stmt, phi, cond_stmt;
tree cvar, cvar_init, initvar, cvar_next, cvar_base, type;
edge exit, nexit, guard, end, e;
+ enum tree_code code;
+ tree rhs;
/* Prepare the GIMPLE_OMP_PARALLEL statement. */
bb = loop_preheader_edge (loop)->src;
*************** create_parallel_loop (struct loop *loop,
*** 1442,1448 ****
gcc_assert (loop->header == single_dom_exit (loop)->src);
cond_stmt = last_stmt (loop->header);
! cvar = gimple_cond_lhs (cond_stmt);
cvar_base = SSA_NAME_VAR (cvar);
phi = SSA_NAME_DEF_STMT (cvar);
cvar_init = PHI_ARG_DEF_FROM_EDGE (phi, loop_preheader_edge (loop));
--- 1447,1453 ----
gcc_assert (loop->header == single_dom_exit (loop)->src);
cond_stmt = last_stmt (loop->header);
! gimple_cond_extract_comparison (cond_stmt, &code, &cvar, &rhs);
cvar_base = SSA_NAME_VAR (cvar);
phi = SSA_NAME_DEF_STMT (cvar);
cvar_init = PHI_ARG_DEF_FROM_EDGE (phi, loop_preheader_edge (loop));
*************** create_parallel_loop (struct loop *loop,
*** 1484,1490 ****
PENDING_STMT (e) = NULL;
/* Emit GIMPLE_OMP_FOR. */
! gimple_cond_set_lhs (cond_stmt, cvar_base);
type = TREE_TYPE (cvar);
t = build_omp_clause (BUILTINS_LOCATION, OMP_CLAUSE_SCHEDULE);
OMP_CLAUSE_SCHEDULE_KIND (t) = OMP_CLAUSE_SCHEDULE_STATIC;
--- 1489,1502 ----
PENDING_STMT (e) = NULL;
/* Emit GIMPLE_OMP_FOR. */
! if (has_zero_uses (gimple_cond_pred (cond_stmt))
! && !SSA_NAME_IS_DEFAULT_DEF (gimple_cond_pred (cond_stmt)))
! {
! gimple def_stmt = SSA_NAME_DEF_STMT (gimple_cond_pred (cond_stmt));
! gimple_stmt_iterator gsi2 = gsi_for_stmt (def_stmt);
! gsi_remove (&gsi2, true);
! release_defs (def_stmt);
! }
type = TREE_TYPE (cvar);
t = build_omp_clause (BUILTINS_LOCATION, OMP_CLAUSE_SCHEDULE);
OMP_CLAUSE_SCHEDULE_KIND (t) = OMP_CLAUSE_SCHEDULE_STATIC;
*************** create_parallel_loop (struct loop *loop,
*** 1492,1499 ****
for_stmt = gimple_build_omp_for (NULL, t, 1, NULL);
gimple_omp_for_set_index (for_stmt, 0, initvar);
gimple_omp_for_set_initial (for_stmt, 0, cvar_init);
! gimple_omp_for_set_final (for_stmt, 0, gimple_cond_rhs (cond_stmt));
! gimple_omp_for_set_cond (for_stmt, 0, gimple_cond_code (cond_stmt));
gimple_omp_for_set_incr (for_stmt, 0, build2 (PLUS_EXPR, type,
cvar_base,
build_int_cst (type, 1)));
--- 1504,1511 ----
for_stmt = gimple_build_omp_for (NULL, t, 1, NULL);
gimple_omp_for_set_index (for_stmt, 0, initvar);
gimple_omp_for_set_initial (for_stmt, 0, cvar_init);
! gimple_omp_for_set_final (for_stmt, 0, rhs);
! gimple_omp_for_set_cond (for_stmt, 0, code);
gimple_omp_for_set_incr (for_stmt, 0, build2 (PLUS_EXPR, type,
cvar_base,
build_int_cst (type, 1)));
Index: trunk/gcc/tree-vrp.c
===================================================================
*** trunk.orig/gcc/tree-vrp.c 2010-08-29 16:30:26.000000000 +0200
--- trunk/gcc/tree-vrp.c 2010-08-30 14:32:23.000000000 +0200
*************** build_assert_expr_for (tree cond, tree v
*** 3948,3965 ****
}
- /* Return false if EXPR is a predicate expression involving floating
- point values. */
-
- static inline bool
- fp_predicate (gimple stmt)
- {
- GIMPLE_CHECK (stmt, GIMPLE_COND);
-
- return FLOAT_TYPE_P (TREE_TYPE (gimple_cond_lhs (stmt)));
- }
-
-
/* If the range of values taken by OP can be inferred after STMT executes,
return the comparison code (COMP_CODE_P) and value (VAL_P) that
describes the inferred range. Return true if a range could be
--- 3948,3953 ----
*************** register_edge_assert_for_1 (tree op, enu
*** 4429,4434 ****
--- 4417,4428 ----
if (TREE_CODE (op) != SSA_NAME)
return false;
+ /* Do not attempt to infer anything in names that flow through
+ abnormal edges. */
+ if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op))
+ return false;
+
+
/* We know that OP will have a zero or nonzero value. If OP is used
more than once go ahead and register an assert for OP.
*************** register_edge_assert_for_1 (tree op, enu
*** 4457,4462 ****
--- 4451,4460 ----
tree op0 = gimple_assign_rhs1 (op_def);
tree op1 = gimple_assign_rhs2 (op_def);
+ /* Do not register asserts for floating-point comparisons. */
+ if (FLOAT_TYPE_P (TREE_TYPE (op0)))
+ return retval;
+
if (TREE_CODE (op0) == SSA_NAME)
retval |= register_edge_assert_for_2 (op0, e, bsi, rhs_code, op0, op1,
invert);
*************** find_conditional_asserts (basic_block bb
*** 4592,4601 ****
{
bool need_assert;
gimple_stmt_iterator bsi;
- tree op;
edge_iterator ei;
edge e;
! ssa_op_iter iter;
need_assert = false;
bsi = gsi_for_stmt (last);
--- 4590,4602 ----
{
bool need_assert;
gimple_stmt_iterator bsi;
edge_iterator ei;
edge e;
! tree pred;
!
! pred = gimple_cond_pred (last);
! if (TREE_CODE (pred) != SSA_NAME)
! return false;
need_assert = false;
bsi = gsi_for_stmt (last);
*************** find_conditional_asserts (basic_block bb
*** 4609,4623 ****
if (e->dest == bb)
continue;
! /* Register the necessary assertions for each operand in the
! conditional predicate. */
! FOR_EACH_SSA_TREE_OPERAND (op, last, iter, SSA_OP_USE)
! {
! need_assert |= register_edge_assert_for (op, e, bsi,
! gimple_cond_code (last),
! gimple_cond_lhs (last),
! gimple_cond_rhs (last));
! }
}
return need_assert;
--- 4610,4618 ----
if (e->dest == bb)
continue;
! need_assert |= register_edge_assert_for_1 (pred,
! (e->flags & EDGE_FALSE_VALUE)
! ? EQ_EXPR : NE_EXPR, e, bsi);
}
return need_assert;
*************** find_assert_locations_1 (basic_block bb,
*** 4815,4825 ****
need_assert = false;
last = last_stmt (bb);
! /* If BB's last statement is a conditional statement involving integer
! operands, determine if we need to add ASSERT_EXPRs. */
if (last
&& gimple_code (last) == GIMPLE_COND
- && !fp_predicate (last)
&& !ZERO_SSA_OPERANDS (last, SSA_OP_USE))
need_assert |= find_conditional_asserts (bb, last);
--- 4810,4819 ----
need_assert = false;
last = last_stmt (bb);
! /* If BB's last statement is a conditional statement, determine if
! we need to add ASSERT_EXPRs. */
if (last
&& gimple_code (last) == GIMPLE_COND
&& !ZERO_SSA_OPERANDS (last, SSA_OP_USE))
need_assert |= find_conditional_asserts (bb, last);
*************** vrp_visit_cond_stmt (gimple stmt, edge *
*** 6073,6081 ****
4 more predicates folded in SPEC. */
sop = false;
! val = vrp_evaluate_conditional_warnv_with_ops (gimple_cond_code (stmt),
! gimple_cond_lhs (stmt),
! gimple_cond_rhs (stmt),
false, &sop, NULL);
if (val)
{
--- 6067,6075 ----
4 more predicates folded in SPEC. */
sop = false;
! val = vrp_evaluate_conditional_warnv_with_ops (NE_EXPR,
! gimple_cond_pred (stmt),
! boolean_false_node,
false, &sop, NULL);
if (val)
{
*************** test_for_singularity (enum tree_code con
*** 7088,7106 ****
return NULL;
}
! /* Simplify a conditional using a relational operator to an equality
test if the range information indicates only one value can satisfy
! the original conditional. */
static bool
simplify_cond_using_ranges (gimple stmt)
{
! tree op0 = gimple_cond_lhs (stmt);
! tree op1 = gimple_cond_rhs (stmt);
! enum tree_code cond_code = gimple_cond_code (stmt);
! if (cond_code != NE_EXPR
! && cond_code != EQ_EXPR
&& TREE_CODE (op0) == SSA_NAME
&& INTEGRAL_TYPE_P (TREE_TYPE (op0))
&& is_gimple_min_invariant (op1))
--- 7082,7102 ----
return NULL;
}
! /* Simplify a comparison using a relational operator to an equality
test if the range information indicates only one value can satisfy
! the original comparison. */
static bool
simplify_cond_using_ranges (gimple stmt)
{
! tree op0 = gimple_assign_rhs1 (stmt);
! tree op1 = gimple_assign_rhs2 (stmt);
! enum tree_code cond_code = gimple_assign_rhs_code (stmt);
! if ((cond_code == LT_EXPR
! || cond_code == LE_EXPR
! || cond_code == GE_EXPR
! || cond_code == GT_EXPR)
&& TREE_CODE (op0) == SSA_NAME
&& INTEGRAL_TYPE_P (TREE_TYPE (op0))
&& is_gimple_min_invariant (op1))
*************** simplify_cond_using_ranges (gimple stmt)
*** 7122,7131 ****
fprintf (dump_file, " into ");
}
! gimple_cond_set_code (stmt, EQ_EXPR);
! gimple_cond_set_lhs (stmt, op0);
! gimple_cond_set_rhs (stmt, new_tree);
!
update_stmt (stmt);
if (dump_file)
--- 7118,7126 ----
fprintf (dump_file, " into ");
}
! gimple_assign_set_rhs_code (stmt, EQ_EXPR);
! gimple_assign_set_rhs1 (stmt, op0);
! gimple_assign_set_rhs2 (stmt, new_tree);
update_stmt (stmt);
if (dump_file)
*************** simplify_cond_using_ranges (gimple stmt)
*** 7152,7161 ****
fprintf (dump_file, " into ");
}
! gimple_cond_set_code (stmt, NE_EXPR);
! gimple_cond_set_lhs (stmt, op0);
! gimple_cond_set_rhs (stmt, new_tree);
!
update_stmt (stmt);
if (dump_file)
--- 7147,7155 ----
fprintf (dump_file, " into ");
}
! gimple_assign_set_rhs_code (stmt, NE_EXPR);
! gimple_assign_set_rhs1 (stmt, op0);
! gimple_assign_set_rhs2 (stmt, new_tree);
update_stmt (stmt);
if (dump_file)
*************** simplify_stmt_using_ranges (gimple_stmt_
*** 7278,7283 ****
--- 7272,7285 ----
switch (rhs_code)
{
+ case LT_EXPR:
+ case LE_EXPR:
+ case GT_EXPR:
+ case GE_EXPR:
+ if (INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (stmt))))
+ return simplify_cond_using_ranges (stmt);
+ break;
+
case EQ_EXPR:
case NE_EXPR:
case TRUTH_NOT_EXPR:
*************** simplify_stmt_using_ranges (gimple_stmt_
*** 7322,7329 ****
break;
}
}
- else if (gimple_code (stmt) == GIMPLE_COND)
- return simplify_cond_using_ranges (stmt);
else if (gimple_code (stmt) == GIMPLE_SWITCH)
return simplify_switch_using_ranges (stmt);
--- 7324,7329 ----
*************** fold_predicate_in (gimple_stmt_iterator
*** 7351,7359 ****
stmt);
}
else if (gimple_code (stmt) == GIMPLE_COND)
! val = vrp_evaluate_conditional (gimple_cond_code (stmt),
! gimple_cond_lhs (stmt),
! gimple_cond_rhs (stmt),
stmt);
else
return false;
--- 7351,7359 ----
stmt);
}
else if (gimple_code (stmt) == GIMPLE_COND)
! val = vrp_evaluate_conditional (NE_EXPR,
! gimple_cond_pred (stmt),
! boolean_false_node,
stmt);
else
return false;
*************** fold_predicate_in (gimple_stmt_iterator
*** 7361,7375 ****
if (val)
{
if (assignment_p)
- val = fold_convert (gimple_expr_type (stmt), val);
-
- if (dump_file)
{
! fprintf (dump_file, "Folding predicate ");
! print_gimple_expr (dump_file, stmt, 0, 0);
! fprintf (dump_file, " to ");
! print_generic_expr (dump_file, val, 0);
! fprintf (dump_file, "\n");
}
if (is_gimple_assign (stmt))
--- 7361,7377 ----
if (val)
{
if (assignment_p)
{
! val = fold_convert (gimple_expr_type (stmt), val);
!
! if (dump_file)
! {
! fprintf (dump_file, "Folding predicate ");
! print_gimple_expr (dump_file, stmt, 0, 0);
! fprintf (dump_file, " to ");
! print_generic_expr (dump_file, val, 0);
! fprintf (dump_file, "\n");
! }
}
if (is_gimple_assign (stmt))
*************** simplify_stmt_for_jump_threading (gimple
*** 7420,7431 ****
/* We only use VRP information to simplify conditionals. This is
overly conservative, but it's unclear if doing more would be
worth the compile time cost. */
! if (gimple_code (stmt) != GIMPLE_COND)
! return NULL;
! return vrp_evaluate_conditional (gimple_cond_code (stmt),
! gimple_cond_lhs (stmt),
! gimple_cond_rhs (stmt), within_stmt);
}
/* Blocks which have more than one predecessor and more than
--- 7422,7436 ----
/* We only use VRP information to simplify conditionals. This is
overly conservative, but it's unclear if doing more would be
worth the compile time cost. */
! if (!is_gimple_assign (stmt))
! return NULL_TREE;
!
! if (TREE_CODE_CLASS (gimple_assign_rhs_code (stmt)) == tcc_comparison)
! return vrp_evaluate_conditional (gimple_assign_rhs_code (stmt),
! gimple_assign_rhs1 (stmt),
! gimple_assign_rhs2 (stmt), within_stmt);
! return NULL_TREE;
}
/* Blocks which have more than one predecessor and more than
*************** identify_jump_threads (void)
*** 7480,7488 ****
/* To avoid lots of silly node creation, we create a single
conditional and just modify it in-place when attempting to
thread jumps. */
! dummy = gimple_build_cond (EQ_EXPR,
! integer_zero_node, integer_zero_node,
! NULL, NULL);
/* Walk through all the blocks finding those which present a
potential jump threading opportunity. We could set this up
--- 7485,7491 ----
/* To avoid lots of silly node creation, we create a single
conditional and just modify it in-place when attempting to
thread jumps. */
! dummy = gimple_build_cond (boolean_true_node, NULL, NULL);
/* Walk through all the blocks finding those which present a
potential jump threading opportunity. We could set this up
*************** identify_jump_threads (void)
*** 7493,7498 ****
--- 7496,7502 ----
FOR_EACH_BB (bb)
{
gimple last;
+ edge_iterator ei;
/* If the generic jump threading code does not find this block
interesting, then there is nothing to do. */
*************** identify_jump_threads (void)
*** 7506,7535 ****
if (gimple_code (last) != GIMPLE_COND)
continue;
! /* We're basically looking for any kind of conditional with
! integral type arguments. */
! if (TREE_CODE (gimple_cond_lhs (last)) == SSA_NAME
! && INTEGRAL_TYPE_P (TREE_TYPE (gimple_cond_lhs (last)))
! && (TREE_CODE (gimple_cond_rhs (last)) == SSA_NAME
! || is_gimple_min_invariant (gimple_cond_rhs (last)))
! && INTEGRAL_TYPE_P (TREE_TYPE (gimple_cond_rhs (last))))
! {
! edge_iterator ei;
!
! /* We've got a block with multiple predecessors and multiple
! successors which also ends in a suitable conditional. For
! each predecessor, see if we can thread it to a specific
! successor. */
! FOR_EACH_EDGE (e, ei, bb->preds)
! {
! /* Do not thread across back edges or abnormal edges
! in the CFG. */
! if (e->flags & (EDGE_DFS_BACK | EDGE_COMPLEX))
! continue;
! thread_across_edge (dummy, e, true, &stack,
! simplify_stmt_for_jump_threading);
! }
}
}
--- 7510,7528 ----
if (gimple_code (last) != GIMPLE_COND)
continue;
! /* We've got a block with multiple predecessors and multiple
! successors which also ends in a suitable conditional. For
! each predecessor, see if we can thread it to a specific
! successor. */
! FOR_EACH_EDGE (e, ei, bb->preds)
! {
! /* Do not thread across back edges or abnormal edges
! in the CFG. */
! if (e->flags & (EDGE_DFS_BACK | EDGE_COMPLEX))
! continue;
! thread_across_edge (dummy, e, true, &stack,
! simplify_stmt_for_jump_threading);
}
}
Index: trunk/gcc/value-prof.c
===================================================================
*** trunk.orig/gcc/value-prof.c 2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/value-prof.c 2010-08-30 14:32:23.000000000 +0200
*************** gimple_divmod_fixed_value (gimple stmt,
*** 577,586 ****
gsi = gsi_for_stmt (stmt);
tmpv = create_tmp_var (optype, "PROF");
! tmp1 = create_tmp_var (optype, "PROF");
stmt1 = gimple_build_assign (tmpv, fold_convert (optype, value));
! stmt2 = gimple_build_assign (tmp1, op2);
! stmt3 = gimple_build_cond (NE_EXPR, tmp1, tmpv, NULL_TREE, NULL_TREE);
gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
--- 577,586 ----
gsi = gsi_for_stmt (stmt);
tmpv = create_tmp_var (optype, "PROF");
! tmp1 = create_tmp_var (boolean_type_node, "PROF");
stmt1 = gimple_build_assign (tmpv, fold_convert (optype, value));
! stmt2 = gimple_build_assign_with_ops (NE_EXPR, tmp1, op2, tmpv);
! stmt3 = gimple_build_cond (tmp1, NULL_TREE, NULL_TREE);
gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
*************** gimple_divmod_fixed_value_transform (gim
*** 710,717 ****
static tree
gimple_mod_pow2 (gimple stmt, int prob, gcov_type count, gcov_type all)
{
! gimple stmt1, stmt2, stmt3, stmt4;
! tree tmp2, tmp3;
gimple bb1end, bb2end, bb3end;
basic_block bb, bb2, bb3, bb4;
tree optype, op1, op2;
--- 710,717 ----
static tree
gimple_mod_pow2 (gimple stmt, int prob, gcov_type count, gcov_type all)
{
! gimple stmt1, stmt2, stmt3, stmt4, stmt5;
! tree tmp2, tmp3, tmp4;
gimple bb1end, bb2end, bb3end;
basic_block bb, bb2, bb3, bb4;
tree optype, op1, op2;
*************** gimple_mod_pow2 (gimple stmt, int prob,
*** 732,745 ****
result = create_tmp_var (optype, "PROF");
tmp2 = create_tmp_var (optype, "PROF");
tmp3 = create_tmp_var (optype, "PROF");
stmt2 = gimple_build_assign_with_ops (PLUS_EXPR, tmp2, op2,
build_int_cst (optype, -1));
stmt3 = gimple_build_assign_with_ops (BIT_AND_EXPR, tmp3, tmp2, op2);
! stmt4 = gimple_build_cond (NE_EXPR, tmp3, build_int_cst (optype, 0),
! NULL_TREE, NULL_TREE);
gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
gsi_insert_before (&gsi, stmt4, GSI_SAME_STMT);
bb1end = stmt4;
/* tmp2 == op2-1 inherited from previous block. */
--- 732,748 ----
result = create_tmp_var (optype, "PROF");
tmp2 = create_tmp_var (optype, "PROF");
tmp3 = create_tmp_var (optype, "PROF");
+ tmp4 = create_tmp_var (boolean_type_node, NULL);
stmt2 = gimple_build_assign_with_ops (PLUS_EXPR, tmp2, op2,
build_int_cst (optype, -1));
stmt3 = gimple_build_assign_with_ops (BIT_AND_EXPR, tmp3, tmp2, op2);
! stmt4 = gimple_build_assign_with_ops (NE_EXPR, tmp4, tmp3,
! build_int_cst (optype, 0));
! stmt5 = gimple_build_cond (tmp4, NULL_TREE, NULL_TREE);
gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
gsi_insert_before (&gsi, stmt4, GSI_SAME_STMT);
+ gsi_insert_before (&gsi, stmt5, GSI_SAME_STMT);
bb1end = stmt4;
/* tmp2 == op2-1 inherited from previous block. */
*************** gimple_mod_subtract (gimple stmt, int pr
*** 882,891 ****
gsi = gsi_for_stmt (stmt);
result = create_tmp_var (optype, "PROF");
! tmp1 = create_tmp_var (optype, "PROF");
stmt1 = gimple_build_assign (result, op1);
! stmt2 = gimple_build_assign (tmp1, op2);
! stmt3 = gimple_build_cond (LT_EXPR, result, tmp1, NULL_TREE, NULL_TREE);
gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
--- 885,894 ----
gsi = gsi_for_stmt (stmt);
result = create_tmp_var (optype, "PROF");
! tmp1 = create_tmp_var (boolean_type_node, "PROF");
stmt1 = gimple_build_assign (result, op1);
! stmt2 = gimple_build_assign_with_ops (LT_EXPR, tmp1, result, op2);
! stmt3 = gimple_build_cond (tmp1, NULL_TREE, NULL_TREE);
gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
gsi_insert_before (&gsi, stmt3, GSI_SAME_STMT);
*************** gimple_mod_subtract (gimple stmt, int pr
*** 893,900 ****
if (ncounts) /* Assumed to be 0 or 1 */
{
! stmt1 = gimple_build_assign_with_ops (MINUS_EXPR, result, result, tmp1);
! stmt2 = gimple_build_cond (LT_EXPR, result, tmp1, NULL_TREE, NULL_TREE);
gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
bb2end = stmt2;
--- 896,904 ----
if (ncounts) /* Assumed to be 0 or 1 */
{
! stmt1 = gimple_build_assign_with_ops (LT_EXPR, tmp1, result, op2);
! stmt2 = gimple_build_assign_with_ops (MINUS_EXPR, result, result, op2);
! stmt3 = gimple_build_cond (tmp1, NULL_TREE, NULL_TREE);
gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
gsi_insert_before (&gsi, stmt2, GSI_SAME_STMT);
bb2end = stmt2;
*************** gimple_mod_subtract (gimple stmt, int pr
*** 902,908 ****
/* Fallback case. */
stmt1 = gimple_build_assign_with_ops (gimple_assign_rhs_code (stmt), result,
! result, tmp1);
gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
bb3end = stmt1;
--- 906,912 ----
/* Fallback case. */
stmt1 = gimple_build_assign_with_ops (gimple_assign_rhs_code (stmt), result,
! result, op2);
gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
bb3end = stmt1;
*************** static gimple
*** 1091,1098 ****
gimple_ic (gimple icall_stmt, struct cgraph_node *direct_call,
int prob, gcov_type count, gcov_type all)
{
! gimple dcall_stmt, load_stmt, cond_stmt;
! tree tmp1, tmpv, tmp;
basic_block cond_bb, dcall_bb, icall_bb, join_bb;
tree optype = build_pointer_type (void_type_node);
edge e_cd, e_ci, e_di, e_dj, e_ij;
--- 1095,1102 ----
gimple_ic (gimple icall_stmt, struct cgraph_node *direct_call,
int prob, gcov_type count, gcov_type all)
{
! gimple dcall_stmt, load_stmt, cond_stmt, comp_stmt;
! tree tmp1, tmpv, tmp, tmp2;
basic_block cond_bb, dcall_bb, icall_bb, join_bb;
tree optype = build_pointer_type (void_type_node);
edge e_cd, e_ci, e_di, e_dj, e_ij;
*************** gimple_ic (gimple icall_stmt, struct cgr
*** 1113,1119 ****
load_stmt = gimple_build_assign (tmp1, tmp);
gsi_insert_before (&gsi, load_stmt, GSI_SAME_STMT);
! cond_stmt = gimple_build_cond (EQ_EXPR, tmp1, tmpv, NULL_TREE, NULL_TREE);
gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT);
dcall_stmt = gimple_copy (icall_stmt);
--- 1117,1126 ----
load_stmt = gimple_build_assign (tmp1, tmp);
gsi_insert_before (&gsi, load_stmt, GSI_SAME_STMT);
! tmp2 = create_tmp_var (boolean_type_node, NULL);
! comp_stmt = gimple_build_assign_with_ops (EQ_EXPR, tmp2, tmp1, tmpv);
! gsi_insert_before (&gsi, comp_stmt, GSI_SAME_STMT);
! cond_stmt = gimple_build_cond (tmp2, NULL_TREE, NULL_TREE);
gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT);
dcall_stmt = gimple_copy (icall_stmt);
*************** static void
*** 1288,1295 ****
gimple_stringop_fixed_value (gimple vcall_stmt, tree icall_size, int prob,
gcov_type count, gcov_type all)
{
! gimple tmp_stmt, cond_stmt, icall_stmt;
! tree tmp1, tmpv, vcall_size, optype;
basic_block cond_bb, icall_bb, vcall_bb, join_bb;
edge e_ci, e_cv, e_iv, e_ij, e_vj;
gimple_stmt_iterator gsi;
--- 1295,1302 ----
gimple_stringop_fixed_value (gimple vcall_stmt, tree icall_size, int prob,
gcov_type count, gcov_type all)
{
! gimple tmp_stmt, cond_stmt, icall_stmt, comp_stmt;
! tree tmp1, tmpv, vcall_size, optype, tmp2;
basic_block cond_bb, icall_bb, vcall_bb, join_bb;
edge e_ci, e_cv, e_iv, e_ij, e_vj;
gimple_stmt_iterator gsi;
*************** gimple_stringop_fixed_value (gimple vcal
*** 1314,1320 ****
tmp_stmt = gimple_build_assign (tmp1, vcall_size);
gsi_insert_before (&gsi, tmp_stmt, GSI_SAME_STMT);
! cond_stmt = gimple_build_cond (EQ_EXPR, tmp1, tmpv, NULL_TREE, NULL_TREE);
gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT);
icall_stmt = gimple_copy (vcall_stmt);
--- 1321,1330 ----
tmp_stmt = gimple_build_assign (tmp1, vcall_size);
gsi_insert_before (&gsi, tmp_stmt, GSI_SAME_STMT);
! tmp2 = create_tmp_var (boolean_type_node, NULL);
! comp_stmt = gimple_build_assign_with_ops (EQ_EXPR, tmp2, tmp1, tmpv);
! gsi_insert_before (&gsi, comp_stmt, GSI_SAME_STMT);
! cond_stmt = gimple_build_cond (tmp2, NULL_TREE, NULL_TREE);
gsi_insert_before (&gsi, cond_stmt, GSI_SAME_STMT);
icall_stmt = gimple_copy (vcall_stmt);
Index: trunk/gcc/tree-ssa-propagate.c
===================================================================
*** trunk.orig/gcc/tree-ssa-propagate.c 2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/tree-ssa-propagate.c 2010-08-30 14:32:23.000000000 +0200
*************** substitute_and_fold (ssa_prop_get_value_
*** 1019,1024 ****
--- 1019,1039 ----
gsi = gsi_for_stmt (def_stmt);
if (is_gimple_assign (def_stmt))
{
+ if (dump_file
+ && (TREE_CODE_CLASS (gimple_assign_rhs_code (def_stmt))
+ == tcc_comparison))
+ {
+ fprintf (dump_file, "Folding predicate ");
+ print_generic_expr (dump_file,
+ gimple_assign_rhs1 (def_stmt), 0);
+ fprintf (dump_file, " %s ",
+ op_symbol_code (gimple_assign_rhs_code (def_stmt)));
+ print_generic_expr (dump_file,
+ gimple_assign_rhs2 (def_stmt), 0);
+ fprintf (dump_file, " to ");
+ print_generic_expr (dump_file, val, 0);
+ fprintf (dump_file, "\n");
+ }
gimple_assign_set_rhs_with_ops (&gsi, TREE_CODE (val),
val, NULL_TREE);
gcc_assert (gsi_stmt (gsi) == def_stmt);
Index: trunk/gcc/tree-eh.c
===================================================================
*** trunk.orig/gcc/tree-eh.c 2010-08-25 16:49:48.000000000 +0200
--- trunk/gcc/tree-eh.c 2010-08-30 14:32:23.000000000 +0200
*************** replace_goto_queue_1 (gimple stmt, struc
*** 520,527 ****
break;
case GIMPLE_COND:
! replace_goto_queue_cond_clause (gimple_op_ptr (stmt, 2), tf, gsi);
! replace_goto_queue_cond_clause (gimple_op_ptr (stmt, 3), tf, gsi);
break;
case GIMPLE_TRY:
--- 520,529 ----
break;
case GIMPLE_COND:
! replace_goto_queue_cond_clause (gimple_cond_true_label_ptr (stmt),
! tf, gsi);
! replace_goto_queue_cond_clause (gimple_cond_false_label_ptr (stmt),
! tf, gsi);
break;
case GIMPLE_TRY:
*************** maybe_record_in_goto_queue (struct leh_s
*** 661,669 ****
switch (gimple_code (stmt))
{
case GIMPLE_COND:
! new_stmt.tp = gimple_op_ptr (stmt, 2);
record_in_goto_queue_label (tf, new_stmt, gimple_cond_true_label (stmt));
! new_stmt.tp = gimple_op_ptr (stmt, 3);
record_in_goto_queue_label (tf, new_stmt, gimple_cond_false_label (stmt));
break;
case GIMPLE_GOTO:
--- 663,671 ----
switch (gimple_code (stmt))
{
case GIMPLE_COND:
! new_stmt.tp = gimple_cond_true_label_ptr (stmt);
record_in_goto_queue_label (tf, new_stmt, gimple_cond_true_label (stmt));
! new_stmt.tp = gimple_cond_false_label_ptr (stmt);
record_in_goto_queue_label (tf, new_stmt, gimple_cond_false_label (stmt));
break;
case GIMPLE_GOTO:
*************** lower_eh_dispatch (basic_block src, gimp
*** 3197,3202 ****
--- 3199,3205 ----
{
edge b_e = BRANCH_EDGE (src);
edge f_e = FALLTHRU_EDGE (src);
+ tree cond;
fn = implicit_built_in_decls[BUILT_IN_EH_FILTER];
x = gimple_build_call (fn, 1, build_int_cst (NULL, region_nr));
*************** lower_eh_dispatch (basic_block src, gimp
*** 3206,3215 ****
gsi_insert_before (&gsi, x, GSI_SAME_STMT);
r->u.allowed.label = NULL;
! x = gimple_build_cond (EQ_EXPR, filter,
! build_int_cst (TREE_TYPE (filter),
! r->u.allowed.filter),
! NULL_TREE, NULL_TREE);
gsi_insert_before (&gsi, x, GSI_SAME_STMT);
b_e->flags = b_e->flags | EDGE_TRUE_VALUE;
--- 3209,3220 ----
gsi_insert_before (&gsi, x, GSI_SAME_STMT);
r->u.allowed.label = NULL;
! cond = fold_build2 (EQ_EXPR, boolean_type_node,
! filter, build_int_cst (TREE_TYPE (filter),
! r->u.allowed.filter));
! cond = force_gimple_operand_gsi (&gsi, cond, true, NULL,
! true, GSI_SAME_STMT);
! x = gimple_build_cond (cond, NULL_TREE, NULL_TREE);
gsi_insert_before (&gsi, x, GSI_SAME_STMT);
b_e->flags = b_e->flags | EDGE_TRUE_VALUE;
Index: trunk/gcc/cp/cp-gimplify.c
===================================================================
*** trunk.orig/gcc/cp/cp-gimplify.c 2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/cp/cp-gimplify.c 2010-08-30 14:32:23.000000000 +0200
*************** gimplify_cp_loop (tree cond, tree body,
*** 238,245 ****
if (cond != error_mark_node)
{
gimplify_expr (&cond, &exit_seq, NULL, is_gimple_val, fb_rvalue);
! stmt = gimple_build_cond (NE_EXPR, cond,
! build_int_cst (TREE_TYPE (cond), 0),
gimple_label_label (top),
get_bc_label (bc_break));
gimple_seq_add_stmt (&exit_seq, stmt);
--- 238,244 ----
if (cond != error_mark_node)
{
gimplify_expr (&cond, &exit_seq, NULL, is_gimple_val, fb_rvalue);
! stmt = gimple_build_cond (cond,
gimple_label_label (top),
get_bc_label (bc_break));
gimple_seq_add_stmt (&exit_seq, stmt);
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/ivopts-3.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/ivopts-3.c 2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/ivopts-3.c 2010-08-30 14:32:23.000000000 +0200
*************** void main (void)
*** 8,12 ****
f2 ();
}
! /* { dg-final { scan-tree-dump-times "!= 0" 5 "ivopts" } } */
/* { dg-final { cleanup-tree-dump "ivopts" } } */
--- 8,12 ----
f2 ();
}
! /* { dg-final { scan-tree-dump-times "!= 0" 3 "ivopts" } } */
/* { dg-final { cleanup-tree-dump "ivopts" } } */
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/builtin-expect-1.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/builtin-expect-1.c 2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/builtin-expect-1.c 2010-08-30 14:32:23.000000000 +0200
*************** f (int i, float j)
*** 7,11 ****
g ();
}
! /* { dg-final { scan-tree-dump-times {builtin_expect[^\n]*, 0\);\n[^\n]*if} 2 "gimple"} } */
/* { dg-final { cleanup-tree-dump "gimple" } } */
--- 7,11 ----
g ();
}
! /* { dg-final { scan-tree-dump-times {builtin_expect[^\n]*, 0\);\n[^\n;]*;\n[^\n]*if} 2 "gimple"} } */
/* { dg-final { cleanup-tree-dump "gimple" } } */
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/builtin-expect-2.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/builtin-expect-2.c 2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/builtin-expect-2.c 2010-08-30 14:32:23.000000000 +0200
*************** f (int i, float j)
*** 9,13 ****
g ();
}
! /* { dg-final { scan-tree-dump-times {builtin_expect[^\n]*, 0\);\n[^\n]*if} 2 "gimple"} } */
/* { dg-final { cleanup-tree-dump "gimple" } } */
--- 9,13 ----
g ();
}
! /* { dg-final { scan-tree-dump-times {builtin_expect[^\n]*, 0\);\n[^\n;]*;\n[^\n]*if} 2 "gimple"} } */
/* { dg-final { cleanup-tree-dump "gimple" } } */
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/builtin-expect-3.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/builtin-expect-3.c 2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/builtin-expect-3.c 2010-08-30 14:32:23.000000000 +0200
*************** f (int i, float j)
*** 9,13 ****
b ();
}
! /* { dg-final { scan-tree-dump-times {builtin_expect[^\n]*, 0\);\n[^\n]*if} 2 "gimple"} } */
/* { dg-final { cleanup-tree-dump "gimple" } } */
--- 9,13 ----
b ();
}
! /* { dg-final { scan-tree-dump-times {builtin_expect[^\n]*, 0\);\n[^\n;]*;\n[^\n]*if} 2 "gimple"} } */
/* { dg-final { cleanup-tree-dump "gimple" } } */
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/builtin-expect-4.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/builtin-expect-4.c 2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/builtin-expect-4.c 2010-08-30 14:32:23.000000000 +0200
*************** f (int i, float j)
*** 9,13 ****
b ();
}
! /* { dg-final { scan-tree-dump-times {builtin_expect[^\n]*, 0\);\n[^\n]*if} 2 "gimple"} } */
/* { dg-final { cleanup-tree-dump "gimple" } } */
--- 9,13 ----
b ();
}
! /* { dg-final { scan-tree-dump-times {builtin_expect[^\n]*, 0\);\n[^\n;]*;\n[^\n]*if} 2 "gimple"} } */
/* { dg-final { cleanup-tree-dump "gimple" } } */
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/builtin-expect-5.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/builtin-expect-5.c 2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/builtin-expect-5.c 2010-08-30 14:32:23.000000000 +0200
*************** f (int i, float j)
*** 10,15 ****
}
/* { dg-final { scan-tree-dump-times { if } 2 "forwprop1"} } */
! /* { dg-final { scan-tree-dump {builtin_expect[^\n]*, 0\);\n[^\n]*if} "forwprop1"} } */
! /* { dg-final { scan-tree-dump {builtin_expect[^\n]*, 1\);\n[^\n]*if} "forwprop1"} } */
/* { dg-final { cleanup-tree-dump "forwprop?" } } */
--- 10,15 ----
}
/* { dg-final { scan-tree-dump-times { if } 2 "forwprop1"} } */
! /* { dg-final { scan-tree-dump {builtin_expect[^\n]*, 0\);\n[^\n;]*;\n[^\n]*if} "forwprop1"} } */
! /* { dg-final { scan-tree-dump {builtin_expect[^\n]*, 1\);\n[^\n;]*;\n[^\n]*if} "forwprop1"} } */
/* { dg-final { cleanup-tree-dump "forwprop?" } } */
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/pr20657.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/pr20657.c 2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/pr20657.c 2010-08-30 14:32:23.000000000 +0200
***************
*** 3,9 ****
statement, which was needed to eliminate the second "if" statement. */
/* { dg-do compile } */
! /* { dg-options "-O2 -fno-tree-dominator-opts -fdump-tree-vrp1-details" } */
int
foo (int a)
--- 3,9 ----
statement, which was needed to eliminate the second "if" statement. */
/* { dg-do compile } */
! /* { dg-options "-O2 -fno-tree-fre -fno-tree-dominator-opts -fdump-tree-vrp1-details" } */
int
foo (int a)
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/pr21001.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/pr21001.c 2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/pr21001.c 2010-08-30 14:32:23.000000000 +0200
***************
*** 5,11 ****
range infomation out of the conditional. */
/* { dg-do compile } */
! /* { dg-options "-O2 -fno-tree-dominator-opts -fdump-tree-vrp1-details" } */
int
foo (int a)
--- 5,11 ----
range infomation out of the conditional. */
/* { dg-do compile } */
! /* { dg-options "-O2 -fno-tree-fre -fno-tree-dominator-opts -fdump-tree-vrp1-details" } */
int
foo (int a)
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-8.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-8.c 2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-8.c 2010-08-30 14:32:23.000000000 +0200
*************** foo (__SIZE_TYPE__ i, struct s *array)
*** 16,23 ****
}
return 0;
}
! /* We should eliminate two address calculations, and one load. */
/* We used to eliminate a cast but that was before POINTER_PLUS_EXPR
was added. */
! /* { dg-final { scan-tree-dump-times "Eliminated: 3" 1 "fre"} } */
/* { dg-final { cleanup-tree-dump "fre" } } */
--- 16,24 ----
}
return 0;
}
! /* We should eliminate two address calculations, and one load and
! simplify the p != q comparison to 0. */
/* We used to eliminate a cast but that was before POINTER_PLUS_EXPR
was added. */
! /* { dg-final { scan-tree-dump-times "Eliminated: 4" 1 "fre"} } */
/* { dg-final { cleanup-tree-dump "fre" } } */
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/vrp04.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/vrp04.c 2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/vrp04.c 2010-08-30 14:32:23.000000000 +0200
***************
*** 1,5 ****
/* { dg-do compile } */
! /* { dg-options "-O2 -fdump-tree-vrp1" } */
foo (int a, int b)
{
--- 1,5 ----
/* { dg-do compile } */
! /* { dg-options "-O2 -fno-tree-fre -fdump-tree-vrp1" } */
foo (int a, int b)
{
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/vrp07.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/vrp07.c 2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/vrp07.c 2010-08-30 14:32:23.000000000 +0200
***************
*** 1,5 ****
/* { dg-do compile } */
! /* { dg-options "-O2 -fdump-tree-vrp1-details" } */
foo (int i, int *p)
{
--- 1,5 ----
/* { dg-do compile } */
! /* { dg-options "-O2 -fno-tree-fre -fdump-tree-vrp1-details" } */
foo (int i, int *p)
{
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/vrp09.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/vrp09.c 2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/vrp09.c 2010-08-30 14:32:23.000000000 +0200
***************
*** 1,5 ****
/* { dg-do compile } */
! /* { dg-options "-O2 -fdump-tree-vrp1" } */
foo (int *p)
{
--- 1,5 ----
/* { dg-do compile } */
! /* { dg-options "-O2 -fno-tree-fre -fdump-tree-vrp1" } */
foo (int *p)
{
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/vrp20.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/vrp20.c 2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/vrp20.c 2010-08-30 14:32:23.000000000 +0200
***************
*** 1,5 ****
/* { dg-do compile } */
! /* { dg-options "-fwrapv -O1 -ftree-vrp -fdump-tree-vrp1" } */
extern void abort ();
extern void exit (int);
--- 1,5 ----
/* { dg-do compile } */
! /* { dg-options "-fwrapv -O1 -fno-tree-fre -ftree-vrp -fdump-tree-vrp1" } */
extern void abort ();
extern void exit (int);
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/vrp25.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/vrp25.c 2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/vrp25.c 2010-08-30 14:32:23.000000000 +0200
*************** L9:
*** 47,52 ****
/* The second test of (code1 != 53) and the test (D18670 <= 2) are
both totally subsumed by earlier tests and thus should be folded
away using VRP. */
! /* { dg-final { scan-tree-dump-times "Folding predicate" 2 "vrp1" } } */
/* { dg-final { cleanup-tree-dump "vrp1" } } */
--- 47,53 ----
/* The second test of (code1 != 53) and the test (D18670 <= 2) are
both totally subsumed by earlier tests and thus should be folded
away using VRP. */
! /* { dg-final { scan-tree-dump "Folding predicate D\[0-9_\]* <= 2 to 0" "vrp1" } } */
! /* { dg-final { scan-tree-dump-times "Folded into: if \\\(0\\\)" 2 "vrp1" } } */
/* { dg-final { cleanup-tree-dump "vrp1" } } */
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/vrp33.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/vrp33.c 2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/vrp33.c 2010-08-30 14:32:23.000000000 +0200
***************
*** 1,9 ****
/* { dg-do compile } */
! /* { dg-options "-O2 -fdump-tree-vrp1" } */
/* This is from PR14052. */
int f2(int x) { return x == 1 || x == 3 || x == 1; }
! /* { dg-final { scan-tree-dump "Folding predicate.*== 1 to 0" "vrp1" } } */
/* { dg-final { cleanup-tree-dump "vrp1" } } */
--- 1,9 ----
/* { dg-do compile } */
! /* { dg-options "-O2 -fdump-tree-vrp1-details" } */
/* This is from PR14052. */
int f2(int x) { return x == 1 || x == 3 || x == 1; }
! /* { dg-final { scan-tree-dump "Folded into: if \\\(0\\\)" "vrp1" } } */
/* { dg-final { cleanup-tree-dump "vrp1" } } */
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/vrp35.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/vrp35.c 2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/vrp35.c 2010-08-30 14:32:23.000000000 +0200
*************** int test1(int i, int k)
*** 11,15 ****
return 1;
}
! /* { dg-final { scan-tree-dump-not "j_.* == 10" "vrp1" } } */
/* { dg-final { cleanup-tree-dump "vrp1" } } */
--- 11,15 ----
return 1;
}
! /* { dg-final { scan-tree-dump "Folding predicate j_\[0-9\]* == 10 to 0" "vrp1" } } */
/* { dg-final { cleanup-tree-dump "vrp1" } } */
Index: trunk/gcc/testsuite/gcc.dg/tree-ssa/vrp36.c
===================================================================
*** trunk.orig/gcc/testsuite/gcc.dg/tree-ssa/vrp36.c 2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/testsuite/gcc.dg/tree-ssa/vrp36.c 2010-08-30 14:32:23.000000000 +0200
*************** int foo(int i)
*** 8,12 ****
return 1;
}
! /* { dg-final { scan-tree-dump-not "i_.* == 1" "vrp1" } } */
/* { dg-final { cleanup-tree-dump "vrp1" } } */
--- 8,12 ----
return 1;
}
! /* { dg-final { scan-tree-dump "Folding predicate i_\[0-9\]* == 1 to 0" "vrp1" } } */
/* { dg-final { cleanup-tree-dump "vrp1" } } */
Index: trunk/gcc/testsuite/gcc.c-torture/execute/920612-1.x
===================================================================
*** /dev/null 1970-01-01 00:00:00.000000000 +0000
--- trunk/gcc/testsuite/gcc.c-torture/execute/920612-1.x 2010-08-30 14:32:23.000000000 +0200
***************
*** 0 ****
--- 1,2 ----
+ set additional_flags "-fwrapv"
+ return 0
Index: trunk/gcc/tree-ssa-threadupdate.c
===================================================================
*** trunk.orig/gcc/tree-ssa-threadupdate.c 2010-08-24 12:02:23.000000000 +0200
--- trunk/gcc/tree-ssa-threadupdate.c 2010-08-30 14:32:23.000000000 +0200
*************** redirection_block_p (basic_block bb)
*** 482,487 ****
--- 482,498 ----
if (gsi_end_p (gsi))
return true;
+ /* The terminating GIMPLE_COND can have a preceding predicate computation. */
+ if (is_gimple_assign (gsi_stmt (gsi)))
+ {
+ gimple pred = gsi_stmt (gsi);
+ gsi_next (&gsi);
+ if (gsi_end_p (gsi)
+ || gimple_code (gsi_stmt (gsi)) != GIMPLE_COND
+ || gimple_cond_pred (gsi_stmt (gsi)) != gimple_assign_lhs (pred))
+ return false;
+ }
+
/* Test that we've reached the terminating control statement. */
return gsi_stmt (gsi)
&& (gimple_code (gsi_stmt (gsi)) == GIMPLE_COND
Index: trunk/gcc/tree-vect-data-refs.c
===================================================================
*** trunk.orig/gcc/tree-vect-data-refs.c 2010-08-24 10:32:38.000000000 +0200
--- trunk/gcc/tree-vect-data-refs.c 2010-08-30 15:26:46.000000000 +0200
*************** tree
*** 64,72 ****
vect_get_smallest_scalar_type (gimple stmt, HOST_WIDE_INT *lhs_size_unit,
HOST_WIDE_INT *rhs_size_unit)
{
! tree scalar_type = gimple_expr_type (stmt);
HOST_WIDE_INT lhs, rhs;
lhs = rhs = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (scalar_type));
if (is_gimple_assign (stmt)
--- 64,77 ----
vect_get_smallest_scalar_type (gimple stmt, HOST_WIDE_INT *lhs_size_unit,
HOST_WIDE_INT *rhs_size_unit)
{
! tree scalar_type;
HOST_WIDE_INT lhs, rhs;
+ if (is_gimple_assign (stmt)
+ && TREE_CODE_CLASS (gimple_assign_rhs_code (stmt)) == tcc_comparison)
+ scalar_type = TREE_TYPE (gimple_assign_rhs1 (stmt));
+ else
+ scalar_type = gimple_expr_type (stmt);
lhs = rhs = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (scalar_type));
if (is_gimple_assign (stmt)
Index: trunk/gcc/tree-vect-loop.c
===================================================================
*** trunk.orig/gcc/tree-vect-loop.c 2010-08-24 10:32:38.000000000 +0200
--- trunk/gcc/tree-vect-loop.c 2010-08-30 15:21:58.000000000 +0200
*************** vect_determine_vectorization_factor (loo
*** 298,304 ****
gcc_assert (!STMT_VINFO_DATA_REF (stmt_info)
&& !is_pattern_stmt_p (stmt_info));
! scalar_type = TREE_TYPE (gimple_get_lhs (stmt));
if (vect_print_dump_info (REPORT_DETAILS))
{
fprintf (vect_dump, "get vectype for scalar type: ");
--- 298,308 ----
gcc_assert (!STMT_VINFO_DATA_REF (stmt_info)
&& !is_pattern_stmt_p (stmt_info));
! if (is_gimple_assign (stmt)
! && TREE_CODE_CLASS (gimple_assign_rhs_code (stmt)) == tcc_comparison)
! scalar_type = TREE_TYPE (gimple_assign_rhs1 (stmt));
! else
! scalar_type = TREE_TYPE (gimple_get_lhs (stmt));
if (vect_print_dump_info (REPORT_DETAILS))
{
fprintf (vect_dump, "get vectype for scalar type: ");
Index: trunk/gcc/tree-vect-stmts.c
===================================================================
*** trunk.orig/gcc/tree-vect-stmts.c 2010-08-25 16:49:48.000000000 +0200
--- trunk/gcc/tree-vect-stmts.c 2010-08-30 15:20:42.000000000 +0200
*************** vectorizable_load (gimple stmt, gimple_s
*** 3945,3982 ****
condition operands are supportable using vec_is_simple_use. */
static bool
! vect_is_simple_cond (tree cond, loop_vec_info loop_vinfo)
{
- tree lhs, rhs;
tree def;
enum vect_def_type dt;
! if (!COMPARISON_CLASS_P (cond))
! return false;
!
! lhs = TREE_OPERAND (cond, 0);
! rhs = TREE_OPERAND (cond, 1);
! if (TREE_CODE (lhs) == SSA_NAME)
{
! gimple lhs_def_stmt = SSA_NAME_DEF_STMT (lhs);
! if (!vect_is_simple_use (lhs, loop_vinfo, NULL, &lhs_def_stmt, &def,
&dt))
return false;
}
! else if (TREE_CODE (lhs) != INTEGER_CST && TREE_CODE (lhs) != REAL_CST
! && TREE_CODE (lhs) != FIXED_CST)
return false;
! if (TREE_CODE (rhs) == SSA_NAME)
{
! gimple rhs_def_stmt = SSA_NAME_DEF_STMT (rhs);
! if (!vect_is_simple_use (rhs, loop_vinfo, NULL, &rhs_def_stmt, &def,
&dt))
return false;
}
! else if (TREE_CODE (rhs) != INTEGER_CST && TREE_CODE (rhs) != REAL_CST
! && TREE_CODE (rhs) != FIXED_CST)
return false;
return true;
--- 3945,3978 ----
condition operands are supportable using vec_is_simple_use. */
static bool
! vect_is_simple_cond (tree cond, loop_vec_info loop_vinfo,
! enum tree_code *code, tree *lhs, tree *rhs)
{
tree def;
enum vect_def_type dt;
! gimple_pred_extract_comparison (cond, code, lhs, rhs);
! if (TREE_CODE (*lhs) == SSA_NAME)
{
! gimple lhs_def_stmt = SSA_NAME_DEF_STMT (*lhs);
! if (!vect_is_simple_use (*lhs, loop_vinfo, NULL, &lhs_def_stmt, &def,
&dt))
return false;
}
! else if (TREE_CODE (*lhs) != INTEGER_CST && TREE_CODE (*lhs) != REAL_CST
! && TREE_CODE (*lhs) != FIXED_CST)
return false;
! if (TREE_CODE (*rhs) == SSA_NAME)
{
! gimple rhs_def_stmt = SSA_NAME_DEF_STMT (*rhs);
! if (!vect_is_simple_use (*rhs, loop_vinfo, NULL, &rhs_def_stmt, &def,
&dt))
return false;
}
! else if (TREE_CODE (*rhs) != INTEGER_CST && TREE_CODE (*rhs) != REAL_CST
! && TREE_CODE (*rhs) != FIXED_CST)
return false;
return true;
*************** vectorizable_condition (gimple stmt, gim
*** 4015,4020 ****
--- 4011,4017 ----
int nunits = TYPE_VECTOR_SUBPARTS (vectype);
int ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits;
enum tree_code code;
+ tree lhs, rhs;
/* FORNOW: unsupported in basic block SLP. */
gcc_assert (loop_vinfo);
*************** vectorizable_condition (gimple stmt, gim
*** 4058,4070 ****
then_clause = TREE_OPERAND (op, 1);
else_clause = TREE_OPERAND (op, 2);
! if (!vect_is_simple_cond (cond_expr, loop_vinfo))
return false;
/* We do not handle two different vector types for the condition
and the values. */
! if (!types_compatible_p (TREE_TYPE (TREE_OPERAND (cond_expr, 0)),
! TREE_TYPE (vectype)))
return false;
if (TREE_CODE (then_clause) == SSA_NAME)
--- 4055,4066 ----
then_clause = TREE_OPERAND (op, 1);
else_clause = TREE_OPERAND (op, 2);
! if (!vect_is_simple_cond (cond_expr, loop_vinfo, &code, &lhs, &rhs))
return false;
/* We do not handle two different vector types for the condition
and the values. */
! if (!types_compatible_p (TREE_TYPE (lhs), TREE_TYPE (vectype)))
return false;
if (TREE_CODE (then_clause) == SSA_NAME)
*************** vectorizable_condition (gimple stmt, gim
*** 4108,4116 ****
/* Handle cond expr. */
vec_cond_lhs =
! vect_get_vec_def_for_operand (TREE_OPERAND (cond_expr, 0), stmt, NULL);
vec_cond_rhs =
! vect_get_vec_def_for_operand (TREE_OPERAND (cond_expr, 1), stmt, NULL);
if (reduc_index == 1)
vec_then_clause = reduc_def;
else
--- 4104,4112 ----
/* Handle cond expr. */
vec_cond_lhs =
! vect_get_vec_def_for_operand (lhs, stmt, NULL);
vec_cond_rhs =
! vect_get_vec_def_for_operand (rhs, stmt, NULL);
if (reduc_index == 1)
vec_then_clause = reduc_def;
else
*************** vectorizable_condition (gimple stmt, gim
*** 4121,4127 ****
vec_else_clause = vect_get_vec_def_for_operand (else_clause, stmt, NULL);
/* Arguments are ready. Create the new vector stmt. */
! vec_compare = build2 (TREE_CODE (cond_expr), vectype,
vec_cond_lhs, vec_cond_rhs);
vec_cond_expr = build3 (VEC_COND_EXPR, vectype,
vec_compare, vec_then_clause, vec_else_clause);
--- 4117,4123 ----
vec_else_clause = vect_get_vec_def_for_operand (else_clause, stmt, NULL);
/* Arguments are ready. Create the new vector stmt. */
! vec_compare = build2 (code, vectype,
vec_cond_lhs, vec_cond_rhs);
vec_cond_expr = build3 (VEC_COND_EXPR, vectype,
vec_compare, vec_then_clause, vec_else_clause);