OSDN Git Service

2012-01-25 Richard Guenther <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 25 Jan 2012 11:14:28 +0000 (11:14 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 25 Jan 2012 11:14:28 +0000 (11:14 +0000)
* tree.h (get_pointer_alignment_1): Declare.
* builtins.c (get_pointer_alignment_1): New function.
(get_pointer_alignment): Use it.

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

gcc/ChangeLog
gcc/builtins.c
gcc/tree.h

index fd5acdb..d252a5a 100644 (file)
@@ -1,3 +1,9 @@
+2012-01-25  Richard Guenther  <rguenther@suse.de>
+
+       * tree.h (get_pointer_alignment_1): Declare.
+       * builtins.c (get_pointer_alignment_1): New function.
+       (get_pointer_alignment): Use it.
+
 2012-01-25  Ramana Radhakrishnan  <ramana.radhakrishnan@linaro.org>
 
        PR rtl-optimization/48308
index 44b8551..d62b419 100644 (file)
@@ -477,37 +477,59 @@ get_object_or_type_alignment (tree exp)
   return align;
 }
 
-/* Return the alignment in bits of EXP, a pointer valued expression.
-   The alignment returned is, by default, the alignment of the thing that
-   EXP points to.  If it is not a POINTER_TYPE, 0 is returned.
+/* 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.
 
-   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.  */
+   If EXP is not a pointer, 0 is returned.  */
 
 unsigned int
-get_pointer_alignment (tree exp)
+get_pointer_alignment_1 (tree exp, unsigned HOST_WIDE_INT *bitposp)
 {
   STRIP_NOPS (exp);
 
   if (TREE_CODE (exp) == ADDR_EXPR)
-    return get_object_alignment (TREE_OPERAND (exp, 0));
+    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);
-      unsigned align;
       if (!pi)
-       return BITS_PER_UNIT;
-      if (pi->misalign != 0)
-       align = (pi->misalign & -pi->misalign);
-      else
-       align = pi->align;
-      return align * BITS_PER_UNIT;
+       {
+         *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.
+   The alignment returned is, by default, the alignment of the thing that
+   EXP points to.  If it is not a POINTER_TYPE, 0 is returned.
+
+   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 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.  */
+
+  if (bitpos != 0)
+    align = (bitpos & -bitpos);
+
+  return align;
+}
+
 /* Compute the length of a C string.  TREE_STRING_LENGTH is not the right
    way, because it could contain a zero byte in the middle.
    TREE_STRING_LENGTH is the size of the character array, not the string.
index 5719b8f..140f23e 100644 (file)
@@ -5450,6 +5450,7 @@ 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);