#include "cfgloop.h"
#include "tree-scalar-evolution.h"
#include "tree-ssa-loop-niter.h"
+#include "gimple-fold.h"
/* This file implements the copy propagation pass and provides a
if (gimple_vuse (stmt))
return false;
+ /* If the assignment is from a constant it generates a useful copy. */
+ if (gimple_assign_single_p (stmt)
+ && is_gimple_min_invariant (gimple_assign_rhs1 (stmt)))
+ return true;
+
/* Otherwise, the only statements that generate useful copies are
- assignments whose RHS is just an SSA name that doesn't flow
- through abnormal edges. */
- return ((gimple_assign_rhs_code (stmt) == SSA_NAME
- && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_assign_rhs1 (stmt)))
- || is_gimple_min_invariant (gimple_assign_rhs1 (stmt)));
+ assignments whose single SSA use doesn't flow through abnormal
+ edges. */
+ tree rhs = single_ssa_tree_operand (stmt, SSA_OP_USE);
+ return (rhs && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs));
}
static enum ssa_prop_result
copy_prop_visit_assignment (gimple *stmt, tree *result_p)
{
- tree lhs, rhs;
-
- lhs = gimple_assign_lhs (stmt);
- rhs = valueize_val (gimple_assign_rhs1 (stmt));
-
- if (TREE_CODE (lhs) == SSA_NAME)
+ tree lhs = gimple_assign_lhs (stmt);
+ tree rhs = gimple_fold_stmt_to_constant_1 (stmt, valueize_val);
+ if (rhs
+ && (TREE_CODE (rhs) == SSA_NAME
+ || is_gimple_min_invariant (rhs)))
{
- /* Straight copy between two SSA names. First, make sure that
+ /* Straight copy between two SSA names or a constant. 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;
+ rhs = lhs;
}
+ else
+ rhs = lhs;
- return SSA_PROP_VARYING;
+ *result_p = lhs;
+ if (set_copy_of_val (*result_p, rhs))
+ return SSA_PROP_INTERESTING;
+ return rhs != lhs ? SSA_PROP_NOT_INTERESTING : SSA_PROP_VARYING;
}
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 (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. */