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]

[PATCH] Conservative alignment tracking (2nd try)


This is a refresh of the conservative alignment tracking patch which
uses bit-CCP to generate and propagate alignment information for
SSA name pointers.  Alongside annotating pointers by amending
the SSA_NAME_PTR_INFO structure this patch makes get_pointer_alignment
conservative and thus always "trustable" (a single call to
can_trust_pointer_alignment () is remaining - that in cp/call.c,
for whatever reason that is concerned).  get_pointer_alignment ()
is mostly used from within string and memory routine expanders,
I adjusted the only other caller, get_builtin_sync_mem, to force
a minimum alignment (even though that alignment requirement isn't
documented(?) sync primitives on data that eventually overlaps
with a cache-line boundary are not going to work(?)).

Bootstrapped and tested on x86_64-unknown-linux-gnu, bootstrapped
on ia64-linux with alignment traps enabled, testing is in progress there.

I'll install this tomorrow if nobody has serious concerns.

Thanks,
Richard.

2010-08-06  Richard Guenther  <rguenther@suse.de>

	* tree-flow.h (struct ptr_info_def): Add align and misalign fields.
	* tree-ssa-alias.c (get_ptr_info): Move ...
	* tree-ssanames.c (get_ptr_info): ... here.  Initialize
	align and misalign fields conservatively.
	* tree-ssa-ccp.c (ccp_finalize): From partially constant pointers
	derive alignment information.
	(evaluate_stmt): Derive alignment information from memory
	allocation functions.
	* tree.h (get_pointer_alignment): Make unsigned.
	* builtins.c (get_object_alignment): Use alignment information we
	have computed for pointers.
	(get_pointer_alignment): Likewise.  Make conservative, return
	and unsigned value.
	(expand_builtin_strlen): Adjust.
	(expand_builtin_memcmp): Likewise.
	(expand_builtin_strcmp): Likewise.
	(expand_builtin_strncmp): Likewise.
	(get_builtin_sync_mem): Use at least mode alignment.
	(fold_builtin_memset): Adjust.
	(fold_builtin_memory_op): Likewise.
	* gimple-pretty-print.c (dump_gimple_phi): Alongside alias
	information also dump pointer alignment knowledge.
	(dump_gimple_stmt): Likewise.

Index: trunk/gcc/builtins.c
===================================================================
*** trunk.orig/gcc/builtins.c	2010-08-11 12:33:14.000000000 +0200
--- trunk/gcc/builtins.c	2010-08-11 12:44:25.000000000 +0200
*************** get_object_alignment (tree exp, unsigned
*** 309,314 ****
--- 309,315 ----
    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)
  	{
*************** get_object_alignment (tree exp, unsigned
*** 319,330 ****
  	}
        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);
--- 320,372 ----
  	}
        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),
  						  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))))
