Commit 66576e1b by Jan Hubicka Committed by Jan Hubicka

ipareference2_0.c: New file.

	* gcc.dg/lto/ipareference2_0.c: New file.
	* gcc.dg/lto/ipareference2_1.c: New file.
	* lto.c (promote_var, promote_fn): New functions.
	(lto_promote_cross_file_statics): Compute correctly boundary including
	static initializers of readonly vars.

From-SVN: r159604
parent 676dd4d4
2010-05-20 Jan Hubicka <jh@suse.cz>
* lto.c (promote_var, promote_fn): New functions.
(lto_promote_cross_file_statics): Compute correctly boundary including
static initializers of readonly vars.
2010-05-18 Jan Hubicka <jh@suse.cz> 2010-05-18 Jan Hubicka <jh@suse.cz>
* lto/lto.c (lto_1_to_1_map): Partition non-inline clones. * lto.c (lto_1_to_1_map): Partition non-inline clones.
(lto_promote_cross_file_statics): Deal with non-inline clones. (lto_promote_cross_file_statics): Deal with non-inline clones.
2010-05-18 Jan Hubicka <jh@suse.cz> 2010-05-18 Jan Hubicka <jh@suse.cz>
......
...@@ -691,6 +691,42 @@ lto_add_all_inlinees (cgraph_node_set set) ...@@ -691,6 +691,42 @@ lto_add_all_inlinees (cgraph_node_set set)
lto_bitmap_free (original_decls); lto_bitmap_free (original_decls);
} }
/* Promote variable VNODE to be static. */
static bool
promote_var (struct varpool_node *vnode)
{
if (TREE_PUBLIC (vnode->decl) || DECL_EXTERNAL (vnode->decl))
return false;
gcc_assert (flag_wpa);
TREE_PUBLIC (vnode->decl) = 1;
DECL_VISIBILITY (vnode->decl) = VISIBILITY_HIDDEN;
return true;
}
/* Promote function NODE to be static. */
static bool
promote_fn (struct cgraph_node *node)
{
gcc_assert (flag_wpa);
if (TREE_PUBLIC (node->decl) || DECL_EXTERNAL (node->decl))
return false;
TREE_PUBLIC (node->decl) = 1;
DECL_VISIBILITY (node->decl) = VISIBILITY_HIDDEN;
if (node->same_body)
{
struct cgraph_node *alias;
for (alias = node->same_body;
alias; alias = alias->next)
{
TREE_PUBLIC (alias->decl) = 1;
DECL_VISIBILITY (alias->decl) = VISIBILITY_HIDDEN;
}
}
return true;
}
/* Find out all static decls that need to be promoted to global because /* Find out all static decls that need to be promoted to global because
of cross file sharing. This function must be run in the WPA mode after of cross file sharing. This function must be run in the WPA mode after
all inlinees are added. */ all inlinees are added. */
...@@ -704,6 +740,8 @@ lto_promote_cross_file_statics (void) ...@@ -704,6 +740,8 @@ lto_promote_cross_file_statics (void)
varpool_node_set vset; varpool_node_set vset;
cgraph_node_set_iterator csi; cgraph_node_set_iterator csi;
varpool_node_set_iterator vsi; varpool_node_set_iterator vsi;
VEC(varpool_node_ptr, heap) *promoted_initializers = NULL;
struct pointer_set_t *inserted = pointer_set_create ();
gcc_assert (flag_wpa); gcc_assert (flag_wpa);
...@@ -725,21 +763,7 @@ lto_promote_cross_file_statics (void) ...@@ -725,21 +763,7 @@ lto_promote_cross_file_statics (void)
if (!DECL_EXTERNAL (node->decl) if (!DECL_EXTERNAL (node->decl)
&& (referenced_from_other_partition_p (&node->ref_list, set, vset) && (referenced_from_other_partition_p (&node->ref_list, set, vset)
|| reachable_from_other_partition_p (node, set))) || reachable_from_other_partition_p (node, set)))
{ promote_fn (node);
gcc_assert (flag_wpa);
TREE_PUBLIC (node->decl) = 1;
DECL_VISIBILITY (node->decl) = VISIBILITY_HIDDEN;
if (node->same_body)
{
struct cgraph_node *alias;
for (alias = node->same_body;
alias; alias = alias->next)
{
TREE_PUBLIC (alias->decl) = 1;
DECL_VISIBILITY (alias->decl) = VISIBILITY_HIDDEN;
}
}
}
} }
for (vsi = vsi_start (vset); !vsi_end_p (vsi); vsi_next (&vsi)) for (vsi = vsi_start (vset); !vsi_end_p (vsi); vsi_next (&vsi))
{ {
...@@ -749,15 +773,72 @@ lto_promote_cross_file_statics (void) ...@@ -749,15 +773,72 @@ lto_promote_cross_file_statics (void)
allow better optimization. */ allow better optimization. */
if (!DECL_IN_CONSTANT_POOL (vnode->decl) if (!DECL_IN_CONSTANT_POOL (vnode->decl)
&& !vnode->externally_visible && vnode->analyzed && !vnode->externally_visible && vnode->analyzed
&& referenced_from_other_partition_p (&vnode->ref_list, set, vset)) && referenced_from_other_partition_p (&vnode->ref_list,
set, vset))
promote_var (vnode);
}
/* We export initializers of read-only var into each partition
referencing it. Folding might take declarations from the
initializers and use it; so everything referenced from the
initializers needs can be accessed from this partition after
folding.
This means that we need to promote all variables and functions
referenced from all initializers from readonly vars referenced
from this partition that are not in this partition.
This needs to be done recursively. */
for (vnode = varpool_nodes; vnode; vnode = vnode->next)
if ((TREE_READONLY (vnode->decl) || DECL_IN_CONSTANT_POOL (vnode->decl))
&& DECL_INITIAL (vnode->decl)
&& !varpool_node_in_set_p (vnode, vset)
&& referenced_from_this_partition_p (&vnode->ref_list, set, vset)
&& !pointer_set_insert (inserted, vnode))
VEC_safe_push (varpool_node_ptr, heap, promoted_initializers, vnode);
while (!VEC_empty (varpool_node_ptr, promoted_initializers))
{ {
gcc_assert (flag_wpa); int i;
TREE_PUBLIC (vnode->decl) = 1; struct ipa_ref *ref;
DECL_VISIBILITY (vnode->decl) = VISIBILITY_HIDDEN;
vnode = VEC_pop (varpool_node_ptr, promoted_initializers);
for (i = 0; ipa_ref_list_reference_iterate (&vnode->ref_list, i, ref); i++)
{
if (ref->refered_type == IPA_REF_CGRAPH)
{
struct cgraph_node *n = ipa_ref_node (ref);
gcc_assert (!n->global.inlined_to);
if (!n->local.externally_visible
&& !cgraph_node_in_set_p (n, set))
promote_fn (n);
}
else
{
struct varpool_node *v = ipa_ref_varpool_node (ref);
if (varpool_node_in_set_p (v, vset))
continue;
/* Constant pool references use internal labels and thus can not
be made global. It is sensible to keep those ltrans local to
allow better optimization. */
if (DECL_IN_CONSTANT_POOL (v->decl))
{
if (!pointer_set_insert (inserted, vnode))
VEC_safe_push (varpool_node_ptr, heap,
promoted_initializers, v);
}
else if (!DECL_IN_CONSTANT_POOL (v->decl)
&& !v->externally_visible && v->analyzed)
{
if (promote_var (v)
&& DECL_INITIAL (v->decl) && TREE_READONLY (v->decl)
&& !pointer_set_insert (inserted, vnode))
VEC_safe_push (varpool_node_ptr, heap,
promoted_initializers, v);
}
}
} }
} }
} }
pointer_set_destroy (inserted);
} }
......
2010-05-19 Jan Hubicka <jh@suse.cz>
* gcc.dg/lto/ipareference2_0.c: New file.
* gcc.dg/lto/ipareference2_1.c: New file.
2010-05-19 Jason Merrill <jason@redhat.com> 2010-05-19 Jason Merrill <jason@redhat.com>
* g++.dg/parse/fn-typedef2.C: New. * g++.dg/parse/fn-typedef2.C: New.
......
/* { dg-lto-options {{ -O1 -fwhopr -fwhole-program}} } */
/* { dg-lto-do run } */
/* Verify that ipa-reference marks A as constant and we fold references
to a[1] and a[2] to &c and that we promote C to hidden vars shared across ltrans units. */
void abort (void);
int b,c,d,e,f;
int *a[5]={&b,&c,&c,&e};
void other_ltrans (void);
main()
{
other_ltrans ();
if (*(a[1])!=11)
abort ();
return 0;
}
void abort (void);
extern int *a[5];
extern int b,c,d,e,f;
__attribute__ ((noinline, noclone))
void
other_ltrans (void)
{
if (!__builtin_constant_p (a[1]==a[2]))
abort ();
if (a[1]!=a[2])
abort ();
*(a[1])=11;
}
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