else if (prob != REG_BR_PROB_BASE)
fprintf (f, "%*s op%i change %f%% of time\n", indent + 2, "", i,
prob * 100.0 / REG_BR_PROB_BASE);
+ if (es->param[i].points_to_local_or_readonly_memory)
+ fprintf (f, "%*s op%i points to local or readonly memory\n",
+ indent + 2, "", i);
}
if (!edge->inline_failed)
{
int prob = param_change_prob (&fbi, stmt, i);
gcc_assert (prob >= 0 && prob <= REG_BR_PROB_BASE);
es->param[i].change_prob = prob;
+ es->param[i].points_to_local_or_readonly_memory
+ = points_to_local_or_readonly_memory_p
+ (gimple_call_arg (stmt, i));
}
}
ipa_call_summaries->get (e)->loop_depth += depth;
}
-/* Update change_prob of EDGE after INLINED_EDGE has been inlined.
+/* Update change_prob and points_to_local_or_readonly_memory of EDGE after
+ INLINED_EDGE has been inlined.
+
When function A is inlined in B and A calls C with parameter that
changes with probability PROB1 and C is known to be passthrough
of argument if B that change with probability PROB2, the probability
of change is now PROB1*PROB2. */
static void
-remap_edge_change_prob (struct cgraph_edge *inlined_edge,
- struct cgraph_edge *edge)
+remap_edge_params (struct cgraph_edge *inlined_edge,
+ struct cgraph_edge *edge)
{
if (ipa_node_params_sum)
{
prob = 1;
es->param[i].change_prob = prob;
+
+ if (inlined_es
+ ->param[id].points_to_local_or_readonly_memory)
+ es->param[i].points_to_local_or_readonly_memory = true;
}
+ if (!es->param[i].points_to_local_or_readonly_memory
+ && jfunc->type == IPA_JF_CONST
+ && points_to_local_or_readonly_memory_p
+ (ipa_get_jf_constant (jfunc)))
+ es->param[i].points_to_local_or_readonly_memory = true;
}
}
}
if (e->inline_failed)
{
class ipa_call_summary *es = ipa_call_summaries->get (e);
- remap_edge_change_prob (inlined_edge, e);
+ remap_edge_params (inlined_edge, e);
if (es->predicate)
{
predicate p;
next = e->next_callee;
- remap_edge_change_prob (inlined_edge, e);
+ remap_edge_params (inlined_edge, e);
if (es->predicate)
{
p = es->predicate->remap_after_inlining
{
es->param.safe_grow_cleared (length, true);
for (i = 0; i < length; i++)
- es->param[i].change_prob = streamer_read_uhwi (ib);
+ {
+ es->param[i].change_prob = streamer_read_uhwi (ib);
+ es->param[i].points_to_local_or_readonly_memory
+ = streamer_read_uhwi (ib);
+ }
}
else
{
for (i = 0; i < length; i++)
- streamer_read_uhwi (ib);
+ {
+ streamer_read_uhwi (ib);
+ streamer_read_uhwi (ib);
+ }
}
}
streamer_write_uhwi (ob, 0);
streamer_write_uhwi (ob, es->param.length ());
for (i = 0; i < (int) es->param.length (); i++)
- streamer_write_uhwi (ob, es->param[i].change_prob);
+ {
+ streamer_write_uhwi (ob, es->param[i].change_prob);
+ streamer_write_uhwi (ob, es->param[i].points_to_local_or_readonly_memory);
+ }
}
parameters REG_BR_PROB_BASE.
Value 0 is reserved for compile time invariants. */
- int change_prob;
+ short change_prob;
+ unsigned points_to_local_or_readonly_memory : 1;
bool equal_to (const inline_param_summary &other) const
{
- return change_prob == other.change_prob;
+ return change_prob == other.change_prob
+ && points_to_local_or_readonly_memory
+ == other.points_to_local_or_readonly_memory;
}
bool useless_p (void) const
{
- return change_prob == REG_BR_PROB_BASE;
+ return change_prob == REG_BR_PROB_BASE
+ && !points_to_local_or_readonly_memory;
}
};