Commit e288e2f5 by Andrew MacLeod Committed by Andrew Macleod

re PR tree-optimization/18587 (build_v_may_defs and build_vuses can be improved when adding)


2004-11-25  Andrew Macleod  <amacleod@redhat.com>

	PR tree-optimization/18587
	* tree-flow-inline.h (mark_call_clobbered, mark_non_addressable): Flag
	call clobbered caches as invalid.
	* tree-ssa-operands.c (ssa_call_clobbered_cache_valid): New.  Flag
	indicating whether the call clobbered operand cache is valid.
	(ssa_ro_call_cache_valid): New.  Flag indicating whether the pure/const
	call operand cache is valid.
	(clobbered_v_may_defs, clobbered_vuses, ro_call_vuses): New.
	cached list of operands for cached call virtual operands.
	(clobbered_aliased_loads, clobbered_aliased_stores,
	ro_call_aliased_load): New.  flags caching whether alias bits are to be
	set in call stmt's.  */
	(fini_ssa_operands): Remove call operand caches if present.
	(get_expr_operands, get_asm_expr_operands, get_indirect_ref_operands):
	Pass stmt annotation to add_stmt_operand.
	(get_call_expr_operands): Add call clobbered variables first.
	(add_stmt_operand): Take stmt annotation rather than stmt as a param.
	(add_call_clobber_ops, add_call_read_ops): Use the call operand cache
	if it is valid, otherise fill the cache.
	* tree-ssa-operands.h (ssa_clobbered_cache_valid): Declare extern.

	* tree-flow.h (struct var_ann_d): Add in_vuse_list and in_v_may_def_list
	bits.
	* tree-ssa-operands.c (cleanup_v_may_defs): New.  Clear the in_list bits
	for the v_may_def elements and empty the operand build array.
	(finalize_ssa_vuses): Use cleanup_v_may_defs and remove redundant VUSES
	by checking the in_v_may_def_list bit.
	(append_v_may_def, append_vuse): Use the in_list bit rather than
	scanning the array for duplicates.

From-SVN: r91305
parent 5257260c
2004-11-25 Andrew MacLeod <amacleod@redhat.com>
PR tree-optimization/18587
* tree-flow-inline.h (mark_call_clobbered, mark_non_addressable): Flag
call clobbered caches as invalid.
* tree-ssa-operands.c (ssa_call_clobbered_cache_valid): New. Flag
indicating whether the call clobbered operand cache is valid.
(ssa_ro_call_cache_valid): New. Flag indicating whether the pure/const
call operand cache is valid.
(clobbered_v_may_defs, clobbered_vuses, ro_call_vuses): New. Cached
list of operands for cached call virtual operands.
(clobbered_aliased_loads, clobbered_aliased_stores,
ro_call_aliased_load): New. flags caching whether alias bits are to be
set in call stmt's.
(fini_ssa_operands): Remove call operand caches if present.
(get_expr_operands, get_asm_expr_operands, get_indirect_ref_operands):
Pass stmt annotation to add_stmt_operand.
(get_call_expr_operands): Add call clobbered variables first.
(add_stmt_operand): Take stmt annotation rather than stmt as a param.
(add_call_clobber_ops, add_call_read_ops): Use the call operand cache
if it is valid, otherise fill the cache.
* tree-ssa-operands.h (ssa_clobbered_cache_valid): Declare extern.
* tree-flow.h (struct var_ann_d): Add in_vuse_list and in_v_may_def_list
bits.
* tree-ssa-operands.c (cleanup_v_may_defs): New. Clear the in_list bits
for the v_may_def elements and empty the operand build array.
(finalize_ssa_vuses): Use cleanup_v_may_defs and remove redundant VUSES
by checking the in_v_may_def_list bit.
(append_v_may_def, append_vuse): Use the in_list bit rather than
scanning the array for duplicates.
2004-11-25 Ulrich Weigand <uweigand@de.ibm.com> 2004-11-25 Ulrich Weigand <uweigand@de.ibm.com>
* config/s390/s390.c (s390_short_displacement): UNSPEC_GOTNTPOFF * config/s390/s390.c (s390_short_displacement): UNSPEC_GOTNTPOFF
......
...@@ -621,6 +621,8 @@ mark_call_clobbered (tree var) ...@@ -621,6 +621,8 @@ mark_call_clobbered (tree var)
if (ann->mem_tag_kind != NOT_A_TAG) if (ann->mem_tag_kind != NOT_A_TAG)
DECL_EXTERNAL (var) = 1; DECL_EXTERNAL (var) = 1;
bitmap_set_bit (call_clobbered_vars, ann->uid); bitmap_set_bit (call_clobbered_vars, ann->uid);
ssa_call_clobbered_cache_valid = false;
ssa_ro_call_cache_valid = false;
} }
/* Mark variable VAR as being non-addressable. */ /* Mark variable VAR as being non-addressable. */
...@@ -629,6 +631,8 @@ mark_non_addressable (tree var) ...@@ -629,6 +631,8 @@ mark_non_addressable (tree var)
{ {
bitmap_clear_bit (call_clobbered_vars, var_ann (var)->uid); bitmap_clear_bit (call_clobbered_vars, var_ann (var)->uid);
TREE_ADDRESSABLE (var) = 0; TREE_ADDRESSABLE (var) = 0;
ssa_call_clobbered_cache_valid = false;
ssa_ro_call_cache_valid = false;
} }
/* Return the common annotation for T. Return NULL if the annotation /* Return the common annotation for T. Return NULL if the annotation
......
...@@ -166,6 +166,14 @@ struct var_ann_d GTY(()) ...@@ -166,6 +166,14 @@ struct var_ann_d GTY(())
states. */ states. */
ENUM_BITFIELD (need_phi_state) need_phi_state : 2; ENUM_BITFIELD (need_phi_state) need_phi_state : 2;
/* Used during operand processing to determine if this variable is already
in the vuse list. */
unsigned in_vuse_list : 1;
/* Used during operand processing to determine if this variable is already
in the v_may_def list. */
unsigned in_v_may_def_list : 1;
/* An artificial variable representing the memory location pointed-to by /* An artificial variable representing the memory location pointed-to by
all the pointers that TBAA (type-based alias analysis) considers all the pointers that TBAA (type-based alias analysis) considers
to be aliased. If the variable is not a pointer or if it is never to be aliased. If the variable is not a pointer or if it is never
......
...@@ -116,6 +116,17 @@ static GTY (()) varray_type build_vuses; ...@@ -116,6 +116,17 @@ static GTY (()) varray_type build_vuses;
/* Array for building all the v_must_def operands. */ /* Array for building all the v_must_def operands. */
static GTY (()) varray_type build_v_must_defs; static GTY (()) varray_type build_v_must_defs;
/* True if the operands for call clobbered vars are cached and valid. */
bool ssa_call_clobbered_cache_valid;
bool ssa_ro_call_cache_valid;
/* These arrays are the cached operand vectors for call clobberd calls. */
static GTY (()) varray_type clobbered_v_may_defs;
static GTY (()) varray_type clobbered_vuses;
static GTY (()) varray_type ro_call_vuses;
static bool clobbered_aliased_loads;
static bool clobbered_aliased_stores;
static bool ro_call_aliased_loads;
#ifdef ENABLE_CHECKING #ifdef ENABLE_CHECKING
/* Used to make sure operand construction is working on the proper stmt. */ /* Used to make sure operand construction is working on the proper stmt. */
...@@ -136,7 +147,7 @@ static void append_v_may_def (tree); ...@@ -136,7 +147,7 @@ static void append_v_may_def (tree);
static void append_v_must_def (tree); static void append_v_must_def (tree);
static void add_call_clobber_ops (tree); static void add_call_clobber_ops (tree);
static void add_call_read_ops (tree); static void add_call_read_ops (tree);
static void add_stmt_operand (tree *, tree, int); static void add_stmt_operand (tree *, stmt_ann_t, int);
/* Return a vector of contiguous memory for NUM def operands. */ /* Return a vector of contiguous memory for NUM def operands. */
...@@ -302,6 +313,18 @@ fini_ssa_operands (void) ...@@ -302,6 +313,18 @@ fini_ssa_operands (void)
build_v_may_defs = NULL; build_v_may_defs = NULL;
build_vuses = NULL; build_vuses = NULL;
build_v_must_defs = NULL; build_v_must_defs = NULL;
if (clobbered_v_may_defs)
{
ggc_free (clobbered_v_may_defs);
ggc_free (clobbered_vuses);
clobbered_v_may_defs = NULL;
clobbered_vuses = NULL;
}
if (ro_call_vuses)
{
ggc_free (ro_call_vuses);
ro_call_vuses = NULL;
}
} }
...@@ -490,6 +513,23 @@ finalize_ssa_v_may_defs (v_may_def_optype *old_ops_p) ...@@ -490,6 +513,23 @@ finalize_ssa_v_may_defs (v_may_def_optype *old_ops_p)
} }
/* Clear the in_list bits and empty the build array for v_may_defs. */
static inline void
cleanup_v_may_defs (void)
{
unsigned x, num;
num = VARRAY_ACTIVE_SIZE (build_v_may_defs);
for (x = 0; x < num; x++)
{
tree t = VARRAY_TREE (build_v_may_defs, x);
var_ann_t ann = var_ann (t);
ann->in_v_may_def_list = 0;
}
VARRAY_POP_ALL (build_v_may_defs);
}
/* Return a new vuse operand vector, comparing to OLD_OPS_P. */ /* Return a new vuse operand vector, comparing to OLD_OPS_P. */
static vuse_optype static vuse_optype
...@@ -502,7 +542,7 @@ finalize_ssa_vuses (vuse_optype *old_ops_p) ...@@ -502,7 +542,7 @@ finalize_ssa_vuses (vuse_optype *old_ops_p)
num = VARRAY_ACTIVE_SIZE (build_vuses); num = VARRAY_ACTIVE_SIZE (build_vuses);
if (num == 0) if (num == 0)
{ {
VARRAY_POP_ALL (build_v_may_defs); cleanup_v_may_defs ();
return NULL; return NULL;
} }
...@@ -522,23 +562,21 @@ finalize_ssa_vuses (vuse_optype *old_ops_p) ...@@ -522,23 +562,21 @@ finalize_ssa_vuses (vuse_optype *old_ops_p)
if (num_v_may_defs > 0) if (num_v_may_defs > 0)
{ {
size_t i, j; size_t i;
tree vuse; tree vuse;
for (i = 0; i < VARRAY_ACTIVE_SIZE (build_vuses); i++) for (i = 0; i < VARRAY_ACTIVE_SIZE (build_vuses); i++)
{ {
vuse = VARRAY_TREE (build_vuses, i); vuse = VARRAY_TREE (build_vuses, i);
for (j = 0; j < num_v_may_defs; j++) if (TREE_CODE (vuse) != SSA_NAME)
{
var_ann_t ann = var_ann (vuse);
ann->in_vuse_list = 0;
if (ann->in_v_may_def_list)
{ {
if (vuse == VARRAY_TREE (build_v_may_defs, j))
break;
}
/* If we found a useless VUSE operand, remove it from the /* If we found a useless VUSE operand, remove it from the
operand array by replacing it with the last active element operand array by replacing it with the last active element
in the operand array (unless the useless VUSE was the in the operand array (unless the useless VUSE was the
last operand, in which case we simply remove it. */ last operand, in which case we simply remove it. */
if (j != num_v_may_defs)
{
if (i != VARRAY_ACTIVE_SIZE (build_vuses) - 1) if (i != VARRAY_ACTIVE_SIZE (build_vuses) - 1)
{ {
VARRAY_TREE (build_vuses, i) VARRAY_TREE (build_vuses, i)
...@@ -554,12 +592,25 @@ finalize_ssa_vuses (vuse_optype *old_ops_p) ...@@ -554,12 +592,25 @@ finalize_ssa_vuses (vuse_optype *old_ops_p)
} }
} }
} }
}
else
/* Clear out the in_list bits. */
for (x = 0; x < num; x++)
{
tree t = VARRAY_TREE (build_vuses, x);
if (TREE_CODE (t) != SSA_NAME)
{
var_ann_t ann = var_ann (t);
ann->in_vuse_list = 0;
}
}
num = VARRAY_ACTIVE_SIZE (build_vuses); num = VARRAY_ACTIVE_SIZE (build_vuses);
/* We could have reduced the size to zero now, however. */ /* We could have reduced the size to zero now, however. */
if (num == 0) if (num == 0)
{ {
VARRAY_POP_ALL (build_v_may_defs); cleanup_v_may_defs ();
return NULL; return NULL;
} }
...@@ -618,7 +669,7 @@ finalize_ssa_vuses (vuse_optype *old_ops_p) ...@@ -618,7 +669,7 @@ finalize_ssa_vuses (vuse_optype *old_ops_p)
/* The v_may_def build vector wasn't freed because we needed it here. /* The v_may_def build vector wasn't freed because we needed it here.
Free it now with the vuses build vector. */ Free it now with the vuses build vector. */
VARRAY_POP_ALL (build_vuses); VARRAY_POP_ALL (build_vuses);
VARRAY_POP_ALL (build_v_may_defs); cleanup_v_may_defs ();
return vuse_ops; return vuse_ops;
} }
...@@ -751,12 +802,12 @@ append_use (tree *use_p) ...@@ -751,12 +802,12 @@ append_use (tree *use_p)
static inline void static inline void
append_v_may_def (tree var) append_v_may_def (tree var)
{ {
unsigned i; var_ann_t ann = get_var_ann (var);
/* Don't allow duplicate entries. */ /* Don't allow duplicate entries. */
for (i = 0; i < VARRAY_ACTIVE_SIZE (build_v_may_defs); i++) if (ann->in_v_may_def_list)
if (var == VARRAY_TREE (build_v_may_defs, i))
return; return;
ann->in_v_may_def_list = 1;
VARRAY_PUSH_TREE (build_v_may_defs, var); VARRAY_PUSH_TREE (build_v_may_defs, var);
} }
...@@ -767,12 +818,16 @@ append_v_may_def (tree var) ...@@ -767,12 +818,16 @@ append_v_may_def (tree var)
static inline void static inline void
append_vuse (tree var) append_vuse (tree var)
{ {
size_t i;
/* Don't allow duplicate entries. */ /* Don't allow duplicate entries. */
for (i = 0; i < VARRAY_ACTIVE_SIZE (build_vuses); i++) if (TREE_CODE (var) != SSA_NAME)
if (var == VARRAY_TREE (build_vuses, i)) {
var_ann_t ann = get_var_ann (var);
if (ann->in_vuse_list || ann->in_v_may_def_list)
return; return;
ann->in_vuse_list = 1;
}
VARRAY_PUSH_TREE (build_vuses, var); VARRAY_PUSH_TREE (build_vuses, var);
} }
...@@ -972,6 +1027,7 @@ get_expr_operands (tree stmt, tree *expr_p, int flags) ...@@ -972,6 +1027,7 @@ get_expr_operands (tree stmt, tree *expr_p, int flags)
enum tree_code code; enum tree_code code;
enum tree_code_class class; enum tree_code_class class;
tree expr = *expr_p; tree expr = *expr_p;
stmt_ann_t s_ann = stmt_ann (stmt);
if (expr == NULL || expr == error_mark_node) if (expr == NULL || expr == error_mark_node)
return; return;
...@@ -987,7 +1043,7 @@ get_expr_operands (tree stmt, tree *expr_p, int flags) ...@@ -987,7 +1043,7 @@ get_expr_operands (tree stmt, tree *expr_p, int flags)
/* Taking the address of a variable does not represent a /* Taking the address of a variable does not represent a
reference to it, but the fact that the stmt takes its address will be reference to it, but the fact that the stmt takes its address will be
of interest to some passes (e.g. alias resolution). */ of interest to some passes (e.g. alias resolution). */
add_stmt_operand (expr_p, stmt, 0); add_stmt_operand (expr_p, s_ann, 0);
/* If the address is invariant, there may be no interesting variable /* If the address is invariant, there may be no interesting variable
references inside. */ references inside. */
...@@ -1010,7 +1066,7 @@ get_expr_operands (tree stmt, tree *expr_p, int flags) ...@@ -1010,7 +1066,7 @@ get_expr_operands (tree stmt, tree *expr_p, int flags)
case CONST_DECL: case CONST_DECL:
/* If we found a variable, add it to DEFS or USES depending /* If we found a variable, add it to DEFS or USES depending
on the operand flags. */ on the operand flags. */
add_stmt_operand (expr_p, stmt, flags); add_stmt_operand (expr_p, s_ann, flags);
return; return;
case MISALIGNED_INDIRECT_REF: case MISALIGNED_INDIRECT_REF:
...@@ -1032,7 +1088,7 @@ get_expr_operands (tree stmt, tree *expr_p, int flags) ...@@ -1032,7 +1088,7 @@ get_expr_operands (tree stmt, tree *expr_p, int flags)
according to the value of IS_DEF. Recurse if the LHS of the according to the value of IS_DEF. Recurse if the LHS of the
ARRAY_REF node is not a regular variable. */ ARRAY_REF node is not a regular variable. */
if (SSA_VAR_P (TREE_OPERAND (expr, 0))) if (SSA_VAR_P (TREE_OPERAND (expr, 0)))
add_stmt_operand (expr_p, stmt, flags); add_stmt_operand (expr_p, s_ann, flags);
else else
get_expr_operands (stmt, &TREE_OPERAND (expr, 0), flags); get_expr_operands (stmt, &TREE_OPERAND (expr, 0), flags);
...@@ -1060,7 +1116,7 @@ get_expr_operands (tree stmt, tree *expr_p, int flags) ...@@ -1060,7 +1116,7 @@ get_expr_operands (tree stmt, tree *expr_p, int flags)
/* If the LHS of the compound reference is not a regular variable, /* If the LHS of the compound reference is not a regular variable,
recurse to keep looking for more operands in the subexpression. */ recurse to keep looking for more operands in the subexpression. */
if (SSA_VAR_P (TREE_OPERAND (expr, 0))) if (SSA_VAR_P (TREE_OPERAND (expr, 0)))
add_stmt_operand (expr_p, stmt, flags); add_stmt_operand (expr_p, s_ann, flags);
else else
get_expr_operands (stmt, &TREE_OPERAND (expr, 0), flags); get_expr_operands (stmt, &TREE_OPERAND (expr, 0), flags);
...@@ -1273,19 +1329,19 @@ get_asm_expr_operands (tree stmt) ...@@ -1273,19 +1329,19 @@ get_asm_expr_operands (tree stmt)
/* Clobber all call-clobbered variables (or .GLOBAL_VAR if we /* Clobber all call-clobbered variables (or .GLOBAL_VAR if we
decided to group them). */ decided to group them). */
if (global_var) if (global_var)
add_stmt_operand (&global_var, stmt, opf_is_def); add_stmt_operand (&global_var, s_ann, opf_is_def);
else else
EXECUTE_IF_SET_IN_BITMAP (call_clobbered_vars, 0, i, bi) EXECUTE_IF_SET_IN_BITMAP (call_clobbered_vars, 0, i, bi)
{ {
tree var = referenced_var (i); tree var = referenced_var (i);
add_stmt_operand (&var, stmt, opf_is_def); add_stmt_operand (&var, s_ann, opf_is_def);
} }
/* Now clobber all addressables. */ /* Now clobber all addressables. */
EXECUTE_IF_SET_IN_BITMAP (addressable_vars, 0, i, bi) EXECUTE_IF_SET_IN_BITMAP (addressable_vars, 0, i, bi)
{ {
tree var = referenced_var (i); tree var = referenced_var (i);
add_stmt_operand (&var, stmt, opf_is_def); add_stmt_operand (&var, s_ann, opf_is_def);
} }
break; break;
...@@ -1300,7 +1356,7 @@ get_indirect_ref_operands (tree stmt, tree expr, int flags) ...@@ -1300,7 +1356,7 @@ get_indirect_ref_operands (tree stmt, tree expr, int flags)
{ {
tree *pptr = &TREE_OPERAND (expr, 0); tree *pptr = &TREE_OPERAND (expr, 0);
tree ptr = *pptr; tree ptr = *pptr;
stmt_ann_t ann = stmt_ann (stmt); stmt_ann_t s_ann = stmt_ann (stmt);
/* Stores into INDIRECT_REF operands are never killing definitions. */ /* Stores into INDIRECT_REF operands are never killing definitions. */
flags &= ~opf_kill_def; flags &= ~opf_kill_def;
...@@ -1327,13 +1383,13 @@ get_indirect_ref_operands (tree stmt, tree expr, int flags) ...@@ -1327,13 +1383,13 @@ get_indirect_ref_operands (tree stmt, tree expr, int flags)
&& pi->name_mem_tag) && pi->name_mem_tag)
{ {
/* PTR has its own memory tag. Use it. */ /* PTR has its own memory tag. Use it. */
add_stmt_operand (&pi->name_mem_tag, stmt, flags); add_stmt_operand (&pi->name_mem_tag, s_ann, flags);
} }
else else
{ {
/* If PTR is not an SSA_NAME or it doesn't have a name /* If PTR is not an SSA_NAME or it doesn't have a name
tag, use its type memory tag. */ tag, use its type memory tag. */
var_ann_t ann; var_ann_t v_ann;
/* If we are emitting debugging dumps, display a warning if /* If we are emitting debugging dumps, display a warning if
PTR is an SSA_NAME with no flow-sensitive alias PTR is an SSA_NAME with no flow-sensitive alias
...@@ -1352,9 +1408,9 @@ get_indirect_ref_operands (tree stmt, tree expr, int flags) ...@@ -1352,9 +1408,9 @@ get_indirect_ref_operands (tree stmt, tree expr, int flags)
if (TREE_CODE (ptr) == SSA_NAME) if (TREE_CODE (ptr) == SSA_NAME)
ptr = SSA_NAME_VAR (ptr); ptr = SSA_NAME_VAR (ptr);
ann = var_ann (ptr); v_ann = var_ann (ptr);
if (ann->type_mem_tag) if (v_ann->type_mem_tag)
add_stmt_operand (&ann->type_mem_tag, stmt, flags); add_stmt_operand (&v_ann->type_mem_tag, s_ann, flags);
} }
} }
...@@ -1363,8 +1419,8 @@ get_indirect_ref_operands (tree stmt, tree expr, int flags) ...@@ -1363,8 +1419,8 @@ get_indirect_ref_operands (tree stmt, tree expr, int flags)
optimizations from messing things up. */ optimizations from messing things up. */
else if (TREE_CODE (ptr) == INTEGER_CST) else if (TREE_CODE (ptr) == INTEGER_CST)
{ {
if (ann) if (s_ann)
ann->has_volatile_ops = true; s_ann->has_volatile_ops = true;
return; return;
} }
...@@ -1379,7 +1435,7 @@ get_indirect_ref_operands (tree stmt, tree expr, int flags) ...@@ -1379,7 +1435,7 @@ get_indirect_ref_operands (tree stmt, tree expr, int flags)
{ {
/* Make sure we know the object is addressable. */ /* Make sure we know the object is addressable. */
pptr = &TREE_OPERAND (ptr, 0); pptr = &TREE_OPERAND (ptr, 0);
add_stmt_operand (pptr, stmt, 0); add_stmt_operand (pptr, s_ann, 0);
/* Mark the object itself with a VUSE. */ /* Mark the object itself with a VUSE. */
pptr = &TREE_OPERAND (*pptr, 0); pptr = &TREE_OPERAND (*pptr, 0);
...@@ -1403,14 +1459,6 @@ get_call_expr_operands (tree stmt, tree expr) ...@@ -1403,14 +1459,6 @@ get_call_expr_operands (tree stmt, tree expr)
tree op; tree op;
int call_flags = call_expr_flags (expr); int call_flags = call_expr_flags (expr);
/* Find uses in the called function. */
get_expr_operands (stmt, &TREE_OPERAND (expr, 0), opf_none);
for (op = TREE_OPERAND (expr, 1); op; op = TREE_CHAIN (op))
get_expr_operands (stmt, &TREE_VALUE (op), opf_none);
get_expr_operands (stmt, &TREE_OPERAND (expr, 2), opf_none);
if (!bitmap_empty_p (call_clobbered_vars)) if (!bitmap_empty_p (call_clobbered_vars))
{ {
/* A 'pure' or a 'const' functions never call clobber anything. /* A 'pure' or a 'const' functions never call clobber anything.
...@@ -1422,6 +1470,15 @@ get_call_expr_operands (tree stmt, tree expr) ...@@ -1422,6 +1470,15 @@ get_call_expr_operands (tree stmt, tree expr)
else if (!(call_flags & ECF_CONST)) else if (!(call_flags & ECF_CONST))
add_call_read_ops (stmt); add_call_read_ops (stmt);
} }
/* Find uses in the called function. */
get_expr_operands (stmt, &TREE_OPERAND (expr, 0), opf_none);
for (op = TREE_OPERAND (expr, 1); op; op = TREE_CHAIN (op))
get_expr_operands (stmt, &TREE_VALUE (op), opf_none);
get_expr_operands (stmt, &TREE_OPERAND (expr, 2), opf_none);
} }
...@@ -1431,11 +1488,10 @@ get_call_expr_operands (tree stmt, tree expr) ...@@ -1431,11 +1488,10 @@ get_call_expr_operands (tree stmt, tree expr)
operands. */ operands. */
static void static void
add_stmt_operand (tree *var_p, tree stmt, int flags) add_stmt_operand (tree *var_p, stmt_ann_t s_ann, int flags)
{ {
bool is_real_op; bool is_real_op;
tree var, sym; tree var, sym;
stmt_ann_t s_ann = stmt_ann (stmt);
var_ann_t v_ann; var_ann_t v_ann;
var = *var_p; var = *var_p;
...@@ -1586,32 +1642,92 @@ note_addressable (tree var, stmt_ann_t s_ann) ...@@ -1586,32 +1642,92 @@ note_addressable (tree var, stmt_ann_t s_ann)
static void static void
add_call_clobber_ops (tree stmt) add_call_clobber_ops (tree stmt)
{ {
unsigned i;
tree t;
bitmap_iterator bi;
stmt_ann_t s_ann = stmt_ann (stmt);
struct stmt_ann_d empty_ann;
/* Functions that are not const, pure or never return may clobber /* Functions that are not const, pure or never return may clobber
call-clobbered variables. */ call-clobbered variables. */
if (stmt_ann (stmt)) if (s_ann)
stmt_ann (stmt)->makes_clobbering_call = true; s_ann->makes_clobbering_call = true;
/* If we had created .GLOBAL_VAR earlier, use it. Otherwise, add /* If we created .GLOBAL_VAR earlier, just use it. See compute_may_aliases
a V_MAY_DEF operand for every call clobbered variable. See for the heuristic used to decide whether to create .GLOBAL_VAR or not. */
compute_may_aliases for the heuristic used to decide whether
to create .GLOBAL_VAR or not. */
if (global_var) if (global_var)
add_stmt_operand (&global_var, stmt, opf_is_def);
else
{ {
unsigned i; add_stmt_operand (&global_var, s_ann, opf_is_def);
bitmap_iterator bi; return;
}
/* If cache is valid, copy the elements into the build vectors. */
if (ssa_call_clobbered_cache_valid)
{
for (i = 0; i < VARRAY_ACTIVE_SIZE (clobbered_vuses); i++)
{
t = VARRAY_TREE (clobbered_vuses, i);
gcc_assert (TREE_CODE (t) != SSA_NAME);
var_ann (t)->in_vuse_list = 1;
VARRAY_PUSH_TREE (build_vuses, t);
}
for (i = 0; i < VARRAY_ACTIVE_SIZE (clobbered_v_may_defs); i++)
{
t = VARRAY_TREE (clobbered_v_may_defs, i);
gcc_assert (TREE_CODE (t) != SSA_NAME);
var_ann (t)->in_v_may_def_list = 1;
VARRAY_PUSH_TREE (build_v_may_defs, t);
}
if (s_ann)
{
s_ann->makes_aliased_loads = clobbered_aliased_loads;
s_ann->makes_aliased_stores = clobbered_aliased_stores;
}
return;
}
memset (&empty_ann, 0, sizeof (struct stmt_ann_d));
/* Add a V_MAY_DEF operand for every call clobbered variable. */
EXECUTE_IF_SET_IN_BITMAP (call_clobbered_vars, 0, i, bi) EXECUTE_IF_SET_IN_BITMAP (call_clobbered_vars, 0, i, bi)
{ {
tree var = referenced_var (i); tree var = referenced_var (i);
if (TREE_READONLY (var) if (TREE_READONLY (var)
&& (TREE_STATIC (var) || DECL_EXTERNAL (var))) && (TREE_STATIC (var) || DECL_EXTERNAL (var)))
add_stmt_operand (&var, stmt, opf_none); add_stmt_operand (&var, &empty_ann, opf_none);
else else
add_stmt_operand (&var, stmt, opf_is_def); add_stmt_operand (&var, &empty_ann, opf_is_def);
} }
clobbered_aliased_loads = empty_ann.makes_aliased_loads;
clobbered_aliased_stores = empty_ann.makes_aliased_stores;
/* Set the flags for a stmt's annotation. */
if (s_ann)
{
s_ann->makes_aliased_loads = empty_ann.makes_aliased_loads;
s_ann->makes_aliased_stores = empty_ann.makes_aliased_stores;
}
/* Perpare empty cache vectors. */
if (clobbered_v_may_defs)
{
VARRAY_POP_ALL (clobbered_vuses);
VARRAY_POP_ALL (clobbered_v_may_defs);
} }
else
{
VARRAY_TREE_INIT (clobbered_v_may_defs, 10, "clobbered_v_may_defs");
VARRAY_TREE_INIT (clobbered_vuses, 10, "clobbered_vuses");
}
/* Now fill the clobbered cache with the values that have been found. */
for (i = 0; i < VARRAY_ACTIVE_SIZE (build_vuses); i++)
VARRAY_PUSH_TREE (clobbered_vuses, VARRAY_TREE (build_vuses, i));
for (i = 0; i < VARRAY_ACTIVE_SIZE (build_v_may_defs); i++)
VARRAY_PUSH_TREE (clobbered_v_may_defs, VARRAY_TREE (build_v_may_defs, i));
ssa_call_clobbered_cache_valid = true;
} }
...@@ -1621,24 +1737,60 @@ add_call_clobber_ops (tree stmt) ...@@ -1621,24 +1737,60 @@ add_call_clobber_ops (tree stmt)
static void static void
add_call_read_ops (tree stmt) add_call_read_ops (tree stmt)
{ {
unsigned i;
tree t;
bitmap_iterator bi; bitmap_iterator bi;
stmt_ann_t s_ann = stmt_ann (stmt);
struct stmt_ann_d empty_ann;
/* Otherwise, if the function is not pure, it may reference memory. Add /* if the function is not pure, it may reference memory. Add
a VUSE for .GLOBAL_VAR if it has been created. Otherwise, add a VUSE a VUSE for .GLOBAL_VAR if it has been created. See add_referenced_var
for each call-clobbered variable. See add_referenced_var for the for the heuristic used to decide whether to create .GLOBAL_VAR. */
heuristic used to decide whether to create .GLOBAL_VAR. */
if (global_var) if (global_var)
add_stmt_operand (&global_var, stmt, opf_none);
else
{ {
unsigned i; add_stmt_operand (&global_var, s_ann, opf_none);
return;
}
/* If cache is valid, copy the elements into the build vector. */
if (ssa_ro_call_cache_valid)
{
for (i = 0; i < VARRAY_ACTIVE_SIZE (ro_call_vuses); i++)
{
t = VARRAY_TREE (ro_call_vuses, i);
gcc_assert (TREE_CODE (t) != SSA_NAME);
var_ann (t)->in_vuse_list = 1;
VARRAY_PUSH_TREE (build_vuses, t);
}
if (s_ann)
s_ann->makes_aliased_loads = ro_call_aliased_loads;
return;
}
memset (&empty_ann, 0, sizeof (struct stmt_ann_d));
/* Add a VUSE for each call-clobbered variable. */
EXECUTE_IF_SET_IN_BITMAP (call_clobbered_vars, 0, i, bi) EXECUTE_IF_SET_IN_BITMAP (call_clobbered_vars, 0, i, bi)
{ {
tree var = referenced_var (i); tree var = referenced_var (i);
add_stmt_operand (&var, stmt, opf_none); add_stmt_operand (&var, &empty_ann, opf_none);
}
} }
ro_call_aliased_loads = empty_ann.makes_aliased_loads;
if (s_ann)
s_ann->makes_aliased_loads = empty_ann.makes_aliased_loads;
/* Perpare empty cache vectors. */
if (ro_call_vuses)
VARRAY_POP_ALL (ro_call_vuses);
else
VARRAY_TREE_INIT (ro_call_vuses, 10, "ro_call_vuses");
/* Now fill the clobbered cache with the values that have been found. */
for (i = 0; i < VARRAY_ACTIVE_SIZE (build_vuses); i++)
VARRAY_PUSH_TREE (ro_call_vuses, VARRAY_TREE (build_vuses, i));
ssa_ro_call_cache_valid = true;
} }
/* Copies virtual operands from SRC to DST. */ /* Copies virtual operands from SRC to DST. */
......
...@@ -188,6 +188,8 @@ extern void get_stmt_operands (tree); ...@@ -188,6 +188,8 @@ extern void get_stmt_operands (tree);
extern void copy_virtual_operands (tree, tree); extern void copy_virtual_operands (tree, tree);
extern void create_ssa_artficial_load_stmt (stmt_operands_p, tree); extern void create_ssa_artficial_load_stmt (stmt_operands_p, tree);
extern bool ssa_call_clobbered_cache_valid;
extern bool ssa_ro_call_cache_valid;
/* This structure is used in the operand iterator loops. It contains the /* This structure is used in the operand iterator loops. It contains the
items required to determine which operand is retrieved next. During items required to determine which operand is retrieved next. During
......
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