builtins.c (get_object_alignment_1): Return whether we can determine the alignment...
authorMartin Jambor <mjambor@suse.cz>
Thu, 3 May 2012 15:48:56 +0000 (17:48 +0200)
committerMartin Jambor <jamborm@gcc.gnu.org>
Thu, 3 May 2012 15:48:56 +0000 (17:48 +0200)
2012-05-03  Martin Jambor  <mjambor@suse.cz>

* builtins.c (get_object_alignment_1): Return whether we can determine
the alignment or conservatively assume byte alignment.  Return the
alignment by reference.  Use get_pointer_alignment_1 for dereference
alignment.
(get_pointer_alignment_1): Return whether we can determine the
alignment or conservatively assume byte alignment.  Return the
alignment by reference.  Use get_ptr_info_alignment to get SSA name
alignment.
(get_object_alignment): Update call to get_object_alignment_1.
(get_object_or_type_alignment): Likewise, fall back to type alignment
only when it returned false.
(get_pointer_alignment): Update call to get_pointer_alignment_1.
* fold-const.c (get_pointer_modulus_and_residue): Update call to
get_object_alignment_1.
* ipa-prop.c (ipa_modify_call_arguments): Update call to
get_pointer_alignment_1.
* tree-sra.c (build_ref_for_offset): Likewise, fall back to the type
of MEM_REF or TARGET_MEM_REF only when it returns false.
* tree-ssa-ccp.c (get_value_from_alignment): Update call to
get_object_alignment_1.
(ccp_finalize): Use set_ptr_info_alignment.
* tree.h (get_object_alignment_1): Update declaration.
(get_pointer_alignment_1): Likewise.
* gimple-pretty-print.c (dump_gimple_phi): Use get_ptr_info_alignment.
(dump_gimple_stmt): Likewise.
* tree-flow.h (ptr_info_def): Updated comments of fields align and
misalign.
(get_ptr_info_alignment): Declared.
(mark_ptr_info_alignment_unknown): Likewise.
(set_ptr_info_alignment): Likewise.
(adjust_ptr_info_misalignment): Likewise.
* tree-ssa-address.c (copy_ref_info): Use new access functions to get
and set alignment of SSA names.
* tree-ssa-loop-ivopts.c (rewrite_use_nonlinear_expr): Call
mark_ptr_info_alignment_unknown.
* tree-ssanames.c (get_ptr_info_alignment): New function.
(mark_ptr_info_alignment_unknown): Likewise.
(set_ptr_info_alignment): Likewise.
(adjust_ptr_info_misalignment): Likewise.
(get_ptr_info): Call mark_ptr_info_alignment_unknown.
* tree-vect-data-refs.c (vect_create_addr_base_for_vector_ref):
Likewise.
(bump_vector_ptr): Likewise.
* tree-vect-stmts.c (create_array_ref): Use set_ptr_info_alignment.
(vectorizable_store): Likewise.
(vectorizable_load): Likewise.

From-SVN: r187101

14 files changed:
gcc/ChangeLog
gcc/builtins.c
gcc/fold-const.c
gcc/gimple-pretty-print.c
gcc/ipa-prop.c
gcc/tree-flow.h
gcc/tree-sra.c
gcc/tree-ssa-address.c
gcc/tree-ssa-ccp.c
gcc/tree-ssa-loop-ivopts.c
gcc/tree-ssanames.c
gcc/tree-vect-data-refs.c
gcc/tree-vect-stmts.c
gcc/tree.h

