* tree-ssa-dom.c (record_equivalences_from_incoming_edge): Record
authorlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 21 Mar 2013 04:42:40 +0000 (04:42 +0000)
committerlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 21 Mar 2013 04:42:40 +0000 (04:42 +0000)
addititional equivalences for equality comparisons between an SSA_NAME
and a constant where the SSA_NAME was set from a widening conversion.

* g++.dg/tree-ssa/ssa-dom.C: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@196855 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/tree-ssa/ssa-dom.C [new file with mode: 0644]
gcc/tree-ssa-dom.c

index 5ecdc8f..5f93edd 100644 (file)
@@ -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.
index 93d02bb..99a366d 100644 (file)
@@ -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 (file)
index 0000000..5f63865
--- /dev/null
@@ -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" } } */
+
index e8b1551..57b814c 100644 (file)
@@ -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);
        }