* [PATCH][tuples] Tuplify SCCVN
@ 2008-06-24 15:04 Richard Guenther
2008-06-27 16:45 ` Diego Novillo
0 siblings, 1 reply; 3+ messages in thread
From: Richard Guenther @ 2008-06-24 15:04 UTC (permalink / raw)
To: gcc-patches; +Cc: Diego Novillo
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)
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH][tuples] Tuplify SCCVN
2008-06-24 15:04 [PATCH][tuples] Tuplify SCCVN Richard Guenther
@ 2008-06-27 16:45 ` Diego Novillo
2008-06-27 17:25 ` Richard Guenther
0 siblings, 1 reply; 3+ messages in thread
From: Diego Novillo @ 2008-06-27 16:45 UTC (permalink / raw)
To: Richard Guenther; +Cc: gcc-patches
On Tue, Jun 24, 2008 at 10:32, Richard Guenther <rguenther@suse.de> wrote:
> Ok for tuples? (I appreciate a review as I'm only getting familiar
> with the new API)
Yes. The GIMPLE bits look fine. Thanks for the conversion.
Diego.
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH][tuples] Tuplify SCCVN
2008-06-27 16:45 ` Diego Novillo
@ 2008-06-27 17:25 ` Richard Guenther
0 siblings, 0 replies; 3+ messages in thread
From: Richard Guenther @ 2008-06-27 17:25 UTC (permalink / raw)
To: Diego Novillo; +Cc: gcc-patches
On Fri, 27 Jun 2008, Diego Novillo wrote:
> On Tue, Jun 24, 2008 at 10:32, Richard Guenther <rguenther@suse.de> wrote:
>
>> Ok for tuples? (I appreciate a review as I'm only getting familiar
>> with the new API)
>
> Yes. The GIMPLE bits look fine. Thanks for the conversion.
This is what I committed (it needed changes with your gimple_subcode
reorg). I'm somewhat stuck with FRE and hope Danny gets along
committing his PRE/FRE rewrite on the trunk soon - that should
really help.
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-25 17:43:11.000000000 +0200
--- gcc/tree-ssa-sccvn.c 2008-06-26 12:07:10.000000000 +0200
*************** along with GCC; see the file COPYING3.
*** 46,53 ****
#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
--- 46,51 ----
*************** VN_INFO_GET (tree name)
*** 274,279 ****
--- 272,326 ----
}
+ /* 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
*************** vn_reference_eq (const void *p1, const v
*** 391,397 ****
/* Place the vuses from STMT into *result */
static inline void
! vuses_to_vec (tree stmt, VEC (tree, gc) **result)
{
ssa_op_iter iter;
tree vuse;
--- 438,444 ----
/* Place the vuses from STMT into *result */
static inline void
! vuses_to_vec (gimple stmt, VEC (tree, gc) **result)
{
ssa_op_iter iter;
tree vuse;
*************** vuses_to_vec (tree stmt, VEC (tree, gc)
*** 411,417 ****
the vector. */
VEC (tree, gc) *
! copy_vuses_from_stmt (tree stmt)
{
VEC (tree, gc) *vuses = NULL;
--- 458,464 ----
the vector. */
VEC (tree, gc) *
! copy_vuses_from_stmt (gimple stmt)
{
VEC (tree, gc) *vuses = NULL;
*************** copy_vuses_from_stmt (tree stmt)
*** 423,429 ****
/* Place the vdefs from STMT into *result */
static inline void
! vdefs_to_vec (tree stmt, VEC (tree, gc) **result)
{
ssa_op_iter iter;
tree vdef;
--- 470,476 ----
/* Place the vdefs from STMT into *result */
static inline void
! vdefs_to_vec (gimple stmt, VEC (tree, gc) **result)
{
ssa_op_iter iter;
tree vdef;
*************** vdefs_to_vec (tree stmt, VEC (tree, gc)
*** 441,447 ****
the vector. */
static VEC (tree, gc) *
! copy_vdefs_from_stmt (tree stmt)
{
VEC (tree, gc) *vdefs = NULL;
--- 488,494 ----
the vector. */
static VEC (tree, gc) *
! copy_vdefs_from_stmt (gimple stmt)
{
VEC (tree, gc) *vdefs = NULL;
*************** static VEC (tree, gc) *shared_lookup_vop
*** 458,464 ****
variable. */
VEC (tree, gc) *
! shared_vuses_from_stmt (tree stmt)
{
VEC_truncate (tree, shared_lookup_vops, 0);
vuses_to_vec (stmt, &shared_lookup_vops);
--- 505,511 ----
variable. */
VEC (tree, gc) *
! shared_vuses_from_stmt (gimple stmt)
{
VEC_truncate (tree, shared_lookup_vops, 0);
vuses_to_vec (stmt, &shared_lookup_vops);
*************** shared_vuses_from_stmt (tree stmt)
*** 466,511 ****
return shared_lookup_vops;
}
! /* 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_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;
--- 513,524 ----
return shared_lookup_vops;
}
! /* 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)
{
if (TREE_CODE (ref) == TARGET_MEM_REF)
{
vn_reference_op_s temp;
*************** copy_reference_ops_from_ref (tree ref, V
*** 612,617 ****
--- 625,666 ----
}
}
+ /* 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. */
*************** create_reference_ops_from_ref (tree ref)
*** 624,629 ****
--- 673,690 ----
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
*************** shared_reference_ops_from_ref (tree ref)
*** 640,645 ****
--- 701,720 ----
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
*************** valueize_vuses (VEC (tree, gc) *orig)
*** 692,707 ****
Take into account only definitions that alias REF if following
back-edges. */
! static tree
get_def_ref_stmt_vuses (tree ref, VEC (tree, gc) *vuses)
{
! tree def_stmt, 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)
{
/* We can only handle lookups over PHI nodes for a single
virtual operand. */
--- 767,783 ----
Take into account only definitions that alias REF if following
back-edges. */
! static gimple
get_def_ref_stmt_vuses (tree ref, VEC (tree, gc) *vuses)
{
! 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 (gimple_code (def_stmt) == GIMPLE_PHI)
{
/* We can only handle lookups over PHI nodes for a single
virtual operand. */
*************** get_def_ref_stmt_vuses (tree ref, VEC (t
*** 711,733 ****
goto cont;
}
else
! return NULL_TREE;
}
/* 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);
if (tmp != def_stmt)
! return NULL_TREE;
}
/* 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)))
def_stmt = get_single_def_stmt_with_phi (ref, def_stmt);
return def_stmt;
--- 787,808 ----
goto cont;
}
else
! return NULL;
}
/* Verify each VUSE reaches the same defining stmt. */
for (i = 1; VEC_iterate (tree, vuses, i, vuse); ++i)
{
! gimple tmp = SSA_NAME_DEF_STMT (vuse);
if (tmp != def_stmt)
! return NULL;
}
/* Now see if the definition aliases ref, and loop until it does. */
cont:
while (def_stmt
! && 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;
*************** tree
*** 763,769 ****
vn_reference_lookup (tree op, VEC (tree, gc) *vuses, bool maywalk)
{
struct vn_reference_s vr1;
! tree result, def_stmt;
vr1.vuses = valueize_vuses (vuses);
vr1.operands = valueize_refs (shared_reference_ops_from_ref (op));
--- 838,845 ----
vn_reference_lookup (tree op, VEC (tree, gc) *vuses, bool maywalk)
{
struct vn_reference_s vr1;
! tree result;
! gimple def_stmt;
vr1.vuses = valueize_vuses (vuses);
vr1.operands = valueize_refs (shared_reference_ops_from_ref (op));
*************** vn_reference_lookup (tree op, VEC (tree,
*** 776,787 ****
&& 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))
{
/* 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. */
--- 852,859 ----
&& maywalk
&& vr1.vuses
&& VEC_length (tree, vr1.vuses) >= 1
&& (def_stmt = get_def_ref_stmt_vuses (op, vr1.vuses))
! && 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. */
*************** vn_nary_op_lookup (tree op)
*** 912,917 ****
--- 984,1016 ----
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_assign_rhs_code (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. */
*************** vn_nary_op_insert (tree op, tree result)
*** 940,945 ****
--- 1039,1072 ----
*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_assign_rhs_code (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
*************** static VEC(tree, heap) *shared_lookup_ph
*** 1005,1020 ****
it does not exist in the hash table. */
static tree
! vn_phi_lookup (tree phi)
{
void **slot;
struct vn_phi_s vp1;
! int 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++)
{
tree def = PHI_ARG_DEF (phi, i);
def = TREE_CODE (def) == SSA_NAME ? SSA_VAL (def) : def;
--- 1132,1147 ----
it does not exist in the hash table. */
static tree
! vn_phi_lookup (gimple phi)
{
void **slot;
struct vn_phi_s vp1;
! unsigned i;
VEC_truncate (tree, shared_lookup_phiargs, 0);
/* Canonicalize the SSA_NAME's to their value number. */
! 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;
*************** vn_phi_lookup (tree phi)
*** 1037,1051 ****
RESULT. */
static void
! vn_phi_insert (tree phi, tree result)
{
void **slot;
vn_phi_t vp1 = (vn_phi_t) pool_alloc (current_info->phis_pool);
! int i;
VEC (tree, heap) *args = NULL;
/* Canonicalize the SSA_NAME's to their value number. */
! for (i = 0; i < PHI_NUM_ARGS (phi); i++)
{
tree def = PHI_ARG_DEF (phi, i);
def = TREE_CODE (def) == SSA_NAME ? SSA_VAL (def) : def;
--- 1164,1178 ----
RESULT. */
static void
! vn_phi_insert (gimple phi, tree result)
{
void **slot;
vn_phi_t vp1 = (vn_phi_t) pool_alloc (current_info->phis_pool);
! unsigned i;
VEC (tree, heap) *args = NULL;
/* Canonicalize the SSA_NAME's to their value number. */
! 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;
*************** set_ssa_val_to (tree from, tree to)
*** 1125,1131 ****
Return true if a value number changed. */
static bool
! defs_to_varying (tree stmt)
{
bool changed = false;
ssa_op_iter iter;
--- 1252,1258 ----
Return true if a value number changed. */
static bool
! defs_to_varying (gimple stmt)
{
bool changed = false;
ssa_op_iter iter;
*************** defs_to_varying (tree stmt)
*** 1142,1148 ****
}
static bool expr_has_constants (tree expr);
! static tree try_to_simplify (tree stmt, tree rhs);
/* Visit a copy between LHS and RHS, return true if the value number
changed. */
--- 1269,1275 ----
}
static bool expr_has_constants (tree expr);
! static tree try_to_simplify (gimple stmt);
/* Visit a copy between LHS and RHS, return true if the value number
changed. */
*************** static tree try_to_simplify (tree stmt,
*** 1150,1156 ****
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);
--- 1277,1282 ----
*************** visit_copy (tree lhs, tree rhs)
*** 1167,1176 ****
value number of LHS has changed as a result. */
static bool
! visit_unary_op (tree lhs, tree op)
{
bool changed = false;
! tree result = vn_nary_op_lookup (op);
if (result)
{
--- 1293,1302 ----
value number of LHS has changed as a result. */
static bool
! visit_unary_op (tree lhs, gimple stmt)
{
bool changed = false;
! tree result = vn_nary_op_lookup_stmt (stmt);
if (result)
{
*************** visit_unary_op (tree lhs, tree op)
*** 1179,1185 ****
else
{
changed = set_ssa_val_to (lhs, lhs);
! vn_nary_op_insert (op, lhs);
}
return changed;
--- 1305,1311 ----
else
{
changed = set_ssa_val_to (lhs, lhs);
! vn_nary_op_insert_stmt (stmt, lhs);
}
return changed;
*************** visit_unary_op (tree lhs, tree op)
*** 1189,1198 ****
value number of LHS has changed as a result. */
static bool
! visit_binary_op (tree lhs, tree op)
{
bool changed = false;
! tree result = vn_nary_op_lookup (op);
if (result)
{
--- 1315,1324 ----
value number of LHS has changed as a result. */
static bool
! visit_binary_op (tree lhs, gimple stmt)
{
bool changed = false;
! tree result = vn_nary_op_lookup_stmt (stmt);
if (result)
{
*************** visit_binary_op (tree lhs, tree op)
*** 1201,1207 ****
else
{
changed = set_ssa_val_to (lhs, lhs);
! vn_nary_op_insert (op, lhs);
}
return changed;
--- 1327,1374 ----
else
{
changed = set_ssa_val_to (lhs, 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;
*************** visit_binary_op (tree lhs, tree op)
*** 1211,1217 ****
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)
{
bool changed = false;
tree result = vn_reference_lookup (op, shared_vuses_from_stmt (stmt), true);
--- 1378,1384 ----
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, gimple stmt)
{
bool changed = false;
tree result = vn_reference_lookup (op, shared_vuses_from_stmt (stmt), true);
*************** visit_reference_op_load (tree lhs, tree
*** 1231,1237 ****
&& !is_gimple_min_invariant (val)
&& TREE_CODE (val) != SSA_NAME)
{
! tree tem = try_to_simplify (stmt, val);
if (tem)
val = tem;
}
--- 1398,1404 ----
&& !is_gimple_min_invariant (val)
&& TREE_CODE (val) != SSA_NAME)
{
! tree tem = try_to_simplify (stmt);
if (tem)
val = tem;
}
*************** visit_reference_op_load (tree lhs, tree
*** 1243,1249 ****
a new SSA_NAME we create. */
if (!result && may_insert)
{
! result = make_ssa_name (SSA_NAME_VAR (lhs), NULL_TREE);
/* Initialize value-number information properly. */
VN_INFO_GET (result)->valnum = result;
VN_INFO (result)->expr = val;
--- 1410,1416 ----
a new SSA_NAME we create. */
if (!result && may_insert)
{
! 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;
*************** visit_reference_op_load (tree lhs, tree
*** 1299,1305 ****
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)
{
bool changed = false;
tree result;
--- 1466,1472 ----
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, gimple stmt)
{
bool changed = false;
tree result;
*************** visit_reference_op_store (tree lhs, tree
*** 1397,1409 ****
changed. */
static bool
! visit_phi (tree phi)
{
bool changed = false;
tree result;
tree sameval = VN_TOP;
bool allsame = true;
! int i;
/* TODO: We could check for this in init_sccvn, and replace this
with a gcc_assert. */
--- 1564,1576 ----
changed. */
static bool
! visit_phi (gimple phi)
{
bool changed = false;
tree result;
tree sameval = VN_TOP;
bool allsame = true;
! unsigned i;
/* TODO: We could check for this in init_sccvn, and replace this
with a gcc_assert. */
*************** visit_phi (tree phi)
*** 1412,1418 ****
/* 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++)
{
tree def = PHI_ARG_DEF (phi, i);
--- 1579,1585 ----
/* See if all non-TOP arguments have the same value. TOP is
equivalent to everything, so we can ignore it. */
! for (i = 0; i < gimple_phi_num_args (phi); i++)
{
tree def = PHI_ARG_DEF (phi, i);
*************** expr_has_constants (tree expr)
*** 1499,1504 ****
--- 1666,1697 ----
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. */
*************** valueize_expr (tree expr)
*** 1531,1541 ****
simplified. */
static tree
! simplify_binary_expression (tree stmt, tree rhs)
{
tree result = NULL_TREE;
! tree op0 = TREE_OPERAND (rhs, 0);
! tree op1 = TREE_OPERAND (rhs, 1);
/* This will not catch every single case we could combine, but will
catch those with constants. The goal here is to simultaneously
--- 1724,1734 ----
simplified. */
static tree
! simplify_binary_expression (gimple stmt)
{
tree result = NULL_TREE;
! 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
*************** simplify_binary_expression (tree stmt, t
*** 1544,1550 ****
if (TREE_CODE (op0) == SSA_NAME)
{
if (VN_INFO (op0)->has_constants)
! op0 = valueize_expr (VN_INFO (op0)->expr);
else if (SSA_VAL (op0) != VN_TOP && SSA_VAL (op0) != op0)
op0 = SSA_VAL (op0);
}
--- 1737,1743 ----
if (TREE_CODE (op0) == SSA_NAME)
{
if (VN_INFO (op0)->has_constants)
! op0 = valueize_expr (vn_get_expr_for (op0));
else if (SSA_VAL (op0) != VN_TOP && SSA_VAL (op0) != op0)
op0 = SSA_VAL (op0);
}
*************** simplify_binary_expression (tree stmt, t
*** 1552,1570 ****
if (TREE_CODE (op1) == SSA_NAME)
{
if (VN_INFO (op1)->has_constants)
! op1 = valueize_expr (VN_INFO (op1)->expr);
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))
return NULL_TREE;
fold_defer_overflow_warnings ();
! result = fold_binary (TREE_CODE (rhs), TREE_TYPE (rhs), op0, op1);
fold_undefer_overflow_warnings (result && valid_gimple_expression_p (result),
stmt, 0);
--- 1745,1764 ----
if (TREE_CODE (op1) == SSA_NAME)
{
if (VN_INFO (op1)->has_constants)
! 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 == gimple_assign_rhs1 (stmt)
! && op1 == gimple_assign_rhs2 (stmt))
return NULL_TREE;
fold_defer_overflow_warnings ();
! result = fold_binary (gimple_assign_rhs_code (stmt),
! TREE_TYPE (gimple_get_lhs (stmt)), op0, op1);
fold_undefer_overflow_warnings (result && valid_gimple_expression_p (result),
stmt, 0);
*************** simplify_binary_expression (tree stmt, t
*** 1583,1606 ****
simplified. */
static tree
! simplify_unary_expression (tree rhs)
{
tree result = NULL_TREE;
! tree op0 = TREE_OPERAND (rhs, 0);
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)
{
/* 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);
if (UNARY_CLASS_P (tem)
|| BINARY_CLASS_P (tem)
|| TREE_CODE (tem) == VIEW_CONVERT_EXPR
--- 1777,1800 ----
simplified. */
static tree
! simplify_unary_expression (gimple stmt)
{
tree result = NULL_TREE;
! 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_get_expr_for (op0));
! else if (gimple_assign_cast_p (stmt)
! || gimple_assign_rhs_code (stmt) == REALPART_EXPR
! || gimple_assign_rhs_code (stmt) == IMAGPART_EXPR
! || gimple_assign_rhs_code (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_get_expr_for (op0));
if (UNARY_CLASS_P (tem)
|| BINARY_CLASS_P (tem)
|| TREE_CODE (tem) == VIEW_CONVERT_EXPR
*************** simplify_unary_expression (tree rhs)
*** 1610,1619 ****
}
/* Avoid folding if nothing changed, but remember the expression. */
! if (op0 == TREE_OPERAND (rhs, 0))
! return rhs;
! result = fold_unary (TREE_CODE (rhs), TREE_TYPE (rhs), op0);
if (result)
{
STRIP_USELESS_TYPE_CONVERSION (result);
--- 1804,1814 ----
}
/* Avoid folding if nothing changed, but remember the expression. */
! if (op0 == gimple_assign_rhs1 (stmt))
! return NULL_TREE;
! result = fold_unary (gimple_assign_rhs_code (stmt),
! TREE_TYPE (gimple_get_lhs (stmt)), op0);
if (result)
{
STRIP_USELESS_TYPE_CONVERSION (result);
*************** simplify_unary_expression (tree rhs)
*** 1621,1645 ****
return result;
}
! return rhs;
}
/* Try to simplify RHS using equivalences and constant folding. */
static tree
! try_to_simplify (tree stmt, tree rhs)
{
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;
! switch (TREE_CODE_CLASS (TREE_CODE (rhs)))
{
case tcc_declaration:
! tem = get_symbol_constant_value (rhs);
if (tem)
return tem;
break;
--- 1816,1841 ----
return result;
}
! return NULL_TREE;
}
/* Try to simplify RHS using equivalences and constant folding. */
static tree
! 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 (gimple_assign_copy_p (stmt)
! && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME)
! return NULL_TREE;
! switch (TREE_CODE_CLASS (gimple_assign_rhs_code (stmt)))
{
case tcc_declaration:
! tem = get_symbol_constant_value (gimple_assign_rhs1 (stmt));
if (tem)
return tem;
break;
*************** try_to_simplify (tree stmt, tree rhs)
*** 1647,1675 ****
case tcc_reference:
/* Do not do full-blown reference lookup here, but simplify
reads from constant aggregates. */
! tem = fold_const_aggregate_ref (rhs);
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))
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);
break;
case tcc_comparison:
case tcc_binary:
! return simplify_binary_expression (stmt, rhs);
break;
default:
break;
}
! return rhs;
}
/* Visit and value number USE, return true if the value number
--- 1843,1871 ----
case tcc_reference:
/* Do not do full-blown reference lookup here, but simplify
reads from constant aggregates. */
! 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 (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 (stmt);
break;
case tcc_comparison:
case tcc_binary:
! return simplify_binary_expression (stmt);
break;
default:
break;
}
! return NULL_TREE;
}
/* Visit and value number USE, return true if the value number
*************** static bool
*** 1679,1745 ****
visit_use (tree use)
{
bool changed = false;
! tree stmt = SSA_NAME_DEF_STMT (use);
! stmt_ann_t ann;
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))
{
fprintf (dump_file, "Value numbering ");
print_generic_expr (dump_file, use, 0);
fprintf (dump_file, " stmt = ");
! print_generic_stmt (dump_file, stmt, 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);
! }
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
{
! tree lhs = GIMPLE_STMT_OPERAND (stmt, 0);
! tree rhs = GIMPLE_STMT_OPERAND (stmt, 1);
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)
{
! changed = visit_copy (lhs, rhs);
goto done;
}
! simplified = try_to_simplify (stmt, rhs);
! if (simplified && simplified != rhs)
{
if (dump_file && (dump_flags & TDF_DETAILS))
{
! fprintf (dump_file, "RHS ");
! print_generic_expr (dump_file, rhs, 0);
fprintf (dump_file, " simplified to ");
print_generic_expr (dump_file, simplified, 0);
if (TREE_CODE (lhs) == SSA_NAME)
--- 1875,1928 ----
visit_use (tree use)
{
bool changed = false;
! 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)
! && !SSA_NAME_IS_DEFAULT_DEF (use))
{
fprintf (dump_file, "Value numbering ");
print_generic_expr (dump_file, use, 0);
fprintf (dump_file, " stmt = ");
! print_gimple_stmt (dump_file, stmt, 0, 0);
}
/* Handle uninitialized uses. */
! if (SSA_NAME_IS_DEFAULT_DEF (use))
! changed = set_ssa_val_to (use, use);
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_assign_lhs (stmt);
tree simplified;
/* Shortcut for copies. Simplifying copies is pointless,
since we copy the expression and value they represent. */
! if (gimple_assign_copy_p (stmt)
! && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
! && TREE_CODE (lhs) == SSA_NAME)
{
! changed = visit_copy (lhs, gimple_assign_rhs1 (stmt));
goto done;
}
! simplified = try_to_simplify (stmt);
! if (simplified)
{
if (dump_file && (dump_flags & TDF_DETAILS))
{
! 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)
*************** visit_use (tree use)
*** 1753,1768 ****
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)
{
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
&& TREE_CODE (lhs) == SSA_NAME)
{
changed = visit_copy (lhs, simplified);
--- 1936,1952 ----
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)
{
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
&& TREE_CODE (lhs) == SSA_NAME)
{
changed = visit_copy (lhs, simplified);
*************** visit_use (tree use)
*** 1777,1789 ****
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 (TREE_CODE (lhs) == SSA_NAME)
{
/* We reset expr and constantness here because we may
--- 1961,1970 ----
valuizing may change the IL stream. */
VN_INFO (lhs)->expr = unshare_expr (simplified);
}
}
+ 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
*************** visit_use (tree use)
*** 1792,1847 ****
even if they were optimistically constant. */
VN_INFO (lhs)->has_constants = false;
! VN_INFO (lhs)->expr = lhs;
}
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)
&& 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);
}
else if (TREE_CODE (lhs) == SSA_NAME)
{
! if (is_gimple_min_invariant (rhs))
{
VN_INFO (lhs)->has_constants = true;
! VN_INFO (lhs)->expr = rhs;
! changed = set_ssa_val_to (lhs, rhs);
}
else
{
! switch (TREE_CODE_CLASS (TREE_CODE (rhs)))
{
! 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);
break;
! case tcc_declaration:
! case tcc_reference:
! changed = visit_reference_op_load (lhs, rhs, stmt);
break;
! case tcc_expression:
! if (TREE_CODE (rhs) == ADDR_EXPR)
{
! changed = visit_unary_op (lhs, rhs);
! goto done;
}
! /* Fallthrough. */
default:
changed = defs_to_varying (stmt);
break;
--- 1973,2033 ----
even if they were optimistically constant. */
VN_INFO (lhs)->has_constants = false;
! 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. */
! && !(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, gimple_assign_rhs1 (stmt), stmt);
}
else if (TREE_CODE (lhs) == SSA_NAME)
{
! 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;
! if (simplified)
! changed = set_ssa_val_to (lhs, simplified);
! else
! changed = set_ssa_val_to (lhs, gimple_assign_rhs1 (stmt));
}
else
{
! switch (get_gimple_rhs_class (gimple_assign_rhs_code (stmt)))
{
! case GIMPLE_UNARY_RHS:
! changed = visit_unary_op (lhs, stmt);
break;
! case GIMPLE_BINARY_RHS:
! changed = visit_binary_op (lhs, stmt);
break;
! case GIMPLE_SINGLE_RHS:
! switch (TREE_CODE_CLASS (gimple_assign_rhs_code (stmt)))
{
! 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);
}
! break;
default:
changed = defs_to_varying (stmt);
break;
*************** visit_use (tree use)
*** 1851,1856 ****
--- 2037,2075 ----
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;
*************** compare_ops (const void *pa, const void
*** 1863,1878 ****
{
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);
basic_block bba;
basic_block bbb;
! if (IS_EMPTY_STMT (opstmta) && IS_EMPTY_STMT (opstmtb))
return 0;
! else if (IS_EMPTY_STMT (opstmta))
return -1;
! else if (IS_EMPTY_STMT (opstmtb))
return 1;
bba = gimple_bb (opstmta);
--- 2082,2097 ----
{
const tree opa = *((const tree *)pa);
const tree opb = *((const tree *)pb);
! gimple opstmta = SSA_NAME_DEF_STMT (opa);
! gimple opstmtb = SSA_NAME_DEF_STMT (opb);
basic_block bba;
basic_block bbb;
! if (gimple_nop_p (opstmta) && gimple_nop_p (opstmtb))
return 0;
! else if (gimple_nop_p (opstmta))
return -1;
! else if (gimple_nop_p (opstmtb))
return 1;
bba = gimple_bb (opstmta);
*************** compare_ops (const void *pa, const void
*** 1887,1899 ****
if (bba == bbb)
{
! if (TREE_CODE (opstmta) == PHI_NODE && TREE_CODE (opstmtb) == PHI_NODE)
return 0;
! else if (TREE_CODE (opstmta) == PHI_NODE)
return -1;
! else if (TREE_CODE (opstmtb) == PHI_NODE)
return 1;
! return gimple_stmt_uid (opstmta) - gimple_stmt_uid (opstmtb);
}
return rpo_numbers[bba->index] - rpo_numbers[bbb->index];
}
--- 2106,2119 ----
if (bba == bbb)
{
! if (gimple_code (opstmta) == GIMPLE_PHI
! && gimple_code (opstmtb) == GIMPLE_PHI)
return 0;
! else if (gimple_code (opstmta) == GIMPLE_PHI)
return -1;
! else if (gimple_code (opstmtb) == GIMPLE_PHI)
return 1;
! return gimple_uid (opstmta) - gimple_uid (opstmtb);
}
return rpo_numbers[bba->index] - rpo_numbers[bbb->index];
}
*************** DFS (tree name)
*** 2019,2025 ****
VEC(ssa_op_iter, heap) *itervec = NULL;
VEC(tree, heap) *namevec = NULL;
use_operand_p usep = NULL;
! tree defstmt, use;
ssa_op_iter iter;
start_over:
--- 2239,2246 ----
VEC(ssa_op_iter, heap) *itervec = NULL;
VEC(tree, heap) *namevec = NULL;
use_operand_p usep = NULL;
! gimple defstmt;
! tree use;
ssa_op_iter iter;
start_over:
*************** start_over:
*** 2033,2042 ****
defstmt = SSA_NAME_DEF_STMT (name);
/* Recursively DFS on our operands, looking for SCC's. */
! if (!IS_EMPTY_STMT (defstmt))
{
/* Push a new iterator. */
! if (TREE_CODE (defstmt) == PHI_NODE)
usep = op_iter_init_phiuse (&iter, defstmt, SSA_OP_ALL_USES);
else
usep = op_iter_init_use (&iter, defstmt, SSA_OP_ALL_USES);
--- 2254,2263 ----
defstmt = SSA_NAME_DEF_STMT (name);
/* Recursively DFS on our operands, looking for SCC's. */
! if (!gimple_nop_p (defstmt))
{
/* Push a new iterator. */
! 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);
*************** run_scc_vn (bool may_insert_arg)
*** 2286,2297 ****
tree name = ssa_name (i);
if (name && VN_INFO (name)->visited
&& (SSA_VAL (name) != name
! || is_gimple_min_invariant (VN_INFO (name)->expr)))
{
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);
else
print_generic_expr (dump_file, SSA_VAL (name), 0);
fprintf (dump_file, "\n");
--- 2507,2518 ----
tree name = ssa_name (i);
if (name && VN_INFO (name)->visited
&& (SSA_VAL (name) != name
! || 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_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");
*************** run_scc_vn (bool may_insert_arg)
*** 2302,2305 ****
may_insert = false;
return true;
}
- #endif
--- 2523,2525 ----
Index: gcc/tree-ssa-sccvn.h
===================================================================
*** gcc/tree-ssa-sccvn.h.orig 2008-06-25 17:43:11.000000000 +0200
--- gcc/tree-ssa-sccvn.h 2008-06-26 12:03:24.000000000 +0200
*************** typedef struct vn_ssa_aux
*** 54,68 ****
/* 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);
bool run_scc_vn (bool);
void free_scc_vn (void);
void switch_to_PRE_table (void);
tree vn_nary_op_lookup (tree);
void vn_nary_op_insert (tree, 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);
#endif /* TREE_SSA_SCCVN_H */
--- 54,71 ----
/* 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 (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-25 17:43:11.000000000 +0200
--- gcc/tree-dfa.c 2008-06-26 12:03:24.000000000 +0200
*************** refs_may_alias_p (tree ref1, tree ref2)
*** 1092,1099 ****
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
--- 1092,1097 ----
*************** refs_may_alias_p (tree ref1, tree ref2)
*** 1102,1126 ****
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)
{
! tree def_stmt = NULL_TREE;
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);
/* ??? 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;
def_stmt = tmp;
}
--- 1100,1124 ----
a PHI node as well. Note that if all VUSEs are default definitions
this function will return an empty statement. */
! gimple
! get_single_def_stmt (gimple stmt)
{
! gimple def_stmt = NULL;
tree use;
ssa_op_iter iter;
FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_VIRTUAL_USES)
{
! 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
! && !(gimple_nop_p (def_stmt)
! && gimple_nop_p (tmp)))
! return NULL;
def_stmt = tmp;
}
*************** get_single_def_stmt (tree stmt)
*** 1134,1158 ****
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)
{
tree def_arg = NULL_TREE;
! int 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)
{
tree arg = PHI_ARG_DEF (phi, i);
! tree def_stmt;
! if (!(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;
def_arg = arg;
continue;
}
--- 1132,1156 ----
from a non-backedge. Returns NULL_TREE if such statement within
the above conditions cannot be found. */
! gimple
! get_single_def_stmt_from_phi (tree ref, gimple phi)
{
tree def_arg = NULL_TREE;
! 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 < gimple_phi_num_args (phi); ++i)
{
tree arg = PHI_ARG_DEF (phi, i);
! gimple def_stmt;
! 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;
def_arg = arg;
continue;
}
*************** get_single_def_stmt_from_phi (tree ref,
*** 1162,1175 ****
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;
/* ??? 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;
}
while (def_stmt != phi);
}
--- 1160,1173 ----
def_stmt = SSA_NAME_DEF_STMT (arg);
do
{
! 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;
}
while (def_stmt != phi);
}
*************** get_single_def_stmt_from_phi (tree ref,
*** 1182,1189 ****
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)
{
switch (NUM_SSA_OPERANDS (stmt, SSA_OP_VIRTUAL_USES))
{
--- 1180,1187 ----
Take into account only definitions that alias REF if following
back-edges when looking through a loop PHI node. */
! gimple
! get_single_def_stmt_with_phi (tree ref, gimple stmt)
{
switch (NUM_SSA_OPERANDS (stmt, SSA_OP_VIRTUAL_USES))
{
*************** get_single_def_stmt_with_phi (tree ref,
*** 1192,1202 ****
case 1:
{
! tree 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)
return get_single_def_stmt_from_phi (ref, def_stmt);
return def_stmt;
}
--- 1190,1200 ----
case 1:
{
! 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 (gimple_code (def_stmt) == GIMPLE_PHI)
return get_single_def_stmt_from_phi (ref, def_stmt);
return def_stmt;
}
*************** get_single_def_stmt_with_phi (tree ref,
*** 1205,1208 ****
return get_single_def_stmt (stmt);
}
}
- #endif
--- 1203,1205 ----
Index: gcc/tree-ssa-pre.c
===================================================================
*** gcc/tree-ssa-pre.c.orig 2008-06-25 17:43:11.000000000 +0200
--- gcc/tree-ssa-pre.c 2008-06-26 12:03:24.000000000 +0200
*************** do_SCCVN_insertion (tree stmt, tree ssa_
*** 3583,3589 ****
/* 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);
if (expr == NULL_TREE)
return NULL_TREE;
set_value_handle (expr, get_value_handle (ssa_vn));
--- 3583,3589 ----
/* 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_get_expr_for (ssa_vn), bb, NULL, true);
if (expr == NULL_TREE)
return NULL_TREE;
set_value_handle (expr, get_value_handle (ssa_vn));
*************** eliminate (void)
*** 3641,3647 ****
tree val = VN_INFO (lhs)->valnum;
if (val != VN_TOP
&& VN_INFO (val)->needs_insertion
! && can_PRE_operation (VN_INFO (val)->expr))
sprime = do_SCCVN_insertion (stmt, val);
}
--- 3641,3647 ----
tree val = VN_INFO (lhs)->valnum;
if (val != VN_TOP
&& VN_INFO (val)->needs_insertion
! && can_PRE_operation (vn_get_expr_for (val)))
sprime = do_SCCVN_insertion (stmt, val);
}
*************** static unsigned int
*** 3972,3977 ****
--- 3972,3981 ----
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;
*************** execute_pre (bool do_fre ATTRIBUTE_UNUSE
*** 4038,4045 ****
fini_pre ();
return todo;
- #else
- gimple_unreachable ();
#endif
return 0;
}
--- 4042,4047 ----
*************** execute_fre (void)
*** 4091,4102 ****
static bool
gate_fre (void)
{
- /* FIXME tuples */
- #if 0
return flag_tree_fre != 0;
- #else
- return 0;
- #endif
}
struct gimple_opt_pass pass_fre =
--- 4093,4099 ----
Index: gcc/tree-flow.h
===================================================================
*** gcc/tree-flow.h.orig 2008-06-25 17:43:11.000000000 +0200
--- gcc/tree-flow.h 2008-06-26 12:03:24.000000000 +0200
*************** extern void set_default_def (tree, tree)
*** 775,783 ****
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);
/* In tree-phinodes.c */
extern void reserve_phi_args_for_new_edge (basic_block);
--- 775,783 ----
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 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);
*************** static inline tree get_value_handle (tre
*** 1093,1103 ****
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_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 (tree);
tree vn_lookup_with_vuses (tree, VEC (tree, gc) *);
--- 1093,1103 ----
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, 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, gimple);
tree vn_lookup (tree);
tree vn_lookup_with_vuses (tree, VEC (tree, gc) *);
Index: gcc/gimple.c
===================================================================
*** gcc/gimple.c.orig 2008-06-26 11:59:53.000000000 +0200
--- gcc/gimple.c 2008-06-26 12:03:24.000000000 +0200
*************** gimple_set_bb (gimple stmt, basic_block
*** 1893,1900 ****
tree
gimple_fold (const_gimple stmt)
{
- tree t;
-
switch (gimple_code (stmt))
{
case GIMPLE_COND:
--- 1893,1898 ----
*************** gimple_fold (const_gimple stmt)
*** 1902,1929 ****
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));
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;
default:
break;
--- 1900,1929 ----
boolean_type_node,
gimple_cond_lhs (stmt),
gimple_cond_rhs (stmt));
case GIMPLE_ASSIGN:
! 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);
case GIMPLE_CALL:
! return NULL_TREE;
default:
break;
Index: gcc/tree-vn.c
===================================================================
*** gcc/tree-vn.c.orig 2008-06-25 17:43:11.000000000 +0200
--- gcc/tree-vn.c 2008-06-26 12:03:24.000000000 +0200
*************** vn_add (tree expr, tree val)
*** 208,215 ****
--- 208,218 ----
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
*************** vn_add_with_vuses (tree expr, tree val,
*** 228,235 ****
--- 231,241 ----
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
}
*************** vn_lookup (tree expr)
*** 281,287 ****
hash value for EXPR for reference operations. */
tree
! vn_lookup_with_stmt (tree expr, tree stmt)
{
if (stmt == NULL)
return vn_lookup (expr);
--- 287,293 ----
hash value for EXPR for reference operations. */
tree
! vn_lookup_with_stmt (tree expr, gimple stmt)
{
if (stmt == NULL)
return vn_lookup (expr);
*************** vn_lookup_or_add (tree expr)
*** 347,353 ****
STMT to get the set of vuses. */
tree
! vn_lookup_or_add_with_stmt (tree expr, tree stmt)
{
tree v;
if (!stmt)
--- 353,359 ----
STMT to get the set of vuses. */
tree
! vn_lookup_or_add_with_stmt (tree expr, gimple stmt)
{
tree v;
if (!stmt)
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2008-06-27 16:51 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-06-24 15:04 [PATCH][tuples] Tuplify SCCVN Richard Guenther
2008-06-27 16:45 ` Diego Novillo
2008-06-27 17:25 ` Richard Guenther
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).