/* Attempt to propagate all definite accesses from ARG_DESC to PARAM_DESC,
(which belongs to CALLER) if they would not violate some constraint there.
- If successful, return NULL, otherwise return the string reason for failure
- (which can be written to the dump file). DELTA_OFFSET is the known offset
- of the actual argument withing the formal parameter (so of ARG_DESCS within
- PARAM_DESCS), ARG_SIZE is the size of the actual argument or zero, if not
- known. In case of success, set *CHANGE_P to true if propagation actually
- changed anything. */
+ CALLER_IPCP_TS describes the caller, PARAM_IDX is the index of the parameter
+ described by PARAM_DESC. If successful, return NULL, otherwise return the
+ string reason for failure (which can be written to the dump file).
+ DELTA_OFFSET is the known offset of the actual argument withing the formal
+ parameter (so of ARG_DESCS within PARAM_DESCS), ARG_SIZE is the size of the
+ actual argument or zero, if not known. In case of success, set *CHANGE_P to
+ true if propagation actually changed anything. */
static const char *
-pull_accesses_from_callee (cgraph_node *caller, isra_param_desc *param_desc,
+pull_accesses_from_callee (cgraph_node *caller,
+ ipcp_transformation *caller_ipcp_ts,
+ int param_idx,
+ isra_param_desc *param_desc,
isra_param_desc *arg_desc,
unsigned delta_offset, unsigned arg_size,
bool *change_p)
continue;
unsigned offset = argacc->unit_offset + delta_offset;
+
+ if (caller_ipcp_ts && !AGGREGATE_TYPE_P (argacc->type))
+ {
+ ipa_argagg_value_list avl (caller_ipcp_ts);
+ tree value = avl.get_value (param_idx, offset);
+ if (value && ((tree_to_uhwi (TYPE_SIZE (TREE_TYPE (value)))
+ / BITS_PER_UNIT)
+ != argacc->unit_size))
+ return " propagated access would conflict with an IPA-CP constant";
+ }
+
/* Given that accesses are initially stored according to increasing
offset and decreasing size in case of equal offsets, the following
searches could be written more efficiently if we kept the ordering
cgraph_node *callee = cs->callee->function_symbol (&availability);
isra_func_summary *from_ifs = func_sums->get (cs->caller);
gcc_checking_assert (from_ifs && from_ifs->m_parameters);
+ ipcp_transformation *caller_ipcp_ts
+ = ipcp_get_transformation_summary (cs->caller);
isra_call_summary *csum = call_sums->get (cs);
gcc_checking_assert (csum);
else
{
const char *pull_failure
- = pull_accesses_from_callee (cs->caller, param_desc, arg_desc,
- 0, 0, &res);
+ = pull_accesses_from_callee (cs->caller, caller_ipcp_ts, idx,
+ param_desc, arg_desc, 0, 0, &res);
if (pull_failure)
{
if (dump_file && (dump_flags & TDF_DETAILS))
else
{
const char *pull_failure
- = pull_accesses_from_callee (cs->caller, param_desc, arg_desc,
+ = pull_accesses_from_callee (cs->caller, caller_ipcp_ts, idx,
+ param_desc, arg_desc,
ipf->unit_offset,
ipf->unit_size, &res);
if (pull_failure)