]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
tree-flow.h (struct ptr_info_def): Add align and misalign fields.
authorRichard Guenther <rguenther@suse.de>
Thu, 12 Aug 2010 10:36:08 +0000 (10:36 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Thu, 12 Aug 2010 10:36:08 +0000 (10:36 +0000)
2010-08-12  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.

From-SVN: r163189

gcc/ChangeLog
gcc/builtins.c
gcc/gimple-pretty-print.c
gcc/tree-flow.h
gcc/tree-ssa-alias.c
gcc/tree-ssa-ccp.c
gcc/tree-ssanames.c
gcc/tree.h

index a20fb37df3d6e796178afc036321480fb0c7419f..61b30e9f751ce90e79a79ab98057939c7c43e92f 100644 (file)
@@ -1,3 +1,29 @@
+2010-08-12  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.
+
 2010-08-12  Uros Bizjak  <ubizjak@gmail.com>
 
        * config/i386/i386.c (LONG_TYPE_SIZE): Remove.
index 3d5ca33989cd1868ce42b7def2fe7762842293cb..ad5d6aae048f738b9e667687534c93d12d1f06d3 100644 (file)
@@ -309,6 +309,7 @@ get_object_alignment (tree exp, unsigned int max_align)
   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)
        {
@@ -319,11 +320,52 @@ get_object_alignment (tree exp, unsigned int max_align)
        }
       else
        align = BITS_PER_UNIT;
-      if (TREE_CODE (addr) == ADDR_EXPR)
+      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))
     {
@@ -417,56 +459,28 @@ can_trust_pointer_alignment (void)
    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
+unsigned 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);
+  STRIP_NOPS (exp);
 