index 8f3228d..c7eb3b0 100644 (file)
@@ -1,3 +1,52 @@
+2012-05-03  Martin Jambor  <mjambor@suse.cz>
+
+       * builtins.c (get_object_alignment_1): Return whether we can determine
+       the alignment or conservatively assume byte alignment.  Return the
+       alignment by reference.  Use get_pointer_alignment_1 for dereference
+       alignment.
+       (get_pointer_alignment_1): Return whether we can determine the
+       alignment or conservatively assume byte alignment.  Return the
+       alignment by reference.  Use get_ptr_info_alignment to get SSA name
+       alignment.
+       (get_object_alignment): Update call to get_object_alignment_1.
+       (get_object_or_type_alignment): Likewise, fall back to type alignment
+       only when it returned false.
+       (get_pointer_alignment): Update call to get_pointer_alignment_1.
+       * fold-const.c (get_pointer_modulus_and_residue): Update call to
+       get_object_alignment_1.
+       * ipa-prop.c (ipa_modify_call_arguments): Update call to
+       get_pointer_alignment_1.
+       * tree-sra.c (build_ref_for_offset): Likewise, fall back to the type
+       of MEM_REF or TARGET_MEM_REF only when it returns false.
+       * tree-ssa-ccp.c (get_value_from_alignment): Update call to
+       get_object_alignment_1.
+       (ccp_finalize): Use set_ptr_info_alignment.
+       * tree.h (get_object_alignment_1): Update declaration.
+       (get_pointer_alignment_1): Likewise.
+       * gimple-pretty-print.c (dump_gimple_phi): Use get_ptr_info_alignment.
+       (dump_gimple_stmt): Likewise.
+       * tree-flow.h (ptr_info_def): Updated comments of fields align and
+       misalign.
+       (get_ptr_info_alignment): Declared.
+       (mark_ptr_info_alignment_unknown): Likewise.
+       (set_ptr_info_alignment): Likewise.
+       (adjust_ptr_info_misalignment): Likewise.
+       * tree-ssa-address.c (copy_ref_info): Use new access functions to get
+       and set alignment of SSA names.
+       * tree-ssa-loop-ivopts.c (rewrite_use_nonlinear_expr): Call
+       mark_ptr_info_alignment_unknown.
+       * tree-ssanames.c (get_ptr_info_alignment): New function.
+       (mark_ptr_info_alignment_unknown): Likewise.
+       (set_ptr_info_alignment): Likewise.
+       (adjust_ptr_info_misalignment): Likewise.
+       (get_ptr_info): Call mark_ptr_info_alignment_unknown.
+       * tree-vect-data-refs.c (vect_create_addr_base_for_vector_ref):
+       Likewise.
+       (bump_vector_ptr): Likewise.
+       * tree-vect-stmts.c (create_array_ref): Use set_ptr_info_alignment.
+       (vectorizable_store): Likewise.
+       (vectorizable_load): Likewise.
+
 2012-05-03  Michael Matz  <matz@suse.de>
 
        * basic-block.h (struct rtl_bb_info, struct gimple_bb_info): Move
index 72e2591..1ce9ac1 100644 (file)
@@ -263,8 +263,10 @@ called_as_built_in (tree node)
   return is_builtin_name (name);
 }
 
-/* Compute values M and N such that M divides (address of EXP - N) and
-   such that N < M.  Store N in *BITPOSP and return M.
+/* Compute values M and N such that M divides (address of EXP - N) and such
+   that N < M.  If these numbers can be determined, store M in alignp and N in
+   *BITPOSP and return true.  Otherwise return false and store BITS_PER_UNIT to
+   *alignp and any bit-offset to *bitposp.
 
    Note that the address (and thus the alignment) computed here is based
    on the address to which a symbol resolves, whereas DECL_ALIGN is based
@@ -273,14 +275,16 @@ called_as_built_in (tree node)
    the address &foo of a Thumb function foo() has the lowest bit set,
    whereas foo() itself starts on an even address.  */
 
-unsigned int
-get_object_alignment_1 (tree exp, unsigned HOST_WIDE_INT *bitposp)
+bool
+get_object_alignment_1 (tree exp, unsigned int *alignp,
+                       unsigned HOST_WIDE_INT *bitposp)
 {
   HOST_WIDE_INT bitsize, bitpos;
   tree offset;
   enum machine_mode mode;
   int unsignedp, volatilep;
-  unsigned int align, inner;
+  unsigned int inner, align = BITS_PER_UNIT;
+  bool known_alignment = false;
 
   /* Get the innermost object and the constant (bitpos) and possibly
      variable (offset) offset of the access.  */
@@ -301,84 +305,97 @@ get_object_alignment_1 (tree exp, unsigned HOST_WIDE_INT *bitposp)
             allows the low bit to be used as a virtual bit, we know
             that the address itself must be 2-byte aligned.  */
          if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn)
-           align = 2 * BITS_PER_UNIT;
-         else
-           align = BITS_PER_UNIT;
+           {
+             known_alignment = true;
+             align = 2 * BITS_PER_UNIT;
+           }
        }
       else
-       align = DECL_ALIGN (exp);
+       {
+         known_alignment = true;
+         align = DECL_ALIGN (exp);
+       }
     }
   else if (CONSTANT_CLASS_P (exp))
     {
+      known_alignment = true;
       align = TYPE_ALIGN (TREE_TYPE (exp));
 #ifdef CONSTANT_ALIGNMENT
       align = (unsigned)CONSTANT_ALIGNMENT (exp, align);
 #endif
     }
   else if (TREE_CODE (exp) == VIEW_CONVERT_EXPR)
