gimple.c (gimple_copy): Do not clear addresses_taken bitmap.

2009-04-16  Richard Guenther  <rguenther@suse.de>

	* gimple.c (gimple_copy): Do not clear addresses_taken bitmap.
	(gimple_ior_addresses_taken_1): New function.
	(gimple_ior_addresses_taken): Likewise.
	* gimple.h (struct gimple_statement_with_ops_base): Remove
	addresses_taken member.
	(gimple_ior_addresses_taken): Declare.
	(gimple_addresses_taken, gimple_addresses_taken_ptr,
	gimple_set_addresses_taken): Remove.
	* ipa-reference.c (mark_address): New function.
	(scan_stmt_for_static_refs): Use it for marking addresses taken.
	* tree-ssa-operands.c (add_to_addressable_set): Rename to ...
	(mark_address_taken): ... this.  Just set TREE_ADDRESSABLE.
	(gimple_add_to_addresses_taken): Remove.
	(get_tmr_operands): Call mark_address_taken.
	(get_asm_expr_operands): Likewise.
	(get_expr_operands): Likewise.
	(build_ssa_operands): Do not clear the addresses_taken bitmap.
	(free_stmt_operands): Do not free it.
	* tree-ssa.c (delete_tree_ssa): Likewise.
	(execute_update_addresses_taken): Use gimple_ior_addresses_taken.

From-SVN: r146191
This commit is contained in:
Richard Guenther 2009-04-16 13:23:13 +00:00 committed by Richard Biener
parent 346ef3faa0
commit ccacdf0682
6 changed files with 96 additions and 108 deletions

View File

@ -1,3 +1,26 @@
2009-04-16 Richard Guenther <rguenther@suse.de>
* gimple.c (gimple_copy): Do not clear addresses_taken bitmap.
(gimple_ior_addresses_taken_1): New function.
(gimple_ior_addresses_taken): Likewise.
* gimple.h (struct gimple_statement_with_ops_base): Remove
addresses_taken member.
(gimple_ior_addresses_taken): Declare.
(gimple_addresses_taken, gimple_addresses_taken_ptr,
gimple_set_addresses_taken): Remove.
* ipa-reference.c (mark_address): New function.
(scan_stmt_for_static_refs): Use it for marking addresses taken.
* tree-ssa-operands.c (add_to_addressable_set): Rename to ...
(mark_address_taken): ... this. Just set TREE_ADDRESSABLE.
(gimple_add_to_addresses_taken): Remove.
(get_tmr_operands): Call mark_address_taken.
(get_asm_expr_operands): Likewise.
(get_expr_operands): Likewise.
(build_ssa_operands): Do not clear the addresses_taken bitmap.
(free_stmt_operands): Do not free it.
* tree-ssa.c (delete_tree_ssa): Likewise.
(execute_update_addresses_taken): Use gimple_ior_addresses_taken.
2009-04-16 Richard Guenther <rguenther@suse.de> 2009-04-16 Richard Guenther <rguenther@suse.de>
* gimple.h (walk_stmt_load_store_addr_ops): Declare. * gimple.h (walk_stmt_load_store_addr_ops): Declare.

View File

