This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH][2/2] Remove addresses_taken bitmap per stmt
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Diego Novillo <dnovillo at google dot com>
- Date: Wed, 15 Apr 2009 17:19:17 +0200 (CEST)
- Subject: [PATCH][2/2] Remove addresses_taken bitmap per stmt
This reduces the gimple memory footprint by removing the addresses_taken
bitmap from statements. Our automated testers didn't find significant
changes in memory-usage nor compile-time though (not too much addresses
in a CU it seems, but certainly wasting a GCed bitmap for a single
address-taking operation is costly).
The patch applies on top of [1/2] posted before. It as well is pending
bootstrap and regtest.
Diego, does this sound good?
Thanks,
Richard.
2009-04-15 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.
Index: trunk/gcc/gimple.c
===================================================================
*** trunk.orig/gcc/gimple.c 2009-04-14 14:15:28.000000000 +0200
--- trunk/gcc/gimple.c 2009-04-14 14:20:06.000000000 +0200
*************** gimple_copy (gimple stmt)
*** 2195,2210 ****
for (i = 0; i < num_ops; i++)
gimple_set_op (copy, i, unshare_expr (gimple_op (stmt, i)));
! /* Clear out SSA operand vectors on COPY. Note that we cannot
! 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))
{
gimple_set_def_ops (copy, NULL);
gimple_set_use_ops (copy, NULL);
- copy->gsops.opbase.addresses_taken = NULL;
}
if (gimple_has_mem_ops (stmt))
--- 2195,2205 ----
for (i = 0; i < num_ops; i++)
gimple_set_op (copy, i, unshare_expr (gimple_op (stmt, i)));
! /* Clear out SSA operand vectors on COPY. */
if (gimple_has_ops (stmt))
{
gimple_set_def_ops (copy, NULL);
gimple_set_use_ops (copy, NULL);
}
if (gimple_has_mem_ops (stmt))
*************** walk_stmt_load_store_ops (gimple stmt, v
*** 3392,3395 ****
--- 3387,3418 ----
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"
Index: trunk/gcc/gimple.h
===================================================================
*** trunk.orig/gcc/gimple.h 2009-04-14 14:17:14.000000000 +0200
--- trunk/gcc/gimple.h 2009-04-14 14:20:26.000000000 +0200
*************** struct gimple_statement_base GTY(())
*** 327,341 ****
struct gimple_statement_with_ops_base GTY(())
{
! /* [ WORD 1-4 ] */
struct gimple_statement_base gsbase;
! /* [ WORD 5 ]
! 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
amalgamate these vectors with the operand vector OP. However,
the SSA operand vectors are organized differently and contain
--- 327,336 ----
struct gimple_statement_with_ops_base GTY(())
{
! /* [ WORD 1-4 ] */
struct gimple_statement_base gsbase;
! /* [ WORD 5-6 ]
SSA operand vectors. NOTE: It should be possible to
amalgamate these vectors with the operand vector OP. However,
the SSA operand vectors are organized differently and contain
*************** struct gimple_statement_with_ops_base GT
*** 349,358 ****
struct gimple_statement_with_ops GTY(())
{
! /* [ WORD 1-7 ] */
struct gimple_statement_with_ops_base opbase;
! /* [ WORD 8 ]
Operand vector. NOTE! This must always be the last field
of this structure. In particular, this means that this
structure cannot be embedded inside another one. */
--- 344,353 ----
struct gimple_statement_with_ops GTY(())
{
! /* [ WORD 1-6 ] */
struct gimple_statement_with_ops_base opbase;
! /* [ WORD 7 ]
Operand vector. NOTE! This must always be the last field
of this structure. In particular, this means that this
structure cannot be embedded inside another one. */
*************** struct gimple_statement_with_ops GTY(())
*** 364,373 ****
struct gimple_statement_with_memory_ops_base GTY(())
{
! /* [ WORD 1-7 ] */
struct gimple_statement_with_ops_base opbase;
! /* [ WORD 8-9 ]
Virtual operands for this statement. The GC will pick them
up via the ssa_names array. */
tree GTY((skip (""))) vdef;
--- 359,368 ----
struct gimple_statement_with_memory_ops_base GTY(())
{
! /* [ WORD 1-6 ] */
struct gimple_statement_with_ops_base opbase;
! /* [ WORD 7-8 ]
Virtual operands for this statement. The GC will pick them
up via the ssa_names array. */
tree GTY((skip (""))) vdef;
*************** struct gimple_statement_with_memory_ops_
*** 379,388 ****
struct gimple_statement_with_memory_ops GTY(())
{
! /* [ WORD 1-9 ] */
struct gimple_statement_with_memory_ops_base membase;
! /* [ WORD 10 ]
Operand vector. NOTE! This must always be the last field
of this structure. In particular, this means that this
structure cannot be embedded inside another one. */
--- 374,383 ----
struct gimple_statement_with_memory_ops GTY(())
{
! /* [ WORD 1-8 ] */
struct gimple_statement_with_memory_ops_base membase;
! /* [ WORD 9 ]
Operand vector. NOTE! This must always be the last field
of this structure. In particular, this means that this
structure cannot be embedded inside another one. */
*************** struct gimple_statement_wce GTY(())
*** 545,564 ****
struct gimple_statement_asm GTY(())
{
! /* [ WORD 1-9 ] */
struct gimple_statement_with_memory_ops_base membase;
! /* [ WORD 10 ]
__asm__ statement. */
const char *string;
! /* [ WORD 11 ]
Number of inputs, outputs and clobbers. */
unsigned char ni;
unsigned char no;
unsigned short nc;
! /* [ WORD 12 ]
Operand vector. NOTE! This must always be the last field
of this structure. In particular, this means that this
structure cannot be embedded inside another one. */
--- 540,559 ----
struct gimple_statement_asm GTY(())
{
! /* [ WORD 1-8 ] */
struct gimple_statement_with_memory_ops_base membase;
! /* [ WORD 9 ]
__asm__ statement. */
const char *string;
! /* [ WORD 10 ]
Number of inputs, outputs and clobbers. */
unsigned char ni;
unsigned char no;
unsigned short nc;
! /* [ WORD 11 ]
Operand vector. NOTE! This must always be the last field
of this structure. In particular, this means that this
structure cannot be embedded inside another one. */
*************** extern bool walk_stmt_load_store_addr_op
*** 916,921 ****
--- 911,917 ----
extern bool walk_stmt_load_store_ops (gimple, void *,
bool (*)(gimple, tree, void *),
bool (*)(gimple, tree, void *));
+ extern bool gimple_ior_addresses_taken (bitmap, gimple);
/* In gimplify.c */
extern tree create_tmp_var_raw (tree, const char *);
*************** gimple_has_mem_ops (const_gimple g)
*** 1242,1282 ****
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. */
--- 1238,1243 ----
Index: trunk/gcc/ipa-reference.c
===================================================================
*** trunk.orig/gcc/ipa-reference.c 2009-04-14 14:13:41.000000000 +0200
--- trunk/gcc/ipa-reference.c 2009-04-14 14:19:38.000000000 +0200
*************** mark_address_taken (tree x)
*** 334,339 ****
--- 334,351 ----
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. */
static bool
*************** scan_stmt_for_static_refs (gimple_stmt_i
*** 429,451 ****
{
gimple stmt = gsi_stmt (*gsip);
ipa_reference_local_vars_info_t local = NULL;
- unsigned int i;
- bitmap_iterator bi;
if (fn)
local = get_reference_vars_info (fn)->local;
/* Look for direct loads and stores. */
! walk_stmt_load_store_addr_ops (stmt, local, mark_load, mark_store, NULL);
if (is_gimple_call (stmt))
check_call (local, stmt);
else if (gimple_code (stmt) == GIMPLE_ASM)
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;
}
--- 441,458 ----
{
gimple stmt = gsi_stmt (*gsip);
ipa_reference_local_vars_info_t local = NULL;
if (fn)
local = get_reference_vars_info (fn)->local;
/* Look for direct loads and stores. */
! walk_stmt_load_store_addr_ops (stmt, local, mark_load, mark_store,
! mark_address);
if (is_gimple_call (stmt))
check_call (local, stmt);
else if (gimple_code (stmt) == GIMPLE_ASM)
check_asm_memory_clobber (local, stmt);
return NULL;
}
Index: trunk/gcc/tree-ssa-operands.c
===================================================================
*** trunk.orig/gcc/tree-ssa-operands.c 2009-04-14 14:13:41.000000000 +0200
--- trunk/gcc/tree-ssa-operands.c 2009-04-14 14:19:38.000000000 +0200
*************** add_stmt_operand (tree *var_p, gimple st
*** 686,695 ****
add_virtual_operand (stmt, flags);
}
! /* Add the base address of REF to SET. */
static void
! add_to_addressable_set (tree ref, bitmap *set)
{
tree var;
--- 686,698 ----
add_virtual_operand (stmt, flags);
}
! /* 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
! mark_address_taken (tree ref)
{
tree var;
*************** add_to_addressable_set (tree ref, bitmap
*** 699,725 ****
be referenced using pointer arithmetic. See PR 21407 and the
ensuing mailing list discussion. */
var = get_base_address (ref);
! if (var && SSA_VAR_P (var))
! {
! 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));
}
--- 702,709 ----
be referenced using pointer arithmetic. See PR 21407 and the
ensuing mailing list discussion. */
var = get_base_address (ref);
! if (var && DECL_P (var))
! TREE_ADDRESSABLE (var) = 1;
}
*************** get_tmr_operands (gimple stmt, tree expr
*** 763,769 ****
get_expr_operands (stmt, &TMR_INDEX (expr), opf_use);
if (TMR_SYMBOL (expr))
! gimple_add_to_addresses_taken (stmt, TMR_SYMBOL (expr));
add_virtual_operand (stmt, flags);
}
--- 747,753 ----
get_expr_operands (stmt, &TMR_INDEX (expr), opf_use);
if (TMR_SYMBOL (expr))
! mark_address_taken (TMR_SYMBOL (expr));
add_virtual_operand (stmt, flags);
}
*************** get_asm_expr_operands (gimple stmt)
*** 824,830 ****
{
tree t = get_base_address (TREE_VALUE (link));
if (t && DECL_P (t))
! gimple_add_to_addresses_taken (stmt, t);
}
get_expr_operands (stmt, &TREE_VALUE (link), opf_def);
--- 808,814 ----
{
tree t = get_base_address (TREE_VALUE (link));
if (t && DECL_P (t))
! mark_address_taken (t);
}
get_expr_operands (stmt, &TREE_VALUE (link), opf_def);
*************** get_asm_expr_operands (gimple stmt)
*** 844,850 ****
{
tree t = get_base_address (TREE_VALUE (link));
if (t && DECL_P (t))
! gimple_add_to_addresses_taken (stmt, t);
}
get_expr_operands (stmt, &TREE_VALUE (link), 0);
--- 828,834 ----
{
tree t = get_base_address (TREE_VALUE (link));
if (t && DECL_P (t))
! mark_address_taken (t);
}
get_expr_operands (stmt, &TREE_VALUE (link), 0);
*************** get_expr_operands (gimple stmt, tree *ex
*** 887,893 ****
reference to it, but the fact that the statement takes its
address will be of interest to some passes (e.g. alias
resolution). */
! gimple_add_to_addresses_taken (stmt, TREE_OPERAND (expr, 0));
/* If the address is invariant, there may be no interesting
variable references inside. */
--- 871,877 ----
reference to it, but the fact that the statement takes its
address will be of interest to some passes (e.g. alias
resolution). */
! mark_address_taken (TREE_OPERAND (expr, 0));
/* If the address is invariant, there may be no interesting
variable references inside. */
*************** parse_ssa_operands (gimple stmt)
*** 1091,1104 ****
static void
build_ssa_operands (gimple stmt)
{
! /* Initially assume that the statement has no volatile operands and
! makes no memory references. */
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 ();
parse_ssa_operands (stmt);
finalize_ssa_stmt_operands (stmt);
--- 1075,1083 ----
static void
build_ssa_operands (gimple stmt)
{
! /* Initially assume that the statement has no volatile operands. */
gimple_set_has_volatile_ops (stmt, false);
start_ssa_stmt_operands ();
parse_ssa_operands (stmt);
finalize_ssa_stmt_operands (stmt);
*************** free_stmt_operands (gimple stmt)
*** 1133,1141 ****
gimple_set_use_ops (stmt, NULL);
}
- if (gimple_has_ops (stmt))
- gimple_set_addresses_taken (stmt, NULL);
-
if (gimple_has_mem_ops (stmt))
{
gimple_set_vuse (stmt, NULL_TREE);
--- 1112,1117 ----
Index: trunk/gcc/tree-ssa.c
===================================================================
*** trunk.orig/gcc/tree-ssa.c 2009-04-14 14:13:41.000000000 +0200
--- trunk/gcc/tree-ssa.c 2009-04-14 14:19:38.000000000 +0200
*************** delete_tree_ssa (void)
*** 834,840 ****
{
gimple_set_def_ops (stmt, NULL);
gimple_set_use_ops (stmt, NULL);
- gimple_set_addresses_taken (stmt, NULL);
}
if (gimple_has_mem_ops (stmt))
--- 834,839 ----
*************** execute_update_addresses_taken (bool do_
*** 1504,1516 ****
{
for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
! const_gimple stmt = gsi_stmt (gsi);
enum gimple_code code = gimple_code (stmt);
! bitmap taken = gimple_addresses_taken (stmt);
!
! if (taken)
! bitmap_ior_into (addresses_taken, taken);
!
/* If we have a call or an assignment, see if the lhs contains
a local decl that requires not to be a gimple register. */
if (code == GIMPLE_ASSIGN || code == GIMPLE_CALL)
--- 1503,1514 ----
{
for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
! gimple stmt = gsi_stmt (gsi);
enum gimple_code code = gimple_code (stmt);
!
! /* Note all addresses taken by the stmt. */
! gimple_ior_addresses_taken (addresses_taken, stmt);
!
/* If we have a call or an assignment, see if the lhs contains
a local decl that requires not to be a gimple register. */
if (code == GIMPLE_ASSIGN || code == GIMPLE_CALL)