@@ -1,5 +1,47 @@
2014-10-28 David Malcolm <dmalcolm@redhat.com>
+ * gimple.h (gimple_goto_dest): Strengthen param from const_gimple to
+ const ggoto *.
+ * cfgexpand.c (expand_gimple_stmt_1): Add checked cast to ggoto *
+ within case GIMPLE_GOTO.
+ * gimple-walk.c (walk_stmt_load_store_addr_ops): Add checked cast
+ to ggoto *.
+ * ipa-icf-gimple.c (ipa_icf_gimple::func_checker::compare_bb): Add
+ checked casts to ggoto * within case GIMPLE_GOTO.
+ (ipa_icf_gimple::func_checker::compare_gimple_goto): Strengthen
+ both params from gimple to const ggoto *.
+ * ipa-icf-gimple.h (ipa_icf_gimple::func_checker::compare_gimple_goto):
+ Likewise.
+ * omp-low.c (diagnose_sb_2): Add checked cast to ggoto * within
+ case GIMPLE_GOTO.
+ * tree-cfg.c (computed_goto_p): Replace check for GIMPLE_GOTO with
+ a dyn_cast <ggoto *>, introducing new local "goto_stmt".
+ (handle_abnormal_edges): Strengthen local "last" from gimple to
+ ggoto *.
+ (make_goto_expr_edges): Add checked cast to ggoto * within region
+ where we know it's a simple goto.
+ (simple_goto_p): Replace check for GIMPLE_GOTO with a
+ dyn_cast <ggoto *>, introducing new local "goto_stmt".
+ * tree-cfgcleanup.c (cleanup_control_flow_bb): Likewise, using
+ new "goto_stmt" in place of "stmt".
+ * tree-eh.c (replace_goto_queue_cond_clause): Likewise, using
+ new "goto_stmt" in place of gimple_seq_first_stmt (new_seq).
+ (maybe_record_in_goto_queue): Add checked cast to ggoto * within
+ case GIMPLE_GOTO.
+ * tree-inline.c (inline_forbidden_p_stmt): Likewise.
+ * tree-nested.c (convert_nonlocal_reference_stmt): Likewise.
+ (convert_nl_goto_reference): Add checked cast to ggoto *.
+ * tree-ssa-dom.c (initialize_hash_element): Replace check for
+ GIMPLE_GOTO with a dyn_cast <ggoto *>, introducing new local
+ "goto_stmt".
+ (optimize_stmt): Likewise.
+ (propagate_rhs_into_lhs): Add checked cast to ggoto *.
+ * tree-ssa-sccvn.c (cond_dom_walker::before_dom_children): Likewise.
+ * tree-ssa-threadedge.c (simplify_control_stmt_condition): Likewise.
+ * tree-ssa-threadupdate.c (bb_ends_with_multiway_branch): Likewise.
+
+2014-10-28 David Malcolm <dmalcolm@redhat.com>
+
* doc/gimple.texi (Class hierarchy of GIMPLE statements): Update
for renaming of gimple_statement_wce to gwce.
* gimple-walk.c (walk_gimple_stmt): Add checked cast to gwce *
@@ -3208,7 +3208,7 @@ expand_gimple_stmt_1 (gimple stmt)
switch (gimple_code (stmt))
{
case GIMPLE_GOTO:
- op0 = gimple_goto_dest (stmt);
+ op0 = gimple_goto_dest (as_a <ggoto *> (stmt));
if (TREE_CODE (op0) == LABEL_DECL)
expand_goto (op0);
else
@@ -890,7 +890,7 @@ walk_stmt_load_store_addr_ops (gimple stmt, void *data,
else if (visit_addr
&& gimple_code (stmt) == GIMPLE_GOTO)
{
- tree op = gimple_goto_dest (stmt);
+ tree op = gimple_goto_dest (as_a <ggoto *> (stmt));
if (TREE_CODE (op) == ADDR_EXPR)
ret |= visit_addr (stmt, TREE_OPERAND (op, 0), op, data);
}
@@ -3196,9 +3196,8 @@ gimple_label_set_label (glabel *gs, tree label)
/* Return the destination of the unconditional jump GS. */
static inline tree
-gimple_goto_dest (const_gimple gs)
+gimple_goto_dest (const ggoto *gs)
{
- GIMPLE_CHECK (gs, GIMPLE_GOTO);
return gimple_op (gs, 0);
}
@@ -622,7 +622,8 @@ func_checker::compare_bb (sem_bb *bb1, sem_bb *bb2)
return return_different_stmts (s1, s2, "GIMPLE_RETURN");
break;
case GIMPLE_GOTO:
- if (!compare_gimple_goto (s1, s2))
+ if (!compare_gimple_goto (as_a <ggoto *> (s1),
+ as_a <ggoto *> (s2)))
return return_different_stmts (s1, s2, "GIMPLE_GOTO");
break;
case GIMPLE_ASM:
@@ -828,11 +829,11 @@ func_checker::compare_gimple_return (const greturn *g1, const greturn *g2)
return compare_operand (t1, t2);
}
-/* Verifies for given GIMPLEs S1 and S2 that
+/* Verifies for given GIMPLE_GOTO stmts S1 and S2 that
goto statements are semantically equivalent. */
bool
-func_checker::compare_gimple_goto (gimple g1, gimple g2)
+func_checker::compare_gimple_goto (const ggoto *g1, const ggoto *g2)
{
tree dest1, dest2;
@@ -181,9 +181,9 @@ public:
return statements are semantically equivalent. */
bool compare_gimple_return (const greturn *s1, const greturn *s2);
- /* Verifies for given GIMPLEs S1 and S2 that
+ /* Verifies for given GIMPLE_GOTO stmts S1 and S2 that
goto statements are semantically equivalent. */
- bool compare_gimple_goto (gimple s1, gimple s2);
+ bool compare_gimple_goto (const ggoto *s1, const ggoto *s2);
/* Verifies for given GIMPLE_RESX stmts S1 and S2 that
resx statements are semantically equivalent. */
@@ -10959,7 +10959,7 @@ diagnose_sb_2 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
case GIMPLE_GOTO:
{
- tree lab = gimple_goto_dest (stmt);
+ tree lab = gimple_goto_dest (as_a <ggoto *> (stmt));
if (TREE_CODE (lab) != LABEL_DECL)
break;
@@ -399,8 +399,10 @@ make_pass_build_cfg (gcc::context *ctxt)
bool
computed_goto_p (gimple t)
{
- return (gimple_code (t) == GIMPLE_GOTO
- && TREE_CODE (gimple_goto_dest (t)) != LABEL_DECL);
+ ggoto *goto_stmt = dyn_cast <ggoto *> (t);
+ if (!goto_stmt)
+ return false;
+ return TREE_CODE (gimple_goto_dest (goto_stmt)) != LABEL_DECL;
}
/* Returns true for edge E where e->src ends with a GIMPLE_COND and
@@ -732,7 +734,7 @@ handle_abnormal_edges (basic_block *dispatcher_bbs,
continue;
gsi = gsi_last_bb (bb);
- gimple last = gsi_stmt (gsi);
+ ggoto *last = as_a <ggoto *> (gsi_stmt (gsi));
gcc_assert (computed_goto_p (last));
@@ -1246,7 +1248,7 @@ make_goto_expr_edges (basic_block bb)
/* A simple GOTO creates normal edges. */
if (simple_goto_p (goto_t))
{
- tree dest = gimple_goto_dest (goto_t);
+ tree dest = gimple_goto_dest (as_a <ggoto *> (goto_t));
basic_block label_bb = label_to_block (dest);
edge e = make_edge (bb, label_bb, EDGE_FALLTHRU);
e->goto_locus = gimple_location (goto_t);
@@ -2470,8 +2472,10 @@ is_ctrl_altering_stmt (gimple t)
bool
simple_goto_p (gimple t)
{
- return (gimple_code (t) == GIMPLE_GOTO
- && TREE_CODE (gimple_goto_dest (t)) == LABEL_DECL);
+ ggoto *goto_stmt = dyn_cast <ggoto *> (t);
+ if (!goto_stmt)
+ return false;
+ return TREE_CODE (gimple_goto_dest (goto_stmt)) == LABEL_DECL;
}
@@ -198,6 +198,7 @@ cleanup_control_flow_bb (basic_block bb)
gimple_stmt_iterator gsi;
bool retval = false;
gimple stmt;
+ ggoto *goto_stmt;
/* If the last statement of the block could throw and now cannot,
we need to prune cfg. */
@@ -215,9 +216,9 @@ cleanup_control_flow_bb (basic_block bb)
if (gimple_code (stmt) == GIMPLE_COND
|| gimple_code (stmt) == GIMPLE_SWITCH)
retval |= cleanup_control_expr_graph (bb, gsi);
- else if (gimple_code (stmt) == GIMPLE_GOTO
- && TREE_CODE (gimple_goto_dest (stmt)) == ADDR_EXPR
- && (TREE_CODE (TREE_OPERAND (gimple_goto_dest (stmt), 0))
+ else if ((goto_stmt = dyn_cast <ggoto *> (stmt))
+ && TREE_CODE (gimple_goto_dest (goto_stmt)) == ADDR_EXPR
+ && (TREE_CODE (TREE_OPERAND (gimple_goto_dest (goto_stmt), 0))
== LABEL_DECL))
{
/* If we had a computed goto which has a compile-time determinable
@@ -230,7 +231,7 @@ cleanup_control_flow_bb (basic_block bb)
/* First look at all the outgoing edges. Delete any outgoing
edges which do not go to the right block. For the one
edge which goes to the right block, fix up its flags. */
- label = TREE_OPERAND (gimple_goto_dest (stmt), 0);
+ label = TREE_OPERAND (gimple_goto_dest (goto_stmt), 0);
target_block = label_to_block (label);
for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); )
{
@@ -483,12 +483,12 @@ replace_goto_queue_cond_clause (tree *tp, struct leh_tf_state *tf,
if (!new_seq)
return;
- if (gimple_seq_singleton_p (new_seq)
- && gimple_code (gimple_seq_first_stmt (new_seq)) == GIMPLE_GOTO)
- {
- *tp = gimple_goto_dest (gimple_seq_first_stmt (new_seq));
- return;
- }
+ if (gimple_seq_singleton_p (new_seq))
+ if (ggoto *goto_stmt = dyn_cast <ggoto *> (gimple_seq_first_stmt (new_seq)))
+ {
+ *tp = gimple_goto_dest (goto_stmt);
+ return;
+ }
label = create_artificial_label (loc);
/* Set the new label for the GIMPLE_COND */
@@ -695,7 +695,8 @@ maybe_record_in_goto_queue (struct leh_state *state, gimple stmt)
break;
case GIMPLE_GOTO:
new_stmt.g = stmt;
- record_in_goto_queue_label (tf, new_stmt, gimple_goto_dest (stmt),
+ record_in_goto_queue_label (tf, new_stmt,
+ gimple_goto_dest (as_a <ggoto *> (stmt)),
gimple_location (stmt));
break;
@@ -3502,7 +3502,7 @@ inline_forbidden_p_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p,
break;
case GIMPLE_GOTO:
- t = gimple_goto_dest (stmt);
+ t = gimple_goto_dest (as_a <ggoto *> (stmt));
/* We will not inline a function which uses computed goto. The
addresses of its local labels, which may be tucked into
@@ -1311,7 +1311,7 @@ convert_nonlocal_reference_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p,
{
case GIMPLE_GOTO:
/* Don't walk non-local gotos for now. */
- if (TREE_CODE (gimple_goto_dest (stmt)) != LABEL_DECL)
+ if (TREE_CODE (gimple_goto_dest (as_a <ggoto *> (stmt))) != LABEL_DECL)
{
wi->val_only = true;
wi->is_lhs = false;
@@ -2081,7 +2081,7 @@ convert_nl_goto_reference (gimple_stmt_iterator *gsi, bool *handled_ops_p,
return NULL_TREE;
}
- label = gimple_goto_dest (stmt);
+ label = gimple_goto_dest (as_a <ggoto *> (stmt));
if (TREE_CODE (label) != LABEL_DECL)
{
*handled_ops_p = false;
@@ -362,11 +362,11 @@ initialize_hash_element (gimple stmt, tree lhs,
expr->kind = EXPR_SINGLE;
expr->ops.single.rhs = gimple_switch_index (swtch_stmt);
}
- else if (code == GIMPLE_GOTO)
+ else if (ggoto *goto_stmt = dyn_cast <ggoto *> (stmt))
{
- expr->type = TREE_TYPE (gimple_goto_dest (stmt));
+ expr->type = TREE_TYPE (gimple_goto_dest (goto_stmt));
expr->kind = EXPR_SINGLE;
- expr->ops.single.rhs = gimple_goto_dest (stmt);
+ expr->ops.single.rhs = gimple_goto_dest (goto_stmt);
}
else if (code == GIMPLE_PHI)
{
@@ -2367,8 +2367,8 @@ optimize_stmt (basic_block bb, gimple_stmt_iterator si)
/* We only need to consider cases that can yield a gimple operand. */
if (gimple_assign_single_p (stmt))
rhs = gimple_assign_rhs1 (stmt);
- else if (gimple_code (stmt) == GIMPLE_GOTO)
- rhs = gimple_goto_dest (stmt);
+ else if (ggoto *goto_stmt = dyn_cast <ggoto *> (stmt))
+ rhs = gimple_goto_dest (goto_stmt);
else if (gswitch *swtch_stmt = dyn_cast <gswitch *> (stmt))
/* This should never be an ADDR_EXPR. */
rhs = gimple_switch_index (swtch_stmt);
@@ -2848,7 +2848,7 @@ propagate_rhs_into_lhs (gimple stmt, tree lhs, tree rhs, bitmap interesting_name
else if (gimple_code (use_stmt) == GIMPLE_SWITCH)
val = gimple_switch_index (as_a <gswitch *> (use_stmt));
else
- val = gimple_goto_dest (use_stmt);
+ val = gimple_goto_dest (as_a <ggoto *> (use_stmt));
if (val && is_gimple_min_invariant (val))
{
@@ -4271,7 +4271,7 @@ cond_dom_walker::before_dom_children (basic_block bb)
val = gimple_switch_index (as_a <gswitch *> (stmt));
break;
case GIMPLE_GOTO:
- val = gimple_goto_dest (stmt);
+ val = gimple_goto_dest (as_a <ggoto *> (stmt));
break;
default:
gcc_unreachable ();
@@ -628,7 +628,7 @@ simplify_control_stmt_condition (edge e,
if (code == GIMPLE_SWITCH)
cond = gimple_switch_index (as_a <gswitch *> (stmt));
else if (code == GIMPLE_GOTO)
- cond = gimple_goto_dest (stmt);
+ cond = gimple_goto_dest (as_a <ggoto *> (stmt));
else
gcc_unreachable ();
@@ -2307,7 +2307,7 @@ bb_ends_with_multiway_branch (basic_block bb ATTRIBUTE_UNUSED)
if (stmt && gimple_code (stmt) == GIMPLE_SWITCH)
return true;
if (stmt && gimple_code (stmt) == GIMPLE_GOTO
- && TREE_CODE (gimple_goto_dest (stmt)) == SSA_NAME)
+ && TREE_CODE (gimple_goto_dest (as_a <ggoto *> (stmt))) == SSA_NAME)
return true;
return false;
}