diff options
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/builtins.c | 25 | ||||
-rw-r--r-- | gcc/fold-const.c | 34 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/fold-bitand-4.c (renamed from gcc/testsuite/gcc.dg/fold-bitand-4.c) | 4 | ||||
-rw-r--r-- | gcc/tree.h | 1 |
6 files changed, 42 insertions, 35 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4469232..6165fdd 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2011-04-14 Richard Guenther <rguenther@suse.de> + + * tree.h (get_object_alignment_1): Declare. + * builtins.c (get_object_alignment_1): Split out worker from ... + (get_object_alignment): ... here. + * fold-const.c (get_pointer_modulus_and_residue): Use + get_object_alignment_1. + 2011-04-14 Richard Sandiford <richard.sandiford@linaro.org> * tree-vectorizer.h (vect_create_data_ref_ptr): Add an extra diff --git a/gcc/builtins.c b/gcc/builtins.c index 7ae3833..81f7ec6 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -268,7 +268,7 @@ called_as_built_in (tree node) Don't return more than MAX_ALIGN no matter what. */ unsigned int -get_object_alignment (tree exp, unsigned int max_align) +get_object_alignment_1 (tree exp, unsigned HOST_WIDE_INT *bitposp) { HOST_WIDE_INT bitsize, bitpos; tree offset; @@ -320,8 +320,7 @@ get_object_alignment (tree exp, unsigned int max_align) align = MAX (pi->align * BITS_PER_UNIT, align); } else if (TREE_CODE (addr) == ADDR_EXPR) - align = MAX (align, get_object_alignment (TREE_OPERAND (addr, 0), - max_align)); + align = MAX (align, get_object_alignment (TREE_OPERAND (addr, 0), ~0U)); bitpos += mem_ref_offset (exp).low * BITS_PER_UNIT; } else if (TREE_CODE (exp) == TARGET_MEM_REF) @@ -345,8 +344,7 @@ get_object_alignment (tree exp, unsigned int max_align) align = MAX (pi->align * BITS_PER_UNIT, align); } else if (TREE_CODE (addr) == ADDR_EXPR) - align = MAX (align, get_object_alignment (TREE_OPERAND (addr, 0), - max_align)); + align = MAX (align, get_object_alignment (TREE_OPERAND (addr, 0), ~0U)); if (TMR_OFFSET (exp)) bitpos += TREE_INT_CST_LOW (TMR_OFFSET (exp)) * BITS_PER_UNIT; if (TMR_INDEX (exp) && TMR_STEP (exp)) @@ -364,7 +362,7 @@ get_object_alignment (tree exp, unsigned int max_align) /* If there is a non-constant offset part extract the maximum alignment that can prevail. */ - inner = max_align; + inner = ~0U; while (offset) { tree next_offset; @@ -411,6 +409,21 @@ get_object_alignment (tree exp, unsigned int max_align) align = MIN (align, inner); bitpos = bitpos & (align - 1); + *bitposp = bitpos; + return align; +} + +/* Return the alignment in bits of EXP, an object. + Don't return more than MAX_ALIGN no matter what. */ + +unsigned int +get_object_alignment (tree exp, unsigned int max_align) +{ + unsigned HOST_WIDE_INT bitpos = 0; + unsigned int align; + + align = get_object_alignment_1 (exp, &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 0c0420d..8d543c4 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -9230,30 +9230,10 @@ get_pointer_modulus_and_residue (tree expr, unsigned HOST_WIDE_INT *residue, code = TREE_CODE (expr); if (code == ADDR_EXPR) { - expr = TREE_OPERAND (expr, 0); - if (handled_component_p (expr)) - { - HOST_WIDE_INT bitsize, bitpos; - tree offset; - enum machine_mode mode; - int unsignedp, volatilep; - - expr = get_inner_reference (expr, &bitsize, &bitpos, &offset, - &mode, &unsignedp, &volatilep, false); - *residue = bitpos / BITS_PER_UNIT; - if (offset) - { - if (TREE_CODE (offset) == INTEGER_CST) - *residue += TREE_INT_CST_LOW (offset); - else - /* We don't handle more complicated offset expressions. */ - return 1; - } - } - - if (DECL_P (expr) - && (allow_func_align || TREE_CODE (expr) != FUNCTION_DECL)) - return DECL_ALIGN_UNIT (expr); + unsigned int bitalign; + bitalign = get_object_alignment_1 (TREE_OPERAND (expr, 0), residue); + *residue /= BITS_PER_UNIT; + return bitalign / BITS_PER_UNIT; } else if (code == POINTER_PLUS_EXPR) { @@ -9298,9 +9278,9 @@ get_pointer_modulus_and_residue (tree expr, unsigned HOST_WIDE_INT *residue, } } - /* If we get here, we were unable to determine anything useful about the - expression. */ - return 1; + /* If we get here, we were unable to determine anything useful about the + expression. */ + return 1; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a86ead5..62c4a6c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-04-14 Richard Guenther <rguenther@suse.de> + + * gcc.dg/fold-bitand-4.c: Move ... + * c-c++-common/fold-bitand-4.c: ... here. Adjust slightly. + 2011-04-14 Georg-Johann Lay <avr@gjlay.de> * gcc.target/avr/trivial.c: Fix line endings. Make PROGMEM diff --git a/gcc/testsuite/gcc.dg/fold-bitand-4.c b/gcc/testsuite/c-c++-common/fold-bitand-4.c index acb0ce9..f4bfe2f 100644 --- a/gcc/testsuite/gcc.dg/fold-bitand-4.c +++ b/gcc/testsuite/c-c++-common/fold-bitand-4.c @@ -38,8 +38,8 @@ int f5 (int i) return 3 & (__SIZE_TYPE__)&c16[i]; } -/* { dg-final { scan-tree-dump-times "return 12" 1 "original" } } */ +/* { dg-final { scan-tree-dump-times "return \[^\n0-9\]*12;" 1 "original" } } */ /* { dg-final { scan-tree-dump-times "\& 15" 1 "original" } } */ -/* { dg-final { scan-tree-dump-times "return 0" 2 "original" } } */ +/* { dg-final { scan-tree-dump-times "return \[^\n0-9\]*0;" 2 "original" } } */ /* { dg-final { scan-tree-dump-times "\& 7" 1 "original" } } */ /* { dg-final { cleanup-tree-dump "original" } } */ @@ -5224,6 +5224,7 @@ extern bool can_trust_pointer_alignment (void); extern unsigned int get_pointer_alignment (tree, unsigned int); extern bool is_builtin_name (const char *); extern bool is_builtin_fn (tree); +extern unsigned int get_object_alignment_1 (tree, unsigned HOST_WIDE_INT *); extern unsigned int get_object_alignment (tree, unsigned int); extern tree fold_call_stmt (gimple, bool); extern tree gimple_fold_builtin_snprintf_chk (gimple, tree, enum built_in_function); |