This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH][tuples] Tuplify SCCVN
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Diego Novillo <dnovillo at google dot com>
- Date: Tue, 24 Jun 2008 16:32:45 +0200 (CEST)
- Subject: [PATCH][tuples] Tuplify SCCVN
This patch tuplifies SCCVN. I have re-enabled FRE as far as to do
the value-numbering. This causes a lot of testcases to change from
FAIL due to missing dump file to a regular FAIL.
The most interesting part is how we treat simplifying across
statements (and thus VN_INFO->expr). I have wrapped the access
to it and create regular tree expressions on demand. We may miss
some simplifications now (gimple_fold is not gimple_fold_build), but
in the end we'll notice only after FRE is fully converted.
Nevertheless - bootstrapped and tested on x86_64-unknown-linux-gnu.
Ok for tuples? (I appreciate a review as I'm only getting familiar
with the new API)
Thanks,
Richard.
2008-06-24 Richard Guenther <rguenther@suse.de>
* tree-ssa-sccvn.c (vn_get_expr_for): New function.
(vuses_to_vec): Tuplify.
(copy_vuses_from_stmt): Likewise.
(vdefs_to_vec): Likewise.
(copy_vdefs_from_stmt): Likewise.
(shared_vuses_from_stmt): Likewise.
(copy_reference_ops_from_call): New function split out from
copy_reference_ops_from_ref.
(create_reference_ops_from_call): New function.
(shared_reference_ops_from_call): Likewise.
(get_def_ref_stmt_vuses): Tuplify.
(vn_reference_lookup): Likewise.
(vn_nary_op_lookup_stmt): New function.
(vn_nary_op_insert_stmt): Likewise.
(vn_phi_lookup): Tuplify.
(vn_phi_insert): Likewise.
(defs_to_varying): Likewise.
(visit_unary_op): Likewise.
(visit_binary_op): Likewise.
(visit_reference_op_call): New function.
(visit_reference_op_load): Tuplify.
(visit_reference_op_store): Likewise.
(visit_phi): Likewise.
(stmt_has_constants): New function.
(simplify_binary_expression): Tuplify.
(simplify_unary_expression): Likewise.
(try_to_simplify): Likewise.
(visit_use): Likewise.
(compare_ops): Likewise.
(DFS): Likewise.
(run_scc_vn): Likewise.
* tree-ssa-sccvn.h (shared_vuses_from_stmt): Adjust prototype.
(copy_vuses_from_stmt): Likewise.
(vn_get_expr_for): Declare.
(vn_nary_op_lookup_stmt): Likewise.
(vn_nary_op_insert_stmt): Likewise.
* tree-dfa.c (get_single_def_stmt): Tuplify.
(get_single_def_stmt_from_phi): Likewise.
(get_single_def_stmt_with_phi): Likewise.
* tree-ssa-pre.c (do_SCCVN_insertion): Use vn_get_expr_for.
(eliminate): Likewise.
(execute_pre): Enable SCCVN.
(gate_fre): Enable.
* tree-flow.h (get_single_def_stmt): Adjust prototype.
(get_single_def_stmt_from_phi): Likewise.
(get_single_def_stmt_with_phi): Likewise.
(vn_lookup_or_add_with_stmt): Likewise.
(vn_lookup_with_stmt): Likewise.
* gimple.c (gimple_fold): Fix.
* tree-vn.c (vn_add): Disable call to add_to_value.
(vn_add_with_vuses): Likewise.
(vn_lookup_with_stmt): Tuplify.
(vn_lookup_or_add_with_stmt): Likewise.
Index: gcc/tree-ssa-sccvn.c
===================================================================
--- gcc/tree-ssa-sccvn.c.orig 2008-06-24 13:13:07.000000000 +0200
+++ gcc/tree-ssa-sccvn.c 2008-06-24 16:15:01.000000000 +0200
@@ -46,8 +46,6 @@ along with GCC; see the file COPYING3.
#include "tree-ssa-propagate.h"
#include "tree-ssa-sccvn.h"
-/* FIXME tuples. */
-#if 0
/* This algorithm is based on the SCC algorithm presented by Keith
Cooper and L. Taylor Simpson in "SCC-Based Value numbering"
(http://citeseer.ist.psu.edu/41805.html). In
@@ -274,6 +272,55 @@ VN_INFO_GET (tree name)
}
+/* Get the representative expression for the SSA_NAME NAME. Returns
+ the representative SSA_NAME if there is no expression associated with it. */
+
+tree
+vn_get_expr_for (tree name)
+{
+ vn_ssa_aux_t vn = VN_INFO (name);
+ gimple def_stmt;
+ tree expr;
+
+ if (vn->valnum == VN_TOP)
+ return name;
+
+ /* If the value-number is a constant it is the representative
+ expression. */
+ if (TREE_CODE (vn->valnum) != SSA_NAME)
+ return vn->valnum;
+
+ /* Get to the information of the value of this SSA_NAME. */
+ vn = VN_INFO (vn->valnum);
+
+ /* If the value-number is a constant it is the representative
+ expression. */
+ if (TREE_CODE (vn->valnum) != SSA_NAME)
+ return vn->valnum;
+
+ /* Else if we have an expression, return it. */
+ if (vn->expr != NULL_TREE)
+ return vn->expr;
+
+ /* Otherwise use the defining statement to build the expression. */
+ def_stmt = SSA_NAME_DEF_STMT (vn->valnum);
+
+ /* If the value number is a default-definition use it directly. */
+ if (gimple_nop_p (def_stmt))
+ return vn->valnum;
+
+ /* ??? This will return NULL_TREE if the stmt cannot be simplified. */
+ expr = gimple_fold (def_stmt);
+ if (!expr)
+ return vn->valnum;
+
+ /* Cache the expression. */
+ vn->expr = expr;
+
+ return expr;
+}
+
+
/* Free a phi operation structure VP. */
static void
@@ -391,7 +438,7 @@ vn_reference_eq (const void *p1, const v
/* Place the vuses from STMT into *result */
static inline void
-vuses_to_vec (tree stmt, VEC (tree, gc) **result)
+vuses_to_vec (gimple stmt, VEC (tree, gc) **result)
{
ssa_op_iter iter;
tree vuse;
@@ -411,7 +458,7 @@ vuses_to_vec (tree stmt, VEC (tree, gc)
the vector. */
VEC (tree, gc) *
-copy_vuses_from_stmt (tree stmt)
+copy_vuses_from_stmt (gimple stmt)
{
VEC (tree, gc) *vuses = NULL;
@@ -423,7 +470,7 @@ copy_vuses_from_stmt (tree stmt)
/* Place the vdefs from STMT into *result */
static inline void
-vdefs_to_vec (tree stmt, VEC (tree, gc) **result)
+vdefs_to_vec (gimple stmt, VEC (tree, gc) **result)
{
ssa_op_iter iter;
tree vdef;
@@ -441,7 +488,7 @@ vdefs_to_vec (tree stmt, VEC (tree, gc)
the vector. */
static VEC (tree, gc) *
-copy_vdefs_from_stmt (tree stmt)
+copy_vdefs_from_stmt (gimple stmt)
{
VEC (tree, gc) *vdefs = NULL;
@@ -458,7 +505,7 @@ static VEC (tree, gc) *shared_lookup_vop
variable. */
VEC (tree, gc) *
-shared_vuses_from_stmt (tree stmt)
+shared_vuses_from_stmt (gimple stmt)
{
VEC_truncate (tree, shared_lookup_vops, 0);
vuses_to_vec (stmt, &shared_lookup_vops);
@@ -466,46 +513,12 @@ shared_vuses_from_stmt (tree stmt)
return shared_lookup_vops;
}
-/* Copy the operations present in load/store/call REF into RESULT, a vector of
+/* Copy the operations present in load/store REF into RESULT, a vector of
vn_reference_op_s's. */
static void
copy_reference_ops_from_ref (tree ref, VEC(vn_reference_op_s, heap) **result)
{
- /* Calls are different from all other reference operations. */
- if (TREE_CODE (ref) == CALL_EXPR)
- {
- vn_reference_op_s temp;
- tree callfn;
- call_expr_arg_iterator iter;
- tree callarg;
-
- /* Copy the call_expr opcode, type, function being called, and
- arguments. */
- memset (&temp, 0, sizeof (temp));
- temp.type = TREE_TYPE (ref);
- temp.opcode = CALL_EXPR;
- VEC_safe_push (vn_reference_op_s, heap, *result, &temp);
-
- callfn = get_callee_fndecl (ref);
- if (!callfn)
- callfn = CALL_EXPR_FN (ref);
- temp.type = TREE_TYPE (callfn);
- temp.opcode = TREE_CODE (callfn);
- temp.op0 = callfn;
- VEC_safe_push (vn_reference_op_s, heap, *result, &temp);
-
- FOR_EACH_CALL_EXPR_ARG (callarg, iter, ref)
- {
- memset (&temp, 0, sizeof (temp));
- temp.type = TREE_TYPE (callarg);
- temp.opcode = TREE_CODE (callarg);
- temp.op0 = callarg;
- VEC_safe_push (vn_reference_op_s, heap, *result, &temp);
- }
- return;
- }
-
if (TREE_CODE (ref) == TARGET_MEM_REF)
{
vn_reference_op_s temp;
@@ -612,6 +625,42 @@ copy_reference_ops_from_ref (tree ref, V
}
}
+/* Copy the operations present in load/store/call REF into RESULT, a vector of
+ vn_reference_op_s's. */
+
+static void
+copy_reference_ops_from_call (gimple call,
+ VEC(vn_reference_op_s, heap) **result)
+{
+ vn_reference_op_s temp;
+ tree callfn;
+ unsigned i;
+
+ /* Copy the call_expr opcode, type, function being called, and
+ arguments. */
+ memset (&temp, 0, sizeof (temp));
+ temp.type = gimple_call_return_type (call);
+ temp.opcode = CALL_EXPR;
+ VEC_safe_push (vn_reference_op_s, heap, *result, &temp);
+
+ callfn = gimple_call_fn (call);
+ temp.type = TREE_TYPE (callfn);
+ temp.opcode = TREE_CODE (callfn);
+ temp.op0 = callfn;
+ VEC_safe_push (vn_reference_op_s, heap, *result, &temp);
+
+ for (i = 0; i < gimple_call_num_args (call); ++i)
+ {
+ tree callarg = gimple_call_arg (call, i);
+ memset (&temp, 0, sizeof (temp));
+ temp.type = TREE_TYPE (callarg);
+ temp.opcode = TREE_CODE (callarg);
+ temp.op0 = callarg;
+ VEC_safe_push (vn_reference_op_s, heap, *result, &temp);
+ }
+ return;
+}
+
/* Create a vector of vn_reference_op_s structures from REF, a
REFERENCE_CLASS_P tree. The vector is not shared. */
@@ -624,6 +673,18 @@ create_reference_ops_from_ref (tree ref)
return result;
}
+/* Create a vector of vn_reference_op_s structures from CALL, a
+ call statement. The vector is not shared. */
+
+static VEC(vn_reference_op_s, heap) *
+create_reference_ops_from_call (gimple call)
+{
+ VEC (vn_reference_op_s, heap) *result = NULL;
+
+ copy_reference_ops_from_call (call, &result);
+ return result;
+}
+
static VEC(vn_reference_op_s, heap) *shared_lookup_references;
/* Create a vector of vn_reference_op_s structures from REF, a
@@ -640,6 +701,20 @@ shared_reference_ops_from_ref (tree ref)
return shared_lookup_references;
}
+/* Create a vector of vn_reference_op_s structures from CALL, a
+ call statement. The vector is shared among all callers of
+ this function. */
+
+static VEC(vn_reference_op_s, heap) *
+shared_reference_ops_from_call (gimple call)
+{
+ if (!call)
+ return NULL;
+ VEC_truncate (vn_reference_op_s, shared_lookup_references, 0);
+ copy_reference_ops_from_call (call, &shared_lookup_references);
+ return shared_lookup_references;
+}
+
/* Transform any SSA_NAME's in a vector of vn_reference_op_s
structures into their value numbers. This is done in-place, and
@@ -692,16 +767,17 @@ valueize_vuses (VEC (tree, gc) *orig)
Take into account only definitions that alias REF if following
back-edges. */
-static tree
+static gimple
get_def_ref_stmt_vuses (tree ref, VEC (tree, gc) *vuses)
{
- tree def_stmt, vuse;
+ gimple def_stmt;
+ tree vuse;
unsigned int i;
gcc_assert (VEC_length (tree, vuses) >= 1);
def_stmt = SSA_NAME_DEF_STMT (VEC_index (tree, vuses, 0));
- if (TREE_CODE (def_stmt) == PHI_NODE)
+ if (gimple_code (def_stmt) == GIMPLE_PHI)
{
/* We can only handle lookups over PHI nodes for a single
virtual operand. */
@@ -711,23 +787,22 @@ get_def_ref_stmt_vuses (tree ref, VEC (t
goto cont;
}
else
- return NULL_TREE;
+ return NULL;
}
/* Verify each VUSE reaches the same defining stmt. */
for (i = 1; VEC_iterate (tree, vuses, i, vuse); ++i)
{
- tree tmp = SSA_NAME_DEF_STMT (vuse);
+ gimple tmp = SSA_NAME_DEF_STMT (vuse);
if (tmp != def_stmt)
- return NULL_TREE;
+ return NULL;
}
/* Now see if the definition aliases ref, and loop until it does. */
cont:
while (def_stmt
- && TREE_CODE (def_stmt) == GIMPLE_MODIFY_STMT
- && !get_call_expr_in (def_stmt)
- && !refs_may_alias_p (ref, GIMPLE_STMT_OPERAND (def_stmt, 0)))
+ && is_gimple_assign (def_stmt)
+ && !refs_may_alias_p (ref, gimple_get_lhs (def_stmt)))
def_stmt = get_single_def_stmt_with_phi (ref, def_stmt);
return def_stmt;
@@ -763,7 +838,8 @@ tree
vn_reference_lookup (tree op, VEC (tree, gc) *vuses, bool maywalk)
{
struct vn_reference_s vr1;
- tree result, def_stmt;
+ tree result;
+ gimple def_stmt;
vr1.vuses = valueize_vuses (vuses);
vr1.operands = valueize_refs (shared_reference_ops_from_ref (op));
@@ -776,12 +852,8 @@ vn_reference_lookup (tree op, VEC (tree,
&& maywalk
&& vr1.vuses
&& VEC_length (tree, vr1.vuses) >= 1
- && !get_call_expr_in (op)
&& (def_stmt = get_def_ref_stmt_vuses (op, vr1.vuses))
- && TREE_CODE (def_stmt) == GIMPLE_MODIFY_STMT
- /* If there is a call involved, op must be assumed to
- be clobbered. */
- && !get_call_expr_in (def_stmt))
+ && is_gimple_assign (def_stmt))
{
/* We are now at an aliasing definition for the vuses we want to
look up. Re-do the lookup with the vdefs for this stmt. */
@@ -912,6 +984,33 @@ vn_nary_op_lookup (tree op)
return ((vn_nary_op_t)*slot)->result;
}
+/* Lookup the rhs of STMT in the current hash table, and return the resulting
+ value number if it exists in the hash table. Return NULL_TREE if
+ it does not exist in the hash table. */
+
+tree
+vn_nary_op_lookup_stmt (gimple stmt)
+{
+ void **slot;
+ struct vn_nary_op_s vno1;
+ unsigned i;
+
+ vno1.opcode = gimple_subcode (stmt);
+ vno1.length = gimple_num_ops (stmt) - 1;
+ vno1.type = TREE_TYPE (gimple_assign_lhs (stmt));
+ for (i = 0; i < vno1.length; ++i)
+ vno1.op[i] = gimple_op (stmt, i + 1);
+ vno1.hashcode = vn_nary_op_compute_hash (&vno1);
+ slot = htab_find_slot_with_hash (current_info->nary, &vno1, vno1.hashcode,
+ NO_INSERT);
+ if (!slot && current_info == optimistic_info)
+ slot = htab_find_slot_with_hash (valid_info->nary, &vno1, vno1.hashcode,
+ NO_INSERT);
+ if (!slot)
+ return NULL_TREE;
+ return ((vn_nary_op_t)*slot)->result;
+}
+
/* Insert OP into the current hash table with a value number of
RESULT. */
@@ -940,6 +1039,34 @@ vn_nary_op_insert (tree op, tree result)
*slot = vno1;
}
+/* Insert the rhs of STMT into the current hash table with a value number of
+ RESULT. */
+
+void
+vn_nary_op_insert_stmt (gimple stmt, tree result)
+{
+ unsigned length = gimple_num_ops (stmt) - 1;
+ void **slot;
+ vn_nary_op_t vno1;
+ unsigned i;
+
+ vno1 = obstack_alloc (¤t_info->nary_obstack,
+ (sizeof (struct vn_nary_op_s)
+ - sizeof (tree) * (4 - length)));
+ vno1->opcode = gimple_subcode (stmt);
+ vno1->length = length;
+ vno1->type = TREE_TYPE (gimple_assign_lhs (stmt));
+ for (i = 0; i < vno1->length; ++i)
+ vno1->op[i] = gimple_op (stmt, i + 1);
+ vno1->result = result;
+ vno1->hashcode = vn_nary_op_compute_hash (vno1);
+ slot = htab_find_slot_with_hash (current_info->nary, vno1, vno1->hashcode,
+ INSERT);
+ gcc_assert (!*slot);
+
+ *slot = vno1;
+}
+
/* Compute a hashcode for PHI operation VP1 and return it. */
static inline hashval_t
@@ -1005,16 +1132,16 @@ static VEC(tree, heap) *shared_lookup_ph
it does not exist in the hash table. */
static tree
-vn_phi_lookup (tree phi)
+vn_phi_lookup (gimple phi)
{
void **slot;
struct vn_phi_s vp1;
- int i;
+ unsigned i;
VEC_truncate (tree, shared_lookup_phiargs, 0);
/* Canonicalize the SSA_NAME's to their value number. */
- for (i = 0; i < PHI_NUM_ARGS (phi); i++)
+ for (i = 0; i < gimple_phi_num_args (phi); i++)
{
tree def = PHI_ARG_DEF (phi, i);
def = TREE_CODE (def) == SSA_NAME ? SSA_VAL (def) : def;
@@ -1037,15 +1164,15 @@ vn_phi_lookup (tree phi)
RESULT. */
static void
-vn_phi_insert (tree phi, tree result)
+vn_phi_insert (gimple phi, tree result)
{
void **slot;
vn_phi_t vp1 = (vn_phi_t) pool_alloc (current_info->phis_pool);
- int i;
+ unsigned i;
VEC (tree, heap) *args = NULL;
/* Canonicalize the SSA_NAME's to their value number. */
- for (i = 0; i < PHI_NUM_ARGS (phi); i++)
+ for (i = 0; i < gimple_phi_num_args (phi); i++)
{
tree def = PHI_ARG_DEF (phi, i);
def = TREE_CODE (def) == SSA_NAME ? SSA_VAL (def) : def;
@@ -1125,7 +1252,7 @@ set_ssa_val_to (tree from, tree to)
Return true if a value number changed. */
static bool
-defs_to_varying (tree stmt)
+defs_to_varying (gimple stmt)
{
bool changed = false;
ssa_op_iter iter;
@@ -1142,7 +1269,7 @@ defs_to_varying (tree stmt)
}
static bool expr_has_constants (tree expr);
-static tree try_to_simplify (tree stmt, tree rhs);
+static tree try_to_simplify (gimple stmt);
/* Visit a copy between LHS and RHS, return true if the value number
changed. */
@@ -1150,7 +1277,6 @@ static tree try_to_simplify (tree stmt,
static bool
visit_copy (tree lhs, tree rhs)
{
-
/* Follow chains of copies to their destination. */
while (SSA_VAL (rhs) != rhs && TREE_CODE (SSA_VAL (rhs)) == SSA_NAME)
rhs = SSA_VAL (rhs);
@@ -1167,10 +1293,10 @@ visit_copy (tree lhs, tree rhs)
value number of LHS has changed as a result. */
static bool
-visit_unary_op (tree lhs, tree op)
+visit_unary_op (tree lhs, gimple stmt)
{
bool changed = false;
- tree result = vn_nary_op_lookup (op);
+ tree result = vn_nary_op_lookup_stmt (stmt);
if (result)
{
@@ -1179,7 +1305,7 @@ visit_unary_op (tree lhs, tree op)
else
{
changed = set_ssa_val_to (lhs, lhs);
- vn_nary_op_insert (op, lhs);
+ vn_nary_op_insert_stmt (stmt, lhs);
}
return changed;
@@ -1189,10 +1315,10 @@ visit_unary_op (tree lhs, tree op)
value number of LHS has changed as a result. */
static bool
-visit_binary_op (tree lhs, tree op)
+visit_binary_op (tree lhs, gimple stmt)
{
bool changed = false;
- tree result = vn_nary_op_lookup (op);
+ tree result = vn_nary_op_lookup_stmt (stmt);
if (result)
{
@@ -1201,7 +1327,48 @@ visit_binary_op (tree lhs, tree op)
else
{
changed = set_ssa_val_to (lhs, lhs);
- vn_nary_op_insert (op, lhs);
+ vn_nary_op_insert_stmt (stmt, lhs);
+ }
+
+ return changed;
+}
+
+/* Visit a call STMT storing into LHS. Return true if the value number
+ of the LHS has changed as a result. */
+
+static bool
+visit_reference_op_call (tree lhs, gimple stmt)
+{
+ bool changed = false;
+ struct vn_reference_s vr1;
+ tree result;
+
+ vr1.vuses = valueize_vuses (shared_vuses_from_stmt (stmt));
+ vr1.operands = valueize_refs (shared_reference_ops_from_call (stmt));
+ vr1.hashcode = vn_reference_compute_hash (&vr1);
+ result = vn_reference_lookup_1 (&vr1);
+ if (result)
+ {
+ changed = set_ssa_val_to (lhs, result);
+ if (TREE_CODE (result) == SSA_NAME
+ && VN_INFO (result)->has_constants)
+ VN_INFO (lhs)->has_constants = true;
+ }
+ else
+ {
+ void **slot;
+ vn_reference_t vr2;
+ changed = set_ssa_val_to (lhs, lhs);
+ vr2 = (vn_reference_t) pool_alloc (current_info->references_pool);
+ vr2->vuses = valueize_vuses (copy_vuses_from_stmt (stmt));
+ vr2->operands = valueize_refs (create_reference_ops_from_call (stmt));
+ vr2->hashcode = vr1.hashcode;
+ vr2->result = lhs;
+ slot = htab_find_slot_with_hash (current_info->references,
+ vr2, vr2->hashcode, INSERT);
+ if (*slot)
+ free_reference (*slot);
+ *slot = vr2;
}
return changed;
@@ -1211,7 +1378,7 @@ visit_binary_op (tree lhs, tree op)
and return true if the value number of the LHS has changed as a result. */
static bool
-visit_reference_op_load (tree lhs, tree op, tree stmt)
+visit_reference_op_load (tree lhs, tree op, gimple stmt)
{
bool changed = false;
tree result = vn_reference_lookup (op, shared_vuses_from_stmt (stmt), true);
@@ -1231,7 +1398,7 @@ visit_reference_op_load (tree lhs, tree
&& !is_gimple_min_invariant (val)
&& TREE_CODE (val) != SSA_NAME)
{
- tree tem = try_to_simplify (stmt, val);
+ tree tem = try_to_simplify (stmt);
if (tem)
val = tem;
}
@@ -1243,7 +1410,7 @@ visit_reference_op_load (tree lhs, tree
a new SSA_NAME we create. */
if (!result && may_insert)
{
- result = make_ssa_name (SSA_NAME_VAR (lhs), NULL_TREE);
+ result = make_ssa_name (SSA_NAME_VAR (lhs), NULL);
/* Initialize value-number information properly. */
VN_INFO_GET (result)->valnum = result;
VN_INFO (result)->expr = val;
@@ -1299,7 +1466,7 @@ visit_reference_op_load (tree lhs, tree
and return true if the value number of the LHS has changed as a result. */
static bool
-visit_reference_op_store (tree lhs, tree op, tree stmt)
+visit_reference_op_store (tree lhs, tree op, gimple stmt)
{
bool changed = false;
tree result;
@@ -1397,13 +1564,13 @@ visit_reference_op_store (tree lhs, tree
changed. */
static bool
-visit_phi (tree phi)
+visit_phi (gimple phi)
{
bool changed = false;
tree result;
tree sameval = VN_TOP;
bool allsame = true;
- int i;
+ unsigned i;
/* TODO: We could check for this in init_sccvn, and replace this
with a gcc_assert. */
@@ -1412,7 +1579,7 @@ visit_phi (tree phi)
/* See if all non-TOP arguments have the same value. TOP is
equivalent to everything, so we can ignore it. */
- for (i = 0; i < PHI_NUM_ARGS (phi); i++)
+ for (i = 0; i < gimple_phi_num_args (phi); i++)
{
tree def = PHI_ARG_DEF (phi, i);
@@ -1499,6 +1666,32 @@ expr_has_constants (tree expr)
return false;
}
+/* Return true if STMT contains constants. */
+
+static bool
+stmt_has_constants (gimple stmt)
+{
+ if (gimple_code (stmt) != GIMPLE_ASSIGN)
+ return false;
+
+ switch (get_gimple_rhs_class (gimple_assign_rhs_code (stmt)))
+ {
+ case GIMPLE_UNARY_RHS:
+ return is_gimple_min_invariant (gimple_assign_rhs1 (stmt));
+
+ case GIMPLE_BINARY_RHS:
+ return (is_gimple_min_invariant (gimple_assign_rhs1 (stmt))
+ || is_gimple_min_invariant (gimple_assign_rhs2 (stmt)));
+ case GIMPLE_SINGLE_RHS:
+ /* Constants inside reference ops are rarely interesting, but
+ it can take a lot of looking to find them. */
+ return is_gimple_min_invariant (gimple_assign_rhs1 (stmt));
+ default:
+ gcc_unreachable ();
+ }
+ return false;
+}
+
/* Replace SSA_NAMES in expr with their value numbers, and return the
result.
This is performed in place. */
@@ -1531,11 +1724,11 @@ valueize_expr (tree expr)
simplified. */
static tree
-simplify_binary_expression (tree stmt, tree rhs)
+simplify_binary_expression (gimple stmt)
{
tree result = NULL_TREE;
- tree op0 = TREE_OPERAND (rhs, 0);
- tree op1 = TREE_OPERAND (rhs, 1);
+ tree op0 = gimple_assign_rhs1 (stmt);
+ tree op1 = gimple_assign_rhs2 (stmt);
/* This will not catch every single case we could combine, but will
catch those with constants. The goal here is to simultaneously
@@ -1544,7 +1737,7 @@ simplify_binary_expression (tree stmt, t
if (TREE_CODE (op0) == SSA_NAME)
{
if (VN_INFO (op0)->has_constants)
- op0 = valueize_expr (VN_INFO (op0)->expr);
+ op0 = valueize_expr (vn_get_expr_for (op0));
else if (SSA_VAL (op0) != VN_TOP && SSA_VAL (op0) != op0)
op0 = SSA_VAL (op0);
}
@@ -1552,19 +1745,20 @@ simplify_binary_expression (tree stmt, t
if (TREE_CODE (op1) == SSA_NAME)
{
if (VN_INFO (op1)->has_constants)
- op1 = valueize_expr (VN_INFO (op1)->expr);
+ op1 = valueize_expr (vn_get_expr_for (op1));
else if (SSA_VAL (op1) != VN_TOP && SSA_VAL (op1) != op1)
op1 = SSA_VAL (op1);
}
/* Avoid folding if nothing changed. */
- if (op0 == TREE_OPERAND (rhs, 0)
- && op1 == TREE_OPERAND (rhs, 1))
+ if (op0 == gimple_assign_rhs1 (stmt)
+ && op1 == gimple_assign_rhs2 (stmt))
return NULL_TREE;
fold_defer_overflow_warnings ();
- result = fold_binary (TREE_CODE (rhs), TREE_TYPE (rhs), op0, op1);
+ result = fold_binary (gimple_subcode (stmt),
+ TREE_TYPE (gimple_get_lhs (stmt)), op0, op1);
fold_undefer_overflow_warnings (result && valid_gimple_expression_p (result),
stmt, 0);
@@ -1583,24 +1777,24 @@ simplify_binary_expression (tree stmt, t
simplified. */
static tree
-simplify_unary_expression (tree rhs)
+simplify_unary_expression (gimple stmt)
{
tree result = NULL_TREE;
- tree op0 = TREE_OPERAND (rhs, 0);
+ tree op0 = gimple_assign_rhs1 (stmt);
if (TREE_CODE (op0) != SSA_NAME)
return NULL_TREE;
if (VN_INFO (op0)->has_constants)
- op0 = valueize_expr (VN_INFO (op0)->expr);
- else if (CONVERT_EXPR_P (rhs)
- || TREE_CODE (rhs) == REALPART_EXPR
- || TREE_CODE (rhs) == IMAGPART_EXPR
- || TREE_CODE (rhs) == VIEW_CONVERT_EXPR)
+ op0 = valueize_expr (vn_get_expr_for (op0));
+ else if (gimple_assign_cast_p (stmt)
+ || gimple_subcode (stmt) == REALPART_EXPR
+ || gimple_subcode (stmt) == IMAGPART_EXPR
+ || gimple_subcode (stmt) == VIEW_CONVERT_EXPR)
{
/* We want to do tree-combining on conversion-like expressions.
Make sure we feed only SSA_NAMEs or constants to fold though. */
- tree tem = valueize_expr (VN_INFO (op0)->expr);
+ tree tem = valueize_expr (vn_get_expr_for (op0));
if (UNARY_CLASS_P (tem)
|| BINARY_CLASS_P (tem)
|| TREE_CODE (tem) == VIEW_CONVERT_EXPR
@@ -1610,10 +1804,11 @@ simplify_unary_expression (tree rhs)
}
/* Avoid folding if nothing changed, but remember the expression. */
- if (op0 == TREE_OPERAND (rhs, 0))
- return rhs;
+ if (op0 == gimple_assign_rhs1 (stmt))
+ return NULL_TREE;
- result = fold_unary (TREE_CODE (rhs), TREE_TYPE (rhs), op0);
+ result = fold_unary (gimple_subcode (stmt),
+ TREE_TYPE (gimple_get_lhs (stmt)), op0);
if (result)
{
STRIP_USELESS_TYPE_CONVERSION (result);
@@ -1621,25 +1816,26 @@ simplify_unary_expression (tree rhs)
return result;
}
- return rhs;
+ return NULL_TREE;
}
/* Try to simplify RHS using equivalences and constant folding. */
static tree
-try_to_simplify (tree stmt, tree rhs)
+try_to_simplify (gimple stmt)
{
tree tem;
/* For stores we can end up simplifying a SSA_NAME rhs. Just return
in this case, there is no point in doing extra work. */
- if (TREE_CODE (rhs) == SSA_NAME)
- return rhs;
+ if (gimple_assign_copy_p (stmt)
+ && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME)
+ return NULL_TREE;
- switch (TREE_CODE_CLASS (TREE_CODE (rhs)))
+ switch (TREE_CODE_CLASS (gimple_subcode (stmt)))
{
case tcc_declaration:
- tem = get_symbol_constant_value (rhs);
+ tem = get_symbol_constant_value (gimple_assign_rhs1 (stmt));
if (tem)
return tem;
break;
@@ -1647,29 +1843,29 @@ try_to_simplify (tree stmt, tree rhs)
case tcc_reference:
/* Do not do full-blown reference lookup here, but simplify
reads from constant aggregates. */
- tem = fold_const_aggregate_ref (rhs);
+ tem = fold_const_aggregate_ref (gimple_assign_rhs1 (stmt));
if (tem)
return tem;
/* Fallthrough for some codes that can operate on registers. */
- if (!(TREE_CODE (rhs) == REALPART_EXPR
- || TREE_CODE (rhs) == IMAGPART_EXPR
- || TREE_CODE (rhs) == VIEW_CONVERT_EXPR))
+ if (!(TREE_CODE (gimple_assign_rhs1 (stmt)) == REALPART_EXPR
+ || TREE_CODE (gimple_assign_rhs1 (stmt)) == IMAGPART_EXPR
+ || TREE_CODE (gimple_assign_rhs1 (stmt)) == VIEW_CONVERT_EXPR))
break;
/* We could do a little more with unary ops, if they expand
into binary ops, but it's debatable whether it is worth it. */
case tcc_unary:
- return simplify_unary_expression (rhs);
+ return simplify_unary_expression (stmt);
break;
case tcc_comparison:
case tcc_binary:
- return simplify_binary_expression (stmt, rhs);
+ return simplify_binary_expression (stmt);
break;
default:
break;
}
- return rhs;
+ return NULL_TREE;
}
/* Visit and value number USE, return true if the value number
@@ -1679,67 +1875,54 @@ static bool
visit_use (tree use)
{
bool changed = false;
- tree stmt = SSA_NAME_DEF_STMT (use);
- stmt_ann_t ann;
+ gimple stmt = SSA_NAME_DEF_STMT (use);
VN_INFO (use)->use_processed = true;
gcc_assert (!SSA_NAME_IN_FREE_LIST (use));
if (dump_file && (dump_flags & TDF_DETAILS)
- && !IS_EMPTY_STMT (stmt))
+ && !SSA_NAME_IS_DEFAULT_DEF (use))
{
fprintf (dump_file, "Value numbering ");
print_generic_expr (dump_file, use, 0);
fprintf (dump_file, " stmt = ");
- print_generic_stmt (dump_file, stmt, 0);
+ print_gimple_stmt (dump_file, stmt, 0, 0);
}
- /* RETURN_EXPR may have an embedded MODIFY_STMT. */
- if (TREE_CODE (stmt) == RETURN_EXPR
- && TREE_CODE (TREE_OPERAND (stmt, 0)) == GIMPLE_MODIFY_STMT)
- stmt = TREE_OPERAND (stmt, 0);
-
- ann = stmt_ann (stmt);
-
/* Handle uninitialized uses. */
- if (IS_EMPTY_STMT (stmt))
- {
- changed = set_ssa_val_to (use, use);
- }
+ if (SSA_NAME_IS_DEFAULT_DEF (use))
+ changed = set_ssa_val_to (use, use);
else
{
- if (TREE_CODE (stmt) == PHI_NODE)
- {
- changed = visit_phi (stmt);
- }
- else if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT
- || (ann && ann->has_volatile_ops)
- || tree_could_throw_p (stmt))
- {
- changed = defs_to_varying (stmt);
- }
- else
+ if (gimple_code (stmt) == GIMPLE_PHI)
+ changed = visit_phi (stmt);
+ else if ((gimple_code (stmt) != GIMPLE_ASSIGN
+ && (gimple_code (stmt) != GIMPLE_CALL
+ || gimple_call_lhs (stmt) == NULL_TREE))
+ || gimple_has_volatile_ops (stmt)
+ || stmt_could_throw_p (stmt))
+ changed = defs_to_varying (stmt);
+ else if (gimple_code (stmt) == GIMPLE_ASSIGN)
{
- tree lhs = GIMPLE_STMT_OPERAND (stmt, 0);
- tree rhs = GIMPLE_STMT_OPERAND (stmt, 1);
+ tree lhs = gimple_assign_lhs (stmt);
tree simplified;
- STRIP_USELESS_TYPE_CONVERSION (rhs);
-
/* Shortcut for copies. Simplifying copies is pointless,
since we copy the expression and value they represent. */
- if (TREE_CODE (rhs) == SSA_NAME && TREE_CODE (lhs) == SSA_NAME)
+ if (gimple_assign_copy_p (stmt)
+ && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
+ && TREE_CODE (lhs) == SSA_NAME)
{
- changed = visit_copy (lhs, rhs);
+ changed = visit_copy (lhs, gimple_assign_rhs1 (stmt));
goto done;
}
- simplified = try_to_simplify (stmt, rhs);
- if (simplified && simplified != rhs)
+ simplified = try_to_simplify (stmt);
+ if (simplified)
{
if (dump_file && (dump_flags & TDF_DETAILS))
{
- fprintf (dump_file, "RHS ");
- print_generic_expr (dump_file, rhs, 0);
+ fprintf (dump_file, "RHS of ");
+ print_gimple_stmt (dump_file, stmt, 0, 0);
fprintf (dump_file, " simplified to ");
print_generic_expr (dump_file, simplified, 0);
if (TREE_CODE (lhs) == SSA_NAME)
@@ -1753,16 +1936,17 @@ visit_use (tree use)
screw up phi congruence because constants are not
uniquely associated with a single ssa name that can be
looked up. */
- if (simplified && is_gimple_min_invariant (simplified)
- && TREE_CODE (lhs) == SSA_NAME
- && simplified != rhs)
+ if (simplified
+ && is_gimple_min_invariant (simplified)
+ && TREE_CODE (lhs) == SSA_NAME)
{
VN_INFO (lhs)->expr = simplified;
VN_INFO (lhs)->has_constants = true;
changed = set_ssa_val_to (lhs, simplified);
goto done;
}
- else if (simplified && TREE_CODE (simplified) == SSA_NAME
+ else if (simplified
+ && TREE_CODE (simplified) == SSA_NAME
&& TREE_CODE (lhs) == SSA_NAME)
{
changed = visit_copy (lhs, simplified);
@@ -1777,13 +1961,10 @@ visit_use (tree use)
valuizing may change the IL stream. */
VN_INFO (lhs)->expr = unshare_expr (simplified);
}
- rhs = simplified;
- }
- else if (expr_has_constants (rhs) && TREE_CODE (lhs) == SSA_NAME)
- {
- VN_INFO (lhs)->has_constants = true;
- VN_INFO (lhs)->expr = unshare_expr (rhs);
}
+ else if (stmt_has_constants (stmt)
+ && TREE_CODE (lhs) == SSA_NAME)
+ VN_INFO (lhs)->has_constants = true;
else if (TREE_CODE (lhs) == SSA_NAME)
{
/* We reset expr and constantness here because we may
@@ -1792,56 +1973,61 @@ visit_use (tree use)
even if they were optimistically constant. */
VN_INFO (lhs)->has_constants = false;
- VN_INFO (lhs)->expr = lhs;
+ VN_INFO (lhs)->expr = NULL_TREE;
}
if (TREE_CODE (lhs) == SSA_NAME
/* We can substitute SSA_NAMEs that are live over
abnormal edges with their constant value. */
- && !is_gimple_min_invariant (rhs)
+ && !(gimple_assign_copy_p (stmt)
+ && is_gimple_min_invariant (gimple_assign_rhs1 (stmt)))
+ && !(simplified
+ && is_gimple_min_invariant (simplified))
&& SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
changed = defs_to_varying (stmt);
else if (REFERENCE_CLASS_P (lhs) || DECL_P (lhs))
{
- changed = visit_reference_op_store (lhs, rhs, stmt);
+ changed = visit_reference_op_store (lhs, gimple_assign_rhs1 (stmt), stmt);
}
else if (TREE_CODE (lhs) == SSA_NAME)
{
- if (is_gimple_min_invariant (rhs))
+ if ((gimple_assign_copy_p (stmt)
+ && is_gimple_min_invariant (gimple_assign_rhs1 (stmt)))
+ || (simplified
+ && is_gimple_min_invariant (simplified)))
{
VN_INFO (lhs)->has_constants = true;
- VN_INFO (lhs)->expr = rhs;
- changed = set_ssa_val_to (lhs, rhs);
+ if (simplified)
+ changed = set_ssa_val_to (lhs, simplified);
+ else
+ changed = set_ssa_val_to (lhs, gimple_assign_rhs1 (stmt));
}
else
{
- switch (TREE_CODE_CLASS (TREE_CODE (rhs)))
+ switch (get_gimple_rhs_class (gimple_assign_rhs_code (stmt)))
{
- case tcc_unary:
- changed = visit_unary_op (lhs, rhs);
- break;
- case tcc_binary:
- changed = visit_binary_op (lhs, rhs);
- break;
- /* If tcc_vl_expr ever encompasses more than
- CALL_EXPR, this will need to be changed. */
- case tcc_vl_exp:
- if (call_expr_flags (rhs) & (ECF_PURE | ECF_CONST))
- changed = visit_reference_op_load (lhs, rhs, stmt);
- else
- changed = defs_to_varying (stmt);
+ case GIMPLE_UNARY_RHS:
+ changed = visit_unary_op (lhs, stmt);
break;
- case tcc_declaration:
- case tcc_reference:
- changed = visit_reference_op_load (lhs, rhs, stmt);
+ case GIMPLE_BINARY_RHS:
+ changed = visit_binary_op (lhs, stmt);
break;
- case tcc_expression:
- if (TREE_CODE (rhs) == ADDR_EXPR)
+ case GIMPLE_SINGLE_RHS:
+ switch (TREE_CODE_CLASS (gimple_assign_rhs_code (stmt)))
{
- changed = visit_unary_op (lhs, rhs);
- goto done;
+ case tcc_declaration:
+ case tcc_reference:
+ changed = visit_reference_op_load
+ (lhs, gimple_assign_rhs1 (stmt), stmt);
+ break;
+ case tcc_expression:
+ if (gimple_assign_rhs_code (stmt) == ADDR_EXPR)
+ changed = visit_unary_op (lhs, stmt);
+ break;
+ default:
+ changed = defs_to_varying (stmt);
}
- /* Fallthrough. */
+ break;
default:
changed = defs_to_varying (stmt);
break;
@@ -1851,6 +2037,39 @@ visit_use (tree use)
else
changed = defs_to_varying (stmt);
}
+ else if (is_gimple_call (stmt))
+ {
+ tree lhs = gimple_call_lhs (stmt);
+
+ /* ??? We could try to simplify calls. */
+
+ if (stmt_has_constants (stmt)
+ && TREE_CODE (lhs) == SSA_NAME)
+ VN_INFO (lhs)->has_constants = true;
+ else if (TREE_CODE (lhs) == SSA_NAME)
+ {
+ /* We reset expr and constantness here because we may
+ have been value numbering optimistically, and
+ iterating. They may become non-constant in this case,
+ even if they were optimistically constant. */
+ VN_INFO (lhs)->has_constants = false;
+ VN_INFO (lhs)->expr = NULL_TREE;
+ }
+
+ if (TREE_CODE (lhs) == SSA_NAME
+ && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
+ changed = defs_to_varying (stmt);
+ /* ??? We should handle stores from calls. */
+ else if (TREE_CODE (lhs) == SSA_NAME)
+ {
+ if (gimple_call_flags (stmt) & (ECF_PURE | ECF_CONST))
+ changed = visit_reference_op_call (lhs, stmt);
+ else
+ changed = defs_to_varying (stmt);
+ }
+ else
+ changed = defs_to_varying (stmt);
+ }
}
done:
return changed;
@@ -1863,16 +2082,16 @@ compare_ops (const void *pa, const void
{
const tree opa = *((const tree *)pa);
const tree opb = *((const tree *)pb);
- tree opstmta = SSA_NAME_DEF_STMT (opa);
- tree opstmtb = SSA_NAME_DEF_STMT (opb);
+ gimple opstmta = SSA_NAME_DEF_STMT (opa);
+ gimple opstmtb = SSA_NAME_DEF_STMT (opb);
basic_block bba;
basic_block bbb;
- if (IS_EMPTY_STMT (opstmta) && IS_EMPTY_STMT (opstmtb))
+ if (gimple_nop_p (opstmta) && gimple_nop_p (opstmtb))
return 0;
- else if (IS_EMPTY_STMT (opstmta))
+ else if (gimple_nop_p (opstmta))
return -1;
- else if (IS_EMPTY_STMT (opstmtb))
+ else if (gimple_nop_p (opstmtb))
return 1;
bba = gimple_bb (opstmta);
@@ -1887,13 +2106,14 @@ compare_ops (const void *pa, const void
if (bba == bbb)
{
- if (TREE_CODE (opstmta) == PHI_NODE && TREE_CODE (opstmtb) == PHI_NODE)
+ if (gimple_code (opstmta) == GIMPLE_PHI
+ && gimple_code (opstmtb) == GIMPLE_PHI)
return 0;
- else if (TREE_CODE (opstmta) == PHI_NODE)
+ else if (gimple_code (opstmta) == GIMPLE_PHI)
return -1;
- else if (TREE_CODE (opstmtb) == PHI_NODE)
+ else if (gimple_code (opstmtb) == GIMPLE_PHI)
return 1;
- return gimple_stmt_uid (opstmta) - gimple_stmt_uid (opstmtb);
+ return gimple_uid (opstmta) - gimple_uid (opstmtb);
}
return rpo_numbers[bba->index] - rpo_numbers[bbb->index];
}
@@ -2019,7 +2239,8 @@ DFS (tree name)
VEC(ssa_op_iter, heap) *itervec = NULL;
VEC(tree, heap) *namevec = NULL;
use_operand_p usep = NULL;
- tree defstmt, use;
+ gimple defstmt;
+ tree use;
ssa_op_iter iter;
start_over:
@@ -2033,10 +2254,10 @@ start_over:
defstmt = SSA_NAME_DEF_STMT (name);
/* Recursively DFS on our operands, looking for SCC's. */
- if (!IS_EMPTY_STMT (defstmt))
+ if (!gimple_nop_p (defstmt))
{
/* Push a new iterator. */
- if (TREE_CODE (defstmt) == PHI_NODE)
+ if (gimple_code (defstmt) == GIMPLE_PHI)
usep = op_iter_init_phiuse (&iter, defstmt, SSA_OP_ALL_USES);
else
usep = op_iter_init_use (&iter, defstmt, SSA_OP_ALL_USES);
@@ -2286,12 +2507,12 @@ run_scc_vn (bool may_insert_arg)
tree name = ssa_name (i);
if (name && VN_INFO (name)->visited
&& (SSA_VAL (name) != name
- || is_gimple_min_invariant (VN_INFO (name)->expr)))
+ || is_gimple_min_invariant (vn_get_expr_for (name))))
{
print_generic_expr (dump_file, name, 0);
fprintf (dump_file, " = ");
- if (is_gimple_min_invariant (VN_INFO (name)->expr))
- print_generic_expr (dump_file, VN_INFO (name)->expr, 0);
+ if (is_gimple_min_invariant (vn_get_expr_for (name)))
+ print_generic_expr (dump_file, vn_get_expr_for (name), 0);
else
print_generic_expr (dump_file, SSA_VAL (name), 0);
fprintf (dump_file, "\n");
@@ -2302,4 +2523,3 @@ run_scc_vn (bool may_insert_arg)
may_insert = false;
return true;
}
-#endif
Index: gcc/tree-ssa-sccvn.h
===================================================================
--- gcc/tree-ssa-sccvn.h.orig 2008-06-24 13:13:07.000000000 +0200
+++ gcc/tree-ssa-sccvn.h 2008-06-24 13:13:34.000000000 +0200
@@ -54,15 +54,18 @@ typedef struct vn_ssa_aux
/* Return the value numbering info for an SSA_NAME. */
extern vn_ssa_aux_t VN_INFO (tree);
extern vn_ssa_aux_t VN_INFO_GET (tree);
+tree vn_get_expr_for (tree);
bool run_scc_vn (bool);
void free_scc_vn (void);
void switch_to_PRE_table (void);
tree vn_nary_op_lookup (tree);
+tree vn_nary_op_lookup_stmt (gimple);
void vn_nary_op_insert (tree, tree);
+void vn_nary_op_insert_stmt (gimple, tree);
tree vn_reference_lookup (tree, VEC (tree, gc) *, bool);
void vn_reference_insert (tree, tree, VEC (tree, gc) *);
-VEC (tree, gc) *shared_vuses_from_stmt (tree);
-VEC (tree, gc) *copy_vuses_from_stmt (tree);
+VEC (tree, gc) *shared_vuses_from_stmt (gimple);
+VEC (tree, gc) *copy_vuses_from_stmt (gimple);
#endif /* TREE_SSA_SCCVN_H */
Index: gcc/tree-dfa.c
===================================================================
--- gcc/tree-dfa.c.orig 2008-06-24 13:13:07.000000000 +0200
+++ gcc/tree-dfa.c 2008-06-24 13:22:26.000000000 +0200
@@ -1092,8 +1092,6 @@ refs_may_alias_p (tree ref1, tree ref2)
return true;
}
-/* FIXME tuples */
-#if 0
/* Given a stmt STMT that references memory, return the single stmt
that is reached by following the VUSE -> VDEF link. Returns
NULL_TREE, if there is no single stmt that defines all VUSEs of
@@ -1102,25 +1100,25 @@ refs_may_alias_p (tree ref1, tree ref2)
a PHI node as well. Note that if all VUSEs are default definitions
this function will return an empty statement. */
-tree
-get_single_def_stmt (tree stmt)
+gimple
+get_single_def_stmt (gimple stmt)
{
- tree def_stmt = NULL_TREE;
+ gimple def_stmt = NULL;
tree use;
ssa_op_iter iter;
FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_VIRTUAL_USES)
{
- tree tmp = SSA_NAME_DEF_STMT (use);
+ gimple tmp = SSA_NAME_DEF_STMT (use);
/* ??? This is too simplistic for multiple virtual operands
reaching different PHI nodes of the same basic blocks or for
reaching all default definitions. */
if (def_stmt
&& def_stmt != tmp
- && !(IS_EMPTY_STMT (def_stmt)
- && IS_EMPTY_STMT (tmp)))
- return NULL_TREE;
+ && !(gimple_nop_p (def_stmt)
+ && gimple_nop_p (tmp)))
+ return NULL;
def_stmt = tmp;
}
@@ -1134,25 +1132,25 @@ get_single_def_stmt (tree stmt)
from a non-backedge. Returns NULL_TREE if such statement within
the above conditions cannot be found. */
-tree
-get_single_def_stmt_from_phi (tree ref, tree phi)
+gimple
+get_single_def_stmt_from_phi (tree ref, gimple phi)
{
tree def_arg = NULL_TREE;
- int i;
+ unsigned i;
/* Find the single PHI argument that is not flowing in from a
back edge and verify that the loop-carried definitions do
not alias the reference we look for. */
- for (i = 0; i < PHI_NUM_ARGS (phi); ++i)
+ for (i = 0; i < gimple_phi_num_args (phi); ++i)
{
tree arg = PHI_ARG_DEF (phi, i);
- tree def_stmt;
+ gimple def_stmt;
- if (!(PHI_ARG_EDGE (phi, i)->flags & EDGE_DFS_BACK))
+ if (!(gimple_phi_arg_edge (phi, i)->flags & EDGE_DFS_BACK))
{
/* Multiple non-back edges? Do not try to handle this. */
if (def_arg)
- return NULL_TREE;
+ return NULL;
def_arg = arg;
continue;
}
@@ -1162,14 +1160,14 @@ get_single_def_stmt_from_phi (tree ref,
def_stmt = SSA_NAME_DEF_STMT (arg);
do
{
- if (TREE_CODE (def_stmt) != GIMPLE_MODIFY_STMT
- || refs_may_alias_p (ref, GIMPLE_STMT_OPERAND (def_stmt, 0)))
- return NULL_TREE;
+ if (!is_gimple_assign (def_stmt)
+ || refs_may_alias_p (ref, gimple_assign_lhs (def_stmt)))
+ return NULL;
/* ??? This will only work, reaching the PHI node again if
there is a single virtual operand on def_stmt. */
def_stmt = get_single_def_stmt (def_stmt);
if (!def_stmt)
- return NULL_TREE;
+ return NULL;
}
while (def_stmt != phi);
}
@@ -1182,8 +1180,8 @@ get_single_def_stmt_from_phi (tree ref,
Take into account only definitions that alias REF if following
back-edges when looking through a loop PHI node. */
-tree
-get_single_def_stmt_with_phi (tree ref, tree stmt)
+gimple
+get_single_def_stmt_with_phi (tree ref, gimple stmt)
{
switch (NUM_SSA_OPERANDS (stmt, SSA_OP_VIRTUAL_USES))
{
@@ -1192,11 +1190,11 @@ get_single_def_stmt_with_phi (tree ref,
case 1:
{
- tree def_stmt = SSA_NAME_DEF_STMT (SINGLE_SSA_TREE_OPERAND
+ gimple def_stmt = SSA_NAME_DEF_STMT (SINGLE_SSA_TREE_OPERAND
(stmt, SSA_OP_VIRTUAL_USES));
/* We can handle lookups over PHI nodes only for a single
virtual operand. */
- if (TREE_CODE (def_stmt) == PHI_NODE)
+ if (gimple_code (def_stmt) == GIMPLE_PHI)
return get_single_def_stmt_from_phi (ref, def_stmt);
return def_stmt;
}
@@ -1205,4 +1203,3 @@ get_single_def_stmt_with_phi (tree ref,
return get_single_def_stmt (stmt);
}
}
-#endif
Index: gcc/tree-ssa-pre.c
===================================================================
--- gcc/tree-ssa-pre.c.orig 2008-06-24 13:13:07.000000000 +0200
+++ gcc/tree-ssa-pre.c 2008-06-24 15:50:55.000000000 +0200
@@ -3583,7 +3583,7 @@ do_SCCVN_insertion (tree stmt, tree ssa_
/* First create a value expression from the expression we want
to insert and associate it with the value handle for SSA_VN. */
- expr = create_value_expr_from (VN_INFO (ssa_vn)->expr, bb, NULL, true);
+ expr = create_value_expr_from (vn_get_expr_for (ssa_vn), bb, NULL, true);
if (expr == NULL_TREE)
return NULL_TREE;
set_value_handle (expr, get_value_handle (ssa_vn));
@@ -3641,7 +3641,7 @@ eliminate (void)
tree val = VN_INFO (lhs)->valnum;
if (val != VN_TOP
&& VN_INFO (val)->needs_insertion
- && can_PRE_operation (VN_INFO (val)->expr))
+ && can_PRE_operation (vn_get_expr_for (val)))
sprime = do_SCCVN_insertion (stmt, val);
}
@@ -3972,6 +3972,10 @@ static unsigned int
execute_pre (bool do_fre ATTRIBUTE_UNUSED)
{
/* FIXME tuples. */
+ if (run_scc_vn (do_fre))
+ free_scc_vn ();
+
+ /* FIXME tuples. */
#if 0
unsigned int todo = 0;
@@ -4038,8 +4042,6 @@ execute_pre (bool do_fre ATTRIBUTE_UNUSE
fini_pre ();
return todo;
-#else
- gimple_unreachable ();
#endif
return 0;
}
@@ -4091,12 +4093,7 @@ execute_fre (void)
static bool
gate_fre (void)
{
- /* FIXME tuples */
-#if 0
return flag_tree_fre != 0;
-#else
- return 0;
-#endif
}
struct gimple_opt_pass pass_fre =
Index: gcc/tree-flow.h
===================================================================
--- gcc/tree-flow.h.orig 2008-06-24 13:13:07.000000000 +0200
+++ gcc/tree-flow.h 2008-06-24 13:57:37.000000000 +0200
@@ -775,9 +775,9 @@ extern void set_default_def (tree, tree)
extern tree gimple_default_def (struct function *, tree);
extern bool stmt_references_abnormal_ssa_name (gimple);
extern bool refs_may_alias_p (tree, tree);
-extern tree get_single_def_stmt (tree);
-extern tree get_single_def_stmt_from_phi (tree, tree);
-extern tree get_single_def_stmt_with_phi (tree, tree);
+extern gimple get_single_def_stmt (gimple);
+extern gimple get_single_def_stmt_from_phi (tree, gimple);
+extern gimple get_single_def_stmt_with_phi (tree, gimple);
/* In tree-phinodes.c */
extern void reserve_phi_args_for_new_edge (basic_block);
@@ -1093,11 +1093,11 @@ static inline tree get_value_handle (tre
void sort_vuses (VEC (tree, gc) *);
void sort_vuses_heap (VEC (tree, heap) *);
tree vn_lookup_or_add (tree);
-tree vn_lookup_or_add_with_stmt (tree, tree);
+tree vn_lookup_or_add_with_stmt (tree, gimple);
tree vn_lookup_or_add_with_vuses (tree, VEC (tree, gc) *);
void vn_add (tree, tree);
void vn_add_with_vuses (tree, tree, VEC (tree, gc) *);
-tree vn_lookup_with_stmt (tree, tree);
+tree vn_lookup_with_stmt (tree, gimple);
tree vn_lookup (tree);
tree vn_lookup_with_vuses (tree, VEC (tree, gc) *);
Index: gcc/gimple.c
===================================================================
--- gcc/gimple.c.orig 2008-06-24 13:13:07.000000000 +0200
+++ gcc/gimple.c 2008-06-24 14:53:15.000000000 +0200
@@ -1878,8 +1878,6 @@ gimple_set_bb (gimple stmt, basic_block
tree
gimple_fold (const_gimple stmt)
{
- tree t;
-
switch (gimple_code (stmt))
{
case GIMPLE_COND:
@@ -1887,28 +1885,30 @@ gimple_fold (const_gimple stmt)
boolean_type_node,
gimple_cond_lhs (stmt),
gimple_cond_rhs (stmt));
- break;
case GIMPLE_ASSIGN:
- if (gimple_num_ops (stmt) > 2)
- return fold_binary (gimple_assign_rhs_code (stmt),
- TREE_TYPE (gimple_assign_lhs (stmt)),
- gimple_assign_rhs1 (stmt),
- gimple_assign_rhs2 (stmt));
- else
- return fold_unary (gimple_assign_rhs_code (stmt),
- TREE_TYPE (gimple_assign_lhs (stmt)),
- gimple_assign_rhs1 (stmt));
+ switch (get_gimple_rhs_class (gimple_assign_rhs_code (stmt)))
+ {
+ case GIMPLE_UNARY_RHS:
+ return fold_unary (gimple_assign_rhs_code (stmt),
+ TREE_TYPE (gimple_assign_lhs (stmt)),
+ gimple_assign_rhs1 (stmt));
+ case GIMPLE_BINARY_RHS:
+ return fold_binary (gimple_assign_rhs_code (stmt),
+ TREE_TYPE (gimple_assign_lhs (stmt)),
+ gimple_assign_rhs1 (stmt),
+ gimple_assign_rhs2 (stmt));
+ case GIMPLE_SINGLE_RHS:
+ return fold (gimple_assign_rhs1 (stmt));
+ default:;
+ }
break;
case GIMPLE_SWITCH:
return gimple_switch_index (stmt);
- break;
case GIMPLE_CALL:
- t = gimple_call_fn (stmt);
- return fold_unary (TREE_CODE (t), TREE_TYPE (t), t);
- break;
+ return NULL_TREE;
default:
break;
Index: gcc/tree-vn.c
===================================================================
--- gcc/tree-vn.c.orig 2008-06-24 13:13:33.000000000 +0200
+++ gcc/tree-vn.c 2008-06-24 13:57:00.000000000 +0200
@@ -208,8 +208,11 @@ vn_add (tree expr, tree val)
gcc_unreachable ();
}
set_value_handle (expr, val);
+ /* FIXME: tuples. */
+#if 0
if (TREE_CODE (val) == VALUE_HANDLE)
add_to_value (val, expr);
+#endif
}
/* Insert EXPR into the value numbering tables with value VAL, and
@@ -228,8 +231,11 @@ vn_add_with_vuses (tree expr, tree val,
vn_reference_insert (expr, val, vuses);
set_value_handle (expr, val);
+ /* FIXME: tuples. */
+#if 0
if (TREE_CODE (val) == VALUE_HANDLE)
add_to_value (val, expr);
+#endif
}
@@ -281,7 +287,7 @@ vn_lookup (tree expr)
hash value for EXPR for reference operations. */
tree
-vn_lookup_with_stmt (tree expr, tree stmt)
+vn_lookup_with_stmt (tree expr, gimple stmt)
{
if (stmt == NULL)
return vn_lookup (expr);
@@ -347,7 +353,7 @@ vn_lookup_or_add (tree expr)
STMT to get the set of vuses. */
tree
-vn_lookup_or_add_with_stmt (tree expr, tree stmt)
+vn_lookup_or_add_with_stmt (tree expr, gimple stmt)
{
tree v;
if (!stmt)