From: Jan Hubicka Date: Sun, 8 Mar 2015 23:12:25 +0000 (+0100) Subject: re PR ipa/65334 (r221099 caused: FAIL: gfortran.fortran-torture/execute/in-pack.f90... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=428f0c67ee75be486ccdbc83bae06cebec2bdb0f;p=gcc.git re PR ipa/65334 (r221099 caused: FAIL: gfortran.fortran-torture/execute/in-pack.f90 execution, -O2 -ftree-vectorize -msse2) 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 275b2d9b44e..db1f1868b6b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2015-03-05 Jan Hubicka + + 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 PR ipa/65316 diff --git a/gcc/cgraph.h b/gcc/cgraph.h index c4f39bab4e1..dcf383bf35a 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 a46ebd49efa..38337349d15 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 ffe83e2b2f3..5ff6307e1ac 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 aa9d43f0fca..41ff80245e5 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 5d43720a37a..415bffa14d5 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");