This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Support for known unknown alignment


Hi,

On Tue, Apr 24, 2012 at 12:31:38PM +0200, Martin Jambor wrote:
> Hi,
> 
> On Mon, Apr 23, 2012 at 03:30:19PM +0200, Richard Guenther wrote:
> > On Mon, 23 Apr 2012, Martin Jambor wrote:
> > 
> > > Hi,
> > > 
> > > On Mon, Apr 23, 2012 at 12:50:51PM +0200, Richard Guenther wrote:
> > > > On Fri, 20 Apr 2012, Martin Jambor wrote:
> > > > 
> > > > > Hi,
> > > > > 
> > > > > two days ago I talked to Richi on IRC about the functions to determine
> > > > > the expected alignment of objects and pointers we have and he
> > > > > suggested that get_object_alignment_1 and get_pointer_alignment_1
> > > > > should return whether the alignment is actually known and return the
> > > > > actual alignment in a reference variable (as they currently return
> > > > > bitpos).
> > > > > 
> 
...

> The testsuite differences I got on Friday were probably noise, tonight
> (on an updated svn tree) I did not get any on ppc64-linux,
> x86_64-linux or i686-linux.  Considering that and the OK above, I'm
> going to bootstrap and test also on sparc64-linux and ia64-linux and
> if those pass too, I'll commit the patch tomorrow, unless there are
> any objections.
> 

There is a Fortran testsuite that, on sparc64-linux, showed that my
clever simplification of get_object_alignment_1 handling of
TARGET_MEM_REFs was actually very dumb.  So this is the working patch,
successfully bootstrapped and tested on x86_64-linux (all languages
and Ada), i686-linux (likewise), sparc64-linux (all languages - Java +
Ada), ia64-linux (all languages) and ppc64-linux (likewise) and tested
on hppa-linux (C and C++ only).

I still consider the patch approved because it actually changes less
stuff but do not want to commit it before a weekend so intend to do it
next week.

Thanks,

Martin


2012-04-25  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.


Index: src/gcc/builtins.c
===================================================================
*** src.orig/gcc/builtins.c
--- src/gcc/builtins.c
*************** called_as_built_in (tree node)
*** 263,270 ****
    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.
  
     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
--- 263,272 ----
    return is_builtin_name (name);
  }
  
! /* 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
*************** called_as_built_in (tree node)
*** 273,286 ****
     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)
  {
    HOST_WIDE_INT bitsize, bitpos;
    tree offset;
    enum machine_mode mode;
    int unsignedp, volatilep;
!   unsigned int align, inner;
  
    /* Get the innermost object and the constant (bitpos) and possibly
       variable (offset) offset of the access.  */
--- 275,290 ----
     the address &foo of a Thumb function foo() has the lowest bit set,
     whereas foo() itself starts on an even address.  */
  
! 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 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.  */
*************** get_object_alignment_1 (tree exp, unsign
*** 301,384 ****
  	     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;
  	}
        else
! 	align = DECL_ALIGN (exp);
      }
    else if (CONSTANT_CLASS_P (exp))
      {
        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));
    else if (TREE_CODE (exp) == INDIRECT_REF)
!     align = TYPE_ALIGN (TREE_TYPE (exp));
    else if (TREE_CODE (exp) == MEM_REF)
      {
        tree addr = TREE_OPERAND (exp, 0);
!       struct ptr_info_def *pi;
        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) == SSA_NAME
! 	  && (pi = SSA_NAME_PTR_INFO (addr)))
  	{
! 	  bitpos += (pi->misalign * BITS_PER_UNIT) & ~(align - 1);
! 	  align = MAX (pi->align * BITS_PER_UNIT, 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;
        tree addr = TMR_BASE (exp);
        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) == SSA_NAME
! 	  && (pi = SSA_NAME_PTR_INFO (addr)))
  	{
! 	  bitpos += (pi->misalign * BITS_PER_UNIT) & ~(align - 1);
! 	  align = MAX (pi->align * BITS_PER_UNIT, 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);
  	}
        else if (TMR_INDEX (exp))
! 	align = BITS_PER_UNIT;
        if (TMR_INDEX2 (exp))
! 	align = BITS_PER_UNIT;
      }
-   else
-     align = BITS_PER_UNIT;
  
    /* If there is a non-constant offset part extract the maximum
       alignment that can prevail.  */
--- 305,401 ----
  	     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)
! 	    {
! 	      known_alignment = true;
! 	      align = 2 * BITS_PER_UNIT;
! 	    }
  	}
        else
! 	{
! 	  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)
!     {
!       known_alignment = true;
!       align = TYPE_ALIGN (TREE_TYPE (exp));
!     }
    else if (TREE_CODE (exp) == INDIRECT_REF)
!     {
!       known_alignment = true;
!       align = TYPE_ALIGN (TREE_TYPE (exp));
!     }
    else if (TREE_CODE (exp) == MEM_REF)
      {
        tree addr = TREE_OPERAND (exp, 0);
!       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);
  	}
! 
!       if (get_pointer_alignment_1 (addr, &ptr_align, &ptr_bitpos))
  	{
! 	  known_alignment = true;
! 	  bitpos += ptr_bitpos & ~(align - 1);
! 	  align = MAX (ptr_align, align);
  	}
! 
        bitpos += mem_ref_offset (exp).low * BITS_PER_UNIT;
      }
    else if (TREE_CODE (exp) == TARGET_MEM_REF)
      {
!       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);
  	}
! 
!       if (get_pointer_alignment_1 (addr, &ptr_align, &ptr_bitpos))
  	{
! 	  known_alignment = true;
! 	  bitpos += ptr_bitpos & ~(align - 1);
! 	  align = MAX (ptr_align, 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);
+ 	  known_alignment = true;
  	}
        else if (TMR_INDEX (exp))
! 	known_alignment = false;
! 
        if (TMR_INDEX2 (exp))
! 	known_alignment = false;
      }
  
    /* If there is a non-constant offset part extract the maximum
       alignment that can prevail.  */
*************** get_object_alignment_1 (tree exp, unsign
*** 418,436 ****
  	}
        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);
! 
    *bitposp = bitpos;
!   return align;
  }
  
  /* Return the alignment in bits of EXP, an object.  */
--- 435,461 ----
  	}
        else
  	{
! 	  known_alignment = false;
  	  break;
  	}
        offset = next_offset;
      }
  
!   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 known_alignment;
  }
  
  /* Return the alignment in bits of EXP, an object.  */
*************** get_object_alignment (tree exp)
*** 441,454 ****
    unsigned HOST_WIDE_INT bitpos = 0;
    unsigned int align;
  
!   align = get_object_alignment_1 (exp, &bitpos);
  
    /* align and bitpos now specify known low bits of the pointer.
       ptr & (align - 1) == bitpos.  */
  
    if (bitpos != 0)
      align = (bitpos & -bitpos);
- 
    return align;
  }
  
--- 466,478 ----
    unsigned HOST_WIDE_INT bitpos = 0;
    unsigned int align;
  
!   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;
  }
  
*************** unsigned int
*** 465,509 ****
  get_object_or_type_alignment (tree exp)
  {
    unsigned HOST_WIDE_INT misalign;
!   unsigned int align = get_object_alignment_1 (exp, &misalign);
  
    gcc_assert (TREE_CODE (exp) == MEM_REF || TREE_CODE (exp) == TARGET_MEM_REF);
! 
    if (misalign != 0)
      align = (misalign & -misalign);
!   else
!     align = MAX (TYPE_ALIGN (TREE_TYPE (exp)), align);
  
    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.
! 
!    If EXP is not a pointer, 0 is returned.  */
! 
! unsigned int
! get_pointer_alignment_1 (tree exp, unsigned HOST_WIDE_INT *bitposp)
  {
    STRIP_NOPS (exp);
  
    if (TREE_CODE (exp) == ADDR_EXPR)
!     return get_object_alignment_1 (TREE_OPERAND (exp, 0), bitposp);
    else if (TREE_CODE (exp) == SSA_NAME
  	   && POINTER_TYPE_P (TREE_TYPE (exp)))
      {
        struct ptr_info_def *pi = SSA_NAME_PTR_INFO (exp);
!       if (!pi)
  	{
  	  *bitposp = 0;
! 	  return BITS_PER_UNIT;
  	}
-       *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;
  }
  
  /* Return the alignment in bits of EXP, a pointer valued expression.
--- 489,545 ----
  get_object_or_type_alignment (tree exp)
  {
    unsigned HOST_WIDE_INT 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 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.  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, false is returned too.  */
! 
! 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), 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 && 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;
! 	  *alignp = BITS_PER_UNIT;
! 	  return false;
  	}
      }
  
    *bitposp = 0;
!   *alignp = BITS_PER_UNIT;
!   return false;
  }
  
  /* Return the alignment in bits of EXP, a pointer valued expression.
*************** get_pointer_alignment (tree exp)
*** 518,525 ****
  {
    unsigned HOST_WIDE_INT bitpos = 0;
    unsigned int align;
!   
!   align = get_pointer_alignment_1 (exp, &bitpos);
  
    /* align and bitpos now specify known low bits of the pointer.
       ptr & (align - 1) == bitpos.  */
--- 554,561 ----
  {
    unsigned HOST_WIDE_INT bitpos = 0;
    unsigned int align;
! 
!   get_pointer_alignment_1 (exp, &align, &bitpos);
  
    /* align and bitpos now specify known low bits of the pointer.
       ptr & (align - 1) == bitpos.  */
Index: src/gcc/fold-const.c
===================================================================
*** src.orig/gcc/fold-const.c
--- src/gcc/fold-const.c
*************** get_pointer_modulus_and_residue (tree ex
*** 9532,9538 ****
    if (code == ADDR_EXPR)
      {
        unsigned int bitalign;
!       bitalign = get_object_alignment_1 (TREE_OPERAND (expr, 0), residue);
        *residue /= BITS_PER_UNIT;
        return bitalign / BITS_PER_UNIT;
      }
--- 9532,9538 ----
    if (code == ADDR_EXPR)
      {
        unsigned int bitalign;
!       get_object_alignment_1 (TREE_OPERAND (expr, 0), &bitalign, residue);
        *residue /= BITS_PER_UNIT;
        return bitalign / BITS_PER_UNIT;
      }
Index: src/gcc/ipa-prop.c
===================================================================
*** src.orig/gcc/ipa-prop.c
--- src/gcc/ipa-prop.c
*************** ipa_modify_call_arguments (struct cgraph
*** 2513,2519 ****
  	      tree type = adj->type;
  	      unsigned int align;
  	      unsigned HOST_WIDE_INT misalign;
! 	      align = get_pointer_alignment_1 (base, &misalign);
  	      misalign += (double_int_sext (tree_to_double_int (off),
  					    TYPE_PRECISION (TREE_TYPE (off))).low
  			   * BITS_PER_UNIT);
--- 2513,2520 ----
  	      tree type = adj->type;
  	      unsigned int align;
  	      unsigned HOST_WIDE_INT 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: src/gcc/tree-sra.c
===================================================================
*** src.orig/gcc/tree-sra.c
--- src/gcc/tree-sra.c
*************** build_ref_for_offset (location_t loc, tr
*** 1472,1482 ****
       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)));
    misalign += (double_int_sext (tree_to_double_int (off),
  				TYPE_PRECISION (TREE_TYPE (off))).low
  	       * BITS_PER_UNIT);
--- 1472,1484 ----
       by looking at the access mode.  That would constrain the
       alignment of base + base_offset which we would need to
       adjust according to offset.  */
!   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: src/gcc/tree-ssa-ccp.c
===================================================================
*** src.orig/gcc/tree-ssa-ccp.c
--- src/gcc/tree-ssa-ccp.c
*************** get_value_from_alignment (tree expr)
*** 513,519 ****
  
    gcc_assert (TREE_CODE (expr) == ADDR_EXPR);
  
!   align = get_object_alignment_1 (TREE_OPERAND (expr, 0), &bitpos);
    val.mask
      = double_int_and_not (POINTER_TYPE_P (type) || TYPE_UNSIGNED (type)
  			  ? double_int_mask (TYPE_PRECISION (type))
--- 513,519 ----
  
    gcc_assert (TREE_CODE (expr) == ADDR_EXPR);
  
!   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))
*************** ccp_finalize (void)
*** 807,813 ****
      {
        tree name = ssa_name (i);
        prop_value_t *val;
-       struct ptr_info_def *pi;
        unsigned int tem, align;
  
        if (!name
--- 807,812 ----
*************** ccp_finalize (void)
*** 823,834 ****
  	 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);
      }
  
    /* Perform substitutions based on the known constant values.  */
--- 822,830 ----
  	 bits the misalignment.  */
        tem = val->mask.low;
        align = (tem & -tem);
!       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: src/gcc/tree.h
===================================================================
*** src.orig/gcc/tree.h
--- src/gcc/tree.h
*************** extern tree build_string_literal (int, c
*** 5464,5473 ****
  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 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 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);
--- 5464,5475 ----
  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 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 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);
Index: src/gcc/gimple-pretty-print.c
===================================================================
*** src.orig/gcc/gimple-pretty-print.c
--- src/gcc/gimple-pretty-print.c
*************** dump_gimple_phi (pretty_printer *buffer,
*** 1590,1603 ****
        && POINTER_TYPE_P (TREE_TYPE (lhs))
        && SSA_NAME_PTR_INFO (lhs))
      {
        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)
  	{
! 	  pp_printf (buffer, "# ALIGN = %u, MISALIGN = %u",
! 		     pi->align, pi->misalign);
  	  newline_and_indent (buffer, spc);
  	}
        pp_string (buffer, "# ");
--- 1590,1603 ----
        && 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 (get_ptr_info_alignment (pi, &align, &misalign))
  	{
! 	  pp_printf (buffer, "# ALIGN = %u, MISALIGN = %u", align, misalign);
  	  newline_and_indent (buffer, spc);
  	}
        pp_string (buffer, "# ");
*************** dump_gimple_stmt (pretty_printer *buffer
*** 1889,1902 ****
  	  && POINTER_TYPE_P (TREE_TYPE (lhs))
  	  && SSA_NAME_PTR_INFO (lhs))
  	{
  	  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)
  	    {
  	      pp_printf (buffer, "# ALIGN = %u, MISALIGN = %u",
! 			 pi->align, pi->misalign);
  	      newline_and_indent (buffer, spc);
  	    }
  	}
--- 1889,1903 ----
  	  && 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 (get_ptr_info_alignment (pi, &align, &misalign))
  	    {
  	      pp_printf (buffer, "# ALIGN = %u, MISALIGN = %u",
! 			 align, misalign);
  	      newline_and_indent (buffer, spc);
  	    }
  	}
Index: src/gcc/tree-flow.h
===================================================================
*** src.orig/gcc/tree-flow.h
--- src/gcc/tree-flow.h
*************** struct GTY(()) ptr_info_def
*** 136,147 ****
       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.  */
    unsigned int align;
  
!   /* The byte offset this pointer differs from the above alignment.  */
    unsigned int misalign;
  };
  
--- 136,152 ----
       align and misalign specify low known bits of the pointer.
       ptr & (align - 1) == misalign.  */
  
!   /* 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;
  
!   /* 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;
  };
  
*************** extern void duplicate_ssa_name_ptr_info
*** 593,598 ****
--- 598,610 ----
  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: src/gcc/tree-ssa-address.c
===================================================================
*** src.orig/gcc/tree-ssa-address.c
--- src/gcc/tree-ssa-address.c
*************** copy_ref_info (tree new_ref, tree old_re
*** 863,888 ****
  	       && SSA_NAME_PTR_INFO (TREE_OPERAND (base, 0)))
  	{
  	  struct ptr_info_def *new_pi;
  	  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
  	      && !(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)))))
  	    {
! 	      new_pi->misalign += double_int_sub (mem_ref_offset (old_ref),
! 						  mem_ref_offset (new_ref)).low;
! 	      new_pi->misalign &= (new_pi->align - 1);
  	    }
  	  else
! 	    {
! 	      new_pi->align = 1;
! 	      new_pi->misalign = 0;
! 	    }
  	}
        else if (TREE_CODE (base) == VAR_DECL
  	       || TREE_CODE (base) == PARM_DECL
--- 863,888 ----
  	       && 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 (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))
! 			       < align)))))
  	    {
! 	      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
! 	    mark_ptr_info_alignment_unknown (new_pi);
  	}
        else if (TREE_CODE (base) == VAR_DECL
  	       || TREE_CODE (base) == PARM_DECL
Index: src/gcc/tree-ssa-loop-ivopts.c
===================================================================
*** src.orig/gcc/tree-ssa-loop-ivopts.c
--- src/gcc/tree-ssa-loop-ivopts.c
*************** rewrite_use_nonlinear_expr (struct ivopt
*** 6258,6267 ****
  	  /* 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;
! 	    }
  	}
      }
  
--- 6258,6264 ----
  	  /* As this isn't a plain copy we have to reset alignment
  	     information.  */
  	  if (SSA_NAME_PTR_INFO (comp))
! 	    mark_ptr_info_alignment_unknown (SSA_NAME_PTR_INFO (comp));
  	}
      }
  
Index: src/gcc/tree-ssanames.c
===================================================================
*** src.orig/gcc/tree-ssanames.c
--- src/gcc/tree-ssanames.c
*************** release_ssa_name (tree var)
*** 238,243 ****
--- 238,299 ----
      }
  }
  
+ /* 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.  */
*************** get_ptr_info (tree t)
*** 254,261 ****
      {
        pi = ggc_alloc_cleared_ptr_info_def ();
        pt_solution_reset (&pi->pt);
!       pi->align = 1;
!       pi->misalign = 0;
        SSA_NAME_PTR_INFO (t) = pi;
      }
  
--- 310,316 ----
      {
        pi = ggc_alloc_cleared_ptr_info_def ();
        pt_solution_reset (&pi->pt);
!       mark_ptr_info_alignment_unknown (pi);
        SSA_NAME_PTR_INFO (t) = pi;
      }
  
Index: src/gcc/tree-vect-data-refs.c
===================================================================
*** src.orig/gcc/tree-vect-data-refs.c
--- src/gcc/tree-vect-data-refs.c
*************** vect_create_addr_base_for_vector_ref (gi
*** 3397,3406 ****
      {
        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;
! 	}
      }
  
    if (vect_print_dump_info (REPORT_DETAILS))
--- 3397,3403 ----
      {
        duplicate_ssa_name_ptr_info (vec_stmt, DR_PTR_INFO (dr));
        if (offset)
! 	mark_ptr_info_alignment_unknown (SSA_NAME_PTR_INFO (vec_stmt));
      }
  
    if (vect_print_dump_info (REPORT_DETAILS))
*************** bump_vector_ptr (tree dataref_ptr, gimpl
*** 3799,3806 ****
    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;
      }
  
    if (!ptr_incr)
--- 3796,3802 ----
    if (DR_PTR_INFO (dr))
      {
        duplicate_ssa_name_ptr_info (new_dataref_ptr, DR_PTR_INFO (dr));
!       mark_ptr_info_alignment_unknown (SSA_NAME_PTR_INFO (new_dataref_ptr));
      }
  
    if (!ptr_incr)
Index: src/gcc/tree-vect-stmts.c
===================================================================
*** src.orig/gcc/tree-vect-stmts.c
--- src/gcc/tree-vect-stmts.c
*************** write_vector_array (gimple stmt, gimple_
*** 106,120 ****
  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;
    return mem_ref;
  }
  
--- 106,117 ----
  static tree
  create_array_ref (tree type, tree ptr, struct data_reference *first_dr)
  {
    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.  */
!   set_ptr_info_alignment (get_ptr_info (ptr), TYPE_ALIGN_UNIT (type), 0);
    return mem_ref;
  }
  
