Allow ADDR_EXPRs of TARGET_MEM_REFs
authorRichard Sandiford <richard.sandiford@linaro.org>
Sat, 13 Jan 2018 17:59:08 +0000 (17:59 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Sat, 13 Jan 2018 17:59:08 +0000 (17:59 +0000)
This patch allows ADDR_EXPR <TARGET_MEM_REF ...>, which is useful
when calling internal functions that take pointers to memory that
is conditionally loaded or stored.  This is a prerequisite to the
following ivopts patch.

2018-01-13  Richard Sandiford  <richard.sandiford@linaro.org>
    Alan Hayward  <alan.hayward@arm.com>
    David Sherwood  <david.sherwood@arm.com>

gcc/
* expr.c (expand_expr_addr_expr_1): Handle ADDR_EXPRs of
TARGET_MEM_REFs.
* gimple-expr.h (is_gimple_addressable: Likewise.
* gimple-expr.c (is_gimple_address): Likewise.
* internal-fn.c (expand_call_mem_ref): New function.
(expand_mask_load_optab_fn): Use it.
(expand_mask_store_optab_fn): Likewise.

Co-Authored-By: Alan Hayward <alan.hayward@arm.com>
Co-Authored-By: David Sherwood <david.sherwood@arm.com>
From-SVN: r256627

gcc/ChangeLog
gcc/expr.c
gcc/gimple-expr.c
gcc/gimple-expr.h
gcc/internal-fn.c

index c08d2b35e5e7a7a90c92d91feccf5382d5a5deeb..79ddaf32d8988573dcb558a1f1ce04c9dd2e7433 100644 (file)
@@ -1,3 +1,15 @@
+2018-01-13  Richard Sandiford  <richard.sandiford@linaro.org>
+           Alan Hayward  <alan.hayward@arm.com>
+           David Sherwood  <david.sherwood@arm.com>
+
+       * expr.c (expand_expr_addr_expr_1): Handle ADDR_EXPRs of
+       TARGET_MEM_REFs.
+       * gimple-expr.h (is_gimple_addressable: Likewise.
+       * gimple-expr.c (is_gimple_address): Likewise.
+       * internal-fn.c (expand_call_mem_ref): New function.
+       (expand_mask_load_optab_fn): Use it.
+       (expand_mask_store_optab_fn): Likewise.
+
 2018-01-13  Richard Sandiford  <richard.sandiford@linaro.org>
            Alan Hayward  <alan.hayward@arm.com>
            David Sherwood  <david.sherwood@arm.com>
index cd1e57d0eecd524f2e0a5bb8530e08478787b7e6..42f889f318c2db11156791ad43ea3055897bb735 100644 (file)
@@ -7885,6 +7885,9 @@ expand_expr_addr_expr_1 (tree exp, rtx target, scalar_int_mode tmode,
        return expand_expr (tem, target, tmode, modifier);
       }
 
+    case TARGET_MEM_REF:
+      return addr_for_mem_ref (exp, as, true);
+
     case CONST_DECL:
       /* Expand the initializer like constants above.  */
       result = XEXP (expand_expr_constant (DECL_INITIAL (exp),
index 7c0f831c785f0b0f61e27f3f15d78436b318a4c5..56caacabba220f31a94af12fafa1f08870935271 100644 (file)
@@ -631,7 +631,9 @@ is_gimple_address (const_tree t)
       op = TREE_OPERAND (op, 0);
     }
 
-  if (CONSTANT_CLASS_P (op) || TREE_CODE (op) == MEM_REF)
+  if (CONSTANT_CLASS_P (op)
+      || TREE_CODE (op) == TARGET_MEM_REF
+      || TREE_CODE (op) == MEM_REF)
     return true;
 
   switch (TREE_CODE (op))
index 7d0445458fb9b2b571429f764db98257d2fddb9e..96733bdd7b43b0ae2cb007016f499ea27654b7dc 100644 (file)
@@ -119,6 +119,7 @@ static inline bool
 is_gimple_addressable (tree t)
 {
   return (is_gimple_id (t) || handled_component_p (t)
+         || TREE_CODE (t) == TARGET_MEM_REF
          || TREE_CODE (t) == MEM_REF);
 }
 
index bc4027bd60359696f06d9c263c4a9bb658be3327..86a196442498cd0872e7bfc62b6f5d534fc9a6fd 100644 (file)
@@ -2412,15 +2412,54 @@ expand_LOOP_DIST_ALIAS (internal_fn, gcall *)
   gcc_unreachable ();
 }
 
+/* Return a memory reference of type TYPE for argument INDEX of STMT.
+   Use argument INDEX + 1 to derive the second (TBAA) operand.  */
+
+static tree
+expand_call_mem_ref (tree type, gcall *stmt, int index)
+{
+  tree addr = gimple_call_arg (stmt, index);
+  tree alias_ptr_type = TREE_TYPE (gimple_call_arg (stmt, index + 1));
+  unsigned int align = tree_to_shwi (gimple_call_arg (stmt, index + 1));
+  if (TYPE_ALIGN (type) != align)
+    type = build_aligned_type (type, align);
+
+  tree tmp = addr;
+  if (TREE_CODE (tmp) == SSA_NAME)
+    {
+      gimple *def = SSA_NAME_DEF_STMT (tmp);
+      if (gimple_assign_single_p (def))
+       tmp = gimple_assign_rhs1 (def);
+    }
+
+  if (TREE_CODE (tmp) == ADDR_EXPR)
+    {
+      tree mem = TREE_OPERAND (tmp, 0);
+      if (TREE_CODE (mem) == TARGET_MEM_REF
+         && types_compatible_p (TREE_TYPE (mem), type))
+       {
+         tree offset = TMR_OFFSET (mem);
+         if (alias_ptr_type != TREE_TYPE (offset) || !integer_zerop (offset))
+           {
+             mem = copy_node (mem);
+             TMR_OFFSET (mem) = wide_int_to_tree (alias_ptr_type,
+                                                  wi::to_poly_wide (offset));
+           }
+         return mem;
+       }
+    }
+
+  return fold_build2 (MEM_REF, type, addr, build_int_cst (alias_ptr_type, 0));
+}
+
 /* Expand MASK_LOAD{,_LANES} call STMT using optab OPTAB.  */
 
 static void
 expand_mask_load_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
 {
   struct expand_operand ops[3];
-  tree type, lhs, rhs, maskt, ptr;
+  tree type, lhs, rhs, maskt;
   rtx mem, target, mask;
-  unsigned align;
   insn_code icode;
 
   maskt = gimple_call_arg (stmt, 2);
@@ -2428,11 +2467,7 @@ expand_mask_load_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
   if (lhs == NULL_TREE)
     return;
   type = TREE_TYPE (lhs);
-  ptr = build_int_cst (TREE_TYPE (gimple_call_arg (stmt, 1)), 0);
-  align = tree_to_shwi (gimple_call_arg (stmt, 1));
-  if (TYPE_ALIGN (type) != align)
-    type = build_aligned_type (type, align);
-  rhs = fold_build2 (MEM_REF, type, gimple_call_arg (stmt, 0), ptr);
+  rhs = expand_call_mem_ref (type, stmt, 0);
 
   if (optab == vec_mask_load_lanes_optab)
     icode = get_multi_vector_move (type, optab);
@@ -2458,19 +2493,14 @@ static void
 expand_mask_store_optab_fn (internal_fn, gcall *stmt, convert_optab optab)
 {
   struct expand_operand ops[3];
-  tree type, lhs, rhs, maskt, ptr;
+  tree type, lhs, rhs, maskt;
   rtx mem, reg, mask;
-  unsigned align;
   insn_code icode;
 
   maskt = gimple_call_arg (stmt, 2);
   rhs = gimple_call_arg (stmt, 3);
   type = TREE_TYPE (rhs);
-  ptr = build_int_cst (TREE_TYPE (gimple_call_arg (stmt, 1)), 0);
-  align = tree_to_shwi (gimple_call_arg (stmt, 1));
-  if (TYPE_ALIGN (type) != align)
-    type = build_aligned_type (type, align);
-  lhs = fold_build2 (MEM_REF, type, gimple_call_arg (stmt, 0), ptr);
+  lhs = expand_call_mem_ref (type, stmt, 0);
 
   if (optab == vec_mask_store_lanes_optab)
     icode = get_multi_vector_move (type, optab);