Commit f3380641 by Jan Hubicka Committed by Jan Hubicka

ipa-reference.c: Include toplev.h

	* ipa-reference.c: Include toplev.h
	(is_proper_for_analysis): Only add to all_module_statics
	if it is allocated.
	(write_node_summary_p, stream_out_bitmap,
	ipa_reference_write_optimization_summary,
	ipa_reference_read_optimization_summary): New.
	(struct ipa_opt_pass_d pass_ipa_reference): Add
	optimization summary streaming.
	* lto-cgraph.c (referenced_from_this_partition_p, 
	reachable_from_this_partition_p): New functions.
	* tree-ssa-alias.c (ref_maybe_used_by_call_p_1,
	call_may_clobber_ref_p_1): Ask ipa-reference even for public vars.
	* opts.c (decode_options): Enable ipa_reference.
	* Makefile.in (ipa-reference.o): Add toplev.h dependency.
	* lto-streamer.h (referenced_from_this_partition_p,
	reachable_from_this_partition_p): Declare.

	* gcc.dg/lto/ipareference_1.c: New file.
	* gcc.dg/lto/ipareference_2.c: New file.

From-SVN: r159435
parent 9d0baae1
2010-05-15 Jan Hubicka <jh@suse.cz>
* ipa-reference.c: Include toplev.h
(is_proper_for_analysis): Only add to all_module_statics
if it is allocated.
(write_node_summary_p, stream_out_bitmap,
ipa_reference_write_optimization_summary,
ipa_reference_read_optimization_summary): New.
(struct ipa_opt_pass_d pass_ipa_reference): Add
optimization summary streaming.
* lto-cgraph.c (referenced_from_this_partition_p,
reachable_from_this_partition_p): New functions.
* tree-ssa-alias.c (ref_maybe_used_by_call_p_1,
call_may_clobber_ref_p_1): Ask ipa-reference even for public vars.
* opts.c (decode_options): Enable ipa_reference.
* Makefile.in (ipa-reference.o): Add toplev.h dependency.
* lto-streamer.h (referenced_from_this_partition_p,
reachable_from_this_partition_p): Declare.
2010-05-15 Richard Guenther <rguenther@suse.de> 2010-05-15 Richard Guenther <rguenther@suse.de>
PR tree-optimization/44038 PR tree-optimization/44038
......
...@@ -2929,7 +2929,7 @@ ipa-reference.o : ipa-reference.c $(CONFIG_H) $(SYSTEM_H) \ ...@@ -2929,7 +2929,7 @@ ipa-reference.o : ipa-reference.c $(CONFIG_H) $(SYSTEM_H) \
coretypes.h $(TM_H) $(TREE_H) $(TREE_FLOW_H) $(TREE_INLINE_H) langhooks.h \ coretypes.h $(TM_H) $(TREE_H) $(TREE_FLOW_H) $(TREE_INLINE_H) langhooks.h \
pointer-set.h $(GGC_H) $(IPA_REFERENCE_H) $(IPA_UTILS_H) $(SPLAY_TREE_H) \ pointer-set.h $(GGC_H) $(IPA_REFERENCE_H) $(IPA_UTILS_H) $(SPLAY_TREE_H) \
$(GIMPLE_H) $(CGRAPH_H) output.h $(FLAGS_H) $(TREE_PASS_H) \ $(GIMPLE_H) $(CGRAPH_H) output.h $(FLAGS_H) $(TREE_PASS_H) \
$(TIMEVAR_H) $(DIAGNOSTIC_H) $(FUNCTION_H) $(LTO_STREAMER_H) $(TIMEVAR_H) $(DIAGNOSTIC_H) $(FUNCTION_H) $(LTO_STREAMER_H) $(TOPLEV_H)
ipa-pure-const.o : ipa-pure-const.c $(CONFIG_H) $(SYSTEM_H) \ ipa-pure-const.o : ipa-pure-const.c $(CONFIG_H) $(SYSTEM_H) \
coretypes.h $(TM_H) $(TREE_H) $(TREE_FLOW_H) $(TREE_INLINE_H) langhooks.h \ coretypes.h $(TM_H) $(TREE_H) $(TREE_FLOW_H) $(TREE_INLINE_H) langhooks.h \
pointer-set.h $(GGC_H) $(IPA_UTILS_H) $(TARGET_H) \ pointer-set.h $(GGC_H) $(IPA_UTILS_H) $(TARGET_H) \
......
...@@ -59,6 +59,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -59,6 +59,7 @@ along with GCC; see the file COPYING3. If not see
#include "diagnostic.h" #include "diagnostic.h"
#include "langhooks.h" #include "langhooks.h"
#include "lto-streamer.h" #include "lto-streamer.h"
#include "toplev.h"
static void remove_node_data (struct cgraph_node *node, static void remove_node_data (struct cgraph_node *node,
void *data ATTRIBUTE_UNUSED); void *data ATTRIBUTE_UNUSED);
...@@ -272,7 +273,8 @@ is_proper_for_analysis (tree t) ...@@ -272,7 +273,8 @@ is_proper_for_analysis (tree t)
/* This is a variable we care about. Check if we have seen it /* This is a variable we care about. Check if we have seen it
before, and if not add it the set of variables we care about. */ before, and if not add it the set of variables we care about. */
if (!bitmap_bit_p (all_module_statics, DECL_UID (t))) if (all_module_statics
&& !bitmap_bit_p (all_module_statics, DECL_UID (t)))
add_static_var (t); add_static_var (t);
return true; return true;
...@@ -884,6 +886,208 @@ propagate (void) ...@@ -884,6 +886,208 @@ propagate (void)
return 0; return 0;
} }
/* Return true if we need to write summary of NODE. */
static bool
write_node_summary_p (struct cgraph_node *node,
cgraph_node_set set,
varpool_node_set vset,
bitmap ltrans_statics)
{
ipa_reference_optimization_summary_t info;
/* See if we have (non-empty) info. */
if (!node->analyzed || node->global.inlined_to)
return false;
info = get_reference_optimization_summary (node);
if (!info || (bitmap_empty_p (info->statics_not_read)
&& bitmap_empty_p (info->statics_not_written)))
return false;
/* See if we want to encode it.
Encode also referenced functions since constant folding might turn it into
a direct call.
In future we might also want to include summaries of functions references
by initializers of constant variables references in current unit. */
if (!reachable_from_this_partition_p (node, set)
&& !referenced_from_this_partition_p (&node->ref_list, set, vset))
return false;
/* See if the info has non-empty intersections with vars we want to encode. */
if (!bitmap_intersect_p (info->statics_not_read, ltrans_statics)
&& !bitmap_intersect_p (info->statics_not_written, ltrans_statics))
return false;
return true;
}
/* Stream out BITS&LTRANS_STATICS as list of decls to OB. */
static void
stream_out_bitmap (struct lto_simple_output_block *ob,
bitmap bits, bitmap ltrans_statics)
{
unsigned int count = 0;
unsigned int index;
bitmap_iterator bi;
EXECUTE_IF_AND_IN_BITMAP (bits, ltrans_statics, 0, index, bi)
count ++;
lto_output_uleb128_stream (ob->main_stream, count);
if (!count)
return;
EXECUTE_IF_AND_IN_BITMAP (bits, ltrans_statics, 0, index, bi)
{
tree decl = (tree)splay_tree_lookup (reference_vars_to_consider, index)->value;
lto_output_var_decl_index(ob->decl_state, ob->main_stream, decl);
}
}
/* Serialize the ipa info for lto. */
static void
ipa_reference_write_optimization_summary (cgraph_node_set set,
varpool_node_set vset)
{
struct cgraph_node *node;
struct varpool_node *vnode;
struct lto_simple_output_block *ob
= lto_create_simple_output_block (LTO_section_ipa_reference);
unsigned int count = 0;
lto_cgraph_encoder_t encoder = ob->decl_state->cgraph_node_encoder;
bitmap ltrans_statics = BITMAP_ALLOC (NULL);
reference_vars_to_consider = splay_tree_new (splay_tree_compare_ints, 0, 0);
/* See what variables we are interested in. */
for (vnode = varpool_nodes; vnode; vnode = vnode->next)
if (referenced_from_this_partition_p (&vnode->ref_list, set, vset))
{
tree decl = vnode->decl;
if (is_proper_for_analysis (decl))
{
bitmap_set_bit (ltrans_statics, DECL_UID (decl));
splay_tree_insert (reference_vars_to_consider,
DECL_UID (decl), (splay_tree_value)decl);
}
}
for (node = cgraph_nodes; node; node = node->next)
if (write_node_summary_p (node, set, vset, ltrans_statics))
count++;
lto_output_uleb128_stream (ob->main_stream, count);
/* Process all of the functions. */
for (node = cgraph_nodes; node; node = node->next)
if (write_node_summary_p (node, set, vset, ltrans_statics))
{
ipa_reference_optimization_summary_t info;
int node_ref;
info = get_reference_optimization_summary (node);
node_ref = lto_cgraph_encoder_encode (encoder, node);
lto_output_uleb128_stream (ob->main_stream, node_ref);
stream_out_bitmap (ob, info->statics_not_read, ltrans_statics);
stream_out_bitmap (ob, info->statics_not_written, ltrans_statics);
}
BITMAP_FREE (ltrans_statics);
lto_destroy_simple_output_block (ob);
splay_tree_delete (reference_vars_to_consider);
}
/* Deserialize the ipa info for lto. */
static void
ipa_reference_read_optimization_summary (void)
{
struct lto_file_decl_data ** file_data_vec
= lto_get_file_decl_data ();
struct lto_file_decl_data * file_data;
unsigned int j = 0;
bitmap_obstack_initialize (&optimization_summary_obstack);
node_removal_hook_holder =
cgraph_add_node_removal_hook (&remove_node_data, NULL);
node_duplication_hook_holder =
cgraph_add_node_duplication_hook (&duplicate_node_data, NULL);
while ((file_data = file_data_vec[j++]))
{
const char *data;
size_t len;
struct lto_input_block *ib
= lto_create_simple_input_block (file_data,
LTO_section_ipa_reference,
&data, &len);
if (ib)
{
unsigned int i;
unsigned int f_count = lto_input_uleb128 (ib);
for (i = 0; i < f_count; i++)
{
unsigned int j, index;
struct cgraph_node *node;
ipa_reference_optimization_summary_t info;
int v_count;
lto_cgraph_encoder_t encoder;
index = lto_input_uleb128 (ib);
encoder = file_data->cgraph_node_encoder;
node = lto_cgraph_encoder_deref (encoder, index);
info = XCNEW (struct ipa_reference_optimization_summary_d);
set_reference_optimization_summary (node, info);
info->statics_not_read = BITMAP_ALLOC (&optimization_summary_obstack);
info->statics_not_written = BITMAP_ALLOC (&optimization_summary_obstack);
if (dump_file)
fprintf (dump_file,
"\nFunction name:%s/%i:\n static not read:",
cgraph_node_name (node), node->uid);
/* Set the statics not read. */
v_count = lto_input_uleb128 (ib);
for (j = 0; j < (unsigned int)v_count; j++)
{
unsigned int var_index = lto_input_uleb128 (ib);
tree v_decl = lto_file_decl_data_get_var_decl (file_data,
var_index);
bitmap_set_bit (info->statics_not_read, DECL_UID (v_decl));
if (dump_file)
fprintf (dump_file, " %s",
lang_hooks.decl_printable_name (v_decl, 2));
}
if (dump_file)
fprintf (dump_file,
"\n static not written:");
/* Set the statics not written. */
v_count = lto_input_uleb128 (ib);
for (j = 0; j < (unsigned int)v_count; j++)
{
unsigned int var_index = lto_input_uleb128 (ib);
tree v_decl = lto_file_decl_data_get_var_decl (file_data,
var_index);
bitmap_set_bit (info->statics_not_written, DECL_UID (v_decl));
if (dump_file)
fprintf (dump_file, " %s",
lang_hooks.decl_printable_name (v_decl, 2));
}
if (dump_file)
fprintf (dump_file, "\n");
}
lto_destroy_simple_input_block (file_data,
LTO_section_ipa_reference,
ib, data, len);
}
else
/* Fatal error here. We do not want to support compiling ltrans units with
different version of compiler or different flags than the WPA unit, so
this should never happen. */
fatal_error ("ipa reference summary is missing in ltrans unit");
}
}
static bool static bool
gate_reference (void) gate_reference (void)
...@@ -913,8 +1117,8 @@ struct ipa_opt_pass_d pass_ipa_reference = ...@@ -913,8 +1117,8 @@ struct ipa_opt_pass_d pass_ipa_reference =
NULL, /* generate_summary */ NULL, /* generate_summary */
NULL, /* write_summary */ NULL, /* write_summary */
NULL, /* read_summary */ NULL, /* read_summary */
NULL, /* write_optimization_summary */ ipa_reference_write_optimization_summary,/* write_optimization_summary */
NULL, /* read_optimization_summary */ ipa_reference_read_optimization_summary,/* read_optimization_summary */
NULL, /* stmt_fixup */ NULL, /* stmt_fixup */
0, /* TODOs */ 0, /* TODOs */
NULL, /* function_transform */ NULL, /* function_transform */
......
...@@ -302,6 +302,7 @@ lto_output_edge (struct lto_simple_output_block *ob, struct cgraph_edge *edge, ...@@ -302,6 +302,7 @@ lto_output_edge (struct lto_simple_output_block *ob, struct cgraph_edge *edge,
} }
/* Return if LIST contain references from other partitions. */ /* Return if LIST contain references from other partitions. */
bool bool
referenced_from_other_partition_p (struct ipa_ref_list *list, cgraph_node_set set, referenced_from_other_partition_p (struct ipa_ref_list *list, cgraph_node_set set,
varpool_node_set vset) varpool_node_set vset)
...@@ -341,6 +342,47 @@ reachable_from_other_partition_p (struct cgraph_node *node, cgraph_node_set set) ...@@ -341,6 +342,47 @@ reachable_from_other_partition_p (struct cgraph_node *node, cgraph_node_set set)
return false; return false;
} }
/* Return if LIST contain references from other partitions. */
bool
referenced_from_this_partition_p (struct ipa_ref_list *list, cgraph_node_set set,
varpool_node_set vset)
{
int i;
struct ipa_ref *ref;
for (i = 0; ipa_ref_list_refering_iterate (list, i, ref); i++)
{
if (ref->refering_type == IPA_REF_CGRAPH)
{
if (cgraph_node_in_set_p (ipa_ref_refering_node (ref), set))
return true;
}
else
{
if (varpool_node_in_set_p (ipa_ref_refering_varpool_node (ref),
vset))
return true;
}
}
return false;
}
/* Return true when node is reachable from other partition. */
bool
reachable_from_this_partition_p (struct cgraph_node *node, cgraph_node_set set)
{
struct cgraph_edge *e;
if (!node->analyzed)
return false;
if (node->global.inlined_to)
return false;
for (e = node->callers; e; e = e->next_caller)
if (cgraph_node_in_set_p (e->caller, set))
return true;
return false;
}
/* Output the cgraph NODE to OB. ENCODER is used to find the /* Output the cgraph NODE to OB. ENCODER is used to find the
reference number of NODE->inlined_to. SET is the set of nodes we reference number of NODE->inlined_to. SET is the set of nodes we
are writing to the current file. If NODE is not in SET, then NODE are writing to the current file. If NODE is not in SET, then NODE
...@@ -694,38 +736,22 @@ output_refs (cgraph_node_set set, varpool_node_set vset, ...@@ -694,38 +736,22 @@ output_refs (cgraph_node_set set, varpool_node_set vset,
lto_destroy_simple_output_block (ob); lto_destroy_simple_output_block (ob);
} }
/* Find out all cgraph and varpool nodes we want to encode in current unit
/* Output the part of the cgraph in SET. */ and insert them to encoders. */
void void
output_cgraph (cgraph_node_set set, varpool_node_set vset) compute_ltrans_boundary (struct lto_out_decl_state *state,
cgraph_node_set set, varpool_node_set vset)
{ {
struct cgraph_node *node; struct cgraph_node *node;
struct lto_simple_output_block *ob;
cgraph_node_set_iterator csi; cgraph_node_set_iterator csi;
varpool_node_set_iterator vsi; varpool_node_set_iterator vsi;
struct cgraph_edge *edge; struct cgraph_edge *edge;
int i, n_nodes; int i;
bitmap written_decls;
lto_cgraph_encoder_t encoder; lto_cgraph_encoder_t encoder;
lto_varpool_encoder_t varpool_encoder; lto_varpool_encoder_t varpool_encoder;
struct cgraph_asm_node *can;
ob = lto_create_simple_output_block (LTO_section_cgraph); encoder = state->cgraph_node_encoder = lto_cgraph_encoder_new ();
varpool_encoder = state->varpool_node_encoder = lto_varpool_encoder_new ();
output_profile_summary (ob);
/* An encoder for cgraph nodes should have been created by
ipa_write_summaries_1. */
gcc_assert (ob->decl_state->cgraph_node_encoder);
gcc_assert (ob->decl_state->varpool_node_encoder);
encoder = ob->decl_state->cgraph_node_encoder;
varpool_encoder = ob->decl_state->varpool_node_encoder;
/* The FUNCTION_DECLs for which we have written a node. The first
node found is written as the "original" node, the remaining nodes
are considered its clones. */
written_decls = lto_bitmap_alloc ();
/* Go over all the nodes in SET and assign references. */ /* Go over all the nodes in SET and assign references. */
for (csi = csi_start (set); !csi_end_p (csi); csi_next (&csi)) for (csi = csi_start (set); !csi_end_p (csi); csi_next (&csi))
...@@ -775,6 +801,37 @@ output_cgraph (cgraph_node_set set, varpool_node_set vset) ...@@ -775,6 +801,37 @@ output_cgraph (cgraph_node_set set, varpool_node_set vset)
} }
} }
} }
}
/* Output the part of the cgraph in SET. */
void
output_cgraph (cgraph_node_set set, varpool_node_set vset)
{
struct cgraph_node *node;
struct lto_simple_output_block *ob;
cgraph_node_set_iterator csi;
int i, n_nodes;
bitmap written_decls;
lto_cgraph_encoder_t encoder;
lto_varpool_encoder_t varpool_encoder;
struct cgraph_asm_node *can;
ob = lto_create_simple_output_block (LTO_section_cgraph);
output_profile_summary (ob);
/* An encoder for cgraph nodes should have been created by
ipa_write_summaries_1. */
gcc_assert (ob->decl_state->cgraph_node_encoder);
gcc_assert (ob->decl_state->varpool_node_encoder);
encoder = ob->decl_state->cgraph_node_encoder;
varpool_encoder = ob->decl_state->varpool_node_encoder;
/* The FUNCTION_DECLs for which we have written a node. The first
node found is written as the "original" node, the remaining nodes
are considered its clones. */
written_decls = lto_bitmap_alloc ();
/* Write out the nodes. We must first output a node and then its clones, /* Write out the nodes. We must first output a node and then its clones,
otherwise at a time reading back the node there would be nothing to clone otherwise at a time reading back the node there would be nothing to clone
......
...@@ -865,6 +865,13 @@ bool referenced_from_other_partition_p (struct ipa_ref_list *, ...@@ -865,6 +865,13 @@ bool referenced_from_other_partition_p (struct ipa_ref_list *,
varpool_node_set vset); varpool_node_set vset);
bool reachable_from_other_partition_p (struct cgraph_node *, bool reachable_from_other_partition_p (struct cgraph_node *,
cgraph_node_set); cgraph_node_set);
bool referenced_from_this_partition_p (struct ipa_ref_list *,
cgraph_node_set,
varpool_node_set vset);
bool reachable_from_this_partition_p (struct cgraph_node *,
cgraph_node_set);
void compute_ltrans_boundary (struct lto_out_decl_state *state,
cgraph_node_set, varpool_node_set);
/* In lto-symtab.c. */ /* In lto-symtab.c. */
......
...@@ -1143,7 +1143,6 @@ decode_options (unsigned int argc, const char **argv) ...@@ -1143,7 +1143,6 @@ decode_options (unsigned int argc, const char **argv)
{ {
/* These passes are not WHOPR compatible yet. */ /* These passes are not WHOPR compatible yet. */
flag_ipa_cp = 0; flag_ipa_cp = 0;
flag_ipa_reference = 0;
flag_ipa_type_escape = 0; flag_ipa_type_escape = 0;
flag_ipa_pta = 0; flag_ipa_pta = 0;
flag_ipa_struct_reorg = 0; flag_ipa_struct_reorg = 0;
......
...@@ -1695,8 +1695,7 @@ static void ...@@ -1695,8 +1695,7 @@ static void
ipa_write_summaries_1 (cgraph_node_set set, varpool_node_set vset) ipa_write_summaries_1 (cgraph_node_set set, varpool_node_set vset)
{ {
struct lto_out_decl_state *state = lto_new_out_decl_state (); struct lto_out_decl_state *state = lto_new_out_decl_state ();
state->cgraph_node_encoder = lto_cgraph_encoder_new (); compute_ltrans_boundary (state, set, vset);
state->varpool_node_encoder = lto_varpool_encoder_new ();
lto_push_out_decl_state (state); lto_push_out_decl_state (state);
...@@ -1809,8 +1808,8 @@ void ...@@ -1809,8 +1808,8 @@ void
ipa_write_optimization_summaries (cgraph_node_set set, varpool_node_set vset) ipa_write_optimization_summaries (cgraph_node_set set, varpool_node_set vset)
{ {
struct lto_out_decl_state *state = lto_new_out_decl_state (); struct lto_out_decl_state *state = lto_new_out_decl_state ();
state->cgraph_node_encoder = lto_cgraph_encoder_new (); compute_ltrans_boundary (state, set, vset);
state->varpool_node_encoder = lto_varpool_encoder_new ();
lto_push_out_decl_state (state); lto_push_out_decl_state (state);
gcc_assert (flag_wpa); gcc_assert (flag_wpa);
......
2010-05-15 Jan Hubicka <jh@suse.cz>
* gcc.dg/lto/ipareference_1.c: New file.
* gcc.dg/lto/ipareference_2.c: New file.
2010-05-15 Richard Guenther <rguenther@suse.de> 2010-05-15 Richard Guenther <rguenther@suse.de>
PR tree-optimization/44038 PR tree-optimization/44038
......
/* { dg-lto-options {{ -O1 -fwhopr }} } */
/* { dg-lto-do run } */
/* Test that ipa-reference notice that get_val will not change since do_nothing does not
modify anything. This needs streaming cross file boundary summaries. */
extern int get_val (void);
extern int set_val (void);
extern do_nothing (void);
void abort (void);
main()
{
int a;
int b;
set_val ();
a = get_val ();
do_nothing();
b = get_val ();
if (a==b)
{
if (!,__builtin_constant_p (a==b))
abort ();
return 0;
}
else
abort ();
}
static int val;
int set_val (void)
{
val = 5;
}
int get_val (void)
{
return val;
}
__attribute__ ((__noinline__))
do_nothing ()
{
asm volatile ("":::"memory");
}
...@@ -1061,8 +1061,7 @@ ref_maybe_used_by_call_p_1 (gimple call, ao_ref *ref) ...@@ -1061,8 +1061,7 @@ ref_maybe_used_by_call_p_1 (gimple call, ao_ref *ref)
/* Check if base is a global static variable that is not read /* Check if base is a global static variable that is not read
by the function. */ by the function. */
if (TREE_CODE (base) == VAR_DECL if (TREE_CODE (base) == VAR_DECL
&& TREE_STATIC (base) && TREE_STATIC (base))
&& !TREE_PUBLIC (base))
{ {
bitmap not_read; bitmap not_read;
...@@ -1316,8 +1315,7 @@ call_may_clobber_ref_p_1 (gimple call, ao_ref *ref) ...@@ -1316,8 +1315,7 @@ call_may_clobber_ref_p_1 (gimple call, ao_ref *ref)
by the function. */ by the function. */
if (callee != NULL_TREE if (callee != NULL_TREE
&& TREE_CODE (base) == VAR_DECL && TREE_CODE (base) == VAR_DECL
&& TREE_STATIC (base) && TREE_STATIC (base))
&& !TREE_PUBLIC (base))
{ {
bitmap not_written; bitmap not_written;
......
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