2010-08-10 Richard Guenther <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 10 Aug 2010 09:16:22 +0000 (09:16 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 10 Aug 2010 09:16:22 +0000 (09:16 +0000)
* tree.h (get_object_alignment): Adjust prototype.
* builtins.c (get_object_alignment): Return unsigned int,
drop the align parameter.  Handle MEM_REF, MISALIGNED_INDIRECT_REF
and TARGET_MEM_REF properly.
(get_pointer_alignment): Adjust.
* emit-rtl.c (get_mem_align_offset): Adjust comment.
(set_mem_attributes_minus_bitpos): Adjust.
* tree-ssa-ccp.c (get_value_from_alignment): Adjust.

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

gcc/ChangeLog
gcc/builtins.c
gcc/emit-rtl.c
gcc/tree-ssa-ccp.c
gcc/tree.h

index 5b066a6..49a95d0 100644 (file)
@@ -1,5 +1,16 @@
 2010-08-10  Richard Guenther  <rguenther@suse.de>
 
+       * tree.h (get_object_alignment): Adjust prototype.
+       * builtins.c (get_object_alignment): Return unsigned int,
+       drop the align parameter.  Handle MEM_REF, MISALIGNED_INDIRECT_REF
+       and TARGET_MEM_REF properly.
+       (get_pointer_alignment): Adjust.
+       * emit-rtl.c (get_mem_align_offset): Adjust comment.
+       (set_mem_attributes_minus_bitpos): Adjust.
+       * tree-ssa-ccp.c (get_value_from_alignment): Adjust.
+
+2010-08-10  Richard Guenther  <rguenther@suse.de>
+
        * tree-ssa-copy.c (set_copy_of_val): Use operand_equal_p.
        (copy_prop_visit_assignment): Simplify.
        (copy_prop_visit_stmt): Also visit assignments from
index 3b9ca5a..3d5ca33 100644 (file)
@@ -267,81 +267,135 @@ called_as_built_in (tree node)
 }
 
 /* Return the alignment in bits of EXP, an object.
-   Don't return more than MAX_ALIGN no matter what, ALIGN is the inital
-   guessed alignment e.g. from type alignment.  */
+   Don't return more than MAX_ALIGN no matter what.  */
 
-int
-get_object_alignment (tree exp, unsigned int align, unsigned int max_align)
+unsigned int
+get_object_alignment (tree exp, unsigned int max_align)
 {
-  unsigned int inner;
-
-  inner = max_align;
-  if (handled_component_p (exp))
-   {
-      HOST_WIDE_INT bitsize, bitpos;
-      tree offset;
-      enum machine_mode mode;
-      int unsignedp, volatilep;
+  HOST_WIDE_INT bitsize, bitpos;
+  tree offset;
+  enum machine_mode mode;
+  int unsignedp, volatilep;
+  unsigned int align, inner;
 
-      exp = get_inner_reference (exp, &bitsize, &bitpos, &offset,
-                                &mode, &unsignedp, &volatilep, true);
-      if (bitpos)
-       inner = MIN (inner, (unsigned) (bitpos & -bitpos));
-      while (offset)
-       {
-         tree next_offset;
+  /* Get the innermost object and the constant (bitpos) and possibly
+     variable (offset) offset of the access.  */
+  exp = get_inner_reference (exp, &bitsize, &bitpos, &offset,
+                            &mode, &unsignedp, &volatilep, true);
 
-         if (TREE_CODE (offset) == PLUS_EXPR)
-           {
-             next_offset = TREE_OPERAND (offset, 0);
-             offset = TREE_OPERAND (offset, 1);
-           }
-         else
-           next_offset = NULL;
-         if (host_integerp (offset, 1))
-           {
-             /* Any overflow in calculating offset_bits won't change
-                the alignment.  */
-             unsigned offset_bits
-               = ((unsigned) tree_low_cst (offset, 1) * BITS_PER_UNIT);
-
-             if (offset_bits)
-               inner = MIN (inner, (offset_bits & -offset_bits));
-           }
-         else if (TREE_CODE (offset) == MULT_EXPR
-                  && host_integerp (TREE_OPERAND (offset, 1), 1))
-           {
-             /* Any overflow in calculating offset_factor won't change
-                the alignment.  */
-             unsigned offset_factor
-               = ((unsigned) tree_low_cst (TREE_OPERAND (offset, 1), 1)
-                  * BITS_PER_UNIT);
-
-             if (offset_factor)
-               inner = MIN (inner, (offset_factor & -offset_factor));
-           }
-         else
-           {
-             inner = MIN (inner, BITS_PER_UNIT);
-             break;
-           }
-         offset = next_offset;
-       }
-    }
+  /* Extract alignment information from the innermost object and
+     possibly adjust bitpos and offset.  */
   if (TREE_CODE (exp) == CONST_DECL)
     exp = DECL_INITIAL (exp);
   if (DECL_P (exp)
       && TREE_CODE (exp) != LABEL_DECL)
-    align = MIN (inner, DECL_ALIGN (exp));
-#ifdef CONSTANT_ALIGNMENT
+    align = DECL_ALIGN (exp);
   else if (CONSTANT_CLASS_P (exp))
-    align = MIN (inner, (unsigned)CONSTANT_ALIGNMENT (exp, align));
+    {
+      align = TYPE_ALIGN (TREE_TYPE (exp));
+#ifdef CONSTANT_ALIGNMENT
+      align = (unsigned)CONSTANT_ALIGNMENT (exp, align);
 #endif
-  else if (TREE_CODE (exp) == VIEW_CONVERT_EXPR
-          || TREE_CODE (exp) == INDIRECT_REF)
-    align = MIN (TYPE_ALIGN (TREE_TYPE (exp)), inner);
+    }
+  else if (TREE_CODE (exp) == VIEW_CONVERT_EXPR)
+    align = TYPE_ALIGN (TREE_TYPE (exp));
+  else if (TREE_CODE (exp) == INDIRECT_REF)
+    align = TYPE_ALIGN (TREE_TYPE (exp));
+  else if (TREE_CODE (exp) == MISALIGNED_INDIRECT_REF)
+    {
+      tree op1 = TREE_OPERAND (exp, 1);
+      align = integer_zerop (op1) ? BITS_PER_UNIT : TREE_INT_CST_LOW (op1);
+    }
+  else if (TREE_CODE (exp) == MEM_REF)
+    {
+      tree addr = TREE_OPERAND (exp, 0);
+      if (TREE_CODE (addr) == BIT_AND_EXPR
+         && TREE_CODE (TREE_OPERAND (addr, 1)) == INTEGER_CST)
+       {
+         align = (TREE_INT_CST_LOW (TREE_OPERAND (addr, 1))
+                   & -TREE_INT_CST_LOW (TREE_OPERAND (addr, 1)));
+         align *= BITS_PER_UNIT;
+         addr = TREE_OPERAND (addr, 0);
+       }
+      else
+       align = BITS_PER_UNIT;
+      if (TREE_CODE (addr) == ADDR_EXPR)
+       align = MAX (align, get_object_alignment (TREE_OPERAND (addr, 0),
+                                                 max_align));
+      bitpos += mem_ref_offset (exp).low * BITS_PER_UNIT;
+    }
+  else if (TREE_CODE (exp) == TARGET_MEM_REF
+          && TMR_SYMBOL (exp))
+    {
+      align = get_object_alignment (TMR_SYMBOL (exp), 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;
+    }
   else
-    align = MIN (align, inner);
+    align = BITS_PER_UNIT;
+
+  /* If there is a non-constant offset part extract the maximum
+     alignment that can prevail.  */
+  inner = max_align;
+  while (offset)
+    {
+      tree next_offset;
+
+      if (TREE_CODE (offset) == PLUS_EXPR)
+       {
+         next_offset = TREE_OPERAND (offset, 0);
+         offset = TREE_OPERAND (offset, 1);
+       }
+      else
+       next_offset = NULL;
+      if (host_integerp (offset, 1))
+       {
+         /* Any overflow in calculating offset_bits won't change
+            the alignment.  */
+         unsigned offset_bits
+           = ((unsigned) tree_low_cst (offset, 1) * BITS_PER_UNIT);
+
+         if (offset_bits)
+           inner = MIN (inner, (offset_bits & -offset_bits));
+       }
+      else if (TREE_CODE (offset) == MULT_EXPR
+              && host_integerp (TREE_OPERAND (offset, 1), 1))
+       {
+         /* Any overflow in calculating offset_factor won't change
+            the alignment.  */
+         unsigned offset_factor
+           = ((unsigned) tree_low_cst (TREE_OPERAND (offset, 1), 1)
+              * BITS_PER_UNIT);
+
+         if (offset_factor)
+           inner = MIN (inner, (offset_factor & -offset_factor));
+       }
+      else
+       {
+         inner = MIN (inner, BITS_PER_UNIT);
+         break;
+       }
+      offset = next_offset;
+    }
+
+  /* Alignment is innermost object alignment adjusted by the constant
+     and non-constant offset parts.  */
+  align = MIN (align, inner);
+  bitpos = bitpos & (align - 1);
+
+  /* align and bitpos now specify known low bits of the pointer.
+     ptr & (align - 1) == bitpos.  */
+
+  if (bitpos != 0)
+    align = (bitpos & -bitpos);
+
   return MIN (align, max_align);
 }
 
@@ -407,7 +461,7 @@ get_pointer_alignment (tree exp, unsigned int max_align)
 
        case ADDR_EXPR:
          /* See what we are pointing at and look at its alignment.  */
-         return get_object_alignment (TREE_OPERAND (exp, 0), align, max_align);
+         return get_object_alignment (TREE_OPERAND (exp, 0), max_align);
 
        default:
          return align;
index 91c5d85..267d634 100644 (file)
@@ -1459,7 +1459,8 @@ get_mem_align_offset (rtx mem, unsigned int align)
   /* This function can't use
      if (!MEM_EXPR (mem) || !MEM_OFFSET (mem)
         || !CONST_INT_P (MEM_OFFSET (mem))
-        || (get_object_alignment (MEM_EXPR (mem), MEM_ALIGN (mem), align)
+        || (MAX (MEM_ALIGN (mem),
+                 get_object_alignment (MEM_EXPR (mem), align))
             < align))
        return -1;
      else
@@ -1796,8 +1797,7 @@ set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp,
 
       if (!align_computed && !INDIRECT_REF_P (t))
        {
-         unsigned int obj_align
-           = get_object_alignment (t, align, BIGGEST_ALIGNMENT);
+         unsigned int obj_align = get_object_alignment (t, BIGGEST_ALIGNMENT);
          align = MAX (align, obj_align);
        }
     }
index a016584..622fe14 100644 (file)
@@ -515,8 +515,7 @@ get_value_from_alignment (tree expr)
     val = bit_value_binop (PLUS_EXPR, TREE_TYPE (expr),
                           TREE_OPERAND (base, 0), TREE_OPERAND (base, 1));
   else if (base
-          && ((align = get_object_alignment (base, BITS_PER_UNIT,
-                                             BIGGEST_ALIGNMENT))
+          && ((align = get_object_alignment (base, BIGGEST_ALIGNMENT))
                > BITS_PER_UNIT))
     {
       val.lattice_val = CONSTANT;
index 271b1fb..bdf4f72 100644 (file)
@@ -5036,7 +5036,7 @@ extern bool can_trust_pointer_alignment (void);
 extern int get_pointer_alignment (tree, unsigned int);
 extern bool is_builtin_name (const char *);
 extern bool is_builtin_fn (tree);
-extern int get_object_alignment (tree, unsigned int, unsigned int);
+extern unsigned int get_object_alignment (tree, unsigned int);
 extern tree fold_call_stmt (gimple, bool);
 extern tree gimple_fold_builtin_snprintf_chk (gimple, tree, enum built_in_function);
 extern tree make_range (tree, int *, tree *, tree *, bool *);