diff options
author | kenner <kenner@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-03-14 03:21:43 +0000 |
---|---|---|
committer | kenner <kenner@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-03-14 03:21:43 +0000 |
commit | bd32979f1ff434920e05cd190bcf20f2b0caf13b (patch) | |
tree | d754afaf3e715d73ac6c2dd0917606a98c462b82 /gcc/alias.c | |
parent | d9ba5e6d4804995e326ad23071146b22833e4b88 (diff) | |
download | gcc-bd32979f1ff434920e05cd190bcf20f2b0caf13b.tar.gz |
* alias.c (handled_component_p, can_address_p): New functions.
(get_alias_set): Use them.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@40449 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/alias.c')
-rw-r--r-- | gcc/alias.c | 86 |
1 files changed, 57 insertions, 29 deletions
diff --git a/gcc/alias.c b/gcc/alias.c index c95b48c8e14..4aca90d5b7c 100644 --- a/gcc/alias.c +++ b/gcc/alias.c @@ -1,5 +1,5 @@ /* Alias analysis for GNU C - Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc. + Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. Contributed by John Carr (jfc@mit.edu). This file is part of GNU CC. @@ -95,6 +95,8 @@ static void record_set PARAMS ((rtx, rtx, void *)); static rtx find_base_term PARAMS ((rtx)); static int base_alias_check PARAMS ((rtx, rtx, enum machine_mode, enum machine_mode)); +static int handled_component_p PARAMS ((tree)); +static int can_address_p PARAMS ((tree)); static rtx find_base_value PARAMS ((rtx)); static int mems_in_disjoint_alias_sets_p PARAMS ((rtx, rtx)); static int insert_subset_children PARAMS ((splay_tree_node, void*)); @@ -400,6 +402,58 @@ find_base_decl (t) } } +/* Return 1 if T is an expression that get_inner_reference handles. */ + +static int +handled_component_p (t) + tree t; +{ + switch (TREE_CODE (t)) + { + case BIT_FIELD_REF: + case COMPONENT_REF: + case ARRAY_REF: + case NON_LVALUE_EXPR: + return 1; + + case NOP_EXPR: + case CONVERT_EXPR: + return (TYPE_MODE (TREE_TYPE (t)) + == TYPE_MODE (TREE_TYPE (TREE_OPERAND (t, 0)))); + + default: + return 0; + } +} + +/* Return 1 if all the nested component references handled by + get_inner_reference in T are such that we can address the object in T. */ + +static int +can_address_p (t) + tree t; +{ + /* If we're at the end, it is vacuously addressable. */ + if (! handled_component_p (t)) + return 1; + + /* Bitfields are never addressable. */ + else if (TREE_CODE (t) == BIT_FIELD_REF) + return 0; + + else if (TREE_CODE (t) == COMPONENT_REF + && ! DECL_NONADDRESSABLE_P (TREE_OPERAND (t, 1)) + && can_address_p (TREE_OPERAND (t, 0))) + return 1; + + else if (TREE_CODE (t) == ARRAY_REF + && ! TYPE_NONALIASED_COMPONENT (TREE_TYPE (TREE_OPERAND (t, 0))) + && can_address_p (TREE_OPERAND (t, 0))) + return 1; + + return 0; +} + /* Return the alias set for T, which may be either a type or an expression. Call language-specific routine for help, if needed. */ @@ -439,35 +493,9 @@ get_alias_set (t) /* Now loop the same way as get_inner_reference and get the alias set to use. Pick up the outermost object that we could have a pointer to. */ - while (1) - { - /* Unnamed bitfields are not an addressable object. */ - if (TREE_CODE (t) == BIT_FIELD_REF) - ; - else if (TREE_CODE (t) == COMPONENT_REF) - { - if (! DECL_NONADDRESSABLE_P (TREE_OPERAND (t, 1))) - /* Stop at an adressable decl. */ - break; - } - else if (TREE_CODE (t) == ARRAY_REF) - { - if (! TYPE_NONALIASED_COMPONENT - (TREE_TYPE (TREE_OPERAND (t, 0)))) - /* Stop at an addresssable array element. */ - break; - } - else if (TREE_CODE (t) != NON_LVALUE_EXPR - && ! ((TREE_CODE (t) == NOP_EXPR - || TREE_CODE (t) == CONVERT_EXPR) - && (TYPE_MODE (TREE_TYPE (t)) - == TYPE_MODE (TREE_TYPE (TREE_OPERAND (t, 0)))))) - /* Stop if not one of above and not mode-preserving conversion. */ - break; + while (handled_component_p (t) && ! can_address_p (t)) + t = TREE_OPERAND (t, 0); - t = TREE_OPERAND (t, 0); - } - if (TREE_CODE (t) == INDIRECT_REF) { /* Check for accesses through restrict-qualified pointers. */ |