-    align = TYPE_ALIGN (TREE_TYPE (exp));
+    {
+      known_alignment = true;
+      align = TYPE_ALIGN (TREE_TYPE (exp));
+    }
   else if (TREE_CODE (exp) == INDIRECT_REF)
-    align = TYPE_ALIGN (TREE_TYPE (exp));
+    {
+      known_alignment = true;
+      align = TYPE_ALIGN (TREE_TYPE (exp));
+    }
   else if (TREE_CODE (exp) == MEM_REF)
     {
       tree addr = TREE_OPERAND (exp, 0);
-      struct ptr_info_def *pi;
+      unsigned ptr_align;
+      unsigned HOST_WIDE_INT ptr_bitpos;
+
       if (TREE_CODE (addr) == BIT_AND_EXPR
          && TREE_CODE (TREE_OPERAND (addr, 1)) == INTEGER_CST)
        {
+         known_alignment = true;
          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) == SSA_NAME
-         && (pi = SSA_NAME_PTR_INFO (addr)))
+
+      if (get_pointer_alignment_1 (addr, &ptr_align, &ptr_bitpos))
        {
-         bitpos += (pi->misalign * BITS_PER_UNIT) & ~(align - 1);
-         align = MAX (pi->align * BITS_PER_UNIT, align);
+         known_alignment = true;
+         bitpos += ptr_bitpos & ~(align - 1);
+         align = MAX (ptr_align, align);
        }
-      else if (TREE_CODE (addr) == ADDR_EXPR)
-       align = MAX (align, get_object_alignment (TREE_OPERAND (addr, 0)));
+
       bitpos += mem_ref_offset (exp).low * BITS_PER_UNIT;
     }
   else if (TREE_CODE (exp) == TARGET_MEM_REF)
     {
-      struct ptr_info_def *pi;
+      unsigned ptr_align;
+      unsigned HOST_WIDE_INT ptr_bitpos;
       tree addr = TMR_BASE (exp);
+
       if (TREE_CODE (addr) == BIT_AND_EXPR
          && TREE_CODE (TREE_OPERAND (addr, 1)) == INTEGER_CST)
        {
+         known_alignment = true;
          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) == SSA_NAME
-         && (pi = SSA_NAME_PTR_INFO (addr)))
+
+      if (get_pointer_alignment_1 (addr, &ptr_align, &ptr_bitpos))
        {
-         bitpos += (pi->misalign * BITS_PER_UNIT) & ~(align - 1);
-         align = MAX (pi->align * BITS_PER_UNIT, align);
+         known_alignment = true;
+         bitpos += ptr_bitpos & ~(align - 1);
+         align = MAX (ptr_align, align);
        }
-      else if (TREE_CODE (addr) == ADDR_EXPR)
-       align = MAX (align, get_object_alignment (TREE_OPERAND (addr, 0)));
+
       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);
+         known_alignment = true;
        }
       else if (TMR_INDEX (exp))
-       align = BITS_PER_UNIT;
+       known_alignment = false;
+
       if (TMR_INDEX2 (exp))
-       align = BITS_PER_UNIT;
+       known_alignment = false;
     }
-  else
-    align = BITS_PER_UNIT;
 
   /* If there is a non-constant offset part extract the maximum
      alignment that can prevail.  */
@@ -418,19 +435,27 @@ get_object_alignment_1 (tree exp, unsigned HOST_WIDE_INT *bitposp)
        }
       else
        {
-         inner = MIN (inner, BITS_PER_UNIT);
+         known_alignment = false;
          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);
-
+  if (known_alignment)
+    {
+      /* Alignment is innermost object alignment adjusted by the constant
+        and non-constant offset parts.  */
+      align = MIN (align, inner);
+      bitpos = bitpos & (align - 1);
+      *alignp = align;
+    }
+  else
+    {
+      bitpos = bitpos & (BITS_PER_UNIT - 1);
+      *alignp = BITS_PER_UNIT;
+    }
   *bitposp = bitpos;
-  return align;
+  return known_alignment;
 }
 
 /* Return the alignment in bits of EXP, an object.  */
@@ -441,14 +466,13 @@ get_object_alignment (tree exp)
   unsigned HOST_WIDE_INT bitpos = 0;
   unsigned int align;
 
-  align = get_object_alignment_1 (exp, &bitpos);
+  get_object_alignment_1 (exp, &align, &bitpos);
 
   /* align and bitpos now specify known low bits of the pointer.
      ptr & (align - 1) == bitpos.  */
 
   if (bitpos != 0)
     align = (bitpos & -bitpos);
