passes.c (init_optimization_passes): Exchange store_copy_prop with copy_prop.
2007-10-29 Richard Guenther <rguenther@suse.de> * passes.c (init_optimization_passes): Exchange store_copy_prop with copy_prop. * tree-pass.h (pass_store_copy_prop): Remove. * tree-ssa-copy.c (do_store_copy_prop): Remove. (stmt_may_generate-copy): Do not handle store_copy_prop. (get_copy_of_val): Likewise. (set_copy_of_val): Likewise. (copy_prop_visit_assignment): Likewise. (copy_prop_visit_stmt): Likewise. (copy_prop_visit_phi_node): Likewise. (init_copy_prop): Likewise. (execute_copy_prop): Likewise. (do_copy_prop): Remove. (gate_store_copy_prop): Likewise. (store_copy_prop): Likewise. (pass_store_copy_prop): Likewise. (pass_copy_prop): Call execute_copy_prop. * opts.c (decode_options): Do not set flag_tree_store_copy_prop. * common.opt (ftree-store-copy-prop): Mark obsolete. * doc/invoke.texi (ftree-store-copy-prop): Remove documentation. * gcc.dg/tree-ssa/ssa-copyprop-1.c: Scan optimized dump. From-SVN: r129734
This commit is contained in:
parent
40abbf1f17
commit
324d22176d
|
@ -1,3 +1,26 @@
|
|||
2007-10-29 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
* passes.c (init_optimization_passes): Exchange store_copy_prop
|
||||
with copy_prop.
|
||||
* tree-pass.h (pass_store_copy_prop): Remove.
|
||||
* tree-ssa-copy.c (do_store_copy_prop): Remove.
|
||||
(stmt_may_generate-copy): Do not handle store_copy_prop.
|
||||
(get_copy_of_val): Likewise.
|
||||
(set_copy_of_val): Likewise.
|
||||
(copy_prop_visit_assignment): Likewise.
|
||||
(copy_prop_visit_stmt): Likewise.
|
||||
(copy_prop_visit_phi_node): Likewise.
|
||||
(init_copy_prop): Likewise.
|
||||
(execute_copy_prop): Likewise.
|
||||
(do_copy_prop): Remove.
|
||||
(gate_store_copy_prop): Likewise.
|
||||
(store_copy_prop): Likewise.
|
||||
(pass_store_copy_prop): Likewise.
|
||||
(pass_copy_prop): Call execute_copy_prop.
|
||||
* opts.c (decode_options): Do not set flag_tree_store_copy_prop.
|
||||
* common.opt (ftree-store-copy-prop): Mark obsolete.
|
||||
* doc/invoke.texi (ftree-store-copy-prop): Remove documentation.
|
||||
|
||||
2007-10-29 Ian Lance Taylor <iant@google.com>
|
||||
|
||||
* ifcvt.c (noce_can_store_speculate_p): New static function.
|
||||
|
|
|
@ -1054,8 +1054,8 @@ Common Report Var(flag_tree_copy_prop) Optimization
|
|||
Enable copy propagation on trees
|
||||
|
||||
ftree-store-copy-prop
|
||||
Common Report Var(flag_tree_store_copy_prop) Optimization
|
||||
Enable copy propagation for stores and loads
|
||||
Common
|
||||
This switch is obsolete
|
||||
|
||||
ftree-cselim
|
||||
Common Report Var(flag_tree_cselim) Init(2) Optimization
|
||||
|
|
|
@ -364,7 +364,7 @@ Objective-C and Objective-C++ Dialects}.
|
|||
-ftree-dominator-opts -ftree-dse -ftree-copyrename -ftree-sink @gol
|
||||
-ftree-ch -ftree-sra -ftree-ter -ftree-fre -ftree-vectorize @gol
|
||||
-ftree-vect-loop-version -fvect-cost-model -ftree-salias -fipa-pta -fweb @gol
|
||||
-ftree-copy-prop -ftree-store-ccp -ftree-store-copy-prop -ftree-vrp @gol
|
||||
-ftree-copy-prop -ftree-store-ccp -ftree-vrp @gol
|
||||
-funit-at-a-time -fwhole-program @gol
|
||||
--param @var{name}=@var{value}
|
||||
-O -O0 -O1 -O2 -O3 -Os}
|
||||
|
@ -5677,13 +5677,6 @@ Perform copy propagation on trees. This pass eliminates unnecessary
|
|||
copy operations. This flag is enabled by default at @option{-O} and
|
||||
higher.
|
||||
|
||||
@item -ftree-store-copy-prop
|
||||
@opindex ftree-store-copy-prop
|
||||
Perform copy propagation of memory loads and stores. This pass
|
||||
eliminates unnecessary copy operations in memory references
|
||||
(structures, global variables, arrays, etc). This flag is enabled by
|
||||
default at @option{-O2} and higher.
|
||||
|
||||
@item -ftree-salias
|
||||
@opindex ftree-salias
|
||||
Perform structural alias analysis on trees. This flag
|
||||
|
|
|
@ -844,7 +844,6 @@ decode_options (unsigned int argc, const char **argv)
|
|||
flag_reorder_blocks = 1;
|
||||
flag_reorder_functions = 1;
|
||||
flag_tree_store_ccp = 1;
|
||||
flag_tree_store_copy_prop = 1;
|
||||
flag_tree_vrp = 1;
|
||||
|
||||
if (!optimize_size)
|
||||
|
|
|
@ -602,7 +602,7 @@ init_optimization_passes (void)
|
|||
NEXT_PASS (pass_phiopt);
|
||||
NEXT_PASS (pass_object_sizes);
|
||||
NEXT_PASS (pass_store_ccp);
|
||||
NEXT_PASS (pass_store_copy_prop);
|
||||
NEXT_PASS (pass_copy_prop);
|
||||
NEXT_PASS (pass_fold_builtins);
|
||||
NEXT_PASS (pass_cse_sincos);
|
||||
NEXT_PASS (pass_split_crit_edges);
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
2007-10-29 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
* gcc.dg/tree-ssa/ssa-copyprop-1.c: Scan optimized dump.
|
||||
|
||||
2007-10-29 Razya Ladelsky <razya@il.ibm.com>
|
||||
|
||||
Automatic parallelization reduction tests.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -fno-tree-dominator-opts -fdump-tree-store_copyprop-details" } */
|
||||
/* { dg-options "-O2 -fno-tree-dominator-opts -fdump-tree-optimized" } */
|
||||
|
||||
typedef struct { int i; int j; } A;
|
||||
int foo(A *a, int i)
|
||||
|
@ -8,5 +8,5 @@ int foo(A *a, int i)
|
|||
return a->i;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump "return i" "store_copyprop" } } */
|
||||
/* { dg-final { cleanup-tree-dump "store_copyprop" } } */
|
||||
/* { dg-final { scan-tree-dump "return i" "optimized" } } */
|
||||
/* { dg-final { cleanup-tree-dump "optimized" } } */
|
||||
|
|
|
@ -321,7 +321,6 @@ extern struct tree_opt_pass pass_linear_transform;
|
|||
extern struct tree_opt_pass pass_check_data_deps;
|
||||
extern struct tree_opt_pass pass_copy_prop;
|
||||
extern struct tree_opt_pass pass_store_ccp;
|
||||
extern struct tree_opt_pass pass_store_copy_prop;
|
||||
extern struct tree_opt_pass pass_vrp;
|
||||
extern struct tree_opt_pass pass_create_structure_vars;
|
||||
extern struct tree_opt_pass pass_uncprop;
|
||||
|
|
|
@ -384,9 +384,6 @@ static prop_value_t *copy_of;
|
|||
chain has changed. */
|
||||
static tree *cached_last_copy_of;
|
||||
|
||||
/* True if we are doing copy propagation on loads and stores. */
|
||||
static bool do_store_copy_prop;
|
||||
|
||||
|
||||
/* Return true if this statement may generate a useful copy. */
|
||||
|
||||
|
@ -411,19 +408,15 @@ stmt_may_generate_copy (tree stmt)
|
|||
if (ann->has_volatile_ops)
|
||||
return false;
|
||||
|
||||
/* If we are not doing store copy-prop, statements with loads and/or
|
||||
stores will never generate a useful copy. */
|
||||
if (!do_store_copy_prop
|
||||
&& !ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS))
|
||||
/* Statements with loads and/or stores will never generate a useful copy. */
|
||||
if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS))
|
||||
return false;
|
||||
|
||||
/* 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 (do_store_copy_prop
|
||||
&& TREE_CODE (lhs) == SSA_NAME)
|
||||
|| (TREE_CODE (rhs) == SSA_NAME
|
||||
&& !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs));
|
||||
return (TREE_CODE (rhs) == SSA_NAME
|
||||
&& !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs));
|
||||
}
|
||||
|
||||
|
||||
|
@ -440,7 +433,6 @@ get_copy_of_val (tree var)
|
|||
/* If the variable will never generate a useful copy relation,
|
||||
make it its own copy. */
|
||||
val->value = var;
|
||||
val->mem_ref = NULL_TREE;
|
||||
}
|
||||
|
||||
return val;
|
||||
|
@ -493,7 +485,7 @@ get_last_copy_of (tree var)
|
|||
and stores. */
|
||||
|
||||
static inline bool
|
||||
set_copy_of_val (tree dest, tree first, tree mem_ref)
|
||||
set_copy_of_val (tree dest, tree first)
|
||||
{
|
||||
unsigned int dest_ver = SSA_NAME_VERSION (dest);
|
||||
tree old_first, old_last, new_last;
|
||||
|
@ -502,7 +494,6 @@ set_copy_of_val (tree dest, tree first, tree mem_ref)
|
|||
changed, return true. */
|
||||
old_first = copy_of[dest_ver].value;
|
||||
copy_of[dest_ver].value = first;
|
||||
copy_of[dest_ver].mem_ref = mem_ref;
|
||||
|
||||
if (old_first != first)
|
||||
return true;
|
||||
|
@ -604,40 +595,11 @@ copy_prop_visit_assignment (tree stmt, tree *result_p)
|
|||
This is different from what we do in copy_prop_visit_phi_node.
|
||||
In those cases, we are interested in the copy-of chains. */
|
||||
*result_p = lhs;
|
||||
if (set_copy_of_val (*result_p, rhs_val->value, rhs_val->mem_ref))
|
||||
if (set_copy_of_val (*result_p, rhs_val->value))
|
||||
return SSA_PROP_INTERESTING;
|
||||
else
|
||||
return SSA_PROP_NOT_INTERESTING;
|
||||
}
|
||||
else if (stmt_makes_single_store (stmt))
|
||||
{
|
||||
/* Otherwise, set the names in VDEF operands to be a copy
|
||||
of RHS. */
|
||||
ssa_op_iter i;
|
||||
tree vdef;
|
||||
bool changed;
|
||||
|
||||
/* This should only be executed when doing store copy-prop. */
|
||||
gcc_assert (do_store_copy_prop);
|
||||
|
||||
/* Set the value of every VDEF to RHS_VAL. */
|
||||
changed = false;
|
||||
FOR_EACH_SSA_TREE_OPERAND (vdef, stmt, i, SSA_OP_VIRTUAL_DEFS)
|
||||
changed |= set_copy_of_val (vdef, rhs_val->value, lhs);
|
||||
|
||||
/* Note that for propagation purposes, we are only interested in
|
||||
visiting statements that load the exact same memory reference
|
||||
stored here. Those statements will have the exact same list
|
||||
of virtual uses, so it is enough to set the output of this
|
||||
statement to be its first virtual definition. */
|
||||
*result_p = first_vdef (stmt);
|
||||
|
||||
if (changed)
|
||||
return SSA_PROP_INTERESTING;
|
||||
else
|
||||
return SSA_PROP_NOT_INTERESTING;
|
||||
}
|
||||
|
||||
|
||||
return SSA_PROP_VARYING;
|
||||
}
|
||||
|
@ -721,41 +683,12 @@ copy_prop_visit_stmt (tree stmt, edge *taken_edge_p, tree *result_p)
|
|||
|
||||
if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
|
||||
&& TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1)) == SSA_NAME
|
||||
&& (do_store_copy_prop
|
||||
|| TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 0)) == SSA_NAME))
|
||||
&& TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 0)) == SSA_NAME)
|
||||
{
|
||||
/* If the statement is a copy assignment, evaluate its RHS to
|
||||
see if the lattice value of its output has changed. */
|
||||
retval = copy_prop_visit_assignment (stmt, result_p);
|
||||
}
|
||||
else if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
|
||||
&& TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 0)) == SSA_NAME
|
||||
&& do_store_copy_prop
|
||||
&& stmt_makes_single_load (stmt))
|
||||
{
|
||||
/* If the statement is a copy assignment with a memory load
|
||||
on the RHS, see if we know the value of this load and
|
||||
update the lattice accordingly. */
|
||||
prop_value_t *val = get_value_loaded_by (stmt, copy_of);
|
||||
if (val
|
||||
&& val->mem_ref
|
||||
&& is_gimple_reg (val->value)
|
||||
&& operand_equal_p (val->mem_ref, GIMPLE_STMT_OPERAND (stmt, 1), 0))
|
||||
{
|
||||
bool changed;
|
||||
changed = set_copy_of_val (GIMPLE_STMT_OPERAND (stmt, 0),
|
||||
val->value, val->mem_ref);
|
||||
if (changed)
|
||||
{
|
||||
*result_p = GIMPLE_STMT_OPERAND (stmt, 0);
|
||||
retval = SSA_PROP_INTERESTING;
|
||||
}
|
||||
else
|
||||
retval = SSA_PROP_NOT_INTERESTING;
|
||||
}
|
||||
else
|
||||
retval = SSA_PROP_VARYING;
|
||||
}
|
||||
else if (TREE_CODE (stmt) == COND_EXPR)
|
||||
{
|
||||
/* See if we can determine which edge goes out of a conditional
|
||||
|
@ -779,7 +712,7 @@ copy_prop_visit_stmt (tree stmt, edge *taken_edge_p, tree *result_p)
|
|||
statement again and mark all the definitions in the statement
|
||||
to be copies of nothing. */
|
||||
FOR_EACH_SSA_TREE_OPERAND (def, stmt, i, SSA_OP_ALL_DEFS)
|
||||
set_copy_of_val (def, def, NULL_TREE);
|
||||
set_copy_of_val (def, def);
|
||||
}
|
||||
|
||||
return retval;
|
||||
|
@ -859,7 +792,6 @@ copy_prop_visit_phi_node (tree phi)
|
|||
if (phi_val.value == NULL_TREE)
|
||||
{
|
||||
phi_val.value = arg;
|
||||
phi_val.mem_ref = arg_val->mem_ref;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -868,18 +800,14 @@ copy_prop_visit_phi_node (tree phi)
|
|||
copy propagating stores and these two arguments came from
|
||||
different memory references, they cannot be considered
|
||||
copies. */
|
||||
if (get_last_copy_of (phi_val.value) != get_last_copy_of (arg)
|
||||
|| (do_store_copy_prop
|
||||
&& phi_val.mem_ref
|
||||
&& arg_val->mem_ref
|
||||
&& simple_cst_equal (phi_val.mem_ref, arg_val->mem_ref) != 1))
|
||||
if (get_last_copy_of (phi_val.value) != get_last_copy_of (arg))
|
||||
{
|
||||
phi_val.value = lhs;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (phi_val.value && set_copy_of_val (lhs, phi_val.value, phi_val.mem_ref))
|
||||
if (phi_val.value && set_copy_of_val (lhs, phi_val.value))
|
||||
retval = (phi_val.value != lhs) ? SSA_PROP_INTERESTING : SSA_PROP_VARYING;
|
||||
else
|
||||
retval = SSA_PROP_NOT_INTERESTING;
|
||||
|
@ -948,7 +876,7 @@ init_copy_prop (void)
|
|||
the copy of anything. */
|
||||
FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_ALL_DEFS)
|
||||
if (DONT_SIMULATE_AGAIN (stmt))
|
||||
set_copy_of_val (def, def, NULL_TREE);
|
||||
set_copy_of_val (def, def);
|
||||
else
|
||||
cached_last_copy_of[SSA_NAME_VERSION (def)] = def;
|
||||
}
|
||||
|
@ -956,13 +884,13 @@ init_copy_prop (void)
|
|||
for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
|
||||
{
|
||||
def = PHI_RESULT (phi);
|
||||
if (!do_store_copy_prop && !is_gimple_reg (def))
|
||||
if (!is_gimple_reg (def))
|
||||
DONT_SIMULATE_AGAIN (phi) = true;
|
||||
else
|
||||
DONT_SIMULATE_AGAIN (phi) = false;
|
||||
|
||||
if (DONT_SIMULATE_AGAIN (phi))
|
||||
set_copy_of_val (def, def, NULL_TREE);
|
||||
set_copy_of_val (def, def);
|
||||
else
|
||||
cached_last_copy_of[SSA_NAME_VERSION (def)] = def;
|
||||
}
|
||||
|
@ -1104,34 +1032,26 @@ fini_copy_prop (void)
|
|||
Once the propagator stabilizes, we end up with the desired result
|
||||
x_53 and x_54 are both copies of x_898. */
|
||||
|
||||
static void
|
||||
execute_copy_prop (bool store_copy_prop)
|
||||
static unsigned int
|
||||
execute_copy_prop (void)
|
||||
{
|
||||
do_store_copy_prop = store_copy_prop;
|
||||
init_copy_prop ();
|
||||
ssa_propagate (copy_prop_visit_stmt, copy_prop_visit_phi_node);
|
||||
fini_copy_prop ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static bool
|
||||
gate_copy_prop (void)
|
||||
{
|
||||
return flag_tree_copy_prop != 0;
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
do_copy_prop (void)
|
||||
{
|
||||
execute_copy_prop (false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct tree_opt_pass pass_copy_prop =
|
||||
{
|
||||
"copyprop", /* name */
|
||||
gate_copy_prop, /* gate */
|
||||
do_copy_prop, /* execute */
|
||||
execute_copy_prop, /* execute */
|
||||
NULL, /* sub */
|
||||
NULL, /* next */
|
||||
0, /* static_pass_number */
|
||||
|
@ -1148,41 +1068,3 @@ struct tree_opt_pass pass_copy_prop =
|
|||
0 /* letter */
|
||||
};
|
||||
|
||||
static bool
|
||||
gate_store_copy_prop (void)
|
||||
{
|
||||
/* STORE-COPY-PROP is enabled only with -ftree-store-copy-prop, but
|
||||
when -fno-tree-store-copy-prop is specified, we should run
|
||||
regular COPY-PROP. That's why the pass is enabled with either
|
||||
flag. */
|
||||
return flag_tree_store_copy_prop != 0 || flag_tree_copy_prop != 0;
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
store_copy_prop (void)
|
||||
{
|
||||
/* If STORE-COPY-PROP is not enabled, we just run regular COPY-PROP. */
|
||||
execute_copy_prop (flag_tree_store_copy_prop != 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct tree_opt_pass pass_store_copy_prop =
|
||||
{
|
||||
"store_copyprop", /* name */
|
||||
gate_store_copy_prop, /* gate */
|
||||
store_copy_prop, /* execute */
|
||||
NULL, /* sub */
|
||||
NULL, /* next */
|
||||
0, /* static_pass_number */
|
||||
TV_TREE_STORE_COPY_PROP, /* tv_id */
|
||||
PROP_ssa | PROP_alias | PROP_cfg, /* properties_required */
|
||||
0, /* properties_provided */
|
||||
0, /* properties_destroyed */
|
||||
0, /* todo_flags_start */
|
||||
TODO_dump_func
|
||||
| TODO_cleanup_cfg
|
||||
| TODO_ggc_collect
|
||||
| TODO_verify_ssa
|
||||
| TODO_update_ssa, /* todo_flags_finish */
|
||||
0 /* letter */
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue