]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
tree.c (reference_alias_ptr_type): New function.
authorRichard Guenther <rguenther@suse.de>
Mon, 5 Jul 2010 14:51:16 +0000 (14:51 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Mon, 5 Jul 2010 14:51:16 +0000 (14:51 +0000)
2010-07-05  Richard Guenther  <rguenther@suse.de>

* tree.c (reference_alias_ptr_type): New function.
* tree.h (reference_alias_ptr_type): Declare.
* tree-ssa-loop-ivopts.c (copy_ref_info): Restructure to
allow non-TARGET_MEM_REF new refs.
(rewrite_use_address): Pass old alias pointer type to
create_mem_ref.
* tree-ssa-address.c (create_mem_ref_raw): Get alias pointer type.
Build a MEM_REF instead of a TARGET_MEM_REF if possible.
(create_mem_ref): Get alias pointer type.  Adjust calls to
create_mem_ref_raw.
(maybe_fold_tmr): Likewise.
* tree-flow.h (create_mem_ref): Adjust prototype.

From-SVN: r161840

gcc/ChangeLog
gcc/tree-flow.h
gcc/tree-ssa-address.c
gcc/tree-ssa-loop-ivopts.c
gcc/tree.c
gcc/tree.h

index 3e7eaa36552a3d0cec3ad02d39d48695cd8738d0..f4ad9076a1ba0e7ab71ae3f88b1d53f1dce6a867 100644 (file)
@@ -1,3 +1,18 @@
+2010-07-05  Richard Guenther  <rguenther@suse.de>
+
+       * tree.c (reference_alias_ptr_type): New function.
+       * tree.h (reference_alias_ptr_type): Declare.
+       * tree-ssa-loop-ivopts.c (copy_ref_info): Restructure to
+       allow non-TARGET_MEM_REF new refs.
+       (rewrite_use_address): Pass old alias pointer type to
+       create_mem_ref.
+       * tree-ssa-address.c (create_mem_ref_raw): Get alias pointer type.
+       Build a MEM_REF instead of a TARGET_MEM_REF if possible.
+       (create_mem_ref): Get alias pointer type.  Adjust calls to
+       create_mem_ref_raw.
+       (maybe_fold_tmr): Likewise.
+       * tree-flow.h (create_mem_ref): Adjust prototype.
+
 2010-07-05  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/44808
index fb1373a1ad0a0af6c5073e11ef661db6be34e6ce..fd9a5425368e93d95733ff6b2605165d23d06d3e 100644 (file)
@@ -833,7 +833,7 @@ struct mem_address
 };
 
 struct affine_tree_combination;