-
   return align;
 }
 
@@ -465,45 +489,57 @@ unsigned int
 get_object_or_type_alignment (tree exp)
 {
   unsigned HOST_WIDE_INT misalign;
-  unsigned int align = get_object_alignment_1 (exp, &misalign);
+  unsigned int align;
+  bool known_alignment;
 
   gcc_assert (TREE_CODE (exp) == MEM_REF || TREE_CODE (exp) == TARGET_MEM_REF);
-
+  known_alignment = get_object_alignment_1 (exp, &align, &misalign);
   if (misalign != 0)
     align = (misalign & -misalign);
-  else
-    align = MAX (TYPE_ALIGN (TREE_TYPE (exp)), align);
+  else if (!known_alignment)
+    align = TYPE_ALIGN (TREE_TYPE (exp));
 
   return align;
 }
 
-/* For a pointer valued expression EXP compute values M and N such that
-   M divides (EXP - N) and such that N < M.  Store N in *BITPOSP and return M.
+/* For a pointer valued expression EXP compute values M and N such that M
+   divides (EXP - N) and such that N < M.  If these numbers can be determined,
+   store M in alignp and N in *BITPOSP and return true.  Otherwise return false
+   and store BITS_PER_UNIT to *alignp and any bit-offset to *bitposp.
 
-   If EXP is not a pointer, 0 is returned.  */
+   If EXP is not a pointer, false is returned too.  */
 
-unsigned int
-get_pointer_alignment_1 (tree exp, unsigned HOST_WIDE_INT *bitposp)
+bool
+get_pointer_alignment_1 (tree exp, unsigned int *alignp,
+                        unsigned HOST_WIDE_INT *bitposp)
 {
   STRIP_NOPS (exp);
 
   if (TREE_CODE (exp) == ADDR_EXPR)
-    return get_object_alignment_1 (TREE_OPERAND (exp, 0), bitposp);
+    return get_object_alignment_1 (TREE_OPERAND (exp, 0), alignp, bitposp);
   else if (TREE_CODE (exp) == SSA_NAME
           && POINTER_TYPE_P (TREE_TYPE (exp)))
     {
+      unsigned int ptr_align, ptr_misalign;
       struct ptr_info_def *pi = SSA_NAME_PTR_INFO (exp);
-      if (!pi)
+
+      if (pi && get_ptr_info_alignment (pi, &ptr_align, &ptr_misalign))
+       {
+         *bitposp = ptr_misalign * BITS_PER_UNIT;
+         *alignp = ptr_align * BITS_PER_UNIT;
+         return true;
+       }
+      else
        {
          *bitposp = 0;
-         return BITS_PER_UNIT;
+         *alignp = BITS_PER_UNIT;
+         return false;
        }
-      *bitposp = pi->misalign * BITS_PER_UNIT;
-      return pi->align * BITS_PER_UNIT;
     }
 
   *bitposp = 0;
-  return POINTER_TYPE_P (TREE_TYPE (exp)) ? BITS_PER_UNIT : 0;
+  *alignp = BITS_PER_UNIT;
+  return false;
 }
 
 /* Return the alignment in bits of EXP, a pointer valued expression.
@@ -518,8 +554,8 @@ get_pointer_alignment (tree exp)
 {
   unsigned HOST_WIDE_INT bitpos = 0;
   unsigned int align;
-  
-  align = get_pointer_alignment_1 (exp, &bitpos);
+
+  get_pointer_alignment_1 (exp, &align, &bitpos);
 
   /* align and bitpos now specify known low bits of the pointer.
      ptr & (align - 1) == bitpos.  */
