@@ -1,3 +1,63 @@
+2014-10-28 David Malcolm <dmalcolm@redhat.com>
+
+ * auto-profile.c (autofdo::function_instance::find_icall_target_map):
+ Strengthen param "stmt" from gimple to gcall *.
+ (autofdo::autofdo_source_profile::update_inlined_ind_target):
+ Likewise.
+ (autofdo::afdo_indirect_call): Rename local gimple "stmt" to "gs",
+ reintroducing "stmt" as a gcall * via a dyn_cast once we've
+ established that we have a GIMPLE_CALL.
+ (autofdo::afdo_set_bb_count): Use a gphi_iterator for the phi
+ iteration, renaming it from "gsi" to "gpi", strengthening
+ local "phi" from gimple to gphi *.
+ (autofdo::afdo_propagate_circuit): Rename local gimple "phi_stmt"
+ to "def_stmt". Reintroduce "phi_stmt" as a gphi * via a dyn_cast
+ once we know we have a GIMPLE_PHI.
+ (autofdo::afdo_vpt_for_early_inline): Strengthen local "stmt" from
+ gimple to gcall *, using a dyn_cast.
+ * gimple-fold.c (replace_stmt_with_simplification): Replace check
+ against GIMPLE_COND with a dyn_cast <gcond *>, introducing local
+ "cond_stmt". Use "cond_stmt" in place of "stmt" for typesafety.
+ * gimple-iterator.h (gsi_next_nonvirtual_phi): Strengthen param
+ from gimple_stmt_iterator * to gphi_iterator *, and local "phi"
+ from gimple to gphi *.
+ * ipa-icf-gimple.c (ipa_icf_gimple::func_checker::parse_labels):
+ Replace check against GIMPLE_LABEL with a dyn_cast <glabel *>,
+ introducing local "label_stmt". Use it in place of "stmt" for
+ typesafety.
+ (ipa_icf_gimple::func_checker::compare_bb): Add checked casts
+ to appropriate gimple subclasses when invoking comparison methods
+ within the cases for GIMPLE_SWITCH, GIMPLE_RESX, GIMPLE_LABEL,
+ GIMPLE_RETURN, GIMPLE_ASM.
+ (ipa_icf_gimple::func_checker::compare_gimple_label): Strengthen
+ both params from gimple to const glabel *.
+ (ipa_icf_gimple::func_checker::compare_gimple_switch): Strengthen
+ both params from gimple to const gswitch *.
+ (ipa_icf_gimple::func_checker::compare_gimple_return): Strengthen
+ both params from gimple to const greturn *.
+ (ipa_icf_gimple::func_checker::compare_gimple_resx): Strengthen
+ both params from gimple to const gresx *.
+ (ipa_icf_gimple::func_checker::compare_gimple_asm): Strengthen
+ both params from gimple to const gasm *.
+ * ipa-icf-gimple.h (ipa_icf_gimple::func_checker::compare_gimple_label):
+ Strengthen both params from gimple to const glabel *.
+ (ipa_icf_gimple::func_checker::compare_gimple_switch): Strengthen
+ both params from gimple to const gswitch *.
+ (ipa_icf_gimple::func_checker::compare_gimple_return): Strengthen
+ both params from gimple to const greturn *.
+ (ipa_icf_gimple::func_checker::compare_gimple_resx): Strengthen
+ both params from gimple to const gresx *.
+ (ipa_icf_gimple::func_checker::compare_gimple_asm): Strengthen
+ both params from gimple to const gasm *.
+ * ipa-icf.c (ipa_icf_gimple::sem_function::compare_phi_node):
+ Strengthen locals "si1" and "si2" from gimple_stmt_iterator to
+ gphi_iterator, and locals "phi1" and "phi2" from gimple to gphi *.
+ * tree-ssa-forwprop.c (fold_all_stmts): Replace check against
+ GIMPLE_COND with a dyn_cast <gcond *>, introducing local
+ "cond_stmt". Use "cond_stmt" in place of "stmt" for typesafety.
+ * tree-ssa-reassoc.c (branch_fixup): Strengthen local "phi" from
+ gimple to gphi *.
+
2014-10-27 David Malcolm <dmalcolm@redhat.com>
* doc/gimple.texi (Class hierarchy of GIMPLE statements): Update
@@ -238,7 +238,7 @@ public:
/* Read the inlined indirect call target profile for STMT and store it in
MAP, return the total count for all inlined indirect calls. */
- gcov_type find_icall_target_map (gimple stmt, icall_target_map *map) const;
+ gcov_type find_icall_target_map (gcall *stmt, icall_target_map *map) const;
/* Sum of counts that is used during annotation. */
gcov_type total_annotated_count () const;
@@ -306,7 +306,7 @@ public:
/* Update value profile INFO for STMT from the inlined indirect callsite.
Return true if INFO is updated. */
- bool update_inlined_ind_target (gimple stmt, count_info *info);
+ bool update_inlined_ind_target (gcall *stmt, count_info *info);
/* Mark LOC as annotated. */
void mark_annotated (location_t loc);
@@ -595,7 +595,7 @@ function_instance::mark_annotated (location_t loc)
MAP, return the total count for all inlined indirect calls. */
gcov_type
-function_instance::find_icall_target_map (gimple stmt,
+function_instance::find_icall_target_map (gcall *stmt,
icall_target_map *map) const
{
gcov_type ret = 0;
@@ -764,7 +764,7 @@ autofdo_source_profile::mark_annotated (location_t loc)
Return true if INFO is updated. */
bool
-autofdo_source_profile::update_inlined_ind_target (gimple stmt,
+autofdo_source_profile::update_inlined_ind_target (gcall *stmt,
count_info *info)
{
if (LOCATION_LOCUS (gimple_location (stmt)) == cfun->function_end_locus)
@@ -958,11 +958,13 @@ static void
afdo_indirect_call (gimple_stmt_iterator *gsi, const icall_target_map &map,
bool transform)
{
- gimple stmt = gsi_stmt (*gsi);
+ gimple gs = gsi_stmt (*gsi);
tree callee;
- if (map.size () == 0 || gimple_code (stmt) != GIMPLE_CALL
- || gimple_call_fndecl (stmt) != NULL_TREE)
+ if (map.size () == 0)
+ return;
+ gcall *stmt = dyn_cast <gcall *> (gs);
+ if ((!stmt) || gimple_call_fndecl (stmt) != NULL_TREE)
return;
callee = gimple_call_fn (stmt);
@@ -1080,9 +1082,11 @@ afdo_set_bb_count (basic_block bb, const stmt_set &promoted)
for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
afdo_source_profile->mark_annotated (gimple_location (gsi_stmt (gsi)));
- for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ for (gphi_iterator gpi = gsi_start_phis (bb);
+ !gsi_end_p (gpi);
+ gsi_next (&gpi))
{
- gimple phi = gsi_stmt (gsi);
+ gphi *phi = gpi.phi ();
size_t i;
for (i = 0; i < gimple_phi_num_args (phi); i++)
afdo_source_profile->mark_annotated (gimple_phi_arg_location (phi, i));
@@ -1240,7 +1244,7 @@ afdo_propagate_circuit (const bb_set &annotated_bb, edge_set *annotated_edge)
basic_block bb;
FOR_ALL_BB_FN (bb, cfun)
{
- gimple phi_stmt;
+ gimple def_stmt;
tree cmp_rhs, cmp_lhs;
gimple cmp_stmt = last_stmt (bb);
edge e;
@@ -1257,12 +1261,15 @@ afdo_propagate_circuit (const bb_set &annotated_bb, edge_set *annotated_edge)
continue;
if (!is_bb_annotated (bb, annotated_bb))
continue;
- phi_stmt = SSA_NAME_DEF_STMT (cmp_lhs);
- while (phi_stmt && gimple_code (phi_stmt) == GIMPLE_ASSIGN
- && gimple_assign_single_p (phi_stmt)
- && TREE_CODE (gimple_assign_rhs1 (phi_stmt)) == SSA_NAME)
- phi_stmt = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (phi_stmt));
- if (!phi_stmt || gimple_code (phi_stmt) != GIMPLE_PHI)
+ def_stmt = SSA_NAME_DEF_STMT (cmp_lhs);
+ while (def_stmt && gimple_code (def_stmt) == GIMPLE_ASSIGN
+ && gimple_assign_single_p (def_stmt)
+ && TREE_CODE (gimple_assign_rhs1 (def_stmt)) == SSA_NAME)
+ def_stmt = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (def_stmt));
+ if (!def_stmt)
+ continue;
+ gphi *phi_stmt = dyn_cast <gphi *> (def_stmt);
+ if (!phi_stmt)
continue;
FOR_EACH_EDGE (e, ei, bb->succs)
{
@@ -1421,11 +1428,11 @@ afdo_vpt_for_early_inline (stmt_set *promoted_stmts)
for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- gimple stmt = gsi_stmt (gsi);
+ gcall *stmt = dyn_cast <gcall *> (gsi_stmt (gsi));
/* IC_promotion and early_inline_2 is done in multiple iterations.
No need to promoted the stmt if its in promoted_stmts (means
it is already been promoted in the previous iterations). */
- if (gimple_code (stmt) != GIMPLE_CALL || gimple_call_fn (stmt) == NULL
+ if ((!stmt) || gimple_call_fn (stmt) == NULL
|| TREE_CODE (gimple_call_fn (stmt)) == FUNCTION_DECL
|| promoted_stmts->find (stmt) != promoted_stmts->end ())
continue;
@@ -2823,7 +2823,7 @@ replace_stmt_with_simplification (gimple_stmt_iterator *gsi,
&& SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[2])))
return false;
- if (gimple_code (stmt) == GIMPLE_COND)
+ if (gcond *cond_stmt = dyn_cast <gcond *> (stmt))
{
gcc_assert (rcode.is_tree_code ());
if (TREE_CODE_CLASS ((enum tree_code)rcode) == tcc_comparison
@@ -2833,16 +2833,16 @@ replace_stmt_with_simplification (gimple_stmt_iterator *gsi,
|| !operation_could_trap_p (rcode,
FLOAT_TYPE_P (TREE_TYPE (ops[0])),
false, NULL_TREE)))
- gimple_cond_set_condition (stmt, rcode, ops[0], ops[1]);
+ gimple_cond_set_condition (cond_stmt, rcode, ops[0], ops[1]);
else if (rcode == SSA_NAME)
- gimple_cond_set_condition (stmt, NE_EXPR, ops[0],
+ gimple_cond_set_condition (cond_stmt, NE_EXPR, ops[0],
build_zero_cst (TREE_TYPE (ops[0])));
else if (rcode == INTEGER_CST)
{
if (integer_zerop (ops[0]))
- gimple_cond_make_false (stmt);
+ gimple_cond_make_false (cond_stmt);
else
- gimple_cond_make_true (stmt);
+ gimple_cond_make_true (cond_stmt);
}
else if (!inplace)
{
@@ -2850,7 +2850,7 @@ replace_stmt_with_simplification (gimple_stmt_iterator *gsi,
ops, seq);
if (!res)
return false;
- gimple_cond_set_condition (stmt, NE_EXPR, res,
+ gimple_cond_set_condition (cond_stmt, NE_EXPR, res,
build_zero_cst (TREE_TYPE (res)));
}
else
@@ -293,14 +293,14 @@ gsi_last_nondebug_bb (basic_block bb)
/* Iterates I statement iterator to the next non-virtual statement. */
static inline void
-gsi_next_nonvirtual_phi (gimple_stmt_iterator *i)
+gsi_next_nonvirtual_phi (gphi_iterator *i)
{
- gimple phi;
+ gphi *phi;
if (gsi_end_p (*i))
return;
- phi = gsi_stmt (*i);
+ phi = i->phi ();
gcc_assert (phi != NULL);
while (virtual_operand_p (gimple_phi_result (phi)))
@@ -310,7 +310,7 @@ gsi_next_nonvirtual_phi (gimple_stmt_iterator *i)
if (gsi_end_p (*i))
return;
- phi = gsi_stmt (*i);
+ phi = i->phi ();
}
}
@@ -531,9 +531,9 @@ func_checker::parse_labels (sem_bb *bb)
{
gimple stmt = gsi_stmt (gsi);
- if (gimple_code (stmt) == GIMPLE_LABEL)
+ if (glabel *label_stmt = dyn_cast <glabel *> (stmt))
{
- tree t = gimple_label_label (stmt);
+ tree t = gimple_label_label (label_stmt);
gcc_assert (TREE_CODE (t) == LABEL_DECL);
m_label_bb_map.put (t, bb->bb->index);
@@ -599,22 +599,26 @@ func_checker::compare_bb (sem_bb *bb1, sem_bb *bb2)
return return_different_stmts (s1, s2, "GIMPLE_COND");
break;
case GIMPLE_SWITCH:
- if (!compare_gimple_switch (s1, s2))
+ if (!compare_gimple_switch (as_a <gswitch *> (s1),
+ as_a <gswitch *> (s2)))
return return_different_stmts (s1, s2, "GIMPLE_SWITCH");
break;
case GIMPLE_DEBUG:
case GIMPLE_EH_DISPATCH:
break;
case GIMPLE_RESX:
- if (!compare_gimple_resx (s1, s2))
+ if (!compare_gimple_resx (as_a <gresx *> (s1),
+ as_a <gresx *> (s2)))
return return_different_stmts (s1, s2, "GIMPLE_RESX");
break;
case GIMPLE_LABEL:
- if (!compare_gimple_label (s1, s2))
+ if (!compare_gimple_label (as_a <glabel *> (s1),
+ as_a <glabel *> (s2)))
return return_different_stmts (s1, s2, "GIMPLE_LABEL");
break;
case GIMPLE_RETURN:
- if (!compare_gimple_return (s1, s2))
+ if (!compare_gimple_return (as_a <greturn *> (s1),
+ as_a <greturn *> (s2)))
return return_different_stmts (s1, s2, "GIMPLE_RETURN");
break;
case GIMPLE_GOTO:
@@ -622,7 +626,8 @@ func_checker::compare_bb (sem_bb *bb1, sem_bb *bb2)
return return_different_stmts (s1, s2, "GIMPLE_GOTO");
break;
case GIMPLE_ASM:
- if (!compare_gimple_asm (s1, s2))
+ if (!compare_gimple_asm (as_a <gasm *> (s1),
+ as_a <gasm *> (s2)))
return return_different_stmts (s1, s2, "GIMPLE_ASM");
break;
case GIMPLE_PREDICT:
@@ -746,11 +751,11 @@ func_checker::compare_tree_ssa_label (tree t1, tree t2)
return compare_operand (t1, t2);
}
-/* Verifies for given GIMPLEs S1 and S2 that
+/* Verifies for given GIMPLE_LABEL stmts S1 and S2 that
label statements are semantically equivalent. */
bool
-func_checker::compare_gimple_label (gimple g1, gimple g2)
+func_checker::compare_gimple_label (const glabel *g1, const glabel *g2)
{
if (m_ignore_labels)
return true;
@@ -764,11 +769,11 @@ func_checker::compare_gimple_label (gimple g1, gimple g2)
return compare_tree_ssa_label (t1, t2);
}
-/* Verifies for given GIMPLEs S1 and S2 that
+/* Verifies for given GIMPLE_SWITCH stmts S1 and S2 that
switch statements are semantically equivalent. */
bool
-func_checker::compare_gimple_switch (gimple g1, gimple g2)
+func_checker::compare_gimple_switch (const gswitch *g1, const gswitch *g2)
{
unsigned lsize1, lsize2, i;
@@ -805,11 +810,11 @@ func_checker::compare_gimple_switch (gimple g1, gimple g2)
return true;
}
-/* Verifies for given GIMPLEs S1 and S2 that
+/* Verifies for given GIMPLE_RETURN stmts S1 and S2 that
return statements are semantically equivalent. */
bool
-func_checker::compare_gimple_return (gimple g1, gimple g2)
+func_checker::compare_gimple_return (const greturn *g1, const greturn *g2)
{
tree t1, t2;
@@ -840,11 +845,11 @@ func_checker::compare_gimple_goto (gimple g1, gimple g2)
return compare_operand (dest1, dest2);
}
-/* Verifies for given GIMPLEs S1 and S2 that
+/* Verifies for given GIMPLE_RESX stmts S1 and S2 that
resx statements are semantically equivalent. */
bool
-func_checker::compare_gimple_resx (gimple g1, gimple g2)
+func_checker::compare_gimple_resx (const gresx *g1, const gresx *g2)
{
return gimple_resx_region (g1) == gimple_resx_region (g2);
}
@@ -854,7 +859,7 @@ func_checker::compare_gimple_resx (gimple g1, gimple g2)
'__asm__ __volatile__ ("", "", "", "memory")'. */
bool
-func_checker::compare_gimple_asm (gimple g1, gimple g2)
+func_checker::compare_gimple_asm (const gasm *g1, const gasm *g2)
{
if (gimple_asm_volatile_p (g1) != gimple_asm_volatile_p (g2))
return false;
@@ -169,30 +169,31 @@ public:
condition statements are semantically equivalent. */
bool compare_gimple_cond (gimple s1, gimple s2);
- /* Verifies for given GIMPLEs S1 and S2 that
+ /* Verifies for given GIMPLE_LABEL stmts S1 and S2 that
label statements are semantically equivalent. */
- bool compare_gimple_label (gimple s1, gimple s2);
+ bool compare_gimple_label (const glabel *s1, const glabel *s2);
- /* Verifies for given GIMPLEs S1 and S2 that
+ /* Verifies for given GIMPLE_SWITCH stmts S1 and S2 that
switch statements are semantically equivalent. */
- bool compare_gimple_switch (gimple s1, gimple s2);
+ bool compare_gimple_switch (const gswitch *s1, const gswitch *s2);
- /* Verifies for given GIMPLEs S1 and S2 that
+ /* Verifies for given GIMPLE_RETURN stmts S1 and S2 that
return statements are semantically equivalent. */
- bool compare_gimple_return (gimple s1, gimple s2);
+ bool compare_gimple_return (const greturn *s1, const greturn *s2);
/* Verifies for given GIMPLEs S1 and S2 that
goto statements are semantically equivalent. */
bool compare_gimple_goto (gimple s1, gimple s2);
- /* Verifies for given GIMPLEs S1 and S2 that
+ /* Verifies for given GIMPLE_RESX stmts S1 and S2 that
resx statements are semantically equivalent. */
- bool compare_gimple_resx (gimple s1, gimple s2);
+ bool compare_gimple_resx (const gresx *s1, const gresx *s2);
- /* Verifies for given GIMPLEs S1 and S2 that ASM statements are equivalent.
+ /* Verifies for given GIMPLE_ASM stmts S1 and S2 that ASM statements
+ are equivalent.
For the beginning, the pass only supports equality for
'__asm__ __volatile__ ("", "", "", "memory")'. */
- bool compare_gimple_asm (gimple s1, gimple s2);
+ bool compare_gimple_asm (const gasm *s1, const gasm *s2);
/* Verification function for declaration trees T1 and T2. */
bool compare_decl (tree t1, tree t2);
@@ -855,8 +855,8 @@ sem_function::parse_tree_args (void)
bool
sem_function::compare_phi_node (basic_block bb1, basic_block bb2)
{
- gimple_stmt_iterator si1, si2;
- gimple phi1, phi2;
+ gphi_iterator si1, si2;
+ gphi *phi1, *phi2;
unsigned size1, size2, i;
tree t1, t2;
edge e1, e2;
@@ -877,8 +877,8 @@ sem_function::compare_phi_node (basic_block bb1, basic_block bb2)
if (gsi_end_p (si1) || gsi_end_p (si2))
return return_false();
- phi1 = gsi_stmt (si1);
- phi2 = gsi_stmt (si2);
+ phi1 = si1.phi ();
+ phi2 = si2.phi ();
tree phi_result1 = gimple_phi_result (phi1);
tree phi_result2 = gimple_phi_result (phi2);
@@ -3656,10 +3656,10 @@ fold_all_stmts (struct function *fun)
cfg_changed = true;
/* Cleanup the CFG if we simplified a condition to
true or false. */
- if (gimple_code (stmt) == GIMPLE_COND
- && (gimple_cond_true_p (stmt)
- || gimple_cond_false_p (stmt)))
- cfg_changed = true;
+ if (gcond *cond_stmt = dyn_cast <gcond *> (stmt))
+ if (gimple_cond_true_p (cond_stmt)
+ || gimple_cond_false_p (cond_stmt))
+ cfg_changed = true;
update_stmt (stmt);
}
@@ -4938,7 +4938,7 @@ branch_fixup (void)
else
gcc_unreachable ();
tree lhs = gimple_assign_lhs (use_stmt);
- gimple phi = create_phi_node (lhs, merge_bb);
+ gphi *phi = create_phi_node (lhs, merge_bb);
add_phi_arg (phi, build_one_cst (TREE_TYPE (lhs)), etrue, loc);
add_phi_arg (phi, othervar, single_succ_edge (then_bb), loc);
gsi = gsi_for_stmt (use_stmt);