@ -2195,16 +2195,11 @@ gimple_copy (gimple stmt)
for (i = 0; i < num_ops; i++) for (i = 0; i < num_ops; i++)
gimple_set_op (copy, i, unshare_expr (gimple_op (stmt, i))); gimple_set_op (copy, i, unshare_expr (gimple_op (stmt, i)));
/* Clear out SSA operand vectors on COPY. Note that we cannot /* Clear out SSA operand vectors on COPY. */
call the API functions for setting addresses_taken, stores
and loads. These functions free the previous values, and we
cannot do that on COPY as it will affect the original
statement. */
if (gimple_has_ops (stmt)) if (gimple_has_ops (stmt))
{ {
gimple_set_def_ops (copy, NULL); gimple_set_def_ops (copy, NULL);
gimple_set_use_ops (copy, NULL); gimple_set_use_ops (copy, NULL);
copy->gsops.opbase.addresses_taken = NULL;
} }
if (gimple_has_mem_ops (stmt)) if (gimple_has_mem_ops (stmt))
@ -3392,4 +3387,32 @@ walk_stmt_load_store_ops (gimple stmt, void *data,
visit_load, visit_store, NULL); visit_load, visit_store, NULL);
} }
/* Helper for gimple_ior_addresses_taken_1. */
static bool
gimple_ior_addresses_taken_1 (gimple stmt ATTRIBUTE_UNUSED,
tree addr, void *data)
{
bitmap addresses_taken = (bitmap)data;
while (handled_component_p (addr))
addr = TREE_OPERAND (addr, 0);
if (DECL_P (addr))
{
bitmap_set_bit (addresses_taken, DECL_UID (addr));
return true;
}
return false;
}
/* Set the bit for the uid of all decls that have their address taken
in STMT in the ADDRESSES_TAKEN bitmap. Returns true if there
were any in this stmt. */
bool
gimple_ior_addresses_taken (bitmap addresses_taken, gimple stmt)
{
return walk_stmt_load_store_addr_ops (stmt, addresses_taken, NULL, NULL,
gimple_ior_addresses_taken_1);
}
#include "gt-gimple.h" #include "gt-gimple.h"

View File

@ -327,15 +327,10 @@ struct gimple_statement_base GTY(())
struct gimple_statement_with_ops_base GTY(()) struct gimple_statement_with_ops_base GTY(())
{ {
/* [ WORD 1-4 ] */ /* [ WORD 1-4 ] */
struct gimple_statement_base gsbase; struct gimple_statement_base gsbase;
/* [ WORD 5 ] /* [ WORD 5-6 ]
Symbols whose addresses are taken by this statement (i.e., they
appear inside ADDR_EXPR nodes). */
bitmap GTY((skip (""))) addresses_taken;
/* [ WORD 6-7 ]
SSA operand vectors. NOTE: It should be possible to SSA operand vectors. NOTE: It should be possible to
amalgamate these vectors with the operand vector OP. However, amalgamate these vectors with the operand vector OP. However,
the SSA operand vectors are organized differently and contain the SSA operand vectors are organized differently and contain
@ -349,10 +344,10 @@ struct gimple_statement_with_ops_base GTY(())
struct gimple_statement_with_ops GTY(()) struct gimple_statement_with_ops GTY(())
{ {
/* [ WORD 1-7 ] */ /* [ WORD 1-6 ] */
struct gimple_statement_with_ops_base opbase; struct gimple_statement_with_ops_base opbase;
/* [ WORD 8 ] /* [ WORD 7 ]
Operand vector. NOTE! This must always be the last field Operand vector. NOTE! This must always be the last field
of this structure. In particular, this means that this of this structure. In particular, this means that this
structure cannot be embedded inside another one. */ structure cannot be embedded inside another one. */
@ -364,10 +359,10 @@ struct gimple_statement_with_ops GTY(())
struct gimple_statement_with_memory_ops_base GTY(()) struct gimple_statement_with_memory_ops_base GTY(())
{ {
/* [ WORD 1-7 ] */ /* [ WORD 1-6 ] */
struct gimple_statement_with_ops_base opbase; struct gimple_statement_with_ops_base opbase;
/* [ WORD 8-9 ] /* [ WORD 7-8 ]
Virtual operands for this statement. The GC will pick them Virtual operands for this statement. The GC will pick them
up via the ssa_names array. */ up via the ssa_names array. */
tree GTY((skip (""))) vdef; tree GTY((skip (""))) vdef;
@ -379,10 +374,10 @@ struct gimple_statement_with_memory_ops_base GTY(())
struct gimple_statement_with_memory_ops GTY(()) struct gimple_statement_with_memory_ops GTY(())
{ {
/* [ WORD 1-9 ] */ /* [ WORD 1-8 ] */
struct gimple_statement_with_memory_ops_base membase; struct gimple_statement_with_memory_ops_base membase;
/* [ WORD 10 ] /* [ WORD 9 ]
Operand vector. NOTE! This must always be the last field Operand vector. NOTE! This must always be the last field
of this structure. In particular, this means that this of this structure. In particular, this means that this
structure cannot be embedded inside another one. */ structure cannot be embedded inside another one. */
@ -545,20 +540,20 @@ struct gimple_statement_wce GTY(())
struct gimple_statement_asm GTY(()) struct gimple_statement_asm GTY(())
{ {
/* [ WORD 1-9 ] */ /* [ WORD 1-8 ] */
struct gimple_statement_with_memory_ops_base membase; struct gimple_statement_with_memory_ops_base membase;
/* [ WORD 10 ] /* [ WORD 9 ]
__asm__ statement. */ __asm__ statement. */
const char *string; const char *string;
/* [ WORD 11 ] /* [ WORD 10 ]
Number of inputs, outputs and clobbers. */ Number of inputs, outputs and clobbers. */
unsigned char ni; unsigned char ni;
unsigned char no; unsigned char no;
unsigned short nc; unsigned short nc;
/* [ WORD 12 ] /* [ WORD 11 ]
Operand vector. NOTE! This must always be the last field Operand vector. NOTE! This must always be the last field
of this structure. In particular, this means that this of this structure. In particular, this means that this
structure cannot be embedded inside another one. */ structure cannot be embedded inside another one. */
@ -916,6 +911,7 @@ extern bool walk_stmt_load_store_addr_ops (gimple, void *,
extern bool walk_stmt_load_store_ops (gimple, void *, extern bool walk_stmt_load_store_ops (gimple, void *,
bool (*)(gimple, tree, void *), bool (*)(gimple, tree, void *),
bool (*)(gimple, tree, void *)); bool (*)(gimple, tree, void *));
extern bool gimple_ior_addresses_taken (bitmap, gimple);
/* In gimplify.c */ /* In gimplify.c */
extern tree create_tmp_var_raw (tree, const char *); extern tree create_tmp_var_raw (tree, const char *);
@ -1242,41 +1238,6 @@ gimple_has_mem_ops (const_gimple g)
return gimple_code (g) >= GIMPLE_ASSIGN && gimple_code (g) <= GIMPLE_RETURN; return gimple_code (g) >= GIMPLE_ASSIGN && gimple_code (g) <= GIMPLE_RETURN;
} }
/* Return the set of addresses taken by statement G. */
static inline bitmap
gimple_addresses_taken (const_gimple g)
{
if (gimple_has_ops (g))
return g->gsops.opbase.addresses_taken;
else
return NULL;
}
/* Return a pointer to the set of addresses taken by statement G. */
static inline bitmap *
gimple_addresses_taken_ptr (gimple g)
{
if (gimple_has_ops (g))
return &g->gsops.opbase.addresses_taken;
else
return NULL;
}
/* Set B to be the set of addresses taken by statement G. The
previous set is freed. */
static inline void
gimple_set_addresses_taken (gimple g, bitmap b)
{
gcc_assert (gimple_has_ops (g));
BITMAP_FREE (g->gsops.opbase.addresses_taken);
g->gsops.opbase.addresses_taken = b;
}
/* Return the set of DEF operands for statement G. */ /* Return the set of DEF operands for statement G. */

View File

@ -334,6 +334,18 @@ mark_address_taken (tree x)
bitmap_set_bit (module_statics_escape, DECL_UID (x)); bitmap_set_bit (module_statics_escape, DECL_UID (x));
} }
/* Wrapper around mark_address_taken for the stmt walker. */
static bool
mark_address (gimple stmt ATTRIBUTE_UNUSED, tree addr,
void *data ATTRIBUTE_UNUSED)
{
while (handled_component_p (addr))
addr = TREE_OPERAND (addr, 0);
mark_address_taken (addr);
return false;
}
/* Mark load of T. */ /* Mark load of T. */
static bool static bool
@ -429,23 +441,18 @@ scan_stmt_for_static_refs (gimple_stmt_iterator *gsip,
{ {
gimple stmt = gsi_stmt (*gsip); gimple stmt = gsi_stmt (*gsip);
ipa_reference_local_vars_info_t local = NULL; ipa_reference_local_vars_info_t local = NULL;
unsigned int i;
bitmap_iterator bi;
if (fn) if (fn)
local = get_reference_vars_info (fn)->local; local = get_reference_vars_info (fn)->local;
/* Look for direct loads and stores. */ /* Look for direct loads and stores. */
walk_stmt_load_store_addr_ops (stmt, local, mark_load, mark_store, NULL); walk_stmt_load_store_addr_ops (stmt, local, mark_load, mark_store,
mark_address);
if (is_gimple_call (stmt)) if (is_gimple_call (stmt))
check_call (local, stmt); check_call (local, stmt);
else if (gimple_code (stmt) == GIMPLE_ASM) else if (gimple_code (stmt) == GIMPLE_ASM)
check_asm_memory_clobber (local, stmt); check_asm_memory_clobber (local, stmt);
if (gimple_addresses_taken (stmt))
EXECUTE_IF_SET_IN_BITMAP (gimple_addresses_taken (stmt), 0, i, bi)
mark_address_taken (referenced_var_lookup (i));
return NULL; return NULL;
} }

View File

@ -686,10 +686,13 @@ add_stmt_operand (tree *var_p, gimple stmt, int flags)
add_virtual_operand (stmt, flags); add_virtual_operand (stmt, flags);
} }
/* Add the base address of REF to SET. */ /* Mark the base address of REF as having its address taken.
REF may be a single variable whose address has been taken or any
other valid GIMPLE memory reference (structure reference, array,
etc). */
static void static void
add_to_addressable_set (tree ref, bitmap *set) mark_address_taken (tree ref)
{ {
tree var; tree var;
@ -699,27 +702,8 @@ add_to_addressable_set (tree ref, bitmap *set)
be referenced using pointer arithmetic. See PR 21407 and the be referenced using pointer arithmetic. See PR 21407 and the
ensuing mailing list discussion. */ ensuing mailing list discussion. */
var = get_base_address (ref); var = get_base_address (ref);
if (var && SSA_VAR_P (var)) if (var && DECL_P (var))
{ TREE_ADDRESSABLE (var) = 1;
if (*set == NULL)
*set = BITMAP_ALLOC (&operands_bitmap_obstack);
bitmap_set_bit (*set, DECL_UID (var));
TREE_ADDRESSABLE (var) = 1;
}
}
/* Add the base address of REF to the set of addresses taken by STMT.
REF may be a single variable whose address has been taken or any
other valid GIMPLE memory reference (structure reference, array,
etc). If the base address of REF is a decl that has sub-variables,
also add all of its sub-variables. */
static void
gimple_add_to_addresses_taken (gimple stmt, tree ref)
{
gcc_assert (gimple_has_ops (stmt));
add_to_addressable_set (ref, gimple_addresses_taken_ptr (stmt));
} }
@ -763,7 +747,7 @@ get_tmr_operands (gimple stmt, tree expr, int flags)
get_expr_operands (stmt, &TMR_INDEX (expr), opf_use); get_expr_operands (stmt, &TMR_INDEX (expr), opf_use);
if (TMR_SYMBOL (expr)) if (TMR_SYMBOL (expr))
gimple_add_to_addresses_taken (stmt, TMR_SYMBOL (expr)); mark_address_taken (TMR_SYMBOL (expr));
add_virtual_operand (stmt, flags); add_virtual_operand (stmt, flags);
} }
@ -824,7 +808,7 @@ get_asm_expr_operands (gimple stmt)
{ {
tree t = get_base_address (TREE_VALUE (link)); tree t = get_base_address (TREE_VALUE (link));
if (t && DECL_P (t)) if (t && DECL_P (t))
gimple_add_to_addresses_taken (stmt, t); mark_address_taken (t);
} }
get_expr_operands (stmt, &TREE_VALUE (link), opf_def); get_expr_operands (stmt, &TREE_VALUE (link), opf_def);
@ -844,7 +828,7 @@ get_asm_expr_operands (gimple stmt)
{ {
tree t = get_base_address (TREE_VALUE (link)); tree t = get_base_address (TREE_VALUE (link));
if (t && DECL_P (t)) if (t && DECL_P (t))
gimple_add_to_addresses_taken (stmt, t); mark_address_taken (t);
} }
get_expr_operands (stmt, &TREE_VALUE (link), 0); get_expr_operands (stmt, &TREE_VALUE (link), 0);
@ -887,7 +871,7 @@ get_expr_operands (gimple stmt, tree *expr_p, int flags)
reference to it, but the fact that the statement takes its reference to it, but the fact that the statement takes its
address will be of interest to some passes (e.g. alias address will be of interest to some passes (e.g. alias
resolution). */ resolution). */
gimple_add_to_addresses_taken (stmt, TREE_OPERAND (expr, 0)); mark_address_taken (TREE_OPERAND (expr, 0));
/* If the address is invariant, there may be no interesting /* If the address is invariant, there may be no interesting
variable references inside. */ variable references inside. */
@ -1091,14 +1075,9 @@ parse_ssa_operands (gimple stmt)
static void static void
build_ssa_operands (gimple stmt) build_ssa_operands (gimple stmt)
{ {
/* Initially assume that the statement has no volatile operands and /* Initially assume that the statement has no volatile operands. */
makes no memory references. */
gimple_set_has_volatile_ops (stmt, false); gimple_set_has_volatile_ops (stmt, false);
/* Just clear the bitmap so we don't end up reallocating it over and over. */
if (gimple_addresses_taken (stmt))
bitmap_clear (gimple_addresses_taken (stmt));
start_ssa_stmt_operands (); start_ssa_stmt_operands ();
parse_ssa_operands (stmt); parse_ssa_operands (stmt);
finalize_ssa_stmt_operands (stmt); finalize_ssa_stmt_operands (stmt);
@ -1133,9 +1112,6 @@ free_stmt_operands (gimple stmt)
gimple_set_use_ops (stmt, NULL); gimple_set_use_ops (stmt, NULL);
} }
if (gimple_has_ops (stmt))
gimple_set_addresses_taken (stmt, NULL);
if (gimple_has_mem_ops (stmt)) if (gimple_has_mem_ops (stmt))
{ {
gimple_set_vuse (stmt, NULL_TREE); gimple_set_vuse (stmt, NULL_TREE);

View File

@ -834,7 +834,6 @@ delete_tree_ssa (void)
{ {
gimple_set_def_ops (stmt, NULL); gimple_set_def_ops (stmt, NULL);
gimple_set_use_ops (stmt, NULL); gimple_set_use_ops (stmt, NULL);
gimple_set_addresses_taken (stmt, NULL);
} }
if (gimple_has_mem_ops (stmt)) if (gimple_has_mem_ops (stmt))
@ -1504,13 +1503,12 @@ execute_update_addresses_taken (bool do_optimize)
{ {
for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{ {
const_gimple stmt = gsi_stmt (gsi); gimple stmt = gsi_stmt (gsi);
enum gimple_code code = gimple_code (stmt); enum gimple_code code = gimple_code (stmt);
bitmap taken = gimple_addresses_taken (stmt);
/* Note all addresses taken by the stmt. */
if (taken) gimple_ior_addresses_taken (addresses_taken, stmt);
bitmap_ior_into (addresses_taken, taken);
/* If we have a call or an assignment, see if the lhs contains /* If we have a call or an assignment, see if the lhs contains
a local decl that requires not to be a gimple register. */ a local decl that requires not to be a gimple register. */
if (code == GIMPLE_ASSIGN || code == GIMPLE_CALL) if (code == GIMPLE_ASSIGN || code == GIMPLE_CALL)