From ceea063b697987925bcb8ae8e1bedd5e5580a55f Mon Sep 17 00:00:00 2001 From: jamborm Date: Thu, 3 May 2012 15:48:56 +0000 Subject: [PATCH] 2012-05-03 Martin Jambor * builtins.c (get_object_alignment_1): Return whether we can determine the alignment or conservatively assume byte alignment. Return the alignment by reference. Use get_pointer_alignment_1 for dereference alignment. (get_pointer_alignment_1): Return whether we can determine the alignment or conservatively assume byte alignment. Return the alignment by reference. Use get_ptr_info_alignment to get SSA name alignment. (get_object_alignment): Update call to get_object_alignment_1. (get_object_or_type_alignment): Likewise, fall back to type alignment only when it returned false. (get_pointer_alignment): Update call to get_pointer_alignment_1. * fold-const.c (get_pointer_modulus_and_residue): Update call to get_object_alignment_1. * ipa-prop.c (ipa_modify_call_arguments): Update call to get_pointer_alignment_1. * tree-sra.c (build_ref_for_offset): Likewise, fall back to the type of MEM_REF or TARGET_MEM_REF only when it returns false. * tree-ssa-ccp.c (get_value_from_alignment): Update call to get_object_alignment_1. (ccp_finalize): Use set_ptr_info_alignment. * tree.h (get_object_alignment_1): Update declaration. (get_pointer_alignment_1): Likewise. * gimple-pretty-print.c (dump_gimple_phi): Use get_ptr_info_alignment. (dump_gimple_stmt): Likewise. * tree-flow.h (ptr_info_def): Updated comments of fields align and misalign. (get_ptr_info_alignment): Declared. (mark_ptr_info_alignment_unknown): Likewise. (set_ptr_info_alignment): Likewise. (adjust_ptr_info_misalignment): Likewise. * tree-ssa-address.c (copy_ref_info): Use new access functions to get and set alignment of SSA names. * tree-ssa-loop-ivopts.c (rewrite_use_nonlinear_expr): Call mark_ptr_info_alignment_unknown. * tree-ssanames.c (get_ptr_info_alignment): New function. (mark_ptr_info_alignment_unknown): Likewise. (set_ptr_info_alignment): Likewise. (adjust_ptr_info_misalignment): Likewise. (get_ptr_info): Call mark_ptr_info_alignment_unknown. * tree-vect-data-refs.c (vect_create_addr_base_for_vector_ref): Likewise. (bump_vector_ptr): Likewise. * tree-vect-stmts.c (create_array_ref): Use set_ptr_info_alignment. (vectorizable_store): Likewise. (vectorizable_load): Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@187101 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 49 +++++++++++++++ gcc/builtins.c | 154 ++++++++++++++++++++++++++++----------------- gcc/fold-const.c | 2 +- gcc/gimple-pretty-print.c | 11 ++-- gcc/ipa-prop.c | 3 +- gcc/tree-flow.h | 20 ++++-- gcc/tree-sra.c | 12 ++-- gcc/tree-ssa-address.c | 18 +++--- gcc/tree-ssa-ccp.c | 12 ++-- gcc/tree-ssa-loop-ivopts.c | 5 +- gcc/tree-ssanames.c | 59 ++++++++++++++++- gcc/tree-vect-data-refs.c | 8 +-- gcc/tree-vect-stmts.c | 36 +++++------ gcc/tree.h | 6 +- 14 files changed, 271 insertions(+), 124 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8f3228d..c7eb3b0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,52 @@ +2012-05-03 Martin Jambor + + * builtins.c (get_object_alignment_1): Return whether we can determine + the alignment or conservatively assume byte alignment. Return the + alignment by reference. Use get_pointer_alignment_1 for dereference + alignment. + (get_pointer_alignment_1): Return whether we can determine the + alignment or conservatively assume byte alignment. Return the + alignment by reference. Use get_ptr_info_alignment to get SSA name + alignment. + (get_object_alignment): Update call to get_object_alignment_1. + (get_object_or_type_alignment): Likewise, fall back to type alignment + only when it returned false. + (get_pointer_alignment): Update call to get_pointer_alignment_1. + * fold-const.c (get_pointer_modulus_and_residue): Update call to + get_object_alignment_1. + * ipa-prop.c (ipa_modify_call_arguments): Update call to + get_pointer_alignment_1. + * tree-sra.c (build_ref_for_offset): Likewise, fall back to the type + of MEM_REF or TARGET_MEM_REF only when it returns false. + * tree-ssa-ccp.c (get_value_from_alignment): Update call to + get_object_alignment_1. + (ccp_finalize): Use set_ptr_info_alignment. + * tree.h (get_object_alignment_1): Update declaration. + (get_pointer_alignment_1): Likewise. + * gimple-pretty-print.c (dump_gimple_phi): Use get_ptr_info_alignment. + (dump_gimple_stmt): Likewise. + * tree-flow.h (ptr_info_def): Updated comments of fields align and + misalign. + (get_ptr_info_alignment): Declared. + (mark_ptr_info_alignment_unknown): Likewise. + (set_ptr_info_alignment): Likewise. + (adjust_ptr_info_misalignment): Likewise. + * tree-ssa-address.c (copy_ref_info): Use new access functions to get + and set alignment of SSA names. + * tree-ssa-loop-ivopts.c (rewrite_use_nonlinear_expr): Call + mark_ptr_info_alignment_unknown. + * tree-ssanames.c (get_ptr_info_alignment): New function. + (mark_ptr_info_alignment_unknown): Likewise. + (set_ptr_info_alignment): Likewise. + (adjust_ptr_info_misalignment): Likewise. + (get_ptr_info): Call mark_ptr_info_alignment_unknown. + * tree-vect-data-refs.c (vect_create_addr_base_for_vector_ref): + Likewise. + (bump_vector_ptr): Likewise. + * tree-vect-stmts.c (create_array_ref): Use set_ptr_info_alignment. + (vectorizable_store): Likewise. + (vectorizable_load): Likewise. + 2012-05-03 Michael Matz * basic-block.h (struct rtl_bb_info, struct gimple_bb_info): Move diff --git a/gcc/builtins.c b/gcc/builtins.c index 72e2591..1ce9ac1 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -263,8 +263,10 @@ called_as_built_in (tree node) return is_builtin_name (name); } -/* Compute values M and N such that M divides (address of EXP - N) and - such that N < M. Store N in *BITPOSP and return M. +/* Compute values M and N such that M divides (address of EXP - N) and such + that N < M. If these numbers can be determined, store M in alignp and N in + *BITPOSP and return true. Otherwise return false and store BITS_PER_UNIT to + *alignp and any bit-offset to *bitposp. Note that the address (and thus the alignment) computed here is based on the address to which a symbol resolves, whereas DECL_ALIGN is based @@ -273,14 +275,16 @@ called_as_built_in (tree node) the address &foo of a Thumb function foo() has the lowest bit set, whereas foo() itself starts on an even address. */ -unsigned int -get_object_alignment_1 (tree exp, unsigned HOST_WIDE_INT *bitposp) +bool +get_object_alignment_1 (tree exp, unsigned int *alignp, + unsigned HOST_WIDE_INT *bitposp) { HOST_WIDE_INT bitsize, bitpos; tree offset; enum machine_mode mode; int unsignedp, volatilep; - unsigned int align, inner; + unsigned int inner, align = BITS_PER_UNIT; + bool known_alignment = false; /* Get the innermost object and the constant (bitpos) and possibly variable (offset) offset of the access. */ @@ -301,84 +305,97 @@ get_object_alignment_1 (tree exp, unsigned HOST_WIDE_INT *bitposp) allows the low bit to be used as a virtual bit, we know that the address itself must be 2-byte aligned. */ if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn) - align = 2 * BITS_PER_UNIT; - else - align = BITS_PER_UNIT; + { + known_alignment = true; + align = 2 * BITS_PER_UNIT; + } } else - align = DECL_ALIGN (exp); + { + known_alignment = true; + align = DECL_ALIGN (exp); + } } else if (CONSTANT_CLASS_P (exp)) { + known_alignment = true; align = TYPE_ALIGN (TREE_TYPE (exp)); #ifdef CONSTANT_ALIGNMENT align = (unsigned)CONSTANT_ALIGNMENT (exp, align); #endif } else if (TREE_CODE (exp) == VIEW_CONVERT_EXPR) - align = TYPE_ALIGN (TREE_TYPE (exp)); + { + known_alignment = true; + align = TYPE_ALIGN (TREE_TYPE (exp)); + } else if (TREE_CODE (exp) == INDIRECT_REF) - align = TYPE_ALIGN (TREE_TYPE (exp)); + { + known_alignment = true; + align = TYPE_ALIGN (TREE_TYPE (exp)); + } else if (TREE_CODE (exp) == MEM_REF) { tree addr = TREE_OPERAND (exp, 0); - struct ptr_info_def *pi; + unsigned ptr_align; + unsigned HOST_WIDE_INT ptr_bitpos; + if (TREE_CODE (addr) == BIT_AND_EXPR && TREE_CODE (TREE_OPERAND (addr, 1)) == INTEGER_CST) { + known_alignment = true; 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))) + + if (get_pointer_alignment_1 (addr, &ptr_align, &ptr_bitpos)) { - bitpos += (pi->misalign * BITS_PER_UNIT) & ~(align - 1); - align = MAX (pi->align * BITS_PER_UNIT, align); + known_alignment = true; + bitpos += ptr_bitpos & ~(align - 1); + align = MAX (ptr_align, align); } - else if (TREE_CODE (addr) == ADDR_EXPR) - align = MAX (align, get_object_alignment (TREE_OPERAND (addr, 0))); + bitpos += mem_ref_offset (exp).low * BITS_PER_UNIT; } else if (TREE_CODE (exp) == TARGET_MEM_REF) { - struct ptr_info_def *pi; + unsigned ptr_align; + unsigned HOST_WIDE_INT ptr_bitpos; tree addr = TMR_BASE (exp); + if (TREE_CODE (addr) == BIT_AND_EXPR && TREE_CODE (TREE_OPERAND (addr, 1)) == INTEGER_CST) { + known_alignment = true; 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))) + + if (get_pointer_alignment_1 (addr, &ptr_align, &ptr_bitpos)) { - bitpos += (pi->misalign * BITS_PER_UNIT) & ~(align - 1); - align = MAX (pi->align * BITS_PER_UNIT, align); + known_alignment = true; + bitpos += ptr_bitpos & ~(align - 1); + align = MAX (ptr_align, align); } - else if (TREE_CODE (addr) == ADDR_EXPR) - align = MAX (align, get_object_alignment (TREE_OPERAND (addr, 0))); + 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); + known_alignment = true; } else if (TMR_INDEX (exp)) - align = BITS_PER_UNIT; + known_alignment = false; + if (TMR_INDEX2 (exp)) - align = BITS_PER_UNIT; + known_alignment = false; } - else - align = BITS_PER_UNIT; /* If there is a non-constant offset part extract the maximum alignment that can prevail. */ @@ -418,19 +435,27 @@ get_object_alignment_1 (tree exp, unsigned HOST_WIDE_INT *bitposp) } else { - inner = MIN (inner, BITS_PER_UNIT); + known_alignment = false; break; } offset = next_offset; } - /* Alignment is innermost object alignment adjusted by the constant - and non-constant offset parts. */ - align = MIN (align, inner); - bitpos = bitpos & (align - 1); - + if (known_alignment) + { + /* Alignment is innermost object alignment adjusted by the constant + and non-constant offset parts. */ + align = MIN (align, inner); + bitpos = bitpos & (align - 1); + *alignp = align; + } + else + { + bitpos = bitpos & (BITS_PER_UNIT - 1); + *alignp = BITS_PER_UNIT; + } *bitposp = bitpos; - return align; + return known_alignment; } /* Return the alignment in bits of EXP, an object. */ @@ -441,14 +466,13 @@ get_object_alignment (tree exp) unsigned HOST_WIDE_INT bitpos = 0; unsigned int align; - align = get_object_alignment_1 (exp, &bitpos); + get_object_alignment_1 (exp, &align, &bitpos); /* align and bitpos now specify known low bits of the pointer. ptr & (align - 1) == bitpos. */ if (bitpos != 0) align = (bitpos & -bitpos); - return align; } @@ -465,45 +489,57 @@ unsigned int get_object_or_type_alignment (tree exp) { unsigned HOST_WIDE_INT misalign; - unsigned int align = get_object_alignment_1 (exp, &misalign); + unsigned int align; + bool known_alignment; gcc_assert (TREE_CODE (exp) == MEM_REF || TREE_CODE (exp) == TARGET_MEM_REF); - + known_alignment = get_object_alignment_1 (exp, &align, &misalign); if (misalign != 0) align = (misalign & -misalign); - else - align = MAX (TYPE_ALIGN (TREE_TYPE (exp)), align); + else if (!known_alignment) + align = TYPE_ALIGN (TREE_TYPE (exp)); return align; } -/* For a pointer valued expression EXP compute values M and N such that - M divides (EXP - N) and such that N < M. Store N in *BITPOSP and return M. +/* For a pointer valued expression EXP compute values M and N such that M + divides (EXP - N) and such that N < M. If these numbers can be determined, + store M in alignp and N in *BITPOSP and return true. Otherwise return false + and store BITS_PER_UNIT to *alignp and any bit-offset to *bitposp. - If EXP is not a pointer, 0 is returned. */ + If EXP is not a pointer, false is returned too. */ -unsigned int -get_pointer_alignment_1 (tree exp, unsigned HOST_WIDE_INT *bitposp) +bool +get_pointer_alignment_1 (tree exp, unsigned int *alignp, + unsigned HOST_WIDE_INT *bitposp) { STRIP_NOPS (exp); if (TREE_CODE (exp) == ADDR_EXPR) - return get_object_alignment_1 (TREE_OPERAND (exp, 0), bitposp); + return get_object_alignment_1 (TREE_OPERAND (exp, 0), alignp, bitposp); else if (TREE_CODE (exp) == SSA_NAME && POINTER_TYPE_P (TREE_TYPE (exp))) { + unsigned int ptr_align, ptr_misalign; struct ptr_info_def *pi = SSA_NAME_PTR_INFO (exp); - if (!pi) + + if (pi && get_ptr_info_alignment (pi, &ptr_align, &ptr_misalign)) + { + *bitposp = ptr_misalign * BITS_PER_UNIT; + *alignp = ptr_align * BITS_PER_UNIT; + return true; + } + else { *bitposp = 0; - return BITS_PER_UNIT; + *alignp = BITS_PER_UNIT; + return false; } - *bitposp = pi->misalign * BITS_PER_UNIT; - return pi->align * BITS_PER_UNIT; } *bitposp = 0; - return POINTER_TYPE_P (TREE_TYPE (exp)) ? BITS_PER_UNIT : 0; + *alignp = BITS_PER_UNIT; + return false; } /* Return the alignment in bits of EXP, a pointer valued expression. @@ -518,8 +554,8 @@ get_pointer_alignment (tree exp) { unsigned HOST_WIDE_INT bitpos = 0; unsigned int align; - - align = get_pointer_alignment_1 (exp, &bitpos); + + get_pointer_alignment_1 (exp, &align, &bitpos); /* align and bitpos now specify known low bits of the pointer. ptr & (align - 1) == bitpos. */ diff --git a/gcc/fold-const.c b/gcc/fold-const.c index fe12942..f8b31b7 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -9536,7 +9536,7 @@ get_pointer_modulus_and_residue (tree expr, unsigned HOST_WIDE_INT *residue, if (code == ADDR_EXPR) { unsigned int bitalign; - bitalign = get_object_alignment_1 (TREE_OPERAND (expr, 0), residue); + get_object_alignment_1 (TREE_OPERAND (expr, 0), &bitalign, residue); *residue /= BITS_PER_UNIT; return bitalign / BITS_PER_UNIT; } diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c index 7b29aa6..2e3cb0c 100644 --- a/gcc/gimple-pretty-print.c +++ b/gcc/gimple-pretty-print.c @@ -1590,14 +1590,14 @@ dump_gimple_phi (pretty_printer *buffer, gimple phi, int spc, int flags) && POINTER_TYPE_P (TREE_TYPE (lhs)) && SSA_NAME_PTR_INFO (lhs)) { + unsigned int align, misalign; struct ptr_info_def *pi = SSA_NAME_PTR_INFO (lhs); pp_string (buffer, "PT = "); pp_points_to_solution (buffer, &pi->pt); newline_and_indent (buffer, spc); - if (pi->align != 1) + if (get_ptr_info_alignment (pi, &align, &misalign)) { - pp_printf (buffer, "# ALIGN = %u, MISALIGN = %u", - pi->align, pi->misalign); + pp_printf (buffer, "# ALIGN = %u, MISALIGN = %u", align, misalign); newline_and_indent (buffer, spc); } pp_string (buffer, "# "); @@ -1889,14 +1889,15 @@ dump_gimple_stmt (pretty_printer *buffer, gimple gs, int spc, int flags) && POINTER_TYPE_P (TREE_TYPE (lhs)) && SSA_NAME_PTR_INFO (lhs)) { + unsigned int align, misalign; struct ptr_info_def *pi = SSA_NAME_PTR_INFO (lhs); pp_string (buffer, "# PT = "); pp_points_to_solution (buffer, &pi->pt); newline_and_indent (buffer, spc); - if (pi->align != 1) + if (get_ptr_info_alignment (pi, &align, &misalign)) { pp_printf (buffer, "# ALIGN = %u, MISALIGN = %u", - pi->align, pi->misalign); + align, misalign); newline_and_indent (buffer, spc); } } diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c index 17a431c..af0f335 100644 --- a/gcc/ipa-prop.c +++ b/gcc/ipa-prop.c @@ -2513,7 +2513,8 @@ ipa_modify_call_arguments (struct cgraph_edge *cs, gimple stmt, tree type = adj->type; unsigned int align; unsigned HOST_WIDE_INT misalign; - align = get_pointer_alignment_1 (base, &misalign); + + get_pointer_alignment_1 (base, &align, &misalign); misalign += (double_int_sext (tree_to_double_int (off), TYPE_PRECISION (TREE_TYPE (off))).low * BITS_PER_UNIT); diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h index 794047b..315d955 100644 --- a/gcc/tree-flow.h +++ b/gcc/tree-flow.h @@ -136,12 +136,17 @@ struct GTY(()) ptr_info_def 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. */ + /* When known, this is 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. When the alignment is not + known, it is zero. Do not access directly but use functions + get_ptr_info_alignment, set_ptr_info_alignment, + mark_ptr_info_alignment_unknown and similar. */ unsigned int align; - /* The byte offset this pointer differs from the above alignment. */ + /* When alignment is known, the byte offset this pointer differs from the + above alignment. Access only through the same helper functions as align + above. */ unsigned int misalign; }; @@ -593,6 +598,13 @@ extern void duplicate_ssa_name_ptr_info (tree, struct ptr_info_def *); extern void release_ssa_name (tree); extern void release_defs (gimple); extern void replace_ssa_name_symbol (tree, tree); +extern bool get_ptr_info_alignment (struct ptr_info_def *, unsigned int *, + unsigned int *); +extern void mark_ptr_info_alignment_unknown (struct ptr_info_def *); +extern void set_ptr_info_alignment (struct ptr_info_def *, unsigned int, + unsigned int); +extern void adjust_ptr_info_misalignment (struct ptr_info_def *, + unsigned int); #ifdef GATHER_STATISTICS extern void ssanames_print_statistics (void); diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index de99b30..3f84f6b 100644 --- a/gcc/tree-sra.c +++ b/gcc/tree-sra.c @@ -1472,11 +1472,13 @@ build_ref_for_offset (location_t loc, tree base, HOST_WIDE_INT offset, by looking at the access mode. That would constrain the alignment of base + base_offset which we would need to adjust according to offset. */ - align = get_pointer_alignment_1 (base, &misalign); - if (misalign == 0 - && (TREE_CODE (prev_base) == MEM_REF - || TREE_CODE (prev_base) == TARGET_MEM_REF)) - align = MAX (align, TYPE_ALIGN (TREE_TYPE (prev_base))); + if (!get_pointer_alignment_1 (base, &align, &misalign)) + { + gcc_assert (misalign == 0); + if (TREE_CODE (prev_base) == MEM_REF + || TREE_CODE (prev_base) == TARGET_MEM_REF) + align = TYPE_ALIGN (TREE_TYPE (prev_base)); + } misalign += (double_int_sext (tree_to_double_int (off), TYPE_PRECISION (TREE_TYPE (off))).low * BITS_PER_UNIT); diff --git a/gcc/tree-ssa-address.c b/gcc/tree-ssa-address.c index cf13157..e11da3e 100644 --- a/gcc/tree-ssa-address.c +++ b/gcc/tree-ssa-address.c @@ -863,26 +863,26 @@ copy_ref_info (tree new_ref, tree old_ref) && SSA_NAME_PTR_INFO (TREE_OPERAND (base, 0))) { struct ptr_info_def *new_pi; + unsigned int align, misalign; + duplicate_ssa_name_ptr_info (new_ptr_base, SSA_NAME_PTR_INFO (TREE_OPERAND (base, 0))); new_pi = SSA_NAME_PTR_INFO (new_ptr_base); /* We have to be careful about transfering alignment information. */ - if (TREE_CODE (old_ref) == MEM_REF + if (get_ptr_info_alignment (new_pi, &align, &misalign) + && TREE_CODE (old_ref) == MEM_REF && !(TREE_CODE (new_ref) == TARGET_MEM_REF && (TMR_INDEX2 (new_ref) || (TMR_STEP (new_ref) && (TREE_INT_CST_LOW (TMR_STEP (new_ref)) - < new_pi->align))))) + < align))))) { - new_pi->misalign += double_int_sub (mem_ref_offset (old_ref), - mem_ref_offset (new_ref)).low; - new_pi->misalign &= (new_pi->align - 1); + unsigned int inc = double_int_sub (mem_ref_offset (old_ref), + mem_ref_offset (new_ref)).low; + adjust_ptr_info_misalignment (new_pi, inc); } else - { - new_pi->align = 1; - new_pi->misalign = 0; - } + mark_ptr_info_alignment_unknown (new_pi); } else if (TREE_CODE (base) == VAR_DECL || TREE_CODE (base) == PARM_DECL diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c index 1257b8b..feded5b 100644 --- a/gcc/tree-ssa-ccp.c +++ b/gcc/tree-ssa-ccp.c @@ -513,7 +513,7 @@ get_value_from_alignment (tree expr) gcc_assert (TREE_CODE (expr) == ADDR_EXPR); - align = get_object_alignment_1 (TREE_OPERAND (expr, 0), &bitpos); + get_object_alignment_1 (TREE_OPERAND (expr, 0), &align, &bitpos); val.mask = double_int_and_not (POINTER_TYPE_P (type) || TYPE_UNSIGNED (type) ? double_int_mask (TYPE_PRECISION (type)) @@ -807,7 +807,6 @@ ccp_finalize (void) { tree name = ssa_name (i); prop_value_t *val; - struct ptr_info_def *pi; unsigned int tem, align; if (!name @@ -823,12 +822,9 @@ ccp_finalize (void) 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); + if (align > 1) + set_ptr_info_alignment (get_ptr_info (name), align, + TREE_INT_CST_LOW (val->value) & (align - 1)); } /* Perform substitutions based on the known constant values. */ diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c index d346e00..af7a1cf 100644 --- a/gcc/tree-ssa-loop-ivopts.c +++ b/gcc/tree-ssa-loop-ivopts.c @@ -6259,10 +6259,7 @@ rewrite_use_nonlinear_expr (struct ivopts_data *data, /* As this isn't a plain copy we have to reset alignment information. */ if (SSA_NAME_PTR_INFO (comp)) - { - SSA_NAME_PTR_INFO (comp)->align = 1; - SSA_NAME_PTR_INFO (comp)->misalign = 0; - } + mark_ptr_info_alignment_unknown (SSA_NAME_PTR_INFO (comp)); } } diff --git a/gcc/tree-ssanames.c b/gcc/tree-ssanames.c index 7c31550..64455af 100644 --- a/gcc/tree-ssanames.c +++ b/gcc/tree-ssanames.c @@ -238,6 +238,62 @@ release_ssa_name (tree var) } } +/* If the alignment of the pointer described by PI is known, return true and + store the alignment and the deviation from it into *ALIGNP and *MISALIGNP + respectively. Otherwise return false. */ + +bool +get_ptr_info_alignment (struct ptr_info_def *pi, unsigned int *alignp, + unsigned int *misalignp) +{ + if (pi->align) + { + *alignp = pi->align; + *misalignp = pi->misalign; + return true; + } + else + return false; +} + +/* State that the pointer described by PI has unknown alignment. */ + +void +mark_ptr_info_alignment_unknown (struct ptr_info_def *pi) +{ + pi->align = 0; + pi->misalign = 0; +} + +/* Store the the power-of-two byte alignment and the deviation from that + alignment of pointer described by PI to ALIOGN and MISALIGN + respectively. */ + +void +set_ptr_info_alignment (struct ptr_info_def *pi, unsigned int align, + unsigned int misalign) +{ + gcc_checking_assert (align != 0); + gcc_assert ((align & (align - 1)) == 0); + gcc_assert ((misalign & ~(align - 1)) == 0); + + pi->align = align; + pi->misalign = misalign; +} + +/* If pointer decribed by PI has known alignment, increase its known + misalignment by INCREMENT modulo its current alignment. */ + +void +adjust_ptr_info_misalignment (struct ptr_info_def *pi, + unsigned int increment) +{ + if (pi->align != 0) + { + pi->misalign += increment; + pi->misalign &= (pi->align - 1); + } +} /* Return the alias information associated with pointer T. It creates a new instance if none existed. */ @@ -254,8 +310,7 @@ get_ptr_info (tree t) { pi = ggc_alloc_cleared_ptr_info_def (); pt_solution_reset (&pi->pt); - pi->align = 1; - pi->misalign = 0; + mark_ptr_info_alignment_unknown (pi); SSA_NAME_PTR_INFO (t) = pi; } diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c index 37df7ab..7464034 100644 --- a/gcc/tree-vect-data-refs.c +++ b/gcc/tree-vect-data-refs.c @@ -3397,10 +3397,7 @@ vect_create_addr_base_for_vector_ref (gimple stmt, { duplicate_ssa_name_ptr_info (vec_stmt, DR_PTR_INFO (dr)); if (offset) - { - SSA_NAME_PTR_INFO (vec_stmt)->align = 1; - SSA_NAME_PTR_INFO (vec_stmt)->misalign = 0; - } + mark_ptr_info_alignment_unknown (SSA_NAME_PTR_INFO (vec_stmt)); } if (vect_print_dump_info (REPORT_DETAILS)) @@ -3799,8 +3796,7 @@ bump_vector_ptr (tree dataref_ptr, gimple ptr_incr, gimple_stmt_iterator *gsi, if (DR_PTR_INFO (dr)) { duplicate_ssa_name_ptr_info (new_dataref_ptr, DR_PTR_INFO (dr)); - SSA_NAME_PTR_INFO (new_dataref_ptr)->align = 1; - SSA_NAME_PTR_INFO (new_dataref_ptr)->misalign = 0; + mark_ptr_info_alignment_unknown (SSA_NAME_PTR_INFO (new_dataref_ptr)); } if (!ptr_incr) diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index 5e6f71a..a0368d8 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -106,15 +106,12 @@ write_vector_array (gimple stmt, gimple_stmt_iterator *gsi, tree vect, static tree create_array_ref (tree type, tree ptr, struct data_reference *first_dr) { - struct ptr_info_def *pi; tree mem_ref, alias_ptr_type; alias_ptr_type = reference_alias_ptr_type (DR_REF (first_dr)); mem_ref = build2 (MEM_REF, type, ptr, build_int_cst (alias_ptr_type, 0)); /* Arrays have the same alignment as their type. */ - pi = get_ptr_info (ptr); - pi->align = TYPE_ALIGN_UNIT (type); - pi->misalign = 0; + set_ptr_info_alignment (get_ptr_info (ptr), TYPE_ALIGN_UNIT (type), 0); return mem_ref; } @@ -4029,7 +4026,7 @@ vectorizable_store (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt, next_stmt = first_stmt; for (i = 0; i < vec_num; i++) { - struct ptr_info_def *pi; + unsigned align, misalign; if (i > 0) /* Bump the vector pointer. */ @@ -4046,25 +4043,26 @@ vectorizable_store (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt, data_ref = build2 (MEM_REF, TREE_TYPE (vec_oprnd), dataref_ptr, build_int_cst (reference_alias_ptr_type (DR_REF (first_dr)), 0)); - pi = get_ptr_info (dataref_ptr); - pi->align = TYPE_ALIGN_UNIT (vectype); + align = TYPE_ALIGN_UNIT (vectype); if (aligned_access_p (first_dr)) - pi->misalign = 0; + misalign = 0; else if (DR_MISALIGNMENT (first_dr) == -1) { TREE_TYPE (data_ref) = build_aligned_type (TREE_TYPE (data_ref), TYPE_ALIGN (elem_type)); - pi->align = TYPE_ALIGN_UNIT (elem_type); - pi->misalign = 0; + align = TYPE_ALIGN_UNIT (elem_type); + misalign = 0; } else { TREE_TYPE (data_ref) = build_aligned_type (TREE_TYPE (data_ref), TYPE_ALIGN (elem_type)); - pi->misalign = DR_MISALIGNMENT (first_dr); + misalign = DR_MISALIGNMENT (first_dr); } + set_ptr_info_alignment (get_ptr_info (dataref_ptr), align, + misalign); /* Arguments are ready. Create the new vector stmt. */ new_stmt = gimple_build_assign (data_ref, vec_oprnd); @@ -4860,33 +4858,35 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt, case dr_aligned: case dr_unaligned_supported: { - struct ptr_info_def *pi; + unsigned int align, misalign; + data_ref = build2 (MEM_REF, vectype, dataref_ptr, build_int_cst (reference_alias_ptr_type (DR_REF (first_dr)), 0)); - pi = get_ptr_info (dataref_ptr); - pi->align = TYPE_ALIGN_UNIT (vectype); + align = TYPE_ALIGN_UNIT (vectype); if (alignment_support_scheme == dr_aligned) { gcc_assert (aligned_access_p (first_dr)); - pi->misalign = 0; + misalign = 0; } else if (DR_MISALIGNMENT (first_dr) == -1) { TREE_TYPE (data_ref) = build_aligned_type (TREE_TYPE (data_ref), TYPE_ALIGN (elem_type)); - pi->align = TYPE_ALIGN_UNIT (elem_type); - pi->misalign = 0; + align = TYPE_ALIGN_UNIT (elem_type); + misalign = 0; } else { TREE_TYPE (data_ref) = build_aligned_type (TREE_TYPE (data_ref), TYPE_ALIGN (elem_type)); - pi->misalign = DR_MISALIGNMENT (first_dr); + misalign = DR_MISALIGNMENT (first_dr); } + set_ptr_info_alignment (get_ptr_info (dataref_ptr), + align, misalign); break; } case dr_explicit_realign: diff --git a/gcc/tree.h b/gcc/tree.h index 3d7fcab..9d53a14 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -5465,10 +5465,12 @@ 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 is_builtin_fn (tree); -extern unsigned int get_object_alignment_1 (tree, unsigned HOST_WIDE_INT *); +extern bool get_object_alignment_1 (tree, unsigned int *, + unsigned HOST_WIDE_INT *); extern unsigned int get_object_alignment (tree); extern unsigned int get_object_or_type_alignment (tree); -extern unsigned int get_pointer_alignment_1 (tree, unsigned HOST_WIDE_INT *); +extern bool get_pointer_alignment_1 (tree, unsigned int *, + unsigned HOST_WIDE_INT *); extern unsigned int get_pointer_alignment (tree); extern tree fold_call_stmt (gimple, bool); extern tree gimple_fold_builtin_snprintf_chk (gimple, tree, enum built_in_function); -- 2.7.4