Commit a6d02559 by Diego Novillo Committed by Diego Novillo

tree-flow.h (addressable_vars): Declare.


	* 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.

From-SVN: r84272
parent 08a8c6b6
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> 2004-07-07 Jan Beulich <jbeulich@novell.com>
Richard Henderson <rth@redhat.com> Richard Henderson <rth@redhat.com>
......
...@@ -395,6 +395,10 @@ extern GTY(()) tree global_var; ...@@ -395,6 +395,10 @@ extern GTY(()) tree global_var;
REFERENCED_VARS (I) is call-clobbered. */ REFERENCED_VARS (I) is call-clobbered. */
extern bitmap call_clobbered_vars; 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). */ /* 'true' after aliases have been computed (see compute_may_aliases). */
extern bool aliases_computed_p; extern bool aliases_computed_p;
......
...@@ -163,6 +163,10 @@ static struct ptr_info_def *get_ptr_info (tree t); ...@@ -163,6 +163,10 @@ static struct ptr_info_def *get_ptr_info (tree t);
REFERENCED_VARS (I) is call-clobbered. */ REFERENCED_VARS (I) is call-clobbered. */
bitmap call_clobbered_vars; 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 /* '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 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 when scanning an operand for a variable that may be aliased. If
...@@ -1196,6 +1200,14 @@ setup_pointers_and_addressables (struct alias_info *ai) ...@@ -1196,6 +1200,14 @@ setup_pointers_and_addressables (struct alias_info *ai)
to rename VAR into SSA afterwards. */ to rename VAR into SSA afterwards. */
bitmap_set_bit (vars_to_rename, v_ann->uid); 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 /* Global variables and addressable locals may be aliased. Create an
......
...@@ -80,6 +80,7 @@ typedef struct voperands_d ...@@ -80,6 +80,7 @@ typedef struct voperands_d
static void note_addressable (tree, stmt_ann_t); static void note_addressable (tree, stmt_ann_t);
static void get_expr_operands (tree, tree *, int, voperands_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_def (tree *, tree);
static inline void append_use (tree *, tree); static inline void append_use (tree *, tree);
static void append_v_may_def (tree, tree, voperands_t); static void append_v_may_def (tree, tree, voperands_t);
...@@ -777,59 +778,7 @@ get_stmt_operands (tree stmt) ...@@ -777,59 +778,7 @@ get_stmt_operands (tree stmt)
break; break;
case ASM_EXPR: case ASM_EXPR:
{ get_asm_expr_operands (stmt, &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;
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);
}
break; break;
case RETURN_EXPR: case RETURN_EXPR:
...@@ -1215,6 +1164,108 @@ get_expr_operands (tree stmt, tree *expr_p, int flags, voperands_t prev_vops) ...@@ -1215,6 +1164,108 @@ get_expr_operands (tree stmt, tree *expr_p, int flags, voperands_t prev_vops)
abort (); 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 /* 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 get_expr_operands. If *VAR_P is a GIMPLE register, it will be added to
......
...@@ -494,6 +494,7 @@ init_tree_ssa (void) ...@@ -494,6 +494,7 @@ init_tree_ssa (void)
{ {
VARRAY_TREE_INIT (referenced_vars, 20, "referenced_vars"); VARRAY_TREE_INIT (referenced_vars, 20, "referenced_vars");
call_clobbered_vars = BITMAP_XMALLOC (); call_clobbered_vars = BITMAP_XMALLOC ();
addressable_vars = BITMAP_XMALLOC ();
init_ssa_operands (); init_ssa_operands ();
init_ssanames (); init_ssanames ();
init_phinodes (); init_phinodes ();
...@@ -532,6 +533,8 @@ delete_tree_ssa (void) ...@@ -532,6 +533,8 @@ delete_tree_ssa (void)
BITMAP_XFREE (call_clobbered_vars); BITMAP_XFREE (call_clobbered_vars);
call_clobbered_vars = NULL; call_clobbered_vars = NULL;
aliases_computed_p = false; aliases_computed_p = false;
BITMAP_XFREE (addressable_vars);
addressable_vars = NULL;
} }
......
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