re PR ipa/65334 (r221099 caused: FAIL: gfortran.fortran-torture/execute/in-pack.f90...
authorJan Hubicka <hubicka@ucw.cz>
Sun, 8 Mar 2015 23:12:25 +0000 (00:12 +0100)
committerJan Hubicka <hubicka@gcc.gnu.org>
Sun, 8 Mar 2015 23:12:25 +0000 (23:12 +0000)
PR ipa/65334
* cgraph.h (symtab_node): Add definition_alignment,
can_increase_alignment_p and increase_alignment.
* symtab.c (symtab_node::can_increase_alignment_p,
increase_alignment_1, symtab_node::increase_alignment,
symtab_node::definition_alignment): New.
* tree-vect-data-refs.c (vect_can_force_dr_alignment_p): Use
can_increase_alignment_p.
* tree-vectorizer.c (increase_alignment): Use increase_alignment.
* tree-vect-stmts.c (ensure_base_align): Likewise.

From-SVN: r221268

gcc/ChangeLog
gcc/cgraph.h
gcc/symtab.c
gcc/tree-vect-data-refs.c
gcc/tree-vect-stmts.c
gcc/tree-vectorizer.c

index 275b2d9b44eed8b33025edb1d1caae51aa1c6113..db1f1868b6b1bf7e6124aaddca16b262c8e6d2b4 100644 (file)
@@ -1,3 +1,16 @@
+2015-03-05  Jan Hubicka  <hubicka@ucw.cz>
+
+       PR ipa/65334
+       * cgraph.h (symtab_node): Add definition_alignment,
+       can_increase_alignment_p and increase_alignment.
+       * symtab.c (symtab_node::can_increase_alignment_p,
+       increase_alignment_1, symtab_node::increase_alignment,
+       symtab_node::definition_alignment): New.
+       * tree-vect-data-refs.c (vect_can_force_dr_alignment_p): Use
+       can_increase_alignment_p.
+       * tree-vectorizer.c (increase_alignment): Use increase_alignment.
+       * tree-vect-stmts.c (ensure_base_align): Likewise.
+
 2015-03-05  Jan Hubicka  <hubicka@ucw.cz>
 
        PR ipa/65316
index c4f39bab4e1347c2f51d47c3434b69d0e75a6e7b..dcf383bf35adba6f6e0d2dca957df1ab8cc1dbab 100644 (file)
@@ -289,6 +289,18 @@ public:
   /* Make DECL local.  */
   void make_decl_local (void);
 
+  /* Return desired alignment of the definition.  This is NOT alignment useful
+     to access THIS, because THIS may be interposable and DECL_ALIGN should
+     be used instead.  It however must be guaranteed when output definition
+     of THIS.  */
+  unsigned int definition_alignment ();
+
+  /* Return true if alignment can be increased.  */
+  bool can_increase_alignment_p ();
+
+  /* Increase alignment of symbol to ALIGN.  */
+  void increase_alignment (unsigned int align);
+
   /* Return true if list contains an alias.  */
   bool has_aliases_p (void);
 
index a46ebd49efafd2b676f5d3ea042ce175d020d51e..38337349d15959dcef18d42a0a739a5005b0980a 100644 (file)
@@ -1908,3 +1908,99 @@ symtab_node::address_matters_p ()
   gcc_assert (!alias);
   return call_for_symbol_and_aliases (address_matters_1, NULL, true);
 }
+
+/* Return ture if symbol's alignment may be increased.  */
+
+bool
+symtab_node::can_increase_alignment_p (void)
+{
+  symtab_node *target = ultimate_alias_target ();
+
+  /* For now support only variables.  */
+  if (TREE_CODE (decl) != VAR_DECL)
+    return false;
+
+  /* With -fno-toplevel-reorder we may have already output the constant.  */
+  if (TREE_ASM_WRITTEN (target->decl))
+    return false;
+
+  /* Constant pool entries may be shared.  */
+  if (DECL_IN_CONSTANT_POOL (target->decl))
+    return false;
+
+  /* We cannot change alignment of symbols that may bind to symbols
+     in other translation unit that may contain a definition with lower
+     alignment.  */
+  if (!decl_binds_to_current_def_p (decl))
+    return false;
+
+  /* When compiling partition, be sure the symbol is not output by other
+     partition.  */
+  if (flag_ltrans
+      && (target->in_other_partition
+         || target->get_partitioning_class () == SYMBOL_DUPLICATE))
+    return false;
+
+  /* Do not override the alignment as specified by the ABI when the used
+     attribute is set.  */
+  if (DECL_PRESERVE_P (decl) || DECL_PRESERVE_P (target->decl))
+    return false;
+
+  /* Do not override explicit alignment set by the user when an explicit
+     section name is also used.  This is a common idiom used by many
+     software projects.  */
+  if (DECL_SECTION_NAME (target->decl) != NULL && !target->implicit_section)
+    return false;
+
+  return true;
+}
+
+/* Worker for symtab_node::increase_alignment.  */
+
+static bool
+increase_alignment_1 (symtab_node *n, void *v)
+{
+  unsigned int align = (size_t)v;
+  if (DECL_ALIGN (n->decl) < align
+      && n->can_increase_alignment_p ())
+    {
+      DECL_ALIGN (n->decl) = align;
+      DECL_USER_ALIGN (n->decl) = 1;
+    }
+  return false;
+}
+
+/* Increase alignment of THIS to ALIGN.  */
+
+void
+symtab_node::increase_alignment (unsigned int align)
+{
+  gcc_assert (can_increase_alignment_p () && align < MAX_OFILE_ALIGNMENT);
+  ultimate_alias_target()->call_for_symbol_and_aliases (increase_alignment_1,
+                                                       (void *)(size_t) align,
+                                                       true);
+  gcc_assert (DECL_ALIGN (decl) >= align);
+}
+
+/* Helper for symtab_node::definition_alignment.  */
+
+static bool
+get_alignment_1 (symtab_node *n, void *v)
+{
+  *((unsigned int *)v) = MAX (*((unsigned int *)v), DECL_ALIGN (n->decl));
+  return false;
+}
+
+/* Return desired alignment of the definition.  This is NOT alignment useful
+   to access THIS, because THIS may be interposable and DECL_ALIGN should
+   be used instead.  It however must be guaranteed when output definition
+   of THIS.  */
+
+unsigned int
+symtab_node::definition_alignment ()
+{
+  unsigned int align = 0;
+  gcc_assert (!alias);
+  call_for_symbol_and_aliases (get_alignment_1, &align, true);
+  return align;
+}
index ffe83e2b2f33d353e1a5abf97381da4c72f95b27..5ff6307e1ac9ebb374b18a13473e5d5314d1d096 100644 (file)
@@ -5703,58 +5703,10 @@ vect_can_force_dr_alignment_p (const_tree decl, unsigned int alignment)
   if (TREE_CODE (decl) != VAR_DECL)
     return false;
 