index fe12942..f8b31b7 100644 (file)
@@ -9536,7 +9536,7 @@ get_pointer_modulus_and_residue (tree expr, unsigned HOST_WIDE_INT *residue,
   if (code == ADDR_EXPR)
     {
       unsigned int bitalign;
-      bitalign = get_object_alignment_1 (TREE_OPERAND (expr, 0), residue);
+      get_object_alignment_1 (TREE_OPERAND (expr, 0), &bitalign, residue);
       *residue /= BITS_PER_UNIT;
       return bitalign / BITS_PER_UNIT;
     }
index 7b29aa6..2e3cb0c 100644 (file)
@@ -1590,14 +1590,14 @@ dump_gimple_phi (pretty_printer *buffer, gimple phi, int spc, int flags)
       && POINTER_TYPE_P (TREE_TYPE (lhs))
       && SSA_NAME_PTR_INFO (lhs))
     {
+      unsigned int align, misalign;
       struct ptr_info_def *pi = SSA_NAME_PTR_INFO (lhs);
       pp_string (buffer, "PT = ");
       pp_points_to_solution (buffer, &pi->pt);
       newline_and_indent (buffer, spc);
-      if (pi->align != 1)
+      if (get_ptr_info_alignment (pi, &align, &misalign))
        {
-         pp_printf (buffer, "# ALIGN = %u, MISALIGN = %u",
-                    pi->align, pi->misalign);
+         pp_printf (buffer, "# ALIGN = %u, MISALIGN = %u", align, misalign);
          newline_and_indent (buffer, spc);
        }
       pp_string (buffer, "# ");
@@ -1889,14 +1889,15 @@ dump_gimple_stmt (pretty_printer *buffer, gimple gs, int spc, int flags)
          && POINTER_TYPE_P (TREE_TYPE (lhs))
          && SSA_NAME_PTR_INFO (lhs))
        {
+         unsigned int align, misalign;
          struct ptr_info_def *pi = SSA_NAME_PTR_INFO (lhs);
          pp_string (buffer, "# PT = ");
          pp_points_to_solution (buffer, &pi->pt);
          newline_and_indent (buffer, spc);
-         if (pi->align != 1)
+         if (get_ptr_info_alignment (pi, &align, &misalign))
            {
              pp_printf (buffer, "# ALIGN = %u, MISALIGN = %u",
-                        pi->align, pi->misalign);
+                        align, misalign);
              newline_and_indent (buffer, spc);
            }
        }
index 17a431c..af0f335 100644 (file)
@@ -2513,7 +2513,8 @@ ipa_modify_call_arguments (struct cgraph_edge *cs, gimple stmt,
              tree type = adj->type;
              unsigned int align;
              unsigned HOST_WIDE_INT misalign;
-             align = get_pointer_alignment_1 (base, &misalign);
+
+             get_pointer_alignment_1 (base, &align, &misalign);
              misalign += (double_int_sext (tree_to_double_int (off),
                                            TYPE_PRECISION (TREE_TYPE (off))).low
                           * BITS_PER_UNIT);
index 794047b..315d955 100644 (file)
@@ -136,12 +136,17 @@ struct GTY(()) ptr_info_def
      align and misalign specify low known bits of the pointer.
      ptr & (align - 1) == misalign.  */
 
-  /* The power-of-two byte alignment of the object this pointer
-     points into.  This is usually DECL_ALIGN_UNIT for decls and
-     MALLOC_ABI_ALIGNMENT for allocated storage.  */
+  /* When known, this is the power-of-two byte alignment of the object this
+     pointer points into.  This is usually DECL_ALIGN_UNIT for decls and
+     MALLOC_ABI_ALIGNMENT for allocated storage.  When the alignment is not
+     known, it is zero.  Do not access directly but use functions
+     get_ptr_info_alignment, set_ptr_info_alignment,
+     mark_ptr_info_alignment_unknown and similar.  */
   unsigned int align;
 
-  /* The byte offset this pointer differs from the above alignment.  */
+  /* When alignment is known, the byte offset this pointer differs from the
+     above alignment.  Access only through the same helper functions as align
+     above.  */
   unsigned int misalign;
 };
 
@@ -593,6 +598,13 @@ extern void duplicate_ssa_name_ptr_info (tree, struct ptr_info_def *);
 extern void release_ssa_name (tree);
 extern void release_defs (gimple);
 extern void replace_ssa_name_symbol (tree, tree);
+extern bool get_ptr_info_alignment (struct ptr_info_def *, unsigned int *,
+                                   unsigned int *);
+extern void mark_ptr_info_alignment_unknown (struct ptr_info_def *);
+extern void set_ptr_info_alignment (struct ptr_info_def *, unsigned int,
+                                   unsigned int);
+extern void adjust_ptr_info_misalignment (struct ptr_info_def *,
+                                         unsigned int);
 
 #ifdef GATHER_STATISTICS
 extern void ssanames_print_statistics (void);
