@@ -2002,7 +2002,7 @@ maybe_cleanup_end_of_block (edge e, rtx last)
block and created a new one. */
static basic_block
-expand_gimple_cond (basic_block bb, gimple stmt)
+expand_gimple_cond (basic_block bb, gimple_cond stmt)
{
basic_block new_bb, dest;
edge new_edge;
@@ -5012,7 +5012,7 @@ expand_gimple_basic_block (basic_block bb, bool disable_tail_calls)
fixup the CFG accordingly. */
if (gimple_code (stmt) == GIMPLE_COND)
{
- new_bb = expand_gimple_cond (bb, stmt);
+ new_bb = expand_gimple_cond (bb, stmt->as_a_gimple_cond ());
if (new_bb)
return new_bb;
}
@@ -776,7 +776,7 @@ create_empty_loop_on_edge (edge entry_edge,
struct loop *loop;
gimple_stmt_iterator gsi;
gimple_seq stmts;
- gimple cond_expr;
+ gimple_cond cond_expr;
tree exit_test;
edge exit_e;
int prob;
@@ -70,6 +70,10 @@ typedef struct gimple_stmt_iterator_d gimple_stmt_iterator;
/* Typedefs for leaf gimple subclasses (for individual gimple codes).
Keep this in the same order as the corresponding codes in gimple.def. */
+struct gimple_statement_cond;
+typedef struct gimple_statement_cond *gimple_cond;
+typedef const struct gimple_statement_cond *const_gimple_cond;
+
struct gimple_statement_switch;
typedef struct gimple_statement_switch *gimple_switch;
typedef const struct gimple_statement_switch *const_gimple_switch;
@@ -457,6 +457,8 @@ def build_pretty_printer():
pp.add_printer_for_types(['gimple', 'gimple_statement_base *',
# Keep this in the same order as gimple.def:
+ 'gimple_cond', 'const_gimple_cond',
+ 'gimple_statement_cond *',
'gimple_switch', 'const_gimple_switch',
'gimple_statement_switch *',
'gimple_bind', 'const_gimple_bind',
@@ -576,7 +576,7 @@ fold_gimple_assign (gimple_stmt_iterator *si)
assumed that the operands have been previously folded. */
static bool
-fold_gimple_cond (gimple stmt)
+fold_gimple_cond (gimple_cond stmt)
{
tree result = fold_binary_loc (gimple_location (stmt),
gimple_cond_code (stmt),
@@ -1246,7 +1246,7 @@ fold_stmt_1 (gimple_stmt_iterator *gsi, bool inplace)
}
case GIMPLE_COND:
- changed |= fold_gimple_cond (stmt);
+ changed |= fold_gimple_cond (stmt->as_a_gimple_cond ());
break;
case GIMPLE_CALL:
@@ -809,7 +809,7 @@ dump_gimple_switch (pretty_printer *buffer, gimple_switch gs, int spc,
pp_gimple_stmt_1. */
static void
-dump_gimple_cond (pretty_printer *buffer, gimple gs, int spc, int flags)
+dump_gimple_cond (pretty_printer *buffer, gimple_cond gs, int spc, int flags)
{
if (flags & TDF_RAW)
dump_gimple_fmt (buffer, spc, flags, "%G <%s, %T, %T, %T, %T>", gs,
@@ -2106,7 +2106,7 @@ pp_gimple_stmt_1 (pretty_printer *buffer, gimple gs, int spc, int flags)
break;
case GIMPLE_COND:
- dump_gimple_cond (buffer, gs, spc, flags);
+ dump_gimple_cond (buffer, gs->as_a_gimple_cond (), spc, flags);
break;
case GIMPLE_LABEL:
@@ -438,14 +438,14 @@ gimple_build_assign_with_ops (enum tree_code subcode, tree lhs, tree op1,
T_LABEL is the label to jump to if the condition is true.
F_LABEL is the label to jump to otherwise. */
-gimple
+gimple_cond
gimple_build_cond (enum tree_code pred_code, tree lhs, tree rhs,
tree t_label, tree f_label)
{
- gimple p;
+ gimple_cond p;
gcc_assert (TREE_CODE_CLASS (pred_code) == tcc_comparison);
- p = gimple_build_with_ops (GIMPLE_COND, pred_code, 4);
+ p = gimple_build_with_ops (GIMPLE_COND, pred_code, 4)->as_a_gimple_cond ();
gimple_cond_set_lhs (p, lhs);
gimple_cond_set_rhs (p, rhs);
gimple_cond_set_true_label (p, t_label);
@@ -456,7 +456,7 @@ gimple_build_cond (enum tree_code pred_code, tree lhs, tree rhs,
/* Build a GIMPLE_COND statement from the conditional expression tree
COND. T_LABEL and F_LABEL are as in gimple_build_cond. */
-gimple
+gimple_cond
gimple_build_cond_from_tree (tree cond, tree t_label, tree f_label)
{
enum tree_code code;
@@ -470,7 +470,7 @@ gimple_build_cond_from_tree (tree cond, tree t_label, tree f_label)
boolean expression tree COND. */
void
-gimple_cond_set_condition_from_tree (gimple stmt, tree cond)
+gimple_cond_set_condition_from_tree (gimple_cond stmt, tree cond)
{
enum tree_code code;
tree lhs, rhs;
@@ -211,6 +211,12 @@ public:
Keep these in the same order as the corresponding entries in
gimple.def. */
+ inline gimple_cond
+ as_a_gimple_cond ()
+ {
+ return as_a <gimple_statement_cond> (this);
+ }
+
inline gimple_switch
as_a_gimple_switch ()
{
@@ -231,6 +237,12 @@ public:
is less verbose than
dyn_cast <gimple_statement_foo> (stmt). */
+ inline gimple_cond
+ dyn_cast_gimple_cond ()
+ {
+ return dyn_cast <gimple_statement_cond> (this);
+ }
+
inline gimple_switch
dyn_cast_gimple_switch ()
{
@@ -809,6 +821,16 @@ enum gimple_statement_structure_enum {
#undef DEFGSSTRUCT
/* A statement with the invariant that
+ stmt->code == GIMPLE_COND
+ i.e. a conditional jump statement. */
+
+struct GTY((tag("GSS_WITH_OPS")))
+ gimple_statement_cond : public gimple_statement_with_ops
+{
+ /* no additional fields; this uses the layout for GSS_WITH_OPS. */
+};
+
+/* A statement with the invariant that
stmt->code == GIMPLE_SWITCH
i.e. a switch statement. */
@@ -853,6 +875,14 @@ is_a_helper <gimple_statement_catch>::test (gimple gs)
template <>
template <>
inline bool
+is_a_helper <gimple_statement_cond>::test (gimple gs)
+{
+ return gs->code == GIMPLE_COND;
+}
+
+template <>
+template <>
+inline bool
is_a_helper <gimple_statement_resx>::test (gimple gs)
{
return gs->code == GIMPLE_RESX;
@@ -1237,9 +1267,9 @@ gimple gimple_build_assign_with_ops (enum tree_code, tree,
tree, tree, tree CXX_MEM_STAT_INFO);
gimple gimple_build_assign_with_ops (enum tree_code, tree,
tree, tree CXX_MEM_STAT_INFO);
-gimple gimple_build_cond (enum tree_code, tree, tree, tree, tree);
-gimple gimple_build_cond_from_tree (tree, tree, tree);
-void gimple_cond_set_condition_from_tree (gimple, tree);
+gimple_cond gimple_build_cond (enum tree_code, tree, tree, tree, tree);
+gimple_cond gimple_build_cond_from_tree (tree, tree, tree);
+void gimple_cond_set_condition_from_tree (gimple_cond, tree);
gimple gimple_build_label (tree label);
gimple gimple_build_goto (tree dest);
gimple gimple_build_nop (void);
@@ -3046,7 +3076,7 @@ gimple_cond_make_true (gimple gs)
'if (0 == 0)', 'if (1 != 0)' or 'if (0 != 1)' */
static inline bool
-gimple_cond_true_p (const_gimple gs)
+gimple_cond_true_p (const_gimple_cond gs)
{
tree lhs = gimple_cond_lhs (gs);
tree rhs = gimple_cond_rhs (gs);
@@ -3071,7 +3101,7 @@ gimple_cond_true_p (const_gimple gs)
'if (0 != 0)', 'if (1 == 0)' or 'if (0 == 1)' */
static inline bool
-gimple_cond_false_p (const_gimple gs)
+gimple_cond_false_p (const_gimple_cond gs)
{
tree lhs = gimple_cond_lhs (gs);
tree rhs = gimple_cond_rhs (gs);
@@ -3095,7 +3125,8 @@ gimple_cond_false_p (const_gimple gs)
/* 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_condition (gimple_cond stmt, enum tree_code code, tree lhs,
+ tree rhs)
{
gimple_cond_set_code (stmt, code);
gimple_cond_set_lhs (stmt, lhs);
@@ -823,7 +823,7 @@ public:
private:
void thread_across_edge (edge);
- gimple m_dummy_cond;
+ gimple_cond m_dummy_cond;
};
/* Jump threading, redundancy elimination and const/copy propagation.
@@ -998,7 +998,7 @@ make_pass_dominator (gcc::context *ctxt)
condition to a canonical form. */
static void
-canonicalize_comparison (gimple condstmt)
+canonicalize_comparison (gimple_cond condstmt)
{
tree op0;
tree op1;
@@ -2334,7 +2334,7 @@ optimize_stmt (basic_block bb, gimple_stmt_iterator si)
}
if (gimple_code (stmt) == GIMPLE_COND)
- canonicalize_comparison (stmt);
+ canonicalize_comparison (stmt->as_a_gimple_cond ());
update_stmt_if_modified (stmt);
opt_stats.num_stmts++;
@@ -501,7 +501,7 @@ forward_propagate_into_comparison (gimple_stmt_iterator *gsi)
This must be kept in sync with forward_propagate_into_cond. */
static int
-forward_propagate_into_gimple_cond (gimple stmt)
+forward_propagate_into_gimple_cond (gimple_cond stmt)
{
tree tmp;
enum tree_code code = gimple_cond_code (stmt);
@@ -3582,7 +3582,8 @@ ssa_forward_propagate_and_combine (void)
case GIMPLE_COND:
{
int did_something;
- did_something = forward_propagate_into_gimple_cond (stmt);
+ did_something =
+ forward_propagate_into_gimple_cond (stmt->as_a_gimple_cond ());
if (did_something == 2)
cfg_changed = true;
changed = did_something != 0;
@@ -188,7 +188,7 @@ get_name_for_bit_test (tree candidate)
Returns true if the pattern matched, false otherwise. */
static bool
-recognize_single_bit_test (gimple cond, tree *name, tree *bit, bool inv)
+recognize_single_bit_test (gimple_cond cond, tree *name, tree *bit, bool inv)
{
gimple stmt;
@@ -296,7 +296,7 @@ recognize_single_bit_test (gimple cond, tree *name, tree *bit, bool inv)
Returns true if the pattern matched, false otherwise. */
static bool
-recognize_bits_test (gimple cond, tree *name, tree *bits, bool inv)
+recognize_bits_test (gimple_cond cond, tree *name, tree *bits, bool inv)
{
gimple stmt;
@@ -327,18 +327,21 @@ ifcombine_ifandif (basic_block inner_cond_bb, bool inner_inv,
basic_block outer_cond_bb, bool outer_inv, bool result_inv)
{
gimple_stmt_iterator gsi;
- gimple inner_cond, outer_cond;
+ gimple inner_stmt, outer_stmt;
+ gimple_cond inner_cond, outer_cond;
tree name1, name2, bit1, bit2, bits1, bits2;
- inner_cond = last_stmt (inner_cond_bb);
- if (!inner_cond
- || gimple_code (inner_cond) != GIMPLE_COND)
+ inner_stmt = last_stmt (inner_cond_bb);
+ if (!inner_stmt
+ || gimple_code (inner_stmt) != GIMPLE_COND)
return false;
+ inner_cond = inner_stmt->as_a_gimple_cond ();
- outer_cond = last_stmt (outer_cond_bb);
- if (!outer_cond
- || gimple_code (outer_cond) != GIMPLE_COND)
+ outer_stmt = last_stmt (outer_cond_bb);
+ if (!outer_stmt
+ || gimple_code (outer_stmt) != GIMPLE_COND)
return false;
+ outer_cond = outer_stmt->as_a_gimple_cond ();
/* See if we test a single bit of the same name in both tests. In
that case remove the outer test, merging both else edges,
@@ -138,15 +138,17 @@ tree_ssa_unswitch_loops (void)
static tree
tree_may_unswitch_on (basic_block bb, struct loop *loop)
{
- gimple stmt, def;
+ gimple last, def;
+ gimple_cond stmt;
tree cond, use;
basic_block def_bb;
ssa_op_iter iter;
/* BB must end in a simple conditional jump. */
- stmt = last_stmt (bb);
- if (!stmt || gimple_code (stmt) != GIMPLE_COND)
+ last = last_stmt (bb);
+ if (!last || gimple_code (last) != GIMPLE_COND)
return NULL_TREE;
+ stmt = last->as_a_gimple_cond ();
/* To keep the things simple, we do not directly remove the conditions,
but just replace tests with 0 != 0 resp. 1 != 0. Prevent the infinite
@@ -248,13 +250,15 @@ tree_unswitch_single_loop (struct loop *loop, int num)
if (integer_nonzerop (cond))
{
/* Remove false path. */
- gimple_cond_set_condition_from_tree (stmt, boolean_true_node);
+ gimple_cond_set_condition_from_tree (stmt->as_a_gimple_cond (),
+ boolean_true_node);
changed = true;
}
else if (integer_zerop (cond))
{
/* Remove true path. */
- gimple_cond_set_condition_from_tree (stmt, boolean_false_node);
+ gimple_cond_set_condition_from_tree (stmt->as_a_gimple_cond (),
+ boolean_false_node);
changed = true;
}
/* Do not unswitch too much. */
@@ -316,9 +320,10 @@ tree_unswitch_single_loop (struct loop *loop, int num)
if (stmt
&& gimple_code (stmt) == GIMPLE_COND)
{
- if (gimple_cond_true_p (stmt))
+ gimple_cond cond_stmt = stmt->as_a_gimple_cond ();
+ if (gimple_cond_true_p (cond_stmt))
flags = EDGE_FALSE_VALUE;
- else if (gimple_cond_false_p (stmt))
+ else if (gimple_cond_false_p (cond_stmt))
flags = EDGE_TRUE_VALUE;
}
}
@@ -536,7 +536,7 @@ dummy_simplify (gimple stmt1 ATTRIBUTE_UNUSED, gimple stmt2 ATTRIBUTE_UNUSED)
static tree
simplify_control_stmt_condition (edge e,
gimple stmt,
- gimple dummy_cond,
+ gimple_cond dummy_cond,
tree (*simplify) (gimple, gimple),
bool handle_dominating_asserts)
{
@@ -800,7 +800,7 @@ propagate_threaded_block_debug_into (basic_block dest, basic_block src)
try and simplify the condition at the end of TAKEN_EDGE->dest. */
static bool
thread_around_empty_blocks (edge taken_edge,
- gimple dummy_cond,
+ gimple_cond dummy_cond,
bool handle_dominating_asserts,
tree (*simplify) (gimple, gimple),
bitmap visited,
@@ -943,7 +943,7 @@ thread_around_empty_blocks (edge taken_edge,
static bool
thread_through_normal_block (edge e,
- gimple dummy_cond,
+ gimple_cond dummy_cond,
bool handle_dominating_asserts,
vec<tree> *stack,
tree (*simplify) (gimple, gimple),
@@ -1064,7 +1064,7 @@ thread_through_normal_block (edge e,
SIMPLIFY is a pass-specific function used to simplify statements. */
void
-thread_across_edge (gimple dummy_cond,
+thread_across_edge (gimple_cond dummy_cond,
edge e,
bool handle_dominating_asserts,
vec<tree> *stack,
@@ -30,7 +30,7 @@ extern void threadedge_initialize_values (void);
extern void threadedge_finalize_values (void);
extern bool potentially_threadable_block (basic_block);
extern void propagate_threaded_block_debug_into (basic_block, basic_block);
-extern void thread_across_edge (gimple, edge, bool,
+extern void thread_across_edge (gimple_cond, edge, bool,
vec<tree> *, tree (*) (gimple, gimple));
#endif /* GCC_TREE_SSA_THREADEDGE_H */
@@ -472,7 +472,7 @@ compute_control_dep_chain (basic_block bb, basic_block dep_bb,
typedef struct use_pred_info
{
- gimple cond;
+ gimple_cond cond;
bool invert;
} *use_pred_info_t;
@@ -559,7 +559,7 @@ convert_control_dep_chain_into_preds (vec<edge> *dep_chains,
break;
}
one_pred = XNEW (struct use_pred_info);
- one_pred->cond = cond_stmt;
+ one_pred->cond = cond_stmt->as_a_gimple_cond ();
one_pred->invert = !!(e->flags & EDGE_FALSE_VALUE);
(*preds)[i].safe_push (one_pred);
has_valid_pred = true;
@@ -1168,7 +1168,7 @@ use_pred_not_overlap_with_undef_path_pred (
n = the_pred_chain.length ();
for (i = 0; i < n; i++)
{
- gimple cond;
+ gimple_cond cond;
tree cond_lhs, cond_rhs, flag = 0;
use_pred_info_t the_pred
@@ -8914,7 +8914,7 @@ range_fits_type_p (value_range_t *vr, unsigned precision, bool unsigned_p)
the original conditional. */
static bool
-simplify_cond_using_ranges (gimple stmt)
+simplify_cond_using_ranges (gimple_cond stmt)
{
tree op0 = gimple_cond_lhs (stmt);
tree op1 = gimple_cond_rhs (stmt);
@@ -9364,7 +9364,7 @@ simplify_stmt_using_ranges (gimple_stmt_iterator *gsi)
}
}
else if (gimple_code (stmt) == GIMPLE_COND)
- return simplify_cond_using_ranges (stmt);
+ return simplify_cond_using_ranges (stmt->as_a_gimple_cond ());
else if (gimple_code (stmt) == GIMPLE_SWITCH)
return simplify_switch_using_ranges (stmt->as_a_gimple_switch ());
@@ -9505,7 +9505,7 @@ static void
identify_jump_threads (void)
{
basic_block bb;
- gimple dummy;
+ gimple_cond dummy;
int i;
edge e;