*************** vectorizable_store (gimple stmt, gimple_
*** 4029,4035 ****
  	  next_stmt = first_stmt;
  	  for (i = 0; i < vec_num; i++)
  	    {
! 	      struct ptr_info_def *pi;
  
  	      if (i > 0)
  		/* Bump the vector pointer.  */
--- 4026,4032 ----
  	  next_stmt = first_stmt;
  	  for (i = 0; i < vec_num; i++)
  	    {
! 	      unsigned align, misalign;
  
  	      if (i > 0)
  		/* Bump the vector pointer.  */
*************** vectorizable_store (gimple stmt, gimple_
*** 4046,4070 ****
  	      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);
  	      if (aligned_access_p (first_dr))
! 		pi->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;
  		}
  	      else
  		{
  		  TREE_TYPE (data_ref)
  		    = build_aligned_type (TREE_TYPE (data_ref),
  					  TYPE_ALIGN (elem_type));
! 		  pi->misalign = DR_MISALIGNMENT (first_dr);
  		}
  
  	      /* Arguments are ready.  Create the new vector stmt.  */
  	      new_stmt = gimple_build_assign (data_ref, vec_oprnd);
--- 4043,4068 ----
  	      data_ref = build2 (MEM_REF, TREE_TYPE (vec_oprnd), dataref_ptr,
  				 build_int_cst (reference_alias_ptr_type
  						(DR_REF (first_dr)), 0));
! 	      align = TYPE_ALIGN_UNIT (vectype);
  	      if (aligned_access_p (first_dr))
! 		misalign = 0;
  	      else if (DR_MISALIGNMENT (first_dr) == -1)
  		{
  		  TREE_TYPE (data_ref)
  		    = build_aligned_type (TREE_TYPE (data_ref),
  					  TYPE_ALIGN (elem_type));
! 		  align = TYPE_ALIGN_UNIT (elem_type);
! 		  misalign = 0;
  		}
  	      else
  		{
  		  TREE_TYPE (data_ref)
  		    = build_aligned_type (TREE_TYPE (data_ref),
  					  TYPE_ALIGN (elem_type));
! 		  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);
*************** vectorizable_load (gimple stmt, gimple_s
*** 4860,4892 ****
  		case dr_aligned:
  		case dr_unaligned_supported:
  		  {
! 		    struct ptr_info_def *pi;
  		    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);
  		    if (alignment_support_scheme == dr_aligned)
  		      {
  			gcc_assert (aligned_access_p (first_dr));
! 			pi->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;
  		      }
  		    else
  		      {
  			TREE_TYPE (data_ref)
  			  = build_aligned_type (TREE_TYPE (data_ref),
  						TYPE_ALIGN (elem_type));
! 			pi->misalign = DR_MISALIGNMENT (first_dr);
  		      }
  		    break;
  		  }
  		case dr_explicit_realign:
--- 4858,4892 ----
  		case dr_aligned:
  		case dr_unaligned_supported:
  		  {
! 		    unsigned int align, misalign;
! 
  		    data_ref
  		      = build2 (MEM_REF, vectype, dataref_ptr,
  				build_int_cst (reference_alias_ptr_type
  					       (DR_REF (first_dr)), 0));
! 		    align = TYPE_ALIGN_UNIT (vectype);
  		    if (alignment_support_scheme == dr_aligned)
  		      {
  			gcc_assert (aligned_access_p (first_dr));
! 			misalign = 0;
  		      }
  		    else if (DR_MISALIGNMENT (first_dr) == -1)
  		      {
  			TREE_TYPE (data_ref)
  			  = build_aligned_type (TREE_TYPE (data_ref),
  						TYPE_ALIGN (elem_type));
! 			align = TYPE_ALIGN_UNIT (elem_type);
! 			misalign = 0;
  		      }
  		    else
  		      {
  			TREE_TYPE (data_ref)
  			  = build_aligned_type (TREE_TYPE (data_ref),
  						TYPE_ALIGN (elem_type));
! 			misalign = DR_MISALIGNMENT (first_dr);
  		      }
+ 		    set_ptr_info_alignment (get_ptr_info (dataref_ptr),
+ 					    align, misalign);
  		    break;
  		  }
  		case dr_explicit_realign:


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]