diff options
author | Jan Hubicka <hubicka@ucw.cz> | 2015-03-09 00:12:25 +0100 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2015-03-08 23:12:25 +0000 |
commit | 428f0c67ee75be486ccdbc83bae06cebec2bdb0f (patch) | |
tree | 1677cdff3ac9a985557890e7fa6db0a63fb9c44c /gcc/symtab.c | |
parent | fb460c3da0b3de006ae596e32826ef63a65c8f2b (diff) | |
download | gcc-428f0c67ee75be486ccdbc83bae06cebec2bdb0f.zip gcc-428f0c67ee75be486ccdbc83bae06cebec2bdb0f.tar.gz gcc-428f0c67ee75be486ccdbc83bae06cebec2bdb0f.tar.bz2 |
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
Diffstat (limited to 'gcc/symtab.c')
-rw-r--r-- | gcc/symtab.c | 96 |
1 files changed, 96 insertions, 0 deletions
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; +} |