-tree create_mem_ref (gimple_stmt_iterator *, tree,
+tree create_mem_ref (gimple_stmt_iterator *, tree, tree,
                     struct affine_tree_combination *, tree, bool);
 rtx addr_for_mem_ref (struct mem_address *, addr_space_t, bool);
 void get_address_description (tree, struct mem_address *);
index 3abfffe25ec8998ac526a13f132d86d87d5591fc..cf7a81d66d00c9475a5ce28be25141dcede3915d 100644 (file)
@@ -338,7 +338,7 @@ valid_mem_ref_p (enum machine_mode mode, addr_space_t as,
    TARGET_MEM_REF.  */
 
 static tree
-create_mem_ref_raw (tree type, struct mem_address *addr)
+create_mem_ref_raw (tree type, tree alias_ptr_type, struct mem_address *addr)
 {
   if (!valid_mem_ref_p (TYPE_MODE (type), TYPE_ADDR_SPACE (type), addr))
     return NULL_TREE;
@@ -349,6 +349,24 @@ create_mem_ref_raw (tree type, struct mem_address *addr)
   if (addr->offset && integer_zerop (addr->offset))
     addr->offset = NULL_TREE;
 
+  /* If possible use a plain MEM_REF instead of a TARGET_MEM_REF.  */
+  if (alias_ptr_type
+      && !addr->index
+      && !addr->step)
+    {
+      tree base, offset;
+      gcc_assert (!addr->symbol ^ !addr->base);
+      if (addr->symbol)
+       base = build_fold_addr_expr (addr->symbol);
+      else
+       base = addr->base;
+      if (addr->offset)
+       offset = fold_convert (alias_ptr_type, addr->offset);
+      else
+       offset = build_int_cst (alias_ptr_type, 0);
+      return fold_build2 (MEM_REF, type, base, offset);
+    }
+
   return build6 (TARGET_MEM_REF, type,
                 addr->symbol, addr->base, addr->index,
                 addr->step, addr->offset, NULL);
@@ -628,8 +646,8 @@ gimplify_mem_ref_parts (gimple_stmt_iterator *gsi, struct mem_address *parts)
    of created memory reference.  */
 
 tree
-create_mem_ref (gimple_stmt_iterator *gsi, tree type, aff_tree *addr,
-               tree base_hint, bool speed)
+create_mem_ref (gimple_stmt_iterator *gsi, tree type, tree alias_ptr_type,
+               aff_tree *addr, tree base_hint, bool speed)
 {
   tree mem_ref, tmp;
   tree atype;
@@ -637,7 +655,7 @@ create_mem_ref (gimple_stmt_iterator *gsi, tree type, aff_tree *addr,
 
   addr_to_parts (type, addr, base_hint, &parts, speed);
   gimplify_mem_ref_parts (gsi, &parts);
-  mem_ref = create_mem_ref_raw (type, &parts);
+  mem_ref = create_mem_ref_raw (type, alias_ptr_type, &parts);
   if (mem_ref)
     return mem_ref;
 
@@ -653,7 +671,7 @@ create_mem_ref (gimple_stmt_iterator *gsi, tree type, aff_tree *addr,
                                true, NULL_TREE, true, GSI_SAME_STMT);
       parts.step = NULL_TREE;
 
-      mem_ref = create_mem_ref_raw (type, &parts);
+      mem_ref = create_mem_ref_raw (type, alias_ptr_type, &parts);
       if (mem_ref)
        return mem_ref;
     }
@@ -688,7 +706,7 @@ create_mem_ref (gimple_stmt_iterator *gsi, tree type, aff_tree *addr,
        parts.base = tmp;
       parts.symbol = NULL_TREE;
 
-      mem_ref = create_mem_ref_raw (type, &parts);
+      mem_ref = create_mem_ref_raw (type, alias_ptr_type, &parts);
       if (mem_ref)
        return mem_ref;
     }
@@ -709,7 +727,7 @@ create_mem_ref (gimple_stmt_iterator *gsi, tree type, aff_tree *addr,
        parts.base = parts.index;
       parts.index = NULL_TREE;
 
-      mem_ref = create_mem_ref_raw (type, &parts);
+      mem_ref = create_mem_ref_raw (type, alias_ptr_type, &parts);
       if (mem_ref)
        return mem_ref;
     }
@@ -731,7 +749,7 @@ create_mem_ref (gimple_stmt_iterator *gsi, tree type, aff_tree *addr,
 
       parts.offset = NULL_TREE;
 
-      mem_ref = create_mem_ref_raw (type, &parts);
+      mem_ref = create_mem_ref_raw (type, alias_ptr_type, &parts);
       if (mem_ref)
        return mem_ref;
     }
@@ -819,7 +837,7 @@ maybe_fold_tmr (tree ref)
   if (!changed)
     return NULL_TREE;
 
-  ret = create_mem_ref_raw (TREE_TYPE (ref), &addr);
+  ret = create_mem_ref_raw (TREE_TYPE (ref), NULL_TREE, &addr);
   if (!ret)
     return NULL_TREE;
 
index 740db68fee06e813c8465c9d75ccdb039c1af21a..db56b93470b3e7d3feba73bd94d8c83e41be13f6 100644 (file)
@@ -5547,33 +5547,41 @@ unshare_and_remove_ssa_names (tree ref)
 static void
 copy_ref_info (tree new_ref, tree old_ref)
 {
-  if (TREE_CODE (old_ref) == TARGET_MEM_REF)
-    copy_mem_ref_info (new_ref, old_ref);
-  else
-    {
-      TMR_ORIGINAL (new_ref) = unshare_and_remove_ssa_names (old_ref);
-      TREE_SIDE_EFFECTS (new_ref) = TREE_SIDE_EFFECTS (old_ref);
-      TREE_THIS_VOLATILE (new_ref) = TREE_THIS_VOLATILE (old_ref);
-      /* We can transfer points-to information from an old pointer
-         or decl base to the new one.  */
-      if (TMR_BASE (new_ref)
-         && TREE_CODE (TMR_BASE (new_ref)) == SSA_NAME
-         && POINTER_TYPE_P (TREE_TYPE (TMR_BASE (new_ref)))
-         && !SSA_NAME_PTR_INFO (TMR_BASE (new_ref)))
+  tree new_ptr_base = NULL_TREE;
+
+  if (TREE_CODE (old_ref) == TARGET_MEM_REF
+      && TREE_CODE (new_ref) == TARGET_MEM_REF)
+    TMR_ORIGINAL (new_ref) = TMR_ORIGINAL (old_ref);
+  else if (TREE_CODE (new_ref) == TARGET_MEM_REF)
+    TMR_ORIGINAL (new_ref) = unshare_and_remove_ssa_names (old_ref);
+
+  TREE_SIDE_EFFECTS (new_ref) = TREE_SIDE_EFFECTS (old_ref);
+  TREE_THIS_VOLATILE (new_ref) = TREE_THIS_VOLATILE (old_ref);
+
+  if (TREE_CODE (new_ref) == TARGET_MEM_REF)
+    new_ptr_base = TMR_BASE (new_ref);
+  else if (TREE_CODE (new_ref) == MEM_REF)
+    new_ptr_base = TREE_OPERAND (new_ref, 0);
+
+  /* We can transfer points-to information from an old pointer
+     or decl base to the new one.  */
+  if (new_ptr_base
+      && TREE_CODE (new_ptr_base) == SSA_NAME
+      && POINTER_TYPE_P (TREE_TYPE (new_ptr_base))
+      && !SSA_NAME_PTR_INFO (new_ptr_base))
+    {
+      tree base = get_base_address (old_ref);
+      if ((INDIRECT_REF_P (base)
+          || TREE_CODE (base) == MEM_REF)
+         && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
+       duplicate_ssa_name_ptr_info
+           (new_ptr_base, SSA_NAME_PTR_INFO (TREE_OPERAND (base, 0)));
+      else if (TREE_CODE (base) == VAR_DECL
+              || TREE_CODE (base) == PARM_DECL
+              || TREE_CODE (base) == RESULT_DECL)
        {
-         tree base = get_base_address (old_ref);
-         if ((INDIRECT_REF_P (base)
-              || TREE_CODE (base) == MEM_REF)
-             && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
-           duplicate_ssa_name_ptr_info
-             (TMR_BASE (new_ref), SSA_NAME_PTR_INFO (TREE_OPERAND (base, 0)));
-         else if (TREE_CODE (base) == VAR_DECL
-                  || TREE_CODE (base) == PARM_DECL
-                  || TREE_CODE (base) == RESULT_DECL)
-           {
-             struct ptr_info_def *pi = get_ptr_info (TMR_BASE (new_ref));
-             pt_solution_set_var (&pi->pt, base);
-           }
+         struct ptr_info_def *pi = get_ptr_info (new_ptr_base);
+         pt_solution_set_var (&pi->pt, base);
        }
     }
 }
@@ -5608,8 +5616,9 @@ rewrite_use_address (struct ivopts_data *data,
   if (cand->iv->base_object)
     base_hint = var_at_stmt (data->current_loop, cand, use->stmt);
 
-  ref = create_mem_ref (&bsi, TREE_TYPE (*use->op_p), &aff, base_hint,
-                       data->speed);
+  ref = create_mem_ref (&bsi, TREE_TYPE (*use->op_p),
+                       reference_alias_ptr_type (*use->op_p),
+                       &aff, base_hint, data->speed);
   copy_ref_info (ref, *use->op_p);
   *use->op_p = ref;
 }
index cb2c276b71568f0c04932843c3a1ace96411bbb7..e6deacce0f79e5868d482725ccac663a22808bf1 100644 (file)
@@ -3913,6 +3913,25 @@ mem_ref_offset (const_tree t)
                          TYPE_PRECISION (TREE_TYPE (toff)));
 }
 
+/* Return the pointer-type relevant for TBAA purposes from the
+   gimple memory reference tree T.  This is the type to be used for
+   the offset operand of MEM_REF or TARGET_MEM_REF replacements of T.  */
+
+tree
+reference_alias_ptr_type (const_tree t)
+{
+  const_tree base = t;
+  while (handled_component_p (base))
+    base = TREE_OPERAND (base, 0);
+  if (TREE_CODE (base) == MEM_REF)
+    return TREE_TYPE (TREE_OPERAND (base, 1));
+  else if (TREE_CODE (base) == TARGET_MEM_REF
+          || TREE_CODE (base) == MISALIGNED_INDIRECT_REF)
+    return NULL_TREE;
+  else
+    return build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (base)));
+}
+
 /* Similar except don't specify the TREE_TYPE
    and leave the TREE_SIDE_EFFECTS as 0.
    It is permissible for arguments to be null,
index ca4ec2ab854604666e5496a884158c6863af3b2d..934de7de68e3bc0a8ca82d4f0b6bd6e7a578e484 100644 (file)
@@ -4965,6 +4965,7 @@ extern tree build_simple_mem_ref_loc (location_t, tree);
 #define build_simple_mem_ref(T)\
        build_simple_mem_ref_loc (UNKNOWN_LOCATION, T)
 extern double_int mem_ref_offset (const_tree);
+extern tree reference_alias_ptr_type (const_tree);
 extern tree constant_boolean_node (int, tree);
 extern tree div_if_zero_remainder (enum tree_code, const_tree, const_tree);