+     {
+       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),
+ 						  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 if (TREE_CODE (exp) == TARGET_MEM_REF
  	   && TMR_SYMBOL (exp))
      {
        align = get_object_alignment (TMR_SYMBOL (exp), max_align);
*************** can_trust_pointer_alignment (void)
*** 417,472 ****
     Otherwise, look at the expression to see if we can do better, i.e., if the
     expression is actually pointing at an object whose alignment is tighter.  */
  
! int
  get_pointer_alignment (tree exp, unsigned int max_align)
  {
!   unsigned int align, inner;
! 
!   if (!can_trust_pointer_alignment ())
!     return 0;
! 
!   if (!POINTER_TYPE_P (TREE_TYPE (exp)))
!     return 0;
! 
!   align = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
!   align = MIN (align, max_align);
! 
!   while (1)
!     {
!       switch (TREE_CODE (exp))
! 	{
! 	CASE_CONVERT:
! 	  exp = TREE_OPERAND (exp, 0);
! 	  if (! POINTER_TYPE_P (TREE_TYPE (exp)))
! 	    return align;
! 
! 	  inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
! 	  align = MIN (inner, max_align);
! 	  break;
! 
! 	case POINTER_PLUS_EXPR:
! 	  /* If sum of pointer + int, restrict our maximum alignment to that
! 	     imposed by the integer.  If not, we can't do any better than
! 	     ALIGN.  */
! 	  if (! host_integerp (TREE_OPERAND (exp, 1), 1))
! 	    return align;
! 
! 	  while (((tree_low_cst (TREE_OPERAND (exp, 1), 1))
! 		  & (max_align / BITS_PER_UNIT - 1))
! 		 != 0)
! 	    max_align >>= 1;
! 
! 	  exp = TREE_OPERAND (exp, 0);
! 	  break;
  
! 	case ADDR_EXPR:
! 	  /* See what we are pointing at and look at its alignment.  */
! 	  return get_object_alignment (TREE_OPERAND (exp, 0), max_align);
! 
! 	default:
! 	  return align;
! 	}
      }
  }
  
  /* Compute the length of a C string.  TREE_STRING_LENGTH is not the right
--- 459,486 ----
     Otherwise, look at the expression to see if we can do better, i.e., if the
     expression is actually pointing at an object whose alignment is tighter.  */
  
! unsigned int
  get_pointer_alignment (tree exp, unsigned int max_align)
  {
!   STRIP_NOPS (exp);
  
!   if (TREE_CODE (exp) == ADDR_EXPR)
!     return get_object_alignment (TREE_OPERAND (exp, 0), max_align);
!   else if (TREE_CODE (exp) == SSA_NAME
! 	   && POINTER_TYPE_P (TREE_TYPE (exp)))
!     {
!       struct ptr_info_def *pi = SSA_NAME_PTR_INFO (exp);
!       unsigned align;
!       if (!pi)
! 	return BITS_PER_UNIT;
!       if (pi->misalign != 0)
! 	align = (pi->misalign & -pi->misalign);
!       else
! 	align = pi->align;
!       return MIN (max_align, align * BITS_PER_UNIT);
      }
+ 
+   return POINTER_TYPE_P (TREE_TYPE (exp)) ? BITS_PER_UNIT : 0;
  }
  
  /* Compute the length of a C string.  TREE_STRING_LENGTH is not the right
*************** expand_builtin_strlen (tree exp, rtx tar
*** 3293,3299 ****
        rtx result, src_reg, char_rtx, before_strlen;
        enum machine_mode insn_mode = target_mode, char_mode;
        enum insn_code icode = CODE_FOR_nothing;
!       int align;
  
        /* If the length can be computed at compile-time, return it.  */
        len = c_strlen (src, 0);
--- 3307,3313 ----
        rtx result, src_reg, char_rtx, before_strlen;
        enum machine_mode insn_mode = target_mode, char_mode;
        enum insn_code icode = CODE_FOR_nothing;
!       unsigned int align;
  
        /* If the length can be computed at compile-time, return it.  */
        len = c_strlen (src, 0);
*************** expand_builtin_memcmp (tree exp, ATTRIBU
*** 4066,4074 ****
      tree arg2 = CALL_EXPR_ARG (exp, 1);
      tree len = CALL_EXPR_ARG (exp, 2);
  
!     int arg1_align
        = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
!     int arg2_align
        = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
      enum machine_mode insn_mode;
  
--- 4080,4088 ----
      tree arg2 = CALL_EXPR_ARG (exp, 1);
      tree len = CALL_EXPR_ARG (exp, 2);
  
!     unsigned int arg1_align
        = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
!     unsigned int arg2_align
        = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
      enum machine_mode insn_mode;
  
*************** expand_builtin_strcmp (tree exp, ATTRIBU
*** 4168,4176 ****
        tree arg1 = CALL_EXPR_ARG (exp, 0);
        tree arg2 = CALL_EXPR_ARG (exp, 1);
  
!       int arg1_align
  	= get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
!       int arg2_align
  	= get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
  
        /* If we don't have POINTER_TYPE, call the function.  */
--- 4182,4190 ----
        tree arg1 = CALL_EXPR_ARG (exp, 0);
        tree arg2 = CALL_EXPR_ARG (exp, 1);
  
!       unsigned int arg1_align
  	= get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
!       unsigned int arg2_align
  	= get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
  
        /* If we don't have POINTER_TYPE, call the function.  */
*************** expand_builtin_strncmp (tree exp, ATTRIB
*** 4319,4327 ****
      tree arg2 = CALL_EXPR_ARG (exp, 1);
      tree arg3 = CALL_EXPR_ARG (exp, 2);
  
!     int arg1_align
        = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
!     int arg2_align
        = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
      enum machine_mode insn_mode
        = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
--- 4333,4341 ----
      tree arg2 = CALL_EXPR_ARG (exp, 1);
      tree arg3 = CALL_EXPR_ARG (exp, 2);
  
!     unsigned int arg1_align
        = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
!     unsigned int arg2_align
        = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
      enum machine_mode insn_mode
        = insn_data[(int) CODE_FOR_cmpstrnsi].operand[0].mode;
*************** get_builtin_sync_mem (tree loc, enum mac
*** 5505,5511 ****
       satisfy the full barrier semantics of the intrinsic.  */
    mem = validize_mem (gen_rtx_MEM (mode, addr));
  
!   set_mem_align (mem, get_pointer_alignment (loc, BIGGEST_ALIGNMENT));
    set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER);
    MEM_VOLATILE_P (mem) = 1;
  
--- 5519,5527 ----
       satisfy the full barrier semantics of the intrinsic.  */
    mem = validize_mem (gen_rtx_MEM (mode, addr));
  
!   /* The alignment needs to be at least according to that of the mode.  */
!   set_mem_align (mem, MAX (GET_MODE_ALIGNMENT (mode),
! 			   get_pointer_alignment (loc, BIGGEST_ALIGNMENT)));
    set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER);
    MEM_VOLATILE_P (mem) = 1;
  
*************** fold_builtin_memset (location_t loc, tre
*** 8280,8286 ****
    length = tree_low_cst (len, 1);
    if (GET_MODE_SIZE (TYPE_MODE (etype)) != length
        || get_pointer_alignment (dest, BIGGEST_ALIGNMENT) / BITS_PER_UNIT
! 	 < (int) length)
      return NULL_TREE;
  
    if (length > HOST_BITS_PER_WIDE_INT / BITS_PER_UNIT)
--- 8296,8302 ----
    length = tree_low_cst (len, 1);
    if (GET_MODE_SIZE (TYPE_MODE (etype)) != length
        || get_pointer_alignment (dest, BIGGEST_ALIGNMENT) / BITS_PER_UNIT
! 	 < length)
      return NULL_TREE;
  
    if (length > HOST_BITS_PER_WIDE_INT / BITS_PER_UNIT)
*************** fold_builtin_memory_op (location_t loc,
*** 8365,8371 ****
    else
      {
        tree srctype, desttype;
!       int src_align, dest_align;
        tree off0;
  
        if (endp == 3)
--- 8381,8387 ----
    else
      {
        tree srctype, desttype;
!       unsigned int src_align, dest_align;
        tree off0;
  
        if (endp == 3)
*************** fold_builtin_memory_op (location_t loc,
*** 8504,8511 ****
  
        src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
        dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
!       if (dest_align < (int) TYPE_ALIGN (desttype)
! 	  || src_align < (int) TYPE_ALIGN (srctype))
  	return NULL_TREE;
  
        if (!ignore)
--- 8520,8527 ----
  
        src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
        dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
!       if (dest_align < TYPE_ALIGN (desttype)
! 	  || src_align < TYPE_ALIGN (srctype))
  	return NULL_TREE;
  
        if (!ignore)
*************** fold_builtin_memory_op (location_t loc,
*** 8531,8537 ****
  	  && tree_int_cst_equal (TYPE_SIZE_UNIT (srctype), len)
  	  && (!STRICT_ALIGNMENT
  	      || !destvar
! 	      || src_align >= (int) TYPE_ALIGN (desttype)))
  	srcvar = fold_build2 (MEM_REF, destvar ? desttype : srctype,
  			      srcvar, off0);
        else
--- 8547,8553 ----
  	  && tree_int_cst_equal (TYPE_SIZE_UNIT (srctype), len)
  	  && (!STRICT_ALIGNMENT
  	      || !destvar
! 	      || src_align >= TYPE_ALIGN (desttype)))
  	srcvar = fold_build2 (MEM_REF, destvar ? desttype : srctype,
  			      srcvar, off0);
        else
*************** fold_builtin_memory_op (location_t loc,
*** 8543,8549 ****
        if (srcvar == NULL_TREE)
  	{
  	  if (STRICT_ALIGNMENT
! 	      && src_align < (int) TYPE_ALIGN (desttype))
  	    return NULL_TREE;
  	  STRIP_NOPS (src);
  	  srcvar = fold_build2 (MEM_REF, desttype, src, off0);
--- 8559,8565 ----
        if (srcvar == NULL_TREE)
  	{
  	  if (STRICT_ALIGNMENT
! 	      && src_align < TYPE_ALIGN (desttype))
  	    return NULL_TREE;
  	  STRIP_NOPS (src);
  	  srcvar = fold_build2 (MEM_REF, desttype, src, off0);
*************** fold_builtin_memory_op (location_t loc,
*** 8551,8557 ****
        else if (destvar == NULL_TREE)
  	{
  	  if (STRICT_ALIGNMENT
! 	      && dest_align < (int) TYPE_ALIGN (srctype))
  	    return NULL_TREE;
  	  STRIP_NOPS (dest);
  	  destvar = fold_build2 (MEM_REF, srctype, dest, off0);
--- 8567,8573 ----
        else if (destvar == NULL_TREE)
  	{
  	  if (STRICT_ALIGNMENT
! 	      && dest_align < TYPE_ALIGN (srctype))
  	    return NULL_TREE;
  	  STRIP_NOPS (dest);
  	  destvar = fold_build2 (MEM_REF, srctype, dest, off0);
Index: trunk/gcc/gimple-pretty-print.c
===================================================================
*** trunk.orig/gcc/gimple-pretty-print.c	2010-08-11 12:33:14.000000000 +0200
--- trunk/gcc/gimple-pretty-print.c	2010-08-11 12:43:31.000000000 +0200
*************** dump_gimple_phi (pretty_printer *buffer,
*** 1363,1370 ****
        && POINTER_TYPE_P (TREE_TYPE (lhs))
        && SSA_NAME_PTR_INFO (lhs))
      {
        pp_string (buffer, "PT = ");
!       pp_points_to_solution (buffer, &SSA_NAME_PTR_INFO (lhs)->pt);
        newline_and_indent (buffer, spc);
        pp_string (buffer, "# ");
      }
--- 1363,1375 ----
        && 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, "# ");
      }
*************** dump_gimple_stmt (pretty_printer *buffer
*** 1650,1658 ****
  	  && POINTER_TYPE_P (TREE_TYPE (lhs))
  	  && SSA_NAME_PTR_INFO (lhs))
  	{
  	  pp_string (buffer, "# PT = ");
! 	  pp_points_to_solution (buffer, &SSA_NAME_PTR_INFO (lhs)->pt);
  	  newline_and_indent (buffer, spc);
  	}
      }
  
--- 1655,1670 ----
  	  && 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);
+ 	    }
  	}
      }
  
Index: trunk/gcc/tree-flow.h
===================================================================
*** trunk.orig/gcc/tree-flow.h	2010-08-11 12:33:14.000000000 +0200
--- trunk/gcc/tree-flow.h	2010-08-11 12:43:31.000000000 +0200
*************** struct GTY(()) ptr_info_def
*** 119,124 ****
--- 119,136 ----
  {
    /* The points-to solution.  */
    struct pt_solution pt;
+ 
+   /* Alignment and misalignment of the pointer in bytes.  Together
+      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;
  };
  
  
Index: trunk/gcc/tree-ssa-alias.c
===================================================================
*** trunk.orig/gcc/tree-ssa-alias.c	2010-08-11 12:33:14.000000000 +0200
--- trunk/gcc/tree-ssa-alias.c	2010-08-11 12:43:31.000000000 +0200
*************** debug_alias_info (void)
*** 368,394 ****
  }
  
  
- /* Return the alias information associated with pointer T.  It creates a
-    new instance if none existed.  */
- 
- struct ptr_info_def *
- get_ptr_info (tree t)
- {
-   struct ptr_info_def *pi;
- 
-   gcc_assert (POINTER_TYPE_P (TREE_TYPE (t)));
- 
-   pi = SSA_NAME_PTR_INFO (t);
-   if (pi == NULL)
-     {
-       pi = ggc_alloc_cleared_ptr_info_def ();
-       pt_solution_reset (&pi->pt);
-       SSA_NAME_PTR_INFO (t) = pi;
-     }
- 
-   return pi;
- }
- 
  /* Dump the points-to set *PT into FILE.  */
  
  void
--- 368,373 ----
Index: trunk/gcc/tree-ssanames.c
===================================================================
*** trunk.orig/gcc/tree-ssanames.c	2010-08-11 12:33:14.000000000 +0200
--- trunk/gcc/tree-ssanames.c	2010-08-11 12:43:31.000000000 +0200
*************** release_ssa_name (tree var)
*** 240,259 ****
      }
  }
  
- /* Creates a duplicate of a ssa name NAME defined in statement STMT.  */
  
! tree
! duplicate_ssa_name (tree name, gimple stmt)
  {
!   tree new_name = make_ssa_name (SSA_NAME_VAR (name), stmt);
!   struct ptr_info_def *old_ptr_info = SSA_NAME_PTR_INFO (name);
  
!   if (old_ptr_info)
!     duplicate_ssa_name_ptr_info (new_name, old_ptr_info);
  
!   return new_name;
! }
  
  
  /* Creates a duplicate of the ptr_info_def at PTR_INFO for use by
     the SSA name NAME.  */
--- 240,268 ----
      }
  }
  
  
! /* Return the alias information associated with pointer T.  It creates a
!    new instance if none existed.  */
! 
! struct ptr_info_def *
! get_ptr_info (tree t)
  {
!   struct ptr_info_def *pi;
  
!   gcc_assert (POINTER_TYPE_P (TREE_TYPE (t)));
  
!   pi = SSA_NAME_PTR_INFO (t);
!   if (pi == NULL)
!     {
!       pi = ggc_alloc_cleared_ptr_info_def ();
!       pt_solution_reset (&pi->pt);
!       pi->align = 1;
!       pi->misalign = 0;
!       SSA_NAME_PTR_INFO (t) = pi;
!     }
  
+   return pi;
+ }
  
  /* Creates a duplicate of the ptr_info_def at PTR_INFO for use by
     the SSA name NAME.  */
*************** duplicate_ssa_name_ptr_info (tree name,
*** 276,281 ****
--- 285,305 ----
  }
  
  
+ /* Creates a duplicate of a ssa name NAME tobe defined by statement STMT.  */
+ 
+ tree
+ duplicate_ssa_name (tree name, gimple stmt)
+ {
+   tree new_name = make_ssa_name (SSA_NAME_VAR (name), stmt);
+   struct ptr_info_def *old_ptr_info = SSA_NAME_PTR_INFO (name);
+ 
+   if (old_ptr_info)
+     duplicate_ssa_name_ptr_info (new_name, old_ptr_info);
+ 
+   return new_name;
+ }
+ 
+ 
  /* Release all the SSA_NAMEs created by STMT.  */
  
  void
Index: trunk/gcc/tree-ssa-ccp.c
===================================================================
*** trunk.orig/gcc/tree-ssa-ccp.c	2010-08-11 12:33:14.000000000 +0200
--- trunk/gcc/tree-ssa-ccp.c	2010-08-11 12:43:31.000000000 +0200
*************** static bool
*** 839,846 ****
--- 839,878 ----
  ccp_finalize (void)
  {
    bool something_changed;
+   unsigned i;
  
    do_dbg_cnt ();
+ 
+   /* Derive alignment and misalignment information from partially
+      constant pointers in the lattice.  */
+   for (i = 1; i < num_ssa_names; ++i)
+     {
+       tree name = ssa_name (i);
+       prop_value_t *val;
+       struct ptr_info_def *pi;
+       unsigned int tem, align;
+ 
+       if (!name
+ 	  || !POINTER_TYPE_P (TREE_TYPE (name)))
+ 	continue;
+ 
+       val = get_value (name);
+       if (val->lattice_val != CONSTANT
+ 	  || TREE_CODE (val->value) != INTEGER_CST)
+ 	continue;
+ 
+       /* Trailing constant bits specify the alignment, trailing value
+ 	 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.  */
    something_changed = substitute_and_fold (get_constant_value,
  					   ccp_fold_stmt, true);
*************** evaluate_stmt (gimple stmt)
*** 1981,1986 ****
--- 2013,2019 ----
        && !is_constant)
      {
        enum gimple_code code = gimple_code (stmt);
+       tree fndecl;
        val.lattice_val = VARYING;
        val.value = NULL_TREE;
        val.mask = double_int_minus_one;
*************** evaluate_stmt (gimple stmt)
*** 2026,2031 ****
--- 2059,2091 ----
  	      || POINTER_TYPE_P (TREE_TYPE (rhs1)))
  	    val = bit_value_binop (code, TREE_TYPE (rhs1), rhs1, rhs2);
  	}
+       else if (code == GIMPLE_CALL
+ 	       && (fndecl = gimple_call_fndecl (stmt))
+ 	       && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
+ 	{
+ 	  switch (DECL_FUNCTION_CODE (fndecl))
+ 	    {
+ 	    case BUILT_IN_MALLOC:
+ 	    case BUILT_IN_REALLOC:
+ 	    case BUILT_IN_CALLOC:
+ 	      val.lattice_val = CONSTANT;
+ 	      val.value = build_int_cst (TREE_TYPE (gimple_get_lhs (stmt)), 0);
+ 	      val.mask = shwi_to_double_int
+ 		  	   (~(((HOST_WIDE_INT) MALLOC_ABI_ALIGNMENT)
+ 			      / BITS_PER_UNIT - 1));
+ 	      break;
+ 
+ 	    case BUILT_IN_ALLOCA:
+ 	      val.lattice_val = CONSTANT;
+ 	      val.value = build_int_cst (TREE_TYPE (gimple_get_lhs (stmt)), 0);
+ 	      val.mask = shwi_to_double_int
+ 		  	   (~(((HOST_WIDE_INT) BIGGEST_ALIGNMENT)
+ 			      / BITS_PER_UNIT - 1));
+ 	      break;
+ 
+ 	    default:;
+ 	    }
+ 	}
        is_constant = (val.lattice_val == CONSTANT);
      }
  
Index: trunk/gcc/tree.h
===================================================================
*** trunk.orig/gcc/tree.h	2010-08-11 12:33:14.000000000 +0200
--- trunk/gcc/tree.h	2010-08-11 12:43:31.000000000 +0200
*************** extern tree build_string_literal (int, c
*** 5033,5039 ****
  extern bool validate_arglist (const_tree, ...);
  extern rtx builtin_memset_read_str (void *, HOST_WIDE_INT, enum machine_mode);
  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 unsigned int get_object_alignment (tree, unsigned int);
--- 5033,5039 ----
  extern bool validate_arglist (const_tree, ...);
  extern rtx builtin_memset_read_str (void *, HOST_WIDE_INT, enum machine_mode);
  extern bool can_trust_pointer_alignment (void);
! extern unsigned int get_pointer_alignment (tree, unsigned int);
  extern bool is_builtin_name (const char *);
  extern bool is_builtin_fn (tree);
  extern unsigned int get_object_alignment (tree, unsigned int);


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