index de99b30..3f84f6b 100644 (file)
@@ -1472,11 +1472,13 @@ build_ref_for_offset (location_t loc, tree base, HOST_WIDE_INT offset,
      by looking at the access mode.  That would constrain the
      alignment of base + base_offset which we would need to
      adjust according to offset.  */
-  align = get_pointer_alignment_1 (base, &misalign);
-  if (misalign == 0
-      && (TREE_CODE (prev_base) == MEM_REF
-         || TREE_CODE (prev_base) == TARGET_MEM_REF))
-    align = MAX (align, TYPE_ALIGN (TREE_TYPE (prev_base)));
+  if (!get_pointer_alignment_1 (base, &align, &misalign))
+    {
+      gcc_assert (misalign == 0);
+      if (TREE_CODE (prev_base) == MEM_REF
+         || TREE_CODE (prev_base) == TARGET_MEM_REF)
+       align = TYPE_ALIGN (TREE_TYPE (prev_base));
+    }
   misalign += (double_int_sext (tree_to_double_int (off),
                                TYPE_PRECISION (TREE_TYPE (off))).low
               * BITS_PER_UNIT);
index cf13157..e11da3e 100644 (file)
@@ -863,26 +863,26 @@ copy_ref_info (tree new_ref, tree old_ref)
               && SSA_NAME_PTR_INFO (TREE_OPERAND (base, 0)))
        {
          struct ptr_info_def *new_pi;
+         unsigned int align, misalign;
+
          duplicate_ssa_name_ptr_info
            (new_ptr_base, SSA_NAME_PTR_INFO (TREE_OPERAND (base, 0)));
          new_pi = SSA_NAME_PTR_INFO (new_ptr_base);
          /* We have to be careful about transfering alignment information.  */
-         if (TREE_CODE (old_ref) == MEM_REF
+         if (get_ptr_info_alignment (new_pi, &align, &misalign)
+             && TREE_CODE (old_ref) == MEM_REF
              && !(TREE_CODE (new_ref) == TARGET_MEM_REF
                   && (TMR_INDEX2 (new_ref)
                       || (TMR_STEP (new_ref)
                           && (TREE_INT_CST_LOW (TMR_STEP (new_ref))
-                              < new_pi->align)))))
+                              < align)))))
            {
-             new_pi->misalign += double_int_sub (mem_ref_offset (old_ref),
-                                                 mem_ref_offset (new_ref)).low;
-             new_pi->misalign &= (new_pi->align - 1);
+             unsigned int inc = double_int_sub (mem_ref_offset (old_ref),
+                                                mem_ref_offset (new_ref)).low;
+             adjust_ptr_info_misalignment (new_pi, inc);
            }
          else
-           {
-             new_pi->align = 1;
-             new_pi->misalign = 0;
-           }
+           mark_ptr_info_alignment_unknown (new_pi);
        }
       else if (TREE_CODE (base) == VAR_DECL
               || TREE_CODE (base) == PARM_DECL
index 1257b8b..feded5b 100644 (file)
@@ -513,7 +513,7 @@ get_value_from_alignment (tree expr)
 
   gcc_assert (TREE_CODE (expr) == ADDR_EXPR);
 
-  align = get_object_alignment_1 (TREE_OPERAND (expr, 0), &bitpos);
+  get_object_alignment_1 (TREE_OPERAND (expr, 0), &align, &bitpos);
   val.mask
     = double_int_and_not (POINTER_TYPE_P (type) || TYPE_UNSIGNED (type)
                          ? double_int_mask (TYPE_PRECISION (type))
@@ -807,7 +807,6 @@ ccp_finalize (void)
     {
       tree name = ssa_name (i);
       prop_value_t *val;
-      struct ptr_info_def *pi;
       unsigned int tem, align;
 
       if (!name
@@ -823,12 +822,9 @@ ccp_finalize (void)
         bits the misalignment.  */
       tem = val->mask.low;
       align = (tem & -tem);
-      if (align == 1)
-       continue;
-
-      pi = get_ptr_info (name);
-      pi->align = align;
-      pi->misalign = TREE_INT_CST_LOW (val->value) & (align - 1);
+      if (align > 1)
+       set_ptr_info_alignment (get_ptr_info (name), align,
+                               TREE_INT_CST_LOW (val->value) & (align - 1));
     }
 
   /* Perform substitutions based on the known constant values.  */
index d346e00..af7a1cf 100644 (file)
@@ -6259,10 +6259,7 @@ rewrite_use_nonlinear_expr (struct ivopts_data *data,
          /* As this isn't a plain copy we have to reset alignment
             information.  */
          if (SSA_NAME_PTR_INFO (comp))
-           {
-             SSA_NAME_PTR_INFO (comp)->align = 1;
-             SSA_NAME_PTR_INFO (comp)->misalign = 0;
-           }
+           mark_ptr_info_alignment_unknown (SSA_NAME_PTR_INFO (comp));
        }
     }
 
index 7c31550..64455af 100644 (file)
@@ -238,6 +238,62 @@ release_ssa_name (tree var)
     }
 }
 