-       default:
-         return align;
-       }
+  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
@@ -3293,7 +3307,7 @@ expand_builtin_strlen (tree exp, rtx target,
       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;
+      unsigned int align;
 
       /* If the length can be computed at compile-time, return it.  */
       len = c_strlen (src, 0);
@@ -4066,9 +4080,9 @@ expand_builtin_memcmp (tree exp, ATTRIBUTE_UNUSED rtx target,
     tree arg2 = CALL_EXPR_ARG (exp, 1);
     tree len = CALL_EXPR_ARG (exp, 2);
 
-    int arg1_align
+    unsigned int arg1_align
       = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
-    int arg2_align
+    unsigned int arg2_align
       = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
     enum machine_mode insn_mode;
 
@@ -4168,9 +4182,9 @@ expand_builtin_strcmp (tree exp, ATTRIBUTE_UNUSED rtx target)
       tree arg1 = CALL_EXPR_ARG (exp, 0);
       tree arg2 = CALL_EXPR_ARG (exp, 1);
 
-      int arg1_align
+      unsigned int arg1_align
        = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
-      int arg2_align
+      unsigned int arg2_align
        = get_pointer_alignment (arg2, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
 
       /* If we don't have POINTER_TYPE, call the function.  */
@@ -4319,9 +4333,9 @@ expand_builtin_strncmp (tree exp, ATTRIBUTE_UNUSED rtx target,
     tree arg2 = CALL_EXPR_ARG (exp, 1);
     tree arg3 = CALL_EXPR_ARG (exp, 2);
 
-    int arg1_align
+    unsigned int arg1_align
       = get_pointer_alignment (arg1, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
-    int arg2_align
+    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;
@@ -5505,7 +5519,9 @@ get_builtin_sync_mem (tree loc, enum machine_mode mode)
      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));
+  /* 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;
 
@@ -8280,7 +8296,7 @@ fold_builtin_memset (location_t loc, tree dest, tree c, tree len,
   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)
+        < length)
     return NULL_TREE;
 
   if (length > HOST_BITS_PER_WIDE_INT / BITS_PER_UNIT)
@@ -8365,7 +8381,7 @@ fold_builtin_memory_op (location_t loc, tree dest, tree src,
   else
     {
       tree srctype, desttype;
-      int src_align, dest_align;
+      unsigned int src_align, dest_align;
       tree off0;
 
       if (endp == 3)
@@ -8504,8 +8520,8 @@ fold_builtin_memory_op (location_t loc, tree dest, tree src,
 
       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))
+      if (dest_align < TYPE_ALIGN (desttype)
+         || src_align < TYPE_ALIGN (srctype))
        return NULL_TREE;
 
       if (!ignore)
@@ -8531,7 +8547,7 @@ fold_builtin_memory_op (location_t loc, tree dest, tree src,
          && tree_int_cst_equal (TYPE_SIZE_UNIT (srctype), len)
          && (!STRICT_ALIGNMENT
              || !destvar
-             || src_align >= (int) TYPE_ALIGN (desttype)))
+             || src_align >= TYPE_ALIGN (desttype)))
        srcvar = fold_build2 (MEM_REF, destvar ? desttype : srctype,
                              srcvar, off0);
       else
@@ -8543,7 +8559,7 @@ fold_builtin_memory_op (location_t loc, tree dest, tree src,
       if (srcvar == NULL_TREE)
        {
          if (STRICT_ALIGNMENT
-             && src_align < (int) TYPE_ALIGN (desttype))
+             && src_align < TYPE_ALIGN (desttype))
            return NULL_TREE;
          STRIP_NOPS (src);
          srcvar = fold_build2 (MEM_REF, desttype, src, off0);
@@ -8551,7 +8567,7 @@ fold_builtin_memory_op (location_t loc, tree dest, tree src,
       else if (destvar == NULL_TREE)
        {
          if (STRICT_ALIGNMENT
-             && dest_align < (int) TYPE_ALIGN (srctype))
+             && dest_align < TYPE_ALIGN (srctype))
            return NULL_TREE;
          STRIP_NOPS (dest);
          destvar = fold_build2 (MEM_REF, srctype, dest, off0);
index 6e1f6b782c2a051443e39ea117cae7e004fe4b84..941d3236eeaba1c1bbe4dc46a171dd231ee03575 100644 (file)
@@ -1363,8 +1363,13 @@ dump_gimple_phi (pretty_printer *buffer, gimple phi, int spc, int flags)
       && 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, &SSA_NAME_PTR_INFO (lhs)->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, "# ");
     }
@@ -1650,9 +1655,16 @@ dump_gimple_stmt (pretty_printer *buffer, gimple gs, int spc, int flags)
          && 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, &SSA_NAME_PTR_INFO (lhs)->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 abbf9172a1ce65a6b1fa91be5300490612f1c3ff..04ba5325f11f0eca6a679bfd6635b9f37b81de09 100644 (file)
@@ -119,6 +119,18 @@ struct GTY(()) ptr_info_def
 {
   /* 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 a95d78caca1824e8fead42f7f5a50707ab9132a0..eddb9b987c3085e396b6f84837e5986a49e28e6e 100644 (file)
@@ -368,27 +368,6 @@ debug_alias_info (void)
 }
 
 
-/* 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
index 622fe146315daf6e5021d68fce3fbada6171aacf..5551df2d5a30c05994b2ff1bc3f4634c4e334e65 100644 (file)
@@ -839,8 +839,40 @@ static bool
 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);
@@ -1981,6 +2013,7 @@ evaluate_stmt (gimple stmt)
       && !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;
@@ -2026,6 +2059,33 @@ evaluate_stmt (gimple stmt)
              || 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 79b844ffe7c477597339db00c3593272bd90133f..0d63fe9fe637e851f93253e11b766f31a4a7ef37 100644 (file)
@@ -240,20 +240,29 @@ release_ssa_name (tree var)
     }
 }
 
-/* Creates a duplicate of a ssa name NAME defined in statement STMT.  */
 
-tree
-duplicate_ssa_name (tree name, gimple stmt)
+/* 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)
 {
-  tree new_name = make_ssa_name (SSA_NAME_VAR (name), stmt);
-  struct ptr_info_def *old_ptr_info = SSA_NAME_PTR_INFO (name);
+  struct ptr_info_def *pi;
 
-  if (old_ptr_info)
-    duplicate_ssa_name_ptr_info (new_name, old_ptr_info);
+  gcc_assert (POINTER_TYPE_P (TREE_TYPE (t)));
 
-  return new_name;
-}
+  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.  */
@@ -276,6 +285,21 @@ duplicate_ssa_name_ptr_info (tree name, struct ptr_info_def *ptr_info)
 }
 
 
+/* 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 bdf4f727c45ac51c09bf73639c633650a61c0138..9a3c93d356f64e325a34748488e933c09e214bd5 100644 (file)
@@ -5033,7 +5033,7 @@ 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 can_trust_pointer_alignment (void);
-extern int get_pointer_alignment (tree, unsigned int);
+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);