&& !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs))
|| is_gimple_min_invariant (rhs)
|| TREE_CODE (rhs) == ADDR_EXPR
- || TREE_INVARIANT (rhs)
|| DECL_P (rhs))
{
/* Eliminate fully redundant computations. */
-static void
+static unsigned int
eliminate (void)
{
basic_block b;
+ unsigned int todo = 0;
FOR_EACH_BB (b)
{
}
}
}
+ /* Visit COND_EXPRs and fold the comparison with the
+ available value-numbers. */
+ else if (TREE_CODE (stmt) == COND_EXPR
+ && COMPARISON_CLASS_P (COND_EXPR_COND (stmt)))
+ {
+ tree cond = COND_EXPR_COND (stmt);
+ tree op0 = TREE_OPERAND (cond, 0);
+ tree op1 = TREE_OPERAND (cond, 1);
+ 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 (TREE_CODE (cond), TREE_TYPE (cond),
+ op0, op1);
+ if (result && TREE_CODE (result) == INTEGER_CST)
+ {
+ COND_EXPR_COND (stmt) = result;
+ update_stmt (stmt);
+ todo = TODO_cleanup_cfg;
+ }
+ }
+ else if (TREE_CODE (stmt) == COND_EXPR
+ && TREE_CODE (COND_EXPR_COND (stmt)) == SSA_NAME)
+ {
+ tree op = COND_EXPR_COND (stmt);
+ op = VN_INFO (op)->valnum;
+ if (TREE_CODE (op) == INTEGER_CST)
+ {
+ COND_EXPR_COND (stmt) = integer_zerop (op)
+ ? boolean_false_node : boolean_true_node;
+ update_stmt (stmt);
+ todo = TODO_cleanup_cfg;
+ }
+ }
}
}
+
+ return todo;
}
/* Borrow a bit of tree-ssa-dce.c for the moment.
/* Main entry point to the SSA-PRE pass. DO_FRE is true if the caller
only wants to do full redundancy elimination. */
-static void
+static unsigned int
execute_pre (bool do_fre)
{
+ unsigned int todo = 0;
do_partial_partial = optimize > 2;
init_pre (do_fre);
if (!do_fre)
remove_dead_inserted_code ();
fini_pre ();
- return;
+ return 0;
}
switch_to_PRE_table ();
compute_avail ();
}
/* Remove all the redundant expressions. */
- eliminate ();
+ todo |= eliminate ();
if (dump_file && (dump_flags & TDF_STATS))
{
}
fini_pre ();
+
+ return todo;
}
/* Gate and execute functions for PRE. */
static unsigned int
do_pre (void)
{
- execute_pre (false);
- return TODO_rebuild_alias;
+ return TODO_rebuild_alias | execute_pre (false);
}
static bool
return flag_tree_pre != 0;
}
-struct tree_opt_pass pass_pre =
+struct gimple_opt_pass pass_pre =
{
+ {
+ GIMPLE_PASS,
"pre", /* name */
gate_pre, /* gate */
do_pre, /* execute */
0, /* properties_destroyed */
0, /* todo_flags_start */
TODO_update_ssa_only_virtuals | TODO_dump_func | TODO_ggc_collect
- | TODO_verify_ssa, /* todo_flags_finish */
- 0 /* letter */
+ | TODO_verify_ssa /* todo_flags_finish */
+ }
};
static unsigned int
execute_fre (void)
{
- execute_pre (true);
- return 0;
+ return execute_pre (true);
}
static bool
return flag_tree_fre != 0;
}
-struct tree_opt_pass pass_fre =
+struct gimple_opt_pass pass_fre =
{
+ {
+ GIMPLE_PASS,
"fre", /* name */
gate_fre, /* gate */
execute_fre, /* execute */
0, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
- TODO_dump_func | TODO_ggc_collect | TODO_verify_ssa, /* todo_flags_finish */
- 0 /* letter */
+ TODO_dump_func | TODO_ggc_collect | TODO_verify_ssa /* todo_flags_finish */
+ }
};