diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/tree-flow.h | 4 | ||||
-rw-r--r-- | gcc/tree-ssa-alias.c | 12 | ||||
-rw-r--r-- | gcc/tree-ssa-operands.c | 157 | ||||
-rw-r--r-- | gcc/tree-ssa.c | 3 |
5 files changed, 137 insertions, 53 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 66b7075..8e5f519 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2004-07-08 Diego Novillo <dnovillo@redhat.com> + + * tree-flow.h (addressable_vars): Declare. + * tree-ssa-alias.c (addressable_vars): Define. + (setup_pointers_and_addressables): Add addressable variables + to addressable_vars. + * tree-ssa-operands.c (get_stmt_operands): Move + handling of ASM_EXPRs ... + (get_asm_expr_operands): ... here. + When the ASM_EXPR clobbers memory, also clobber addressable + variables. + * tree-ssa.c (init_tree_ssa): Initialize addressable_vars. + (delete_tree_ssa): Reset addressable_vars. + 2004-07-07 Jan Beulich <jbeulich@novell.com> Richard Henderson <rth@redhat.com> diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h index dc4ddb2..f9f8115 100644 --- a/gcc/tree-flow.h +++ b/gcc/tree-flow.h @@ -395,6 +395,10 @@ extern GTY(()) tree global_var; REFERENCED_VARS (I) is call-clobbered. */ extern bitmap call_clobbered_vars; +/* Addressable variables in the function. If bit I is set, then + REFERENCED_VARS (I) has had its address taken. */ +extern bitmap addressable_vars; + /* 'true' after aliases have been computed (see compute_may_aliases). */ extern bool aliases_computed_p; diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c index 75c98e1..3cf27ae 100644 --- a/gcc/tree-ssa-alias.c +++ b/gcc/tree-ssa-alias.c @@ -163,6 +163,10 @@ static struct ptr_info_def *get_ptr_info (tree t); REFERENCED_VARS (I) is call-clobbered. */ bitmap call_clobbered_vars; +/* Addressable variables in the function. If bit I is set, then + REFERENCED_VARS (I) has had its address taken. */ +bitmap addressable_vars; + /* 'true' after aliases have been computed (see compute_may_aliases). This is used by get_stmt_operands and its helpers to determine what to do when scanning an operand for a variable that may be aliased. If @@ -1196,6 +1200,14 @@ setup_pointers_and_addressables (struct alias_info *ai) to rename VAR into SSA afterwards. */ bitmap_set_bit (vars_to_rename, v_ann->uid); } + else + { + /* Add the variable to the set of addressables. Mostly + used when scanning operands for ASM_EXPRs that + clobber memory. In those cases, we need to clobber + all call-clobbered variables and all addressables. */ + bitmap_set_bit (addressable_vars, v_ann->uid); + } } /* Global variables and addressable locals may be aliased. Create an diff --git a/gcc/tree-ssa-operands.c b/gcc/tree-ssa-operands.c index c44189f..46f9f59 100644 --- a/gcc/tree-ssa-operands.c +++ b/gcc/tree-ssa-operands.c @@ -80,6 +80,7 @@ typedef struct voperands_d static void note_addressable (tree, stmt_ann_t); static void get_expr_operands (tree, tree *, int, voperands_t); +static void get_asm_expr_operands (tree, voperands_t); static inline void append_def (tree *, tree); static inline void append_use (tree *, tree); static void append_v_may_def (tree, tree, voperands_t); @@ -777,59 +778,7 @@ get_stmt_operands (tree stmt) break; case ASM_EXPR: - { - int noutputs = list_length (ASM_OUTPUTS (stmt)); - const char **oconstraints - = (const char **) alloca ((noutputs) * sizeof (const char *)); - int i; - tree link; - const char *constraint; - bool allows_mem, allows_reg, is_inout; - - for (i=0, link = ASM_OUTPUTS (stmt); link; - ++i, link = TREE_CHAIN (link)) - { - oconstraints[i] = constraint - = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link))); - parse_output_constraint (&constraint, i, 0, 0, - &allows_mem, &allows_reg, &is_inout); - if (allows_reg && is_inout) - /* This should have been split in gimplify_asm_expr. */ - abort (); - - if (!allows_reg && allows_mem) - { - tree t = get_base_address (TREE_VALUE (link)); - if (t && DECL_P (t)) - mark_call_clobbered (t); - } - - get_expr_operands (stmt, &TREE_VALUE (link), opf_is_def, - &prev_vops); - } - - for (link = ASM_INPUTS (stmt); link; link = TREE_CHAIN (link)) - { - constraint - = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link))); - parse_input_constraint (&constraint, 0, 0, noutputs, 0, - oconstraints, &allows_mem, &allows_reg); - - if (!allows_reg && allows_mem) - { - tree t = get_base_address (TREE_VALUE (link)); - if (t && DECL_P (t)) - mark_call_clobbered (t); - } - - get_expr_operands (stmt, &TREE_VALUE (link), 0, &prev_vops); - } - - /* Clobber memory for asm ("" : : : "memory"); */ - for (link = ASM_CLOBBERS (stmt); link; link = TREE_CHAIN (link)) - if (!strcmp (TREE_STRING_POINTER (TREE_VALUE (link)), "memory")) - add_call_clobber_ops (stmt, &prev_vops); - } + get_asm_expr_operands (stmt, &prev_vops); break; case RETURN_EXPR: @@ -1215,6 +1164,108 @@ get_expr_operands (tree stmt, tree *expr_p, int flags, voperands_t prev_vops) abort (); } +/* Scan operands in ASM_EXPR STMT. PREV_VOPS is as in + append_v_may_def and append_vuse. */ + +static void +get_asm_expr_operands (tree stmt, voperands_t prev_vops) +{ + int noutputs = list_length (ASM_OUTPUTS (stmt)); + const char **oconstraints + = (const char **) alloca ((noutputs) * sizeof (const char *)); + int i; + tree link; + const char *constraint; + bool allows_mem, allows_reg, is_inout; + stmt_ann_t s_ann = stmt_ann (stmt); + + for (i=0, link = ASM_OUTPUTS (stmt); link; ++i, link = TREE_CHAIN (link)) + { + oconstraints[i] = constraint + = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link))); + parse_output_constraint (&constraint, i, 0, 0, + &allows_mem, &allows_reg, &is_inout); + +#if defined ENABLE_CHECKING + /* This should have been split in gimplify_asm_expr. */ + if (allows_reg && is_inout) + abort (); +#endif + + /* Memory operands are addressable. Note that STMT needs the + address of this operand. */ + if (!allows_reg && allows_mem) + { + tree t = get_base_address (TREE_VALUE (link)); + if (t && DECL_P (t)) + note_addressable (t, s_ann); + } + + get_expr_operands (stmt, &TREE_VALUE (link), opf_is_def, prev_vops); + } + + for (link = ASM_INPUTS (stmt); link; link = TREE_CHAIN (link)) + { + constraint + = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (link))); + parse_input_constraint (&constraint, 0, 0, noutputs, 0, + oconstraints, &allows_mem, &allows_reg); + + /* Memory operands are addressable. Note that STMT needs the + address of this operand. */ + if (!allows_reg && allows_mem) + { + tree t = get_base_address (TREE_VALUE (link)); + if (t && DECL_P (t)) + note_addressable (t, s_ann); + } + + get_expr_operands (stmt, &TREE_VALUE (link), 0, prev_vops); + } + + /* Clobber memory for asm ("" : : : "memory"); */ + if (!aliases_computed_p) + { + /* If we still have not computed aliasing information, + mark the statement as having volatile operands to avoid + optimizations from messing around with it. */ + stmt_ann (stmt)->has_volatile_ops = true; + } + else + { + /* Otherwise, if this ASM_EXPR clobbers memory, clobber + all the call-clobbered variables and the addressable + variables found by the alias analyzer. */ + for (link = ASM_CLOBBERS (stmt); link; link = TREE_CHAIN (link)) + if (!strcmp (TREE_STRING_POINTER (TREE_VALUE (link)), "memory")) + { + /* If we had created .GLOBAL_VAR earlier, use it. + Otherwise, add a V_MAY_DEF operand for every + call-clobbered and addressable variable. See + compute_may_aliases for the heuristic used to decide + whether to create .GLOBAL_VAR or not. */ + if (global_var) + add_stmt_operand (&global_var, stmt, opf_is_def, prev_vops); + else + { + size_t i; + + EXECUTE_IF_SET_IN_BITMAP (call_clobbered_vars, 0, i, + { + tree var = referenced_var (i); + add_stmt_operand (&var, stmt, opf_is_def, prev_vops); + }); + + EXECUTE_IF_SET_IN_BITMAP (addressable_vars, 0, i, + { + tree var = referenced_var (i); + add_stmt_operand (&var, stmt, opf_is_def, prev_vops); + }); + } + } + } +} + /* Add *VAR_P to the appropriate operand array of STMT. FLAGS is as in get_expr_operands. If *VAR_P is a GIMPLE register, it will be added to diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c index 4cdfd3d..3ab7ac2 100644 --- a/gcc/tree-ssa.c +++ b/gcc/tree-ssa.c @@ -494,6 +494,7 @@ init_tree_ssa (void) { VARRAY_TREE_INIT (referenced_vars, 20, "referenced_vars"); call_clobbered_vars = BITMAP_XMALLOC (); + addressable_vars = BITMAP_XMALLOC (); init_ssa_operands (); init_ssanames (); init_phinodes (); @@ -532,6 +533,8 @@ delete_tree_ssa (void) BITMAP_XFREE (call_clobbered_vars); call_clobbered_vars = NULL; aliases_computed_p = false; + BITMAP_XFREE (addressable_vars); + addressable_vars = NULL; } |