r->ref ? get_alias_set (r->ref) : 0);
if (r->every_access)
{
- fprintf (out, " Every access\n");
+ fprintf (out, " Every access\n");
continue;
}
size_t k;
void
modref_summary::dump (FILE *out)
{
- if (loads)
- {
- fprintf (out, " loads:\n");
- dump_records (loads, out);
- }
- if (stores)
- {
- fprintf (out, " stores:\n");
- dump_records (stores, out);
- }
+ fprintf (out, " loads:\n");
+ dump_records (loads, out);
+ fprintf (out, " stores:\n");
+ dump_records (stores, out);
}
/* Dump summary. */
void
modref_summary_lto::dump (FILE *out)
{
- if (loads)
- {
- fprintf (out, " loads:\n");
- dump_lto_records (loads, out);
- }
- if (stores)
- {
- fprintf (out, " stores:\n");
- dump_lto_records (stores, out);
- }
+ fprintf (out, " loads:\n");
+ dump_lto_records (loads, out);
+ fprintf (out, " stores:\n");
+ dump_lto_records (stores, out);
}
/* Get function summary for FUNC if it exists, return NULL otherwise. */
bool
merge_call_side_effects (modref_summary *cur_summary,
gimple *stmt, modref_summary *callee_summary,
- bool ignore_stores)
+ bool ignore_stores, cgraph_node *callee_node)
{
auto_vec <modref_parm_map, 32> parm_map;
bool changed = false;
+ if (dump_file)
+ fprintf (dump_file, " - Merging side effects of %s with parm map:",
+ callee_node->dump_name ());
+
parm_map.safe_grow_cleared (gimple_call_num_args (stmt));
for (unsigned i = 0; i < gimple_call_num_args (stmt); i++)
{
tree op = gimple_call_arg (stmt, i);
- STRIP_NOPS (op);
if (TREE_CODE (op) == SSA_NAME
&& SSA_NAME_IS_DEFAULT_DEF (op)
&& TREE_CODE (SSA_NAME_VAR (op)) == PARM_DECL)
parm_map[i].parm_index = -2;
else
parm_map[i].parm_index = -1;
+ if (dump_file)
+ fprintf (dump_file, " %i", parm_map[i].parm_index);
}
+ if (dump_file)
+ fprintf (dump_file, "\n");
/* Merge with callee's summary. */
- if (cur_summary->loads)
- changed |= cur_summary->loads->merge (callee_summary->loads, &parm_map);
+ changed |= cur_summary->loads->merge (callee_summary->loads, &parm_map);
if (!ignore_stores)
- {
- if (cur_summary->stores)
- changed |= cur_summary->stores->merge (callee_summary->stores,
- &parm_map);
- }
+ changed |= cur_summary->stores->merge (callee_summary->stores,
+ &parm_map);
return changed;
}
{
if (ignore_stores)
{
- if (cur_summary->loads)
- cur_summary->loads->collapse ();
+ cur_summary->loads->collapse ();
return true;
}
if (dump_file)
return false;
}
- merge_call_side_effects (cur_summary, stmt, callee_summary, ignore_stores);
+ merge_call_side_effects (cur_summary, stmt, callee_summary, ignore_stores,
+ callee_node);
return true;
}
else /* Remove existing summary if we are re-running the pass. */
{
if (dump_file
- && optimization_summaries->get (cgraph_node::get (f->decl)))
+ && (summary
+ = optimization_summaries->get (cgraph_node::get (f->decl)))
+ != NULL
+ && summary->loads)
{
fprintf (dump_file, "Past summary:\n");
optimization_summaries->get
(summary, recursive_calls[i], summary,
ignore_stores_p (current_function_decl,
gimple_call_flags
- (recursive_calls[i])));
+ (recursive_calls[i])),
+ fnode);
if (!summary->useful_p (ecf_flags))
{
remove_summary (lto, nolto, ipa);
void
modref_summaries::insert (struct cgraph_node *node, modref_summary *)
{
- if (!DECL_STRUCT_FUNCTION (node->decl))
+ /* Local passes ought to be executed by the pass manager. */
+ if (this == optimization_summaries)
{
optimization_summaries->remove (node);
+ return;
+ }
+ if (!DECL_STRUCT_FUNCTION (node->decl))
+ {
summaries->remove (node);
+ return;
}
push_cfun (DECL_STRUCT_FUNCTION (node->decl));
- /* This is not very pretty: We do not know if we insert into optimization
- summary or summary. Do both but check for duplicated effort. */
- if (optimization_summaries && !optimization_summaries->get (node)->loads)
- analyze_function (DECL_STRUCT_FUNCTION (node->decl), false);
- if (summaries && !summaries->get (node)->loads)
- analyze_function (DECL_STRUCT_FUNCTION (node->decl), true);
+ analyze_function (DECL_STRUCT_FUNCTION (node->decl), true);
pop_cfun ();
}
/* Called when new clone is inserted to callgraph late. */
void
-modref_summaries::duplicate (cgraph_node *, cgraph_node *,
+modref_summaries::duplicate (cgraph_node *, cgraph_node *dst,
modref_summary *src_data,
modref_summary *dst_data)
{
- if (src_data->stores)
+ /* Do not duplicte optimization summaries; we do not handle parameter
+ transforms on them. */
+ if (this == optimization_summaries)
{
- dst_data->stores = modref_records::create_ggc
- (src_data->stores->max_bases,
- src_data->stores->max_refs,
- src_data->stores->max_accesses);
- dst_data->stores->copy_from (src_data->stores);
- }
- if (src_data->loads)
- {
- dst_data->loads = modref_records::create_ggc
- (src_data->loads->max_bases,
- src_data->loads->max_refs,
- src_data->loads->max_accesses);
- dst_data->loads->copy_from (src_data->loads);
+ optimization_summaries->remove (dst);
+ return;
}
+ dst_data->stores = modref_records::create_ggc
+ (src_data->stores->max_bases,
+ src_data->stores->max_refs,
+ src_data->stores->max_accesses);
+ dst_data->stores->copy_from (src_data->stores);
+ dst_data->loads = modref_records::create_ggc
+ (src_data->loads->max_bases,
+ src_data->loads->max_refs,
+ src_data->loads->max_accesses);
+ dst_data->loads->copy_from (src_data->loads);
}
/* Called when new clone is inserted to callgraph late. */
modref_summary_lto *src_data,
modref_summary_lto *dst_data)
{
- if (src_data->stores)
- {
- dst_data->stores = modref_records_lto::create_ggc
- (src_data->stores->max_bases,
- src_data->stores->max_refs,
- src_data->stores->max_accesses);
- dst_data->stores->copy_from (src_data->stores);
- }
- if (src_data->loads)
- {
- dst_data->loads = modref_records_lto::create_ggc
- (src_data->loads->max_bases,
- src_data->loads->max_refs,
- src_data->loads->max_accesses);
- dst_data->loads->copy_from (src_data->loads);
- }
+ dst_data->stores = modref_records_lto::create_ggc
+ (src_data->stores->max_bases,
+ src_data->stores->max_refs,
+ src_data->stores->max_accesses);
+ dst_data->stores->copy_from (src_data->stores);
+ dst_data->loads = modref_records_lto::create_ggc
+ (src_data->loads->max_bases,
+ src_data->loads->max_refs,
+ src_data->loads->max_accesses);
+ dst_data->loads->copy_from (src_data->loads);
}
namespace
modref_access_node *access_node;
FOR_EACH_VEC_SAFE_ELT (ref_node->accesses, k, access_node)
{
- streamer_write_uhwi (ob, access_node->parm_index);
+ streamer_write_hwi (ob, access_node->parm_index);
if (access_node->parm_index != -1)
{
streamer_write_uhwi (ob, access_node->parm_offset_known);
for (size_t k = 0; k < naccesses; k++)
{
- int parm_index = streamer_read_uhwi (ib);
+ int parm_index = streamer_read_hwi (ib);
bool parm_offset_known = false;
poly_int64 parm_offset = 0;
poly_int64 offset = 0;
streamer_write_uhwi (ob, lto_symtab_encoder_encode (encoder, cnode));
- streamer_write_uhwi (ob, r->loads ? 1 : 0);
- streamer_write_uhwi (ob, r->stores ? 1 : 0);
- if (r->loads)
- write_modref_records (r->loads, ob);
- if (r->stores)
- write_modref_records (r->stores, ob);
+ write_modref_records (r->loads, ob);
+ write_modref_records (r->stores, ob);
}
}
streamer_write_char_stream (ob->main_stream, 0);
modref_summary_lto *modref_sum_lto = summaries_lto
? summaries_lto->get_create (node)
: NULL;
- int have_loads = streamer_read_uhwi (&ib);
- int have_stores = streamer_read_uhwi (&ib);
if (optimization_summaries)
modref_sum = optimization_summaries->get_create (node);
&& !modref_sum->stores));
gcc_assert (!modref_sum_lto || (!modref_sum_lto->loads
&& !modref_sum_lto->stores));
- if (have_loads)
- read_modref_records (&ib, data_in,
- modref_sum ? &modref_sum->loads : NULL,
- modref_sum_lto ? &modref_sum_lto->loads : NULL);
- if (have_stores)
- read_modref_records (&ib, data_in,
- modref_sum ? &modref_sum->stores : NULL,
- modref_sum_lto ? &modref_sum_lto->stores : NULL);
+ read_modref_records (&ib, data_in,
+ modref_sum ? &modref_sum->loads : NULL,
+ modref_sum_lto ? &modref_sum_lto->loads : NULL);
+ read_modref_records (&ib, data_in,
+ modref_sum ? &modref_sum->stores : NULL,
+ modref_sum_lto ? &modref_sum_lto->stores : NULL);
if (dump_file)
{
fprintf (dump_file, "Read modref for %s\n",
unsigned int pass_modref::execute (function *f)
{
- /* If new function is being added during IPA, we can skip analysis. */
- if (!optimization_summaries)
- return 0;
analyze_function (f, false);
return 0;
}
(&avail, e->caller);
return (avail <= AVAIL_INTERPOSABLE
- || ((!summaries || !summaries->get (callee))
+ || ((!optimization_summaries || !optimization_summaries->get (callee))
&& (!summaries_lto || !summaries_lto->get (callee)))
|| flags_from_decl_or_type (e->callee->decl)
& (ECF_CONST | ECF_NOVOPS));
if (jf && jf->type == IPA_JF_PASS_THROUGH)
{
(*parm_map)[i].parm_index
- = ipa_get_jf_pass_through_formal_id (jf);
+ = ipa_get_jf_pass_through_formal_id (jf);
(*parm_map)[i].parm_offset_known
= ipa_get_jf_pass_through_operation (jf) == NOP_EXPR;
(*parm_map)[i].parm_offset = 0;
optimization_summaries->remove (node);
if (summaries_lto)
summaries_lto->remove (node);
+ cur_summary = NULL;
+ cur_summary_lto = NULL;
changed = true;
break;
}
/* Merge in callee's information. */
if (callee_summary)
{
- if (callee_summary->loads)
- changed |= cur_summary->loads->merge
- (callee_summary->loads, &parm_map);
- if (callee_summary->stores)
+ changed |= cur_summary->loads->merge
+ (callee_summary->loads, &parm_map);
+ if (!ignore_stores)
changed |= cur_summary->stores->merge
(callee_summary->stores, &parm_map);
}
if (callee_summary_lto)
{
- if (callee_summary_lto->loads)
- changed |= cur_summary_lto->loads->merge
- (callee_summary_lto->loads, &parm_map);
- if (callee_summary_lto->stores)
+ changed |= cur_summary_lto->loads->merge
+ (callee_summary_lto->loads, &parm_map);
+ if (!ignore_stores)
changed |= cur_summary_lto->stores->merge
(callee_summary_lto->stores, &parm_map);
}