builtins.c (get_object_alignment_1): Return whether we can determine the alignment or conservatively assume byte...
2012-05-03 Martin Jambor <mjambor@suse.cz> * 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. From-SVN: r187101
This commit is contained in:
parent
445db530c3
commit
644ffefd9b
|
@ -1,3 +1,52 @@
|
|||
2012-05-03 Martin Jambor <mjambor@suse.cz>
|
||||
|
||||
* 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 <matz@suse.de>
|
||||
|
||||
* basic-block.h (struct rtl_bb_info, struct gimple_bb_info): Move
|
||||
|
|
154
gcc/builtins.c
154
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. */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue