aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/tree-ssa/ssa-dom.C104
-rw-r--r--gcc/tree-ssa-dom.c27
4 files changed, 142 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5ecdc8f..5f93edd 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2013-03-20 Jeff Law <law@redhat.com>
+
+ * tree-ssa-dom.c (record_equivalences_from_incoming_edge): Record
+ addititional equivalences for equality comparisons between an SSA_NAME
+ and a constant where the SSA_NAME was set from a widening conversion.
+
2013-03-20 Walter Lee <walt@tilera.com>
* config/tilegx/sync.md (atomic_test_and_set): New pattern.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 93d02bb..99a366d7 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2013-03-20 Jeff Law <law@redhat.com>
+
+ * g++.dg/tree-ssa/ssa-dom.C: New test.
+
+
2013-03-20 Michael Meissner <meissner@linux.vnet.ibm.com>
* gcc.target/powerpc/mmfpgpr.c: New test.
diff --git a/gcc/testsuite/g++.dg/tree-ssa/ssa-dom.C b/gcc/testsuite/g++.dg/tree-ssa/ssa-dom.C
new file mode 100644
index 0000000..5f63865
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tree-ssa/ssa-dom.C
@@ -0,0 +1,104 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-dom1" } */
+
+typedef long unsigned int size_t;
+extern void abort (void) __attribute__ ((__noreturn__));
+union tree_node;
+typedef union tree_node *tree;
+union gimple_statement_d;
+typedef union gimple_statement_d *gimple;
+typedef const union gimple_statement_d *const_gimple;
+
+enum gimple_code
+{
+ GIMPLE_RETURN = 10,
+};
+
+
+
+
+
+struct gimple_statement_base
+{
+
+
+ enum gimple_code code:8;
+};
+
+
+enum gimple_statement_structure_enum
+{
+ xyz
+};
+
+
+
+
+
+
+union gimple_statement_d
+{
+ struct gimple_statement_base gsbase;
+};
+
+
+
+
+
+extern size_t const gimple_ops_offset_[];
+
+
+extern enum gimple_statement_structure_enum const gss_for_code_[];
+
+
+static inline enum gimple_code
+gimple_code (const_gimple g)
+{
+ return g->gsbase.code;
+}
+
+
+
+
+static inline enum gimple_statement_structure_enum
+gss_for_code (enum gimple_code code)
+{
+ return gss_for_code_[code];
+}
+
+
+
+
+static inline enum gimple_statement_structure_enum
+gimple_statement_structure (gimple gs)
+{
+ return gss_for_code (gimple_code (gs));
+}
+
+
+static inline tree *
+gimple_ops (gimple gs)
+{
+ size_t off;
+ off = gimple_ops_offset_[gimple_statement_structure (gs)];
+ return (tree *) ((char *) gs + off);
+}
+
+
+static inline void
+gimple_set_op (gimple gs, unsigned i, tree op)
+{
+ gimple_ops (gs)[i] = op;
+}
+
+void
+gimple_return_set_retval (gimple gs, tree retval)
+{
+ const_gimple __gs = (gs);
+ if (gimple_code (__gs) != (GIMPLE_RETURN))
+ abort ();
+ gimple_set_op (gs, 0, retval);
+}
+/* { dg-final { scan-tree-dump-times "gss_for_code_.10." 1 "dom1"} } */
+/* { dg-final { cleanup-tree-dump "dom1" } } */
+
diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c
index e8b1551..57b814c 100644
--- a/gcc/tree-ssa-dom.c
+++ b/gcc/tree-ssa-dom.c
@@ -1135,6 +1135,33 @@ record_equivalences_from_incoming_edge (basic_block bb)
if (lhs)
record_equality (lhs, rhs);
+ /* If LHS is an SSA_NAME and RHS is a constant and LHS was set
+ via a widening type conversion, then we may be able to record
+ additional equivalences. */
+ if (lhs
+ && TREE_CODE (lhs) == SSA_NAME
+ && is_gimple_constant (rhs))
+ {
+ gimple defstmt = SSA_NAME_DEF_STMT (lhs);
+
+ if (defstmt
+ && is_gimple_assign (defstmt)
+ && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (defstmt)))
+ {
+ tree old_rhs = gimple_assign_rhs1 (defstmt);
+ tree newval = fold_convert (TREE_TYPE (old_rhs), rhs);
+
+ /* If this was a widening conversion and if RHS is converted
+ to the type of OLD_RHS and has the same value, then we
+ can record an equivalence between OLD_RHS and the
+ converted representation of RHS. */
+ if ((TYPE_PRECISION (TREE_TYPE (lhs))
+ > TYPE_PRECISION (TREE_TYPE (old_rhs)))
+ && operand_equal_p (rhs, newval, 0))
+ record_equality (old_rhs, newval);
+ }
+ }
+
for (i = 0; edge_info->cond_equivalences.iterate (i, &eq); ++i)
record_cond (eq);
}