Commit 87c0fb4b by Richard Guenther Committed by Richard Biener

tree.h (get_pointer_alignment_1): Declare.

2012-01-25  Richard Guenther  <rguenther@suse.de>

	* tree.h (get_pointer_alignment_1): Declare.
	* builtins.c (get_pointer_alignment_1): New function.
	(get_pointer_alignment): Use it.

From-SVN: r183514
parent fcc82a7a
2012-01-25 Richard Guenther <rguenther@suse.de>
* tree.h (get_pointer_alignment_1): Declare.
* builtins.c (get_pointer_alignment_1): New function.
(get_pointer_alignment): Use it.
2012-01-25 Ramana Radhakrishnan <ramana.radhakrishnan@linaro.org> 2012-01-25 Ramana Radhakrishnan <ramana.radhakrishnan@linaro.org>
PR rtl-optimization/48308 PR rtl-optimization/48308
......
...@@ -477,37 +477,59 @@ get_object_or_type_alignment (tree exp) ...@@ -477,37 +477,59 @@ get_object_or_type_alignment (tree exp)
return align; return align;
} }
/* Return the alignment in bits of EXP, a pointer valued expression. /* For a pointer valued expression EXP compute values M and N such that
The alignment returned is, by default, the alignment of the thing that M divides (EXP - N) and such that N < M. Store N in *BITPOSP and return M.
EXP points to. If it is not a POINTER_TYPE, 0 is returned.
Otherwise, look at the expression to see if we can do better, i.e., if the If EXP is not a pointer, 0 is returned. */
expression is actually pointing at an object whose alignment is tighter. */
unsigned int unsigned int
get_pointer_alignment (tree exp) get_pointer_alignment_1 (tree exp, unsigned HOST_WIDE_INT *bitposp)
{ {
STRIP_NOPS (exp); STRIP_NOPS (exp);
if (TREE_CODE (exp) == ADDR_EXPR) if (TREE_CODE (exp) == ADDR_EXPR)
return get_object_alignment (TREE_OPERAND (exp, 0)); return get_object_alignment_1 (TREE_OPERAND (exp, 0), bitposp);
else if (TREE_CODE (exp) == SSA_NAME else if (TREE_CODE (exp) == SSA_NAME
&& POINTER_TYPE_P (TREE_TYPE (exp))) && POINTER_TYPE_P (TREE_TYPE (exp)))
{ {
struct ptr_info_def *pi = SSA_NAME_PTR_INFO (exp); struct ptr_info_def *pi = SSA_NAME_PTR_INFO (exp);
unsigned align;
if (!pi) if (!pi)
return BITS_PER_UNIT; {
if (pi->misalign != 0) *bitposp = 0;
align = (pi->misalign & -pi->misalign); return BITS_PER_UNIT;
else }
align = pi->align; *bitposp = pi->misalign * BITS_PER_UNIT;
return align * BITS_PER_UNIT; return pi->align * BITS_PER_UNIT;
} }
*bitposp = 0;
return POINTER_TYPE_P (TREE_TYPE (exp)) ? BITS_PER_UNIT : 0; return POINTER_TYPE_P (TREE_TYPE (exp)) ? BITS_PER_UNIT : 0;
} }
/* Return the alignment in bits of EXP, a pointer valued expression.
The alignment returned is, by default, the alignment of the thing that
EXP points to. If it is not a POINTER_TYPE, 0 is returned.
Otherwise, look at the expression to see if we can do better, i.e., if the
expression is actually pointing at an object whose alignment is tighter. */
unsigned int
get_pointer_alignment (tree exp)
{
unsigned HOST_WIDE_INT bitpos = 0;
unsigned int align;
align = get_pointer_alignment_1 (exp, &bitpos);
/* align and bitpos now specify known low bits of the pointer.
ptr & (align - 1) == bitpos. */
if (bitpos != 0)
align = (bitpos & -bitpos);
return align;
}
/* Compute the length of a C string. TREE_STRING_LENGTH is not the right /* Compute the length of a C string. TREE_STRING_LENGTH is not the right
way, because it could contain a zero byte in the middle. way, because it could contain a zero byte in the middle.
TREE_STRING_LENGTH is the size of the character array, not the string. TREE_STRING_LENGTH is the size of the character array, not the string.
......
...@@ -5450,6 +5450,7 @@ extern bool is_builtin_fn (tree); ...@@ -5450,6 +5450,7 @@ extern bool is_builtin_fn (tree);
extern unsigned int get_object_alignment_1 (tree, unsigned HOST_WIDE_INT *); extern unsigned int get_object_alignment_1 (tree, unsigned HOST_WIDE_INT *);
extern unsigned int get_object_alignment (tree); extern unsigned int get_object_alignment (tree);
extern unsigned int get_object_or_type_alignment (tree); extern unsigned int get_object_or_type_alignment (tree);
extern unsigned int get_pointer_alignment_1 (tree, unsigned HOST_WIDE_INT *);
extern unsigned int get_pointer_alignment (tree); extern unsigned int get_pointer_alignment (tree);
extern tree fold_call_stmt (gimple, bool); extern tree fold_call_stmt (gimple, bool);
extern tree gimple_fold_builtin_snprintf_chk (gimple, tree, enum built_in_function); extern tree gimple_fold_builtin_snprintf_chk (gimple, tree, enum built_in_function);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment