]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
tree.def (TARGET_MEM_REF): Merge TMR_SYMBOL and TMR_BASE.
authorRichard Guenther <rguenther@suse.de>
Fri, 3 Sep 2010 09:50:17 +0000 (09:50 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Fri, 3 Sep 2010 09:50:17 +0000 (09:50 +0000)
2010-09-03  Richard Guenther  <rguenther@suse.de>

* tree.def (TARGET_MEM_REF): Merge TMR_SYMBOL and TMR_BASE.
Move TMR_OFFSET to second operand.  Add TMR_INDEX2.
* tree.h (TMR_SYMBOL): Remove.
(TMR_BASE, TMR_OFFSET): Adjust.
(TMR_INDEX2): New.
* alias.c (ao_ref_from_mem): Use TMR_BASE.
* builtins.c (get_object_alignment): Merge TMR_BASE and
TMR_SYMBOL handling.
* cfgexpand.c (expand_debug_expr): Use TMR_BASE.
* gimple.c (get_base_address): Merge MEM_REF and TARGET_MEM_REF
handling.  Also allow TARGET_MEM_REF as base address.
(walk_stmt_load_store_addr_ops): TMR_BASE is always non-NULL.
* gimplify.c (gimplify_expr): Gimplify TMR_BASE like MEM_REF
base.  Gimplify TMR_INDEX2.
* tree-cfg.c (verify_types_in_gimple_reference): Adjust.
* tree-dfa.c (get_ref_base_and_extent): Likewise.
(get_addr_base_and_unit_offset): Likewise.
* tree-eh.c (tree_could_trap_p): Likewise.
* tree-pretty-print.c (dump_generic_node): Likewise.
* tree-ssa-address.c (tree_mem_ref_addr): Simplify.  Handle
TMR_INDEX2.
(create_mem_ref_raw): Merge symbol and base.  Move 2ndary
base to index2.
(get_address_description): Reconstruct addres description
from merged TMR_BASE and TMR_INDEX2.
(maybe_fold_tmr): Fold propagated addresses.
* tree-ssa-alias.c (indirect_ref_may_alias_decl_p): Merge
MEM_REF and TARGET_MEM_REF paths.
(indirect_refs_may_alias_p): Likewise.
* tree-ssa-live.c (mark_all_vars_used_1): Handle TMR_INDEX2
instead of TMR_SYMBOL.
* tree-ssa-operands.c (get_tmr_operands): Simplify.
* tree-ssa-pre.c (create_component_ref_by_pieces_1): Adjust
according to changes ...
* tree-ssa-sccvn.c (copy_reference_ops_from_ref): ... here.
Split TARGET_MEM_REF into two fields plus the base.
* tree.c (mem_ref_offset): Simplify.
* tree-ssa-loop-im.c (for_each_index): Handle TMR_INDEX2.
* tree-ssa-loop-ivopts.c (find_interesting_uses_address): Likewise.
Strip NOPs when folding MEM_REF addresses.
* tree-ssa-sink.c (is_hidden_global_store): Handle TARGET_MEM_REF.
* gimple-fold.c (maybe_fold_reference): Fold TARGET_MEM_REF here ...
(fold_gimple_assign): ... not here.

From-SVN: r163802

23 files changed:
gcc/ChangeLog
gcc/alias.c
gcc/builtins.c
gcc/cfgexpand.c
gcc/gimple-fold.c
gcc/gimple.c
gcc/gimplify.c
gcc/tree-cfg.c
gcc/tree-dfa.c
gcc/tree-eh.c
gcc/tree-pretty-print.c
gcc/tree-ssa-address.c
gcc/tree-ssa-alias.c
gcc/tree-ssa-live.c
gcc/tree-ssa-loop-im.c
gcc/tree-ssa-loop-ivopts.c
gcc/tree-ssa-operands.c
gcc/tree-ssa-pre.c
gcc/tree-ssa-sccvn.c
gcc/tree-ssa-sink.c
gcc/tree.c
gcc/tree.def
gcc/tree.h

index dc4f9a0bf612448bcac60593df8fb2635e04a8e6..9368985a8dd4e6ef76051f3d7c6c54665058c8d9 100644 (file)
@@ -1,3 +1,49 @@
+2010-09-03  Richard Guenther  <rguenther@suse.de>
+
+       * tree.def (TARGET_MEM_REF): Merge TMR_SYMBOL and TMR_BASE.
+       Move TMR_OFFSET to second operand.  Add TMR_INDEX2.
+       * tree.h (TMR_SYMBOL): Remove.
+       (TMR_BASE, TMR_OFFSET): Adjust.
+       (TMR_INDEX2): New.
+       * alias.c (ao_ref_from_mem): Use TMR_BASE.
+       * builtins.c (get_object_alignment): Merge TMR_BASE and
+       TMR_SYMBOL handling.
+       * cfgexpand.c (expand_debug_expr): Use TMR_BASE.
+       * gimple.c (get_base_address): Merge MEM_REF and TARGET_MEM_REF
+       handling.  Also allow TARGET_MEM_REF as base address.
+       (walk_stmt_load_store_addr_ops): TMR_BASE is always non-NULL.
+       * gimplify.c (gimplify_expr): Gimplify TMR_BASE like MEM_REF
+       base.  Gimplify TMR_INDEX2.
+       * tree-cfg.c (verify_types_in_gimple_reference): Adjust.
+       * tree-dfa.c (get_ref_base_and_extent): Likewise.
+       (get_addr_base_and_unit_offset): Likewise.
+       * tree-eh.c (tree_could_trap_p): Likewise.
+       * tree-pretty-print.c (dump_generic_node): Likewise.
+       * tree-ssa-address.c (tree_mem_ref_addr): Simplify.  Handle
+       TMR_INDEX2.
+       (create_mem_ref_raw): Merge symbol and base.  Move 2ndary
+       base to index2.
+       (get_address_description): Reconstruct addres description
+       from merged TMR_BASE and TMR_INDEX2.
+       (maybe_fold_tmr): Fold propagated addresses.
+       * tree-ssa-alias.c (indirect_ref_may_alias_decl_p): Merge
+       MEM_REF and TARGET_MEM_REF paths.
+       (indirect_refs_may_alias_p): Likewise.
+       * tree-ssa-live.c (mark_all_vars_used_1): Handle TMR_INDEX2
+       instead of TMR_SYMBOL.
+       * tree-ssa-operands.c (get_tmr_operands): Simplify.
+       * tree-ssa-pre.c (create_component_ref_by_pieces_1): Adjust
+       according to changes ...
+       * tree-ssa-sccvn.c (copy_reference_ops_from_ref): ... here.
+       Split TARGET_MEM_REF into two fields plus the base.
+       * tree.c (mem_ref_offset): Simplify.
+       * tree-ssa-loop-im.c (for_each_index): Handle TMR_INDEX2.
+       * tree-ssa-loop-ivopts.c (find_interesting_uses_address): Likewise.
+       Strip NOPs when folding MEM_REF addresses.
+       * tree-ssa-sink.c (is_hidden_global_store): Handle TARGET_MEM_REF.
+       * gimple-fold.c (maybe_fold_reference): Fold TARGET_MEM_REF here ...
+       (fold_gimple_assign): ... not here.
+
 2010-09-03  Mingjie Xing  <mingjie.xing@gmail.com>
 
        * config/mips/mips.h (SHIFT_COUNT_TRUNCATED): Change the definition.
index 580f8987d684d84464c3d7c63b93236117aafc77..854ac27aa9df7c1fabc621fe0218e65ece0dadc0 100644 (file)
@@ -301,14 +301,14 @@ ao_ref_from_mem (ao_ref *ref, const_rtx mem)
        ref->base = build_simple_mem_ref (*(tree *)namep);
     }
   else if (TREE_CODE (base) == TARGET_MEM_REF
-          && TMR_SYMBOL (base)
-          && TREE_CODE (TREE_OPERAND (TMR_SYMBOL (base), 0)) == VAR_DECL
-          && ! TREE_STATIC (TREE_OPERAND (TMR_SYMBOL (base), 0))
+          && TREE_CODE (TMR_BASE (base)) == ADDR_EXPR
+          && TREE_CODE (TREE_OPERAND (TMR_BASE (base), 0)) == VAR_DECL
+          && ! TREE_STATIC (TREE_OPERAND (TMR_BASE (base), 0))
           && cfun->gimple_df->decls_to_pointers != NULL)
     {
       void *namep;
       namep = pointer_map_contains (cfun->gimple_df->decls_to_pointers,
-                                   TREE_OPERAND (TMR_SYMBOL (base), 0));
+                                   TREE_OPERAND (TMR_BASE (base), 0));
       if (namep)
        ref->base = build_simple_mem_ref (*(tree *)namep);
     }
index 2cebb0e9dcd4f3740c2965efc803c327e2cc9a6f..c2176d9aae3a73ce36a0007d97405915c7636402 100644 (file)
@@ -331,9 +331,7 @@ get_object_alignment (tree exp, unsigned int max_align)
                                                  max_align));
       bitpos += mem_ref_offset (exp).low * BITS_PER_UNIT;
     }
-  else if (TREE_CODE (exp) == TARGET_MEM_REF
-          && TMR_BASE (exp)
-          && POINTER_TYPE_P (TREE_TYPE (TMR_BASE (exp))))
+  else if (TREE_CODE (exp) == TARGET_MEM_REF)
     {
       struct ptr_info_def *pi;
       tree addr = TMR_BASE (exp);
@@ -365,22 +363,7 @@ get_object_alignment (tree exp, unsigned int max_align)
        }
       else if (TMR_INDEX (exp))
        align = BITS_PER_UNIT;
-    }
-  else if (TREE_CODE (exp) == TARGET_MEM_REF
-          && TMR_SYMBOL (exp))
-    {
-      align = get_object_alignment (TREE_OPERAND (TMR_SYMBOL (exp), 0),
-                                   max_align);
-      if (TMR_OFFSET (exp))
-        bitpos += TREE_INT_CST_LOW (TMR_OFFSET (exp)) * BITS_PER_UNIT;
-      if (TMR_INDEX (exp) && TMR_STEP (exp))
-       {
-         unsigned HOST_WIDE_INT step = TREE_INT_CST_LOW (TMR_STEP (exp));
-         align = MIN (align, (step & -step) * BITS_PER_UNIT);
-       }
-      else if (TMR_INDEX (exp))
-       align = BITS_PER_UNIT;
-      if (TMR_BASE (exp))
+      if (TMR_INDEX2 (exp))
        align = BITS_PER_UNIT;
     }
   else
index 1852885fba0daf83af9c6a267b606f6c908f82cf..a979d6f3c1ae2d6496191999046484df5b25a704 100644 (file)
@@ -2468,8 +2468,8 @@ expand_debug_expr (tree exp)
       return op0;
 
     case TARGET_MEM_REF:
-      if (TMR_SYMBOL (exp)
-         && !DECL_RTL_SET_P (TREE_OPERAND (TMR_SYMBOL (exp), 0)))
+      if (TREE_CODE (TMR_BASE (exp)) == ADDR_EXPR
+         && !DECL_RTL_SET_P (TREE_OPERAND (TMR_BASE (exp), 0)))
        return NULL;
 
       op0 = expand_debug_expr
index 59aa946a883114aedb92bf7a33d256d9cbdb1cdc..8a48316f00de3b26321e91bf799cdab9401e0129 100644 (file)
@@ -528,6 +528,18 @@ maybe_fold_reference (tree expr, bool is_lhs)
          return expr;
        }
     }
+  else if (TREE_CODE (*t) == TARGET_MEM_REF)
+    {
+      tree tem = maybe_fold_tmr (*t);
+      if (tem)
+       {
+         *t = tem;
+         tem = maybe_fold_reference (expr, is_lhs);
+         if (tem)
+           return tem;
+         return expr;
+       }
+    }
   else if (!is_lhs
           && DECL_P (*t))
     {
@@ -602,9 +614,6 @@ fold_gimple_assign (gimple_stmt_iterator *si)
                                    COND_EXPR_THEN (rhs), COND_EXPR_ELSE (rhs));
           }
 
-       else if (TREE_CODE (rhs) == TARGET_MEM_REF)
-         return maybe_fold_tmr (rhs);
-
        else if (REFERENCE_CLASS_P (rhs))
          return maybe_fold_reference (rhs, false);
 
index c0b5052eb5424f9b517b9b831fa9591dce6b15c0..bb68be691adf2764eff261ae97076e6cdb2ae408 100644 (file)
@@ -3004,18 +3004,17 @@ get_base_address (tree t)
   while (handled_component_p (t))
     t = TREE_OPERAND (t, 0);
 
-  if (TREE_CODE (t) == MEM_REF
+  if ((TREE_CODE (t) == MEM_REF
+       || TREE_CODE (t) == TARGET_MEM_REF)
       && TREE_CODE (TREE_OPERAND (t, 0)) == ADDR_EXPR)
     t = TREE_OPERAND (TREE_OPERAND (t, 0), 0);
-  else if (TREE_CODE (t) == TARGET_MEM_REF
-          && TMR_SYMBOL (t))
-    t = TREE_OPERAND (TMR_SYMBOL (t), 0);
 
   if (SSA_VAR_P (t)
       || TREE_CODE (t) == STRING_CST
       || TREE_CODE (t) == CONSTRUCTOR
       || INDIRECT_REF_P (t)
-      || TREE_CODE (t) == MEM_REF)
+      || TREE_CODE (t) == MEM_REF
+      || TREE_CODE (t) == TARGET_MEM_REF)
     return t;
   else
     return NULL_TREE;
@@ -4725,7 +4724,6 @@ walk_stmt_load_store_addr_ops (gimple stmt, void *data,
          if (TREE_CODE (rhs) == ADDR_EXPR)
            ret |= visit_addr (stmt, TREE_OPERAND (rhs, 0), data);
          else if (TREE_CODE (rhs) == TARGET_MEM_REF
-                   && TMR_BASE (rhs) != NULL_TREE
                   && TREE_CODE (TMR_BASE (rhs)) == ADDR_EXPR)
            ret |= visit_addr (stmt, TREE_OPERAND (TMR_BASE (rhs), 0), data);
          else if (TREE_CODE (rhs) == OBJ_TYPE_REF
@@ -4734,7 +4732,6 @@ walk_stmt_load_store_addr_ops (gimple stmt, void *data,
                                                   0), data);
           lhs = gimple_assign_lhs (stmt);
          if (TREE_CODE (lhs) == TARGET_MEM_REF
-              && TMR_BASE (lhs) != NULL_TREE
               && TREE_CODE (TMR_BASE (lhs)) == ADDR_EXPR)
             ret |= visit_addr (stmt, TREE_OPERAND (TMR_BASE (lhs), 0), data);
        }
index bdb97ec9ba0061aa57286bf071777552657b28a8..1723f42d8a2e76b0d647a94fe5ebdc702f1873fa 100644 (file)
@@ -6977,20 +6977,15 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
          {
            enum gimplify_status r0 = GS_ALL_DONE, r1 = GS_ALL_DONE;
 
-           if (TMR_SYMBOL (*expr_p))
-             /* We can't gimplify the symbol part.  Assert it is
-                already gimple instead.
-                ???  This isn't exactly the same as ADDR_EXPR
-                plus is_gimple_mem_ref_addr (), see fixed_address_object_p.  */
-             gcc_assert (TREE_CODE (TMR_SYMBOL (*expr_p)) == ADDR_EXPR
-                         && (TREE_CODE (TREE_OPERAND (TMR_SYMBOL (*expr_p), 0))
-                             == VAR_DECL));
            if (TMR_BASE (*expr_p))
              r0 = gimplify_expr (&TMR_BASE (*expr_p), pre_p,
-                                 post_p, is_gimple_val, fb_either);
+                                 post_p, is_gimple_mem_ref_addr, fb_either);
            if (TMR_INDEX (*expr_p))
              r1 = gimplify_expr (&TMR_INDEX (*expr_p), pre_p,
                                  post_p, is_gimple_val, fb_rvalue);
+           if (TMR_INDEX2 (*expr_p))
+             r1 = gimplify_expr (&TMR_INDEX2 (*expr_p), pre_p,
+                                 post_p, is_gimple_val, fb_rvalue);
            /* TMR_STEP and TMR_OFFSET are always integer constants.  */
            ret = MIN (r0, r1);
          }
index 1dc99aaf8d7b5bc25ccbc6734fe02f6ad0dd92a9..14982ffa8498bd7fee14dc26244f1c98cb029589 100644 (file)
@@ -2990,11 +2990,10 @@ verify_types_in_gimple_reference (tree expr, bool require_lvalue)
     }
   else if (TREE_CODE (expr) == TARGET_MEM_REF)
     {
-      if (TMR_SYMBOL (expr)
-         && TMR_BASE (expr)
-         && !useless_type_conversion_p (sizetype, TREE_TYPE (TMR_BASE (expr))))
+      if (!TMR_BASE (expr)
+         || !is_gimple_mem_ref_addr (TMR_BASE (expr)))
        {
-         error ("Non-sizetype base in TARGET_MEM_REF with symbol");
+         error ("Invalid address operand in in TARGET_MEM_REF.");
          return true;
        }
       if (!TMR_OFFSET (expr)
index c60e107f7b19697538427ff05bc8f1bba858770e..0bc9f41755a90bdad5b8b84640ef4b9cba206a10 100644 (file)
@@ -880,19 +880,19 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset,
 
        case TARGET_MEM_REF:
          /* Hand back the decl for MEM[&decl, off].  */
-         if (TMR_SYMBOL (exp))
+         if (TREE_CODE (TMR_BASE (exp)) == ADDR_EXPR)
            {
-             /* Via the variable index or base we can reach the
+             /* Via the variable index or index2 we can reach the
                 whole object.  */
-             if (TMR_INDEX (exp) || TMR_BASE (exp))
+             if (TMR_INDEX (exp) || TMR_INDEX2 (exp))
                {
-                 exp = TREE_OPERAND (TMR_SYMBOL (exp), 0);
+                 exp = TREE_OPERAND (TMR_BASE (exp), 0);
                  bit_offset = 0;
                  maxsize = -1;
                  goto done;
                }
              if (integer_zerop (TMR_OFFSET (exp)))
-               exp = TREE_OPERAND (TMR_SYMBOL (exp), 0);
+               exp = TREE_OPERAND (TMR_BASE (exp), 0);
              else
                {
                  double_int off = mem_ref_offset (exp);
@@ -904,7 +904,7 @@ get_ref_base_and_extent (tree exp, HOST_WIDE_INT *poffset,
                  if (double_int_fits_in_shwi_p (off))
                    {
                      bit_offset = double_int_to_shwi (off);
-                     exp = TREE_OPERAND (TMR_SYMBOL (exp), 0);
+                     exp = TREE_OPERAND (TMR_BASE (exp), 0);
                    }
                }
            }
@@ -1044,9 +1044,9 @@ get_addr_base_and_unit_offset (tree exp, HOST_WIDE_INT *poffset)
 
        case TARGET_MEM_REF:
          /* Hand back the decl for MEM[&decl, off].  */
-         if (TMR_SYMBOL (exp))
+         if (TREE_CODE (TMR_BASE (exp)) == ADDR_EXPR)
            {
-             if (TMR_INDEX (exp) || TMR_BASE (exp))
+             if (TMR_INDEX (exp) || TMR_INDEX2 (exp))
                return NULL_TREE;
              if (!integer_zerop (TMR_OFFSET (exp)))
                {
@@ -1054,7 +1054,7 @@ get_addr_base_and_unit_offset (tree exp, HOST_WIDE_INT *poffset)
                  gcc_assert (off.high == -1 || off.high == 0);
                  byte_offset += double_int_to_shwi (off);
                }
-             exp = TREE_OPERAND (TMR_SYMBOL (exp), 0);
+             exp = TREE_OPERAND (TMR_BASE (exp), 0);
            }
          goto done;
 
index 3d7859ba6f40bb0771478ea884d6b6dc6f0129c6..1faa682fbd9ad4e8213177d122e507d6ee6f373a 100644 (file)
@@ -2404,8 +2404,8 @@ tree_could_trap_p (tree expr)
   switch (code)
     {
     case TARGET_MEM_REF:
-      if (TMR_SYMBOL (expr)
-         && !TMR_INDEX (expr) && !TMR_BASE (expr))
+      if (TREE_CODE (TMR_BASE (expr)) == ADDR_EXPR
+         && !TMR_INDEX (expr) && !TMR_INDEX2 (expr))
        return false;
       return !TREE_THIS_NOTRAP (expr);
 
index dbbd06cc6aef72cc2785b977b5369914014dba41..2c697ec500dddda3399afb87118b96a484743aed 100644 (file)
@@ -852,16 +852,22 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
 
        pp_string (buffer, "MEM[");
 
-       tmp = TMR_SYMBOL (node);
-       if (tmp)
+       if (TREE_CODE (TMR_BASE (node)) == ADDR_EXPR)
          {
            pp_string (buffer, sep);
            sep = ", ";
            pp_string (buffer, "symbol: ");
-           dump_generic_node (buffer, TREE_OPERAND (tmp, 0),
+           dump_generic_node (buffer, TREE_OPERAND (TMR_BASE (node), 0),
                               spc, flags, false);
          }
-       tmp = TMR_BASE (node);
+       else
+         {
+           pp_string (buffer, sep);
+           sep = ", ";
+           pp_string (buffer, "base: ");
+           dump_generic_node (buffer, TMR_BASE (node), spc, flags, false);
+         }
+       tmp = TMR_INDEX2 (node);
        if (tmp)
          {
            pp_string (buffer, sep);
index d642425df3a89a401c52d4da04af4b174269416a..99b87bbd198150b1cdc66373152dfe6b119ad6db 100644 (file)
@@ -268,17 +268,9 @@ tree_mem_ref_addr (tree type, tree mem_ref)
   tree addr;
   tree act_elem;
   tree step = TMR_STEP (mem_ref), offset = TMR_OFFSET (mem_ref);
-  tree sym = TMR_SYMBOL (mem_ref), base = TMR_BASE (mem_ref);
   tree addr_base = NULL_TREE, addr_off = NULL_TREE;
 
-  if (sym)
-    addr_base = fold_convert (type, sym);
-  else if (base)
-    {
-      gcc_assert (POINTER_TYPE_P (TREE_TYPE (base)));
-      addr_base = fold_convert (type, base);
-      base = NULL_TREE;
-    }
+  addr_base = fold_convert (type, TMR_BASE (mem_ref));
 
   act_elem = TMR_INDEX (mem_ref);
   if (act_elem)
@@ -288,7 +280,7 @@ tree_mem_ref_addr (tree type, tree mem_ref)
       addr_off = act_elem;
     }
 
-  act_elem = base;
+  act_elem = TMR_INDEX2 (mem_ref);
   if (act_elem)
     {
       if (addr_off)
@@ -307,16 +299,9 @@ tree_mem_ref_addr (tree type, tree mem_ref)
     }
 
   if (addr_off)
-    {
-      if (addr_base)
-       addr = fold_build2 (POINTER_PLUS_EXPR, type, addr_base, addr_off);
-      else
-       addr = fold_convert (type, addr_off);
-    }
-  else if (addr_base)
-    addr = addr_base;
+    addr = fold_build2 (POINTER_PLUS_EXPR, type, addr_base, addr_off);
   else
-    addr = build_int_cst (type, 0);
+    addr = addr_base;
 
   return addr;
 }
@@ -344,6 +329,8 @@ valid_mem_ref_p (enum machine_mode mode, addr_space_t as,
 static tree
 create_mem_ref_raw (tree type, tree alias_ptr_type, struct mem_address *addr)
 {
+  tree base, index2;
+
   if (!valid_mem_ref_p (TYPE_MODE (type), TYPE_ADDR_SPACE (type), addr))
     return NULL_TREE;
 
@@ -355,23 +342,31 @@ create_mem_ref_raw (tree type, tree alias_ptr_type, struct mem_address *addr)
   else
     addr->offset = build_int_cst (alias_ptr_type, 0);
 
-  /* If possible use a plain MEM_REF instead of a TARGET_MEM_REF.  */
-  if (alias_ptr_type
-      && (!addr->index || integer_zerop (addr->index))
-      && (!addr->base || POINTER_TYPE_P (TREE_TYPE (addr->base))))
+  if (addr->symbol)
     {
-      tree base;
-      gcc_assert (!addr->symbol ^ !addr->base);
-      if (addr->symbol)
-       base = addr->symbol;
-      else
-       base = addr->base;
-      return fold_build2 (MEM_REF, type, base, addr->offset);
+      base = addr->symbol;
+      index2 = addr->base;
+    }
+  else if (addr->base
+          && POINTER_TYPE_P (TREE_TYPE (addr->base)))
+    {
+      base = addr->base;
+      index2 = NULL_TREE;
     }
+  else
+    {
+      base = build_int_cst (ptr_type_node, 0);
+      index2 = addr->base;
+    }
+
+  /* If possible use a plain MEM_REF instead of a TARGET_MEM_REF.  */
+  if (alias_ptr_type
+      && (!index2 || integer_zerop (index2))
+      && (!addr->index || integer_zerop (addr->index)))
+    return fold_build2 (MEM_REF, type, base, addr->offset);
 
   return build5 (TARGET_MEM_REF, type,
-                addr->symbol, addr->base, addr->index,
-                addr->step, addr->offset);
+                base, addr->offset, addr->index, addr->step, index2);
 }
 
 /* Returns true if OBJ is an object whose address is a link time constant.  */
@@ -808,8 +803,22 @@ create_mem_ref (gimple_stmt_iterator *gsi, tree type, aff_tree *addr,
 void
 get_address_description (tree op, struct mem_address *addr)
 {
-  addr->symbol = TMR_SYMBOL (op);
-  addr->base = TMR_BASE (op);
+  if (TREE_CODE (TMR_BASE (op)) == ADDR_EXPR)
+    {
+      addr->symbol = TMR_BASE (op);
+      addr->base = TMR_INDEX2 (op);
+    }
+  else
+    {
+      addr->symbol = NULL_TREE;
+      if (TMR_INDEX2 (op))
+       {
+         gcc_assert (integer_zerop (TMR_BASE (op)));
+         addr->base = TMR_INDEX2 (op);
+       }
+      else
+       addr->base = TMR_BASE (op);
+    }
   addr->index = TMR_INDEX (op);
   addr->step = TMR_STEP (op);
   addr->offset = TMR_OFFSET (op);
@@ -837,7 +846,9 @@ maybe_fold_tmr (tree ref)
 
   get_address_description (ref, &addr);
 
-  if (addr.base && TREE_CODE (addr.base) == INTEGER_CST)
+  if (addr.base
+      && TREE_CODE (addr.base) == INTEGER_CST
+      && !integer_zerop (addr.base))
     {
       addr.offset = fold_binary_to_constant (PLUS_EXPR,
                                             TREE_TYPE (addr.offset),
@@ -846,6 +857,28 @@ maybe_fold_tmr (tree ref)
       changed = true;
     }
 
+  if (addr.symbol
+      && TREE_CODE (TREE_OPERAND (addr.symbol, 0)) == MEM_REF)
+    {
+      addr.offset = fold_binary_to_constant
+                       (PLUS_EXPR, TREE_TYPE (addr.offset),
+                        addr.offset,
+                        TREE_OPERAND (TREE_OPERAND (addr.symbol, 0), 1));
+      addr.symbol = TREE_OPERAND (TREE_OPERAND (addr.symbol, 0), 0);
+      changed = true;
+    }
+  else if (addr.symbol
+          && handled_component_p (TREE_OPERAND (addr.symbol, 0)))
+    {
+      HOST_WIDE_INT offset;
+      addr.symbol = build_fold_addr_expr
+                     (get_addr_base_and_unit_offset
+                        (TREE_OPERAND (addr.symbol, 0), &offset));
+      addr.offset = int_const_binop (PLUS_EXPR,
+                                    addr.offset, size_int (offset), 0);
+      changed = true;
+    }
+
   if (addr.index && TREE_CODE (addr.index) == INTEGER_CST)
     {
       off = addr.index;
index fe017d7a15ec5926929b175ed9b75cada7f46ae3..a9f1c19f7acb38903b4634b6135780c80720a083 100644 (file)
@@ -670,21 +670,7 @@ indirect_ref_may_alias_decl_p (tree ref1 ATTRIBUTE_UNUSED, tree base1,
   tree ptrtype1;
   HOST_WIDE_INT offset1p = offset1, offset2p = offset2;
 
-  if (TREE_CODE (base1) == TARGET_MEM_REF)
-    {
-      if (TMR_SYMBOL (base1))
-       ptr1 = TMR_SYMBOL (base1);
-      else if (TMR_BASE (base1))
-       {
-         if (!POINTER_TYPE_P (TREE_TYPE (TMR_BASE (base1))))
-           return true;
-         ptr1 = TMR_BASE (base1);
-       }
-      else
-       return true;
-    }
-  else
-    ptr1 = TREE_OPERAND (base1, 0);
+  ptr1 = TREE_OPERAND (base1, 0);
 
   /* The offset embedded in MEM_REFs can be negative.  Bias them
      so that the resulting offset adjustment is positive.  */
@@ -812,37 +798,8 @@ indirect_refs_may_alias_p (tree ref1 ATTRIBUTE_UNUSED, tree base1,
   tree ptr2;
   tree ptrtype1, ptrtype2;
 
-  if (TREE_CODE (base1) == TARGET_MEM_REF)
-    {
-      if (TMR_SYMBOL (base1))
-       ptr1 = TMR_SYMBOL (base1);
-      else if (TMR_BASE (base1))
-       {
-         if (!POINTER_TYPE_P (TREE_TYPE (TMR_BASE (base1))))
-           return true;
-         ptr1 = TMR_BASE (base1);
-       }
-      else
-       return true;
-    }
-  else
-    ptr1 = TREE_OPERAND (base1, 0);
-
-  if (TREE_CODE (base2) == TARGET_MEM_REF)
-    {
-      if (TMR_SYMBOL (base2))
-       ptr2 = TMR_SYMBOL (base2);
-      else if (TMR_BASE (base2))
-       {
-         if (!POINTER_TYPE_P (TREE_TYPE (TMR_BASE (base2))))
-           return true;
-         ptr2 = TMR_BASE (base2);
-       }
-      else
-       return true;
-    }
-  else
-    ptr2 = TREE_OPERAND (base2, 0);
+  ptr1 = TREE_OPERAND (base1, 0);
+  ptr2 = TREE_OPERAND (base2, 0);
 
   /* If both bases are based on pointers they cannot alias if they may not
      point to the same memory object or if they point to the same object
index 9b5c3583332939d9778054092c25d136026f4cdc..715b5a71c0744a35cac4aa4fc3722e5cbf8ad41b 100644 (file)
@@ -362,13 +362,13 @@ mark_all_vars_used_1 (tree *tp, int *walk_subtrees, void *data)
       && (b = TREE_BLOCK (t)) != NULL)
     TREE_USED (b) = true;
 
-  /* Ignore TREE_ORIGINAL for TARGET_MEM_REFS, as well as other
-     fields that do not contain vars.  */
+  /* Ignore TMR_OFFSET and TMR_STEP for TARGET_MEM_REFS, as those
+     fields do not contain vars.  */
   if (TREE_CODE (t) == TARGET_MEM_REF)
     {
-      mark_all_vars_used (&TMR_SYMBOL (t), data);
       mark_all_vars_used (&TMR_BASE (t), data);
       mark_all_vars_used (&TMR_INDEX (t), data);
+      mark_all_vars_used (&TMR_INDEX2 (t), data);
       *walk_subtrees = 0;
       return NULL;
     }
index 477c4d2b260dd96ebeaf13ff8955e29fcb623568..3e71b5c19637e73e5167ef06b23e0551e3bae350 100644 (file)
@@ -324,6 +324,10 @@ for_each_index (tree *addr_p, bool (*cbck) (tree, tree *, void *), void *data)
              && !cbck (*addr_p, idx, data))
            return false;
          idx = &TMR_INDEX (*addr_p);
+         if (*idx
+             && !cbck (*addr_p, idx, data))
+           return false;
+         idx = &TMR_INDEX2 (*addr_p);
          if (*idx
              && !cbck (*addr_p, idx, data))
            return false;
index 78bbd8eb296bfab7ca5c36981a0b221e75f1ba44..0a1c44ec964019df64a83079d2eb8151578ecfda 100644 (file)
@@ -1722,6 +1722,16 @@ find_interesting_uses_address (struct ivopts_data *data, gimple stmt, tree *op_p
          TMR_BASE (base) = civ->base;
          step = civ->step;
        }
+      if (TMR_INDEX2 (base)
+         && TREE_CODE (TMR_INDEX2 (base)) == SSA_NAME)
+       {
+         civ = get_iv (data, TMR_INDEX2 (base));
+         if (!civ)
+           goto fail;
+
+         TMR_INDEX2 (base) = civ->base;
+         step = civ->step;
+       }
       if (TMR_INDEX (base)
          && TREE_CODE (TMR_INDEX (base)) == SSA_NAME)
        {
@@ -1778,9 +1788,14 @@ find_interesting_uses_address (struct ivopts_data *data, gimple stmt, tree *op_p
            ref = &TREE_OPERAND (*ref, 0);
          if (TREE_CODE (*ref) == MEM_REF)
            {
-             tree tem = fold_binary (MEM_REF, TREE_TYPE (*ref),
-                                     TREE_OPERAND (*ref, 0),
-                                     TREE_OPERAND (*ref, 1));
+             tree tem = TREE_OPERAND (*ref, 0);
+             STRIP_NOPS (tem);
+             if (tem != TREE_OPERAND (*ref, 0))
+               tem = fold_build2 (MEM_REF, TREE_TYPE (*ref),
+                                  tem, TREE_OPERAND (*ref, 1));
+             else
+               tem = fold_binary (MEM_REF, TREE_TYPE (*ref),
+                                  tem, TREE_OPERAND (*ref, 1));
              if (tem)
                *ref = tem;
            }
index 90c2460d80e8e599ac4536fe2ced670d26ad17b2..09f12ef52ba5c4686fb5ced8ba3c45307452ece9 100644 (file)
@@ -754,9 +754,7 @@ get_tmr_operands (gimple stmt, tree expr, int flags)
   /* First record the real operands.  */
   get_expr_operands (stmt, &TMR_BASE (expr), opf_use | (flags & opf_no_vops));
   get_expr_operands (stmt, &TMR_INDEX (expr), opf_use | (flags & opf_no_vops));
-
-  if (TMR_SYMBOL (expr))
-    mark_address_taken (TREE_OPERAND (TMR_SYMBOL (expr), 0));
+  get_expr_operands (stmt, &TMR_INDEX2 (expr), opf_use | (flags & opf_no_vops));
 
   add_virtual_operand (stmt, flags);
 }
index fd3da9e9a208adcf0044fe905cc5bd6e3b01cb15..6e457208b5f178ff6b97191a75b39af1e379559a 100644 (file)
@@ -2772,8 +2772,10 @@ create_component_ref_by_pieces_1 (basic_block block, vn_reference_t ref,
       break;
     case TARGET_MEM_REF:
       {
-       pre_expr op0expr;
-       tree genop0 = NULL_TREE;
+       pre_expr op0expr, op1expr;
+       tree genop0 = NULL_TREE, genop1 = NULL_TREE;
+       vn_reference_op_t nextop = VEC_index (vn_reference_op_s, ref->operands,
+                                             ++*operand);
        tree baseop = create_component_ref_by_pieces_1 (block, ref, operand,
                                                        stmts, domstmt);
        if (!baseop)
@@ -2786,14 +2788,16 @@ create_component_ref_by_pieces_1 (basic_block block, vn_reference_t ref,
            if (!genop0)
              return NULL_TREE;
          }
-       if (DECL_P (baseop))
-         return build5 (TARGET_MEM_REF, currop->type,
-                        baseop, NULL_TREE,
-                        genop0, currop->op1, currop->op2);
-       else
-         return build5 (TARGET_MEM_REF, currop->type,
-                        NULL_TREE, baseop,
-                        genop0, currop->op1, currop->op2);
+       if (nextop->op0)
+         {
+           op1expr = get_or_alloc_expr_for (nextop->op0);
+           genop1 = find_or_generate_expression (block, op1expr,
+                                                 stmts, domstmt);
+           if (!genop1)
+             return NULL_TREE;
+         }
+       return build5 (TARGET_MEM_REF, currop->type,
+                      baseop, currop->op2, genop0, currop->op1, genop1);
       }
       break;
     case ADDR_EXPR:
index cbf0e25712f4224971a9ca58173dc7a53e9454c3..c440a28f413cb3df76bf106f9f7e698adb3fd852 100644 (file)
@@ -575,11 +575,6 @@ copy_reference_ops_from_ref (tree ref, VEC(vn_reference_op_s, heap) **result)
   if (TREE_CODE (ref) == TARGET_MEM_REF)
     {
       vn_reference_op_s temp;
-      tree base;
-
-      base = TMR_SYMBOL (ref) ? TMR_SYMBOL (ref) : TMR_BASE (ref);
-      if (!base)
-       base = null_pointer_node;
 
       memset (&temp, 0, sizeof (temp));
       /* We do not care for spurious type qualifications.  */
@@ -593,8 +588,15 @@ copy_reference_ops_from_ref (tree ref, VEC(vn_reference_op_s, heap) **result)
 
       memset (&temp, 0, sizeof (temp));
       temp.type = NULL_TREE;
-      temp.opcode = TREE_CODE (base);
-      temp.op0 = base;
+      temp.opcode = ERROR_MARK;
+      temp.op0 = TMR_INDEX2 (ref);
+      temp.off = -1;
+      VEC_safe_push (vn_reference_op_s, heap, *result, &temp);
+
+      memset (&temp, 0, sizeof (temp));
+      temp.type = NULL_TREE;
+      temp.opcode = TREE_CODE (TMR_BASE (ref));
+      temp.op0 = TMR_BASE (ref);
       temp.off = -1;
       VEC_safe_push (vn_reference_op_s, heap, *result, &temp);
       return;
index 9deec26b11d5bbcc461247a5385a64ed6fcddcf6..436047b8e93f4d5cbf28a49752e8b08b7dd041d1 100644 (file)
@@ -191,7 +191,8 @@ is_hidden_global_store (gimple stmt)
 
        }
       else if (INDIRECT_REF_P (lhs)
-              || TREE_CODE (lhs) == MEM_REF)
+              || TREE_CODE (lhs) == MEM_REF
+              || TREE_CODE (lhs) == TARGET_MEM_REF)
        return ptr_deref_may_alias_global_p (TREE_OPERAND (lhs, 0));
       else if (CONSTANT_CLASS_P (lhs))
        return true;
index 55275fa0a787cff34ce8e0a1d448152a951351f0..4659a105d32b97368a91e5d6560a1d6e014a810e 100644 (file)
@@ -3910,7 +3910,7 @@ build_simple_mem_ref_loc (location_t loc, tree ptr)
 double_int
 mem_ref_offset (const_tree t)
 {
-  tree toff = TREE_CODE (t) == MEM_REF ? TREE_OPERAND (t, 1) : TMR_OFFSET (t);
+  tree toff = TREE_OPERAND (t, 1);
   return double_int_sext (tree_to_double_int (toff),
                          TYPE_PRECISION (TREE_TYPE (toff)));
 }
index bd8434aa095fc3765cdafee04723829c1ddd0200..43bdd42ea9492297fb46c8bdd5e41083def977c4 100644 (file)
@@ -952,14 +952,16 @@ DEFTREECODE (WITH_SIZE_EXPR, "with_size_expr", tcc_expression, 2)
    generated by the builtin targetm.vectorize.mask_for_load_builtin_decl.  */
 DEFTREECODE (REALIGN_LOAD_EXPR, "realign_load", tcc_expression, 3)
 
-/* Low-level memory addressing.  Operands are SYMBOL (address of static or
-   global variable), BASE (register), INDEX (register), STEP (integer constant),
-   OFFSET (integer constant).  Corresponding address is
-   SYMBOL + BASE + STEP * INDEX + OFFSET.  Only variations and values valid on
-   the target are allowed.
-
-   The type of STEP and INDEX is sizetype.  The type of BASE is
-   sizetype or a pointer type (if SYMBOL is NULL).
+/* Low-level memory addressing.  Operands are BASE (address of static or
+   global variable or register), OFFSET (integer constant),
+   INDEX (register), STEP (integer constant), INDEX2 (register),
+   The corresponding address is BASE + STEP * INDEX + INDEX2 + OFFSET.
+   Only variations and values valid on the target are allowed.
+
+   The type of STEP, INDEX and INDEX2 is sizetype.
+
+   The type of BASE is a pointer type.  If BASE is not an address of
+   a static or global variable INDEX2 will be NULL.
 
    The type of OFFSET is a pointer type and determines TBAA the same as
    the constant offset operand in MEM_REF.  */
index 17eeba7e81c51718b3712113c59075b4ad27f3d5..e667742c2bbba23fd7a749ce58a58eac686e2926 100644 (file)
@@ -1632,12 +1632,13 @@ extern void protected_set_expr_location (tree, location_t);
 #define CASE_HIGH(NODE)                TREE_OPERAND (CASE_LABEL_EXPR_CHECK (NODE), 1)
 #define CASE_LABEL(NODE)               TREE_OPERAND (CASE_LABEL_EXPR_CHECK (NODE), 2)
 
-/* The operands of a TARGET_MEM_REF.  */
-#define TMR_SYMBOL(NODE) (TREE_OPERAND (TARGET_MEM_REF_CHECK (NODE), 0))
-#define TMR_BASE(NODE) (TREE_OPERAND (TARGET_MEM_REF_CHECK (NODE), 1))
+/* The operands of a TARGET_MEM_REF.  Operands 0 and 1 have to match
+   corresponding MEM_REF operands.  */
+#define TMR_BASE(NODE) (TREE_OPERAND (TARGET_MEM_REF_CHECK (NODE), 0))
+#define TMR_OFFSET(NODE) (TREE_OPERAND (TARGET_MEM_REF_CHECK (NODE), 1))
 #define TMR_INDEX(NODE) (TREE_OPERAND (TARGET_MEM_REF_CHECK (NODE), 2))
 #define TMR_STEP(NODE) (TREE_OPERAND (TARGET_MEM_REF_CHECK (NODE), 3))
-#define TMR_OFFSET(NODE) (TREE_OPERAND (TARGET_MEM_REF_CHECK (NODE), 4))
+#define TMR_INDEX2(NODE) (TREE_OPERAND (TARGET_MEM_REF_CHECK (NODE), 4))
 
 /* The operands of a BIND_EXPR.  */
 #define BIND_EXPR_VARS(NODE) (TREE_OPERAND (BIND_EXPR_CHECK (NODE), 0))