aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/cgraph.h12
-rw-r--r--gcc/symtab.c96
-rw-r--r--gcc/tree-vect-data-refs.c52
-rw-r--r--gcc/tree-vect-stmts.c9
-rw-r--r--gcc/tree-vectorizer.c9
6 files changed, 131 insertions, 60 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 275b2d9..db1f186 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,18 @@
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
* tree.c (free_lang_data_in_type): Be sure to keep BINFO_VTABLE
when outputting debug.
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index c4f39ba..dcf383b 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -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);
diff --git a/gcc/symtab.c b/gcc/symtab.c
index a46ebd4..3833734 100644
--- a/gcc/symtab.c
+++ b/gcc/symtab.c
@@ -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;
+}
diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c
index ffe83e2..5ff6307 100644
--- a/gcc/tree-vect-data-refs.c
+++ b/gcc/tree-vect-data-refs.c
@@ -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
diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
index aa9d43f..41ff8024 100644
--- a/gcc/tree-vect-stmts.c
+++ b/gcc/tree-vect-stmts.c
@@ -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;
}
}
diff --git a/gcc/tree-vectorizer.c b/gcc/tree-vectorizer.c
index 5d43720..415bffa 100644
--- a/gcc/tree-vectorizer.c
+++ b/gcc/tree-vectorizer.c
@@ -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");