-  /* With -fno-toplevel-reorder we may have already output the constant.  */
-  if (TREE_ASM_WRITTEN (decl))
+  if (decl_in_symtab_p (decl)
+      && !symtab_node::get (decl)->can_increase_alignment_p ())
     return false;
 
-  /* Constant pool entries may be shared and not properly merged by LTO.  */
-  if (DECL_IN_CONSTANT_POOL (decl))
-    return false;
-
-  if (TREE_PUBLIC (decl) || DECL_EXTERNAL (decl))
-    {
-      symtab_node *snode;
-
-      /* We cannot change alignment of symbols that may bind to symbols
-        in other translation unit that may contain a definition with lower
-        alignment.  */
-      if (!decl_binds_to_current_def_p (decl))
-       return false;
-
-      /* When compiling partition, be sure the symbol is not output by other
-        partition.  */
-      snode = symtab_node::get (decl);
-      if (flag_ltrans
-         && (snode->in_other_partition
-             || snode->get_partitioning_class () == SYMBOL_DUPLICATE))
-       return false;
-    }
-
-  /* Do not override the alignment as specified by the ABI when the used
-     attribute is set.  */
-  if (DECL_PRESERVE_P (decl))
-    return false;
-
-  /* Do not override explicit alignment set by the user when an explicit
-     section name is also used.  This is a common idiom used by many
-     software projects.  */
-  if (TREE_STATIC (decl) 
-      && DECL_SECTION_NAME (decl) != NULL
-      && !symtab_node::get (decl)->implicit_section)
-    return false;
-
-  /* If symbol is an alias, we need to check that target is OK.  */
-  if (TREE_STATIC (decl))
-    {
-      tree target = symtab_node::get (decl)->ultimate_alias_target ()->decl;
-      if (target != decl)
-       {
-         if (DECL_PRESERVE_P (target))
-           return false;
-         decl = target;
-       }
-    }
-
   if (TREE_STATIC (decl))
     return (alignment <= MAX_OFILE_ALIGNMENT);
   else
index aa9d43f0fca38bfae74f556814e1b5e9169208fe..41ff80245e559869a405d9ad867694e91a27a555 100644 (file)
@@ -4956,8 +4956,13 @@ ensure_base_align (stmt_vec_info stmt_info, struct data_reference *dr)
       tree vectype = STMT_VINFO_VECTYPE (stmt_info);
       tree base_decl = ((dataref_aux *)dr->aux)->base_decl;
 
-      DECL_ALIGN (base_decl) = TYPE_ALIGN (vectype);
-      DECL_USER_ALIGN (base_decl) = 1;
+      if (decl_in_symtab_p (base_decl))
+       symtab_node::get (base_decl)->increase_alignment (TYPE_ALIGN (vectype));
+      else
+       {
+          DECL_ALIGN (base_decl) = TYPE_ALIGN (vectype);
+          DECL_USER_ALIGN (base_decl) = 1;
+       }
       ((dataref_aux *)dr->aux)->base_misaligned = false;
     }
 }
index 5d43720a37a3df0f82b152d0e55dc96df084725f..415bffa14d52329d5edcf153eb069c94e1aec037 100644 (file)
@@ -719,14 +719,7 @@ increase_alignment (void)
 
       if (vect_can_force_dr_alignment_p (decl, alignment))
         {
-          DECL_ALIGN (decl) = TYPE_ALIGN (vectype);
-          DECL_USER_ALIGN (decl) = 1;
-         if (TREE_STATIC (decl))
-           {
-             tree target = symtab_node::get (decl)->ultimate_alias_target ()->decl;
-              DECL_ALIGN (target) = TYPE_ALIGN (vectype);
-              DECL_USER_ALIGN (target) = 1;
-           }
+         vnode->increase_alignment (TYPE_ALIGN (vectype));
           dump_printf (MSG_NOTE, "Increasing alignment of decl: ");
           dump_generic_expr (MSG_NOTE, TDF_SLIM, decl);
           dump_printf (MSG_NOTE, "\n");