This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH][RFC] Share variable annotations for globals across functions
- 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: Thu, 22 May 2008 23:56:26 +0200 (CEST)
- Subject: Re: [PATCH][RFC] Share variable annotations for globals across functions
- References: <Pine.LNX.4.64.0805222126570.4039@zhemvz.fhfr.qr>
On Thu, 22 May 2008, Richard Guenther wrote:
>
> This removes the per-function variable annotation code we use for
> global variables. A scheme like this is only needed if we have aliasing
> computed for multiple functions at a time. For which we better find
> a different solution. For PR36291 we have tons of referenced global
> vars (the usual chaining of global data problem) and tons of functions.
> This results in
>
> tree-dfa.c:153 (create_var_ann) 482008296:30.4% 0: 0.0% 0: 0.0% 43818936:30.6% 5477367
>
> and a peak memory usage of about 2GB on x86_64 (without checking but with
> mem-stats enabled). If we share the variable annotations of globals
> this goes down to
>
> tree-dfa.c:150 (create_var_ann) 206016: 0.0% 15094400: 3.2% 142592: 0.1% 0: 0.0% 241297
>
> and a peak memory usage of about 1GB.
>
> Bootstrapped and tested on x86_64-unknown-linux-gnu for C and C++
> (I expect I can remove the tree-ssa-alias.c hunk), full testing will
> follow.
>
> Diego, I suppose tuples doesn't change the above picture, so is the
> general idea ok?
Final patch appended. Bootstrapped and tested on x86_64-unknown-linux-gnu
for all languages including ada.
Ok for mainline?
Thanks,
Richard.
2008-05-22 Richard Guenther <rguenther@suse.de>
PR tree-optimization/36291
* tree-flow. h (struct gimple_df): Remove var_anns member.
* tree-flow-inline.h (gimple_var_anns): Remove.
(var_ann): Simplify.
* tree-dfa.c (create_var_ann): Simplify.
(remove_referenced_var): Clear alias info from var_anns of globals.
* tree-ssa.c (init_tree_ssa): Do not allocate var_anns.
(delete_tree_ssa): Clear alias info from var_anns of globals.
Do not free var_anns.
(var_ann_eq): Remove.
(var_ann_hash): Likewise.
Index: gcc/tree-flow-inline.h
===================================================================
*** gcc/tree-flow-inline.h.orig 2008-05-22 21:53:47.000000000 +0200
--- gcc/tree-flow-inline.h 2008-05-22 21:54:39.000000000 +0200
*************** gimple_nonlocal_all (const struct functi
*** 91,104 ****
return fun->gimple_df->nonlocal_all;
}
- /* Hashtable of variables annotations. Used for static variables only;
- local variables have direct pointer in the tree node. */
- static inline htab_t
- gimple_var_anns (const struct function *fun)
- {
- return fun->gimple_df->var_anns;
- }
-
/* Initialize the hashtable iterator HTI to point to hashtable TABLE */
static inline void *
--- 91,96 ----
*************** var_ann (const_tree t)
*** 192,213 ****
{
var_ann_t ann;
! if (!MTAG_P (t)
! && (TREE_STATIC (t) || DECL_EXTERNAL (t)))
! {
! struct static_var_ann_d *sann
! = ((struct static_var_ann_d *)
! htab_find_with_hash (gimple_var_anns (cfun), t, DECL_UID (t)));
! if (!sann)
! return NULL;
! ann = &sann->ann;
! }
! else
! {
! if (!t->base.ann)
! return NULL;
! ann = (var_ann_t) t->base.ann;
! }
gcc_assert (ann->common.type == VAR_ANN);
--- 184,192 ----
{
var_ann_t ann;
! if (!t->base.ann)
! return NULL;
! ann = (var_ann_t) t->base.ann;
gcc_assert (ann->common.type == VAR_ANN);
Index: gcc/tree-dfa.c
===================================================================
*** gcc/tree-dfa.c.orig 2008-05-22 21:53:47.000000000 +0200
--- gcc/tree-dfa.c 2008-05-22 21:54:09.000000000 +0200
*************** var_ann_t
*** 142,174 ****
create_var_ann (tree t)
{
var_ann_t ann;
- struct static_var_ann_d *sann = NULL;
gcc_assert (t);
gcc_assert (DECL_P (t));
gcc_assert (!t->base.ann || t->base.ann->common.type == VAR_ANN);
! if (!MTAG_P (t) && (TREE_STATIC (t) || DECL_EXTERNAL (t)))
! {
! sann = GGC_CNEW (struct static_var_ann_d);
! ann = &sann->ann;
! }
! else
! ann = GGC_CNEW (struct var_ann_d);
!
ann->common.type = VAR_ANN;
!
! if (!MTAG_P (t) && (TREE_STATIC (t) || DECL_EXTERNAL (t)))
! {
! void **slot;
! sann->uid = DECL_UID (t);
! slot = htab_find_slot_with_hash (gimple_var_anns (cfun),
! t, DECL_UID (t), INSERT);
! gcc_assert (!*slot);
! *slot = sann;
! }
! else
! t->base.ann = (tree_ann_t) ann;
return ann;
}
--- 142,155 ----
create_var_ann (tree t)
{
var_ann_t ann;
gcc_assert (t);
gcc_assert (DECL_P (t));
gcc_assert (!t->base.ann || t->base.ann->common.type == VAR_ANN);
! ann = GGC_CNEW (struct var_ann_d);
ann->common.type = VAR_ANN;
! t->base.ann = (tree_ann_t) ann;
return ann;
}
*************** remove_referenced_var (tree var)
*** 765,772 ****
clear_call_clobbered (var);
if ((v_ann = var_ann (var)))
! ggc_free (v_ann);
! var->base.ann = NULL;
gcc_assert (DECL_P (var));
in.uid = uid;
loc = htab_find_slot_with_hash (gimple_referenced_vars (cfun), &in, uid,
--- 746,765 ----
clear_call_clobbered (var);
if ((v_ann = var_ann (var)))
! {
! /* Preserve var_anns of globals, but clear their alias info. */
! if (MTAG_P (var)
! || (!TREE_STATIC (var) && !DECL_EXTERNAL (var)))
! {
! ggc_free (v_ann);
! var->base.ann = NULL;
! }
! else
! {
! v_ann->mpt = NULL_TREE;
! v_ann->symbol_mem_tag = NULL_TREE;
! }
! }
gcc_assert (DECL_P (var));
in.uid = uid;
loc = htab_find_slot_with_hash (gimple_referenced_vars (cfun), &in, uid,
Index: gcc/tree-ssa.c
===================================================================
*** gcc/tree-ssa.c.orig 2008-05-22 21:53:47.000000000 +0200
--- gcc/tree-ssa.c 2008-05-22 22:41:24.000000000 +0200
*************** uid_decl_map_hash (const void *item)
*** 904,927 ****
return ((const_tree)item)->decl_minimal.uid;
}
- /* Return true if the uid in both int tree maps are equal. */
-
- static int
- var_ann_eq (const void *va, const void *vb)
- {
- const struct static_var_ann_d *a = (const struct static_var_ann_d *) va;
- const_tree const b = (const_tree) vb;
- return (a->uid == DECL_UID (b));
- }
-
- /* Hash a UID in a int_tree_map. */
-
- static unsigned int
- var_ann_hash (const void *item)
- {
- return ((const struct static_var_ann_d *)item)->uid;
- }
-
/* Return true if the DECL_UID in both trees are equal. */
static int
--- 904,909 ----
*************** init_tree_ssa (struct function *fn)
*** 951,958 ****
uid_decl_map_eq, NULL);
fn->gimple_df->default_defs = htab_create_ggc (20, uid_ssaname_map_hash,
uid_ssaname_map_eq, NULL);
- fn->gimple_df->var_anns = htab_create_ggc (20, var_ann_hash,
- var_ann_eq, NULL);
fn->gimple_df->call_clobbered_vars = BITMAP_GGC_ALLOC ();
fn->gimple_df->addressable_vars = BITMAP_GGC_ALLOC ();
init_ssanames (fn, 0);
--- 933,938 ----
*************** delete_tree_ssa (void)
*** 998,1006 ****
set_phi_nodes (bb, NULL);
}
! /* Remove annotations from every referenced variable. */
FOR_EACH_REFERENCED_VAR (var, rvi)
{
if (var->base.ann)
ggc_free (var->base.ann);
var->base.ann = NULL;
--- 978,993 ----
set_phi_nodes (bb, NULL);
}
! /* Remove annotations from every referenced local variable. */
FOR_EACH_REFERENCED_VAR (var, rvi)
{
+ if (!MTAG_P (var)
+ && (TREE_STATIC (var) || DECL_EXTERNAL (var)))
+ {
+ var_ann (var)->mpt = NULL_TREE;
+ var_ann (var)->symbol_mem_tag = NULL_TREE;
+ continue;
+ }
if (var->base.ann)
ggc_free (var->base.ann);
var->base.ann = NULL;
*************** delete_tree_ssa (void)
*** 1018,1025 ****
htab_delete (cfun->gimple_df->default_defs);
cfun->gimple_df->default_defs = NULL;
- htab_delete (cfun->gimple_df->var_anns);
- cfun->gimple_df->var_anns = NULL;
cfun->gimple_df->call_clobbered_vars = NULL;
cfun->gimple_df->addressable_vars = NULL;
cfun->gimple_df->modified_noreturn_calls = NULL;
--- 1005,1010 ----
Index: gcc/tree-flow.h
===================================================================
*** gcc/tree-flow.h.orig 2008-05-22 21:54:23.000000000 +0200
--- gcc/tree-flow.h 2008-05-22 21:55:22.000000000 +0200
*************** struct gimple_df GTY(())
*** 188,197 ****
struct ssa_operands ssa_operands;
- /* Hashtable of variables annotations. Used for static variables only;
- local variables have direct pointer in the tree node. */
- htab_t GTY((param_is (struct static_var_ann_d))) var_anns;
-
/* Memory reference statistics collected during alias analysis.
This information is used to drive the memory partitioning
heuristics in compute_memory_partitions. */
--- 188,193 ----