[PATCH 1/6]tree-ssa-dom.c: Normalize exprs, starting with ARRAY_REF to MEM_REF

Alan Lawrence alan.lawrence@arm.com
Thu Oct 29 19:20:00 GMT 2015


This patch just teaches DOM that ARRAY_REFs can be equivalent to MEM_REFs (with
pointer type to the array element type).

gcc/ChangeLog:

	* tree-ssa-dom.c (dom_normalize_single_rhs): New.
	(dom_normalize_gimple_stmt): New.
	(lookup_avail_expr): Call dom_normalize_gimple_stmt.
---
 gcc/tree-ssa-dom.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 67 insertions(+), 1 deletion(-)

diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c
index 38cceff..fca8a80 100644
--- a/gcc/tree-ssa-dom.c
+++ b/gcc/tree-ssa-dom.c
@@ -1897,6 +1897,72 @@ vuse_eq (ao_ref *, tree vuse1, unsigned int cnt, void *data)
   return NULL;
 }
 
+/* Return the normal form of EXPR, the gimple_assign_rhs1 of a GIMPLE_SINGLE_RHS
+   assignment, or NULL_TREE if EXPR is already in normal form.
+   The normal form is such that if two expressions normalize to trees that are
+   operand_equal_p, then dominator optimizations can replace one by the value
+   produced by the other.
+   It is not necessary that expressions with equal canonical forms are
+   equivalent in all other situations, e.g. aliasing.  */
+
+static tree
+dom_normalize_single_rhs (tree expr)
+{
+  switch (TREE_CODE (expr))
+  {
+    case ARRAY_REF:
+    {
+      tree index = TREE_OPERAND (expr, 1);
+      tree low_bound = array_ref_low_bound (expr);
+      if (!TREE_CONSTANT (index) || !TREE_CONSTANT (low_bound))
+	return NULL_TREE;
+
+      if (! integer_zerop (low_bound))
+	index = fold_build2 (MINUS_EXPR, TREE_TYPE (index), index, low_bound);
+
+      tree esz = array_ref_element_size (expr);
+      gcc_assert (TREE_CONSTANT (esz));
+      tree offset = fold_build2 (MULT_EXPR, sizetype, index, esz);
+
+      offset = fold_convert (build_pointer_type (TREE_TYPE (expr)), offset);
+
+      tree base = TREE_OPERAND (expr, 0);
+      base = build_fold_addr_expr (base);
+
+      return fold_build2 (MEM_REF, TREE_TYPE (expr), base, offset);
+    }
+    default:
+      return NULL_TREE;
+  }
+}
+
+/* Return the normal form of STMT, or STMT if it is already normalized.  */
+
+static gimple *
+dom_normalize_gimple_stmt (gimple *stmt)
+{
+  if (gimple_code (stmt) == GIMPLE_ASSIGN)
+    {
+      enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
+      if (get_gimple_rhs_class (rhs_code) == GIMPLE_SINGLE_RHS)
+	if (tree nrhs = dom_normalize_single_rhs (gimple_assign_rhs1 (stmt)))
+	  {
+	    tree lhs = gimple_assign_lhs (stmt);
+	    /* Exchanged statements, which are never part of the CFG,
+	       can have invalid LHS.  */
+	    gimple *defstmt = 0;
+	    if (TREE_CODE (lhs) == SSA_NAME)
+	      defstmt = SSA_NAME_DEF_STMT (lhs);
+	    gassign *new_stmt = gimple_build_assign (lhs, nrhs);
+	    if (TREE_CODE (lhs) == SSA_NAME)
+	      SSA_NAME_DEF_STMT (lhs) = defstmt;
+	    gimple_set_vuse (new_stmt, gimple_vuse (stmt));
+	    return new_stmt;
+	  }
+    }
+  return stmt;
+}
+
 /* Search for an existing instance of STMT in the AVAIL_EXPRS_STACK table.
    If found, return its LHS. Otherwise insert STMT in the table and
    return NULL_TREE.
@@ -1918,7 +1984,7 @@ lookup_avail_expr (gimple *stmt, bool insert,
   else
     lhs = gimple_get_lhs (stmt);
 
-  class expr_hash_elt element (stmt, lhs);
+  class expr_hash_elt element (dom_normalize_gimple_stmt (stmt), lhs);
 
   if (dump_file && (dump_flags & TDF_DETAILS))
     {
-- 
1.9.1



More information about the Gcc-patches mailing list