This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch] tree-ssa-copy.c: Clean up copy_prop_visit_assignment.
- From: Kazu Hirata <kazu at cs dot umass dot edu>
- To: gcc-patches at gcc dot gnu dot org
- Cc: dnovillo at redhat dot com
- Date: Mon, 16 May 2005 13:00:15 -0400 (EDT)
- Subject: [patch] tree-ssa-copy.c: Clean up copy_prop_visit_assignment.
Hi,
Attached is a patch to clean up copy_prop_visit_assignment.
copy_prop_visit_assignment tries to fold a COND_EXPR_COND and find a
taken edge.
The current code proceeds like so:
1. Check to see if we have at least one SSA_NAME in COND_EXPR_COND.
2. Replace each SSA_NAME with what get_last_copy_of returns.
3. Check to see if we have two identical SSA_NAMEs on both sides of a
comparison.
4. Fold COND_EXPR_COND and determine a taken edge (if possible).
5. Restore operands.
This is really long winded. In particular, I don't like
1. use of malloc,
2. use of SET_USE, which involves maintenance of immediate uses, or
3. three uses of FOR_EACH_SSA_USE_OPERAND with one of them hidden in
NUM_SSA_OPERANDS.
This patch simplifies the process by doing replacement and folding in
a nondestructive manner. Thanks to fold_binary, we don't have to have
a complete tree node for a comparison. We just have to have a
comparison's operands and a comparison code.
The only externally visible change is that the dump message now prints
out the original COND_EXPR_COND, not the one with its operands
replaced. I don't think this is too big a deal, but if this bothers,
let me know.
Tested on i686-pc-linux-gnu. OK to apply?
Kazu Hirata
2005-05-16 Kazu Hirata <kazu@cs.umass.edu>
* tree-ssa-copy.c (copy_prop_visit_assignment): Clean up by
folding a COND_EXPR_COND in a nondestructive manner.
Index: tree-ssa-copy.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-copy.c,v
retrieving revision 2.29
diff -C5 -d -p -r2.29 tree-ssa-copy.c
*** tree-ssa-copy.c 3 May 2005 12:19:43 -0000 2.29
--- tree-ssa-copy.c 15 May 2005 20:33:14 -0000
*************** copy_prop_visit_assignment (tree stmt, t
*** 592,652 ****
static enum ssa_prop_result
copy_prop_visit_cond_stmt (tree stmt, edge *taken_edge_p)
{
enum ssa_prop_result retval;
tree cond;
- use_operand_p use_p;
- ssa_op_iter iter;
- unsigned num;
-
cond = COND_EXPR_COND (stmt);
retval = SSA_PROP_VARYING;
- num = NUM_SSA_OPERANDS (stmt, SSA_OP_USE);
/* The only conditionals that we may be able to compute statically
! are predicates involving at least one SSA_NAME. */
if (COMPARISON_CLASS_P (cond)
! && num >= 1)
{
! unsigned i;
! tree *orig;
!
! /* Save the original operands. */
! orig = xmalloc (sizeof (tree) * num);
! i = 0;
! FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
! {
! tree use = USE_FROM_PTR (use_p);
! orig[i++] = use;
! SET_USE (use_p, get_last_copy_of (use));
! }
/* See if we can determine the predicate's value. */
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Trying to determine truth value of ");
fprintf (dump_file, "predicate ");
print_generic_stmt (dump_file, cond, 0);
}
! /* We can fold COND only and get a useful result only when we
! have the same SSA_NAME on both sides of a comparison
! operator. */
! if (TREE_CODE (TREE_OPERAND (cond, 0)) == SSA_NAME
! && TREE_OPERAND (cond, 0) == TREE_OPERAND (cond, 1))
{
! *taken_edge_p = find_taken_edge (bb_for_stmt (stmt), fold (cond));
! if (*taken_edge_p)
! retval = SSA_PROP_INTERESTING;
}
-
- /* Restore the original operands. */
- i = 0;
- FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
- SET_USE (use_p, orig[i++]);
- free (orig);
}
if (dump_file && (dump_flags & TDF_DETAILS) && *taken_edge_p)
fprintf (dump_file, "\nConditional will always take edge %d->%d\n",
(*taken_edge_p)->src->index, (*taken_edge_p)->dest->index);
--- 592,636 ----
static enum ssa_prop_result
copy_prop_visit_cond_stmt (tree stmt, edge *taken_edge_p)
{
enum ssa_prop_result retval;
tree cond;
cond = COND_EXPR_COND (stmt);
retval = SSA_PROP_VARYING;
/* The only conditionals that we may be able to compute statically
! are predicates involving two SSA_NAMEs. */
if (COMPARISON_CLASS_P (cond)
! && TREE_CODE (TREE_OPERAND (cond, 0)) == SSA_NAME
! && TREE_CODE (TREE_OPERAND (cond, 1)) == SSA_NAME)
{
! tree op0 = get_last_copy_of (TREE_OPERAND (cond, 0));
! tree op1 = get_last_copy_of (TREE_OPERAND (cond, 1));
/* See if we can determine the predicate's value. */
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Trying to determine truth value of ");
fprintf (dump_file, "predicate ");
print_generic_stmt (dump_file, cond, 0);
}
! /* We can fold COND and get a useful result only when we have
! the same SSA_NAME on both sides of a comparison operator. */
! if (op0 == op1)
{
! tree folded_cond = fold_binary (TREE_CODE (cond), boolean_type_node,
! op0, op1);
! if (folded_cond)
! {
! basic_block bb = bb_for_stmt (stmt);
! *taken_edge_p = find_taken_edge (bb, folded_cond);
! if (*taken_edge_p)
! retval = SSA_PROP_INTERESTING;
! }
}
}
if (dump_file && (dump_flags & TDF_DETAILS) && *taken_edge_p)
fprintf (dump_file, "\nConditional will always take edge %d->%d\n",
(*taken_edge_p)->src->index, (*taken_edge_p)->dest->index);