+/* If the alignment of the pointer described by PI is known, return true and
+   store the alignment and the deviation from it into *ALIGNP and *MISALIGNP
+   respectively.  Otherwise return false.  */
+
+bool
+get_ptr_info_alignment (struct ptr_info_def *pi, unsigned int *alignp,
+                       unsigned int *misalignp)
+{
+  if (pi->align)
+    {
+      *alignp = pi->align;
+      *misalignp = pi->misalign;
+      return true;
+    }
+  else
+    return false;
+}
+
+/* State that the pointer described by PI has unknown alignment.  */
+
+void
+mark_ptr_info_alignment_unknown (struct ptr_info_def *pi)
+{
+  pi->align = 0;
+  pi->misalign = 0;
+}
+
+/* Store the the power-of-two byte alignment and the deviation from that
+   alignment of pointer described by PI to ALIOGN and MISALIGN
+   respectively.  */
+
+void
+set_ptr_info_alignment (struct ptr_info_def *pi, unsigned int align,
+                           unsigned int misalign)
+{
+  gcc_checking_assert (align != 0);
+  gcc_assert ((align & (align - 1)) == 0);
+  gcc_assert ((misalign & ~(align - 1)) == 0);
+
+  pi->align = align;
+  pi->misalign = misalign;
+}
+
+/* If pointer decribed by PI has known alignment, increase its known
+   misalignment by INCREMENT modulo its current alignment.  */
+
+void
+adjust_ptr_info_misalignment (struct ptr_info_def *pi,
+                             unsigned int increment)
+{
+  if (pi->align != 0)
+    {
+      pi->misalign += increment;
+      pi->misalign &= (pi->align - 1);
+    }
+}
 
 /* Return the alias information associated with pointer T.  It creates a
    new instance if none existed.  */
@@ -254,8 +310,7 @@ get_ptr_info (tree t)
     {
       pi = ggc_alloc_cleared_ptr_info_def ();
       pt_solution_reset (&pi->pt);
-      pi->align = 1;
-      pi->misalign = 0;
+      mark_ptr_info_alignment_unknown (pi);
       SSA_NAME_PTR_INFO (t) = pi;
     }
 
