Commit 1ce7f3c2 by Richard Kenner Committed by Richard Kenner

expr.c (is_aligning_offset): New function.

	* expr.c (is_aligning_offset): New function.
	(expand_expr, case COMPONENT_EXPR): Call it.

From-SVN: r52077
parent dcf5a5de
Tue Apr 9 09:35:45 2002 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* expr.c (is_aligning_offset): New function.
(expand_expr, case COMPONENT_EXPR): Call it.
2002-04-08 David S. Miller <davem@redhat.com> 2002-04-08 David S. Miller <davem@redhat.com>
PR target/6082 PR target/6082
......
...@@ -147,6 +147,7 @@ static rtx store_field PARAMS ((rtx, HOST_WIDE_INT, ...@@ -147,6 +147,7 @@ static rtx store_field PARAMS ((rtx, HOST_WIDE_INT,
int)); int));
static rtx var_rtx PARAMS ((tree)); static rtx var_rtx PARAMS ((tree));
static HOST_WIDE_INT highest_pow2_factor PARAMS ((tree)); static HOST_WIDE_INT highest_pow2_factor PARAMS ((tree));
static int is_aligning_offset PARAMS ((tree, tree));
static rtx expand_increment PARAMS ((tree, int, int)); static rtx expand_increment PARAMS ((tree, int, int));
static void do_jump_by_parts_greater PARAMS ((tree, int, rtx, rtx)); static void do_jump_by_parts_greater PARAMS ((tree, int, rtx, rtx));
static void do_jump_by_parts_equality PARAMS ((tree, rtx, rtx)); static void do_jump_by_parts_equality PARAMS ((tree, rtx, rtx));
...@@ -6927,6 +6928,12 @@ expand_expr (exp, target, tmode, modifier) ...@@ -6927,6 +6928,12 @@ expand_expr (exp, target, tmode, modifier)
highest_pow2_factor (offset)); highest_pow2_factor (offset));
} }
/* If OFFSET is making OP0 more aligned than BIGGEST_ALIGNMENT,
record its alignment as BIGGEST_ALIGNMENT. */
if (GET_CODE (op0) == MEM && bitpos == 0 && offset != 0
&& is_aligning_offset (offset, tem))
set_mem_align (op0, BIGGEST_ALIGNMENT);
/* Don't forget about volatility even if this is a bitfield. */ /* Don't forget about volatility even if this is a bitfield. */
if (GET_CODE (op0) == MEM && volatilep && ! MEM_VOLATILE_P (op0)) if (GET_CODE (op0) == MEM && volatilep && ! MEM_VOLATILE_P (op0))
{ {
...@@ -8823,6 +8830,56 @@ expand_expr (exp, target, tmode, modifier) ...@@ -8823,6 +8830,56 @@ expand_expr (exp, target, tmode, modifier)
return temp; return temp;
} }
/* Subroutine of above: returns 1 if OFFSET corresponds to an offset that
when applied to the address of EXP produces an address known to be
aligned more than BIGGEST_ALIGNMENT. */
static int
is_aligning_offset (offset, exp)
tree offset;
tree exp;
{
/* Strip off any conversions and WITH_RECORD_EXPR nodes. */
while (TREE_CODE (offset) == NON_LVALUE_EXPR
|| TREE_CODE (offset) == NOP_EXPR
|| TREE_CODE (offset) == CONVERT_EXPR
|| TREE_CODE (offset) == WITH_RECORD_EXPR)
offset = TREE_OPERAND (offset, 0);
/* We must now have a BIT_AND_EXPR with a constant that is one less than
power of 2 and which is larger than BIGGEST_ALIGNMENT. */
if (TREE_CODE (offset) != BIT_AND_EXPR
|| !host_integerp (TREE_OPERAND (offset, 1), 1)
|| compare_tree_int (TREE_OPERAND (offset, 1), BIGGEST_ALIGNMENT) <= 0
|| !exact_log2 (tree_low_cst (TREE_OPERAND (offset, 1), 1) + 1) < 0)
return 0;
/* Look at the first operand of BIT_AND_EXPR and strip any conversion.
It must be NEGATE_EXPR. Then strip any more conversions. */
offset = TREE_OPERAND (offset, 0);
while (TREE_CODE (offset) == NON_LVALUE_EXPR
|| TREE_CODE (offset) == NOP_EXPR
|| TREE_CODE (offset) == CONVERT_EXPR)
offset = TREE_OPERAND (offset, 0);
if (TREE_CODE (offset) != NEGATE_EXPR)
return 0;
offset = TREE_OPERAND (offset, 0);
while (TREE_CODE (offset) == NON_LVALUE_EXPR
|| TREE_CODE (offset) == NOP_EXPR
|| TREE_CODE (offset) == CONVERT_EXPR)
offset = TREE_OPERAND (offset, 0);
/* This must now be the address either of EXP or of a PLACEHOLDER_EXPR
whose type is the same as EXP. */
return (TREE_CODE (offset) == ADDR_EXPR
&& (TREE_OPERAND (offset, 0) == exp
|| (TREE_CODE (TREE_OPERAND (offset, 0)) == PLACEHOLDER_EXPR
&& (TREE_TYPE (TREE_OPERAND (offset, 0))
== TREE_TYPE (exp)))));
}
/* Return the tree node if a ARG corresponds to a string constant or zero /* Return the tree node if a ARG corresponds to a string constant or zero
if it doesn't. If we return non-zero, set *PTR_OFFSET to the offset if it doesn't. If we return non-zero, set *PTR_OFFSET to the offset
in bytes within the string that ARG is accessing. The type of the in bytes within the string that ARG is accessing. The type of the
......
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