From: kenner Date: Tue, 9 Apr 2002 13:41:58 +0000 (+0000) Subject: * expr.c (is_aligning_offset): New function. X-Git-Tag: upstream/4.9.2~87420 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=67c68e458488c5836b972ebf666d5d4adb9e0d4b;p=platform%2Fupstream%2Flinaro-gcc.git * expr.c (is_aligning_offset): New function. (expand_expr, case COMPONENT_EXPR): Call it. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@52077 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 81074d5..b38c09a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +Tue Apr 9 09:35:45 2002 Richard Kenner + + * expr.c (is_aligning_offset): New function. + (expand_expr, case COMPONENT_EXPR): Call it. + 2002-04-08 David S. Miller PR target/6082 diff --git a/gcc/expr.c b/gcc/expr.c index 066b454..11f1a53 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -147,6 +147,7 @@ static rtx store_field PARAMS ((rtx, HOST_WIDE_INT, int)); static rtx var_rtx 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 void do_jump_by_parts_greater PARAMS ((tree, int, rtx, rtx)); static void do_jump_by_parts_equality PARAMS ((tree, rtx, rtx)); @@ -6927,6 +6928,12 @@ expand_expr (exp, target, tmode, modifier) 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. */ if (GET_CODE (op0) == MEM && volatilep && ! MEM_VOLATILE_P (op0)) { @@ -8823,6 +8830,56 @@ expand_expr (exp, target, tmode, modifier) 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 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