index 37df7ab..7464034 100644 (file)
@@ -3397,10 +3397,7 @@ vect_create_addr_base_for_vector_ref (gimple stmt,
     {
       duplicate_ssa_name_ptr_info (vec_stmt, DR_PTR_INFO (dr));
       if (offset)
-       {
-         SSA_NAME_PTR_INFO (vec_stmt)->align = 1;
-         SSA_NAME_PTR_INFO (vec_stmt)->misalign = 0;
-       }
+       mark_ptr_info_alignment_unknown (SSA_NAME_PTR_INFO (vec_stmt));
     }
 
   if (vect_print_dump_info (REPORT_DETAILS))
@@ -3799,8 +3796,7 @@ bump_vector_ptr (tree dataref_ptr, gimple ptr_incr, gimple_stmt_iterator *gsi,
   if (DR_PTR_INFO (dr))
     {
       duplicate_ssa_name_ptr_info (new_dataref_ptr, DR_PTR_INFO (dr));
-      SSA_NAME_PTR_INFO (new_dataref_ptr)->align = 1;
-      SSA_NAME_PTR_INFO (new_dataref_ptr)->misalign = 0;
+      mark_ptr_info_alignment_unknown (SSA_NAME_PTR_INFO (new_dataref_ptr));
     }
 
   if (!ptr_incr)
index 5e6f71a..a0368d8 100644 (file)
@@ -106,15 +106,12 @@ write_vector_array (gimple stmt, gimple_stmt_iterator *gsi, tree vect,
 static tree
 create_array_ref (tree type, tree ptr, struct data_reference *first_dr)
 {
-  struct ptr_info_def *pi;
   tree mem_ref, alias_ptr_type;
 
   alias_ptr_type = reference_alias_ptr_type (DR_REF (first_dr));
   mem_ref = build2 (MEM_REF, type, ptr, build_int_cst (alias_ptr_type, 0));
   /* Arrays have the same alignment as their type.  */
-  pi = get_ptr_info (ptr);
-  pi->align = TYPE_ALIGN_UNIT (type);
-  pi->misalign = 0;
+  set_ptr_info_alignment (get_ptr_info (ptr), TYPE_ALIGN_UNIT (type), 0);
   return mem_ref;
 }
 
@@ -4029,7 +4026,7 @@ vectorizable_store (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
          next_stmt = first_stmt;
          for (i = 0; i < vec_num; i++)
            {
-             struct ptr_info_def *pi;
+             unsigned align, misalign;
 
              if (i > 0)
                /* Bump the vector pointer.  */
@@ -4046,25 +4043,26 @@ vectorizable_store (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
              data_ref = build2 (MEM_REF, TREE_TYPE (vec_oprnd), dataref_ptr,
                                 build_int_cst (reference_alias_ptr_type
                                                (DR_REF (first_dr)), 0));
-             pi = get_ptr_info (dataref_ptr);
-             pi->align = TYPE_ALIGN_UNIT (vectype);
+             align = TYPE_ALIGN_UNIT (vectype);
              if (aligned_access_p (first_dr))
-               pi->misalign = 0;
+               misalign = 0;
              else if (DR_MISALIGNMENT (first_dr) == -1)
                {
                  TREE_TYPE (data_ref)
                    = build_aligned_type (TREE_TYPE (data_ref),
                                          TYPE_ALIGN (elem_type));
-                 pi->align = TYPE_ALIGN_UNIT (elem_type);
-                 pi->misalign = 0;
+                 align = TYPE_ALIGN_UNIT (elem_type);
+                 misalign = 0;
                }
              else
                {
                  TREE_TYPE (data_ref)
                    = build_aligned_type (TREE_TYPE (data_ref),
                                          TYPE_ALIGN (elem_type));
-                 pi->misalign = DR_MISALIGNMENT (first_dr);
+                 misalign = DR_MISALIGNMENT (first_dr);
                }
+             set_ptr_info_alignment (get_ptr_info (dataref_ptr), align,
+                                     misalign);
 
              /* Arguments are ready.  Create the new vector stmt.  */
              new_stmt = gimple_build_assign (data_ref, vec_oprnd);
@@ -4860,33 +4858,35 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
                case dr_aligned:
                case dr_unaligned_supported:
                  {
-                   struct ptr_info_def *pi;
+                   unsigned int align, misalign;
+
                    data_ref
                      = build2 (MEM_REF, vectype, dataref_ptr,
                                build_int_cst (reference_alias_ptr_type
                                               (DR_REF (first_dr)), 0));
-                   pi = get_ptr_info (dataref_ptr);
-                   pi->align = TYPE_ALIGN_UNIT (vectype);
+                   align = TYPE_ALIGN_UNIT (vectype);
                    if (alignment_support_scheme == dr_aligned)
                      {
                        gcc_assert (aligned_access_p (first_dr));
-                       pi->misalign = 0;
+                       misalign = 0;
                      }
                    else if (DR_MISALIGNMENT (first_dr) == -1)
                      {
                        TREE_TYPE (data_ref)
                          = build_aligned_type (TREE_TYPE (data_ref),
                                                TYPE_ALIGN (elem_type));
-                       pi->align = TYPE_ALIGN_UNIT (elem_type);
-                       pi->misalign = 0;
+                       align = TYPE_ALIGN_UNIT (elem_type);
+                       misalign = 0;
                      }
                    else
                      {
                        TREE_TYPE (data_ref)
                          = build_aligned_type (TREE_TYPE (data_ref),
                                                TYPE_ALIGN (elem_type));
-                       pi->misalign = DR_MISALIGNMENT (first_dr);
+                       misalign = DR_MISALIGNMENT (first_dr);
                      }
+                   set_ptr_info_alignment (get_ptr_info (dataref_ptr),
+                                           align, misalign);
                    break;
                  }
                case dr_explicit_realign:
index 3d7fcab..9d53a14 100644 (file)
@@ -5465,10 +5465,12 @@ extern tree build_string_literal (int, const char *);
 extern bool validate_arglist (const_tree, ...);
 extern rtx builtin_memset_read_str (void *, HOST_WIDE_INT, enum machine_mode);
 extern bool is_builtin_fn (tree);
-extern unsigned int get_object_alignment_1 (tree, unsigned HOST_WIDE_INT *);
+extern bool get_object_alignment_1 (tree, unsigned int *,
+                                   unsigned HOST_WIDE_INT *);
 extern unsigned int get_object_alignment (tree);
 extern unsigned int get_object_or_type_alignment (tree);
-extern unsigned int get_pointer_alignment_1 (tree, unsigned HOST_WIDE_INT *);
+extern bool get_pointer_alignment_1 (tree, unsigned int *,
+                                    unsigned HOST_WIDE_INT *);
 extern unsigned int get_pointer_alignment (tree);
 extern tree fold_call_stmt (gimple, bool);
 extern tree gimple_fold_builtin_snprintf_chk (gimple, tree, enum built_in_function);