/* Interprocedural scalar replacement of aggregates
- Copyright (C) 2008-2022 Free Software Foundation, Inc.
-
+ Copyright (C) 2019-2022 Free Software Foundation, Inc.
Contributed by Martin Jambor <mjambor@suse.cz>
This file is part of GCC.
/* IPA-SRA is an interprocedural pass that removes unused function return
values (turning functions returning a value which is never used into void
- functions), removes unused function parameters. It can also replace an
+ functions) and removes unused function parameters. It can also replace an
aggregate parameter by a set of other parameters representing part of the
original, turning those passed by reference into new ones which pass the
value directly.
ipa-param-manipulation.h for more details. */
-
#include "config.h"
#include "system.h"
#include "coretypes.h"
#define ISRA_ARG_SIZE_LIMIT_BITS 16
#define ISRA_ARG_SIZE_LIMIT (1 << ISRA_ARG_SIZE_LIMIT_BITS)
/* How many parameters can feed into a call actual argument and still be
- tracked. */
+ tracked. */
#define IPA_SRA_MAX_PARAM_FLOW_LEN 7
/* Structure describing accesses to a specific portion of an aggregate
transformed function - initially not set for portions of formal parameters
that are only used as actual function arguments passed to callees. */
unsigned certain : 1;
- /* Set if the access has a reversed scalar storage order. */
+ /* Set if the access has reverse scalar storage order. */
unsigned reverse : 1;
};
arguments to a function call that can be tracked. */
bool nonarg;
- /* Set if the access has a reversed scalar storage order. */
+ /* Set if the access has reverse scalar storage order. */
bool reverse;
};
};
/* Properly deallocate accesses of DESC. TODO: Since this data structure is
- not in GC memory, this is not necessary and we can consider removing the
- function. */
+ allocated in GC memory, this is not necessary and we can consider removing
+ the function. */
static void
free_param_decl_accesses (isra_param_desc *desc)
unsigned m_queued : 1;
};
-/* Clean up and deallocate isra_func_summary points to. TODO: Since this data
- structure is not in GC memory, this is not necessary and we can consider
- removing the destructor. */
+/* Deallocate the memory pointed to by isra_func_summary. TODO: Since this
+ data structure is allocated in GC memory, this is not necessary and we can
+ consider removing the destructor. */
isra_func_summary::~isra_func_summary ()
{
vec_free (m_parameters);
}
-
/* Mark the function as not a candidate for any IPA-SRA transformation. Return
true if it was a candidate until now. */
bool ret = m_candidate;
m_candidate = false;
+ /* TODO: see the destructor above. */
unsigned len = vec_safe_length (m_parameters);
for (unsigned i = 0; i < len; ++i)
free_param_decl_accesses (&(*m_parameters)[i]);
}
/* Structure to describe which formal parameters feed into a particular actual
- arguments. */
+ argument. */
struct isra_param_flow
{
to->unit_offset = from->unit_offset;
to->unit_size = from->unit_size;
to->certain = from->certain;
+ to->reverse = from->reverse;
d->accesses->quick_push (to);
}
}
hash_map<tree, gensum_param_desc *> *decl2desc;
-/* Countdown of allowed Alias analysis steps during summary building. */
+/* Countdown of allowed Alias Analysis steps during summary building. */
int aa_walking_limit;
if (access->certain)
fprintf (f, ", certain");
else
- fprintf (f, ", not-certain");
+ fprintf (f, ", not certain");
if (access->reverse)
fprintf (f, ", reverse");
fprintf (f, "\n");
This function is similar to ptr_parm_has_nonarg_uses but its results are
meant for unused parameter removal, as opposed to splitting of parameters
- passed by reference or converting them to passed by value.
- */
+ passed by reference or converting them to passed by value. */
static bool
isra_track_scalar_param_local_uses (function *fun, cgraph_node *node, tree parm,
This function is similar to isra_track_scalar_param_local_uses but its
results are meant for splitting of parameters passed by reference or turning
them into bits passed by value, as opposed to generic unused parameter
- removal.
- */
+ removal. */
static bool
ptr_parm_has_nonarg_uses (cgraph_node *node, function *fun, tree parm,
}
/* Callback of walk_aliased_vdefs, just mark that there was a possible
- modification. */
+ modification. */
static bool
mark_maybe_modified (ao_ref *, tree, void *data)
check_gensum_access (tree parm, gensum_param_desc *desc,
gensum_param_access *access,
HOST_WIDE_INT *nonarg_acc_size, bool *only_calls,
- int entry_bb_index)
+ int entry_bb_index)
{
if (access->nonarg)
{
offset in this function at IPA level.
TODO: Measure the overhead and the effect of just being pessimistic.
- Maybe this is only -O3 material?
- */
+ Maybe this is only -O3 material? */
+
bool pdoms_calculated = false;
if (check_pass_throughs)
for (cgraph_edge *cs = node->callees; cs; cs = cs->next_callee)
streamer_write_uhwi (ob, acc->unit_size);
bitpack_d bp = bitpack_create (ob->main_stream);
bp_pack_value (&bp, acc->certain, 1);
+ bp_pack_value (&bp, acc->reverse, 1);
streamer_write_bitpack (&bp);
}
streamer_write_uhwi (ob, desc->param_size_limit);
acc->unit_size = streamer_read_uhwi (ib);
bitpack_d bp = streamer_read_bitpack (ib);
acc->certain = bp_unpack_value (&bp, 1);
+ acc->reverse = bp_unpack_value (&bp, 1);
vec_safe_push (desc->accesses, acc);
}
desc->param_size_limit = streamer_read_uhwi (ib);
/* Propagate information that any parameter is not used only locally within a
SCC across CS to the caller, which must be in the same SCC as the
- callee. Push any callers that need to be re-processed to STACK. */
+ callee. Push any callers that need to be re-processed to STACK. */
static void
propagate_used_across_scc_edge (cgraph_edge *cs, vec<cgraph_node *> *stack)
/* Propagate information that any parameter is not used only locally within a
SCC (i.e. is used also elsewhere) to all callers of NODE that are in the
- same SCC. Push any callers that need to be re-processed to STACK. */
+ same SCC. Push any callers that need to be re-processed to STACK. */
static bool
propagate_used_to_scc_callers (cgraph_node *node, void *data)
&& pacc->unit_size == argacc->unit_size)
{
if (argacc->alias_ptr_type != pacc->alias_ptr_type
- || !types_compatible_p (argacc->type, pacc->type))
+ || !types_compatible_p (argacc->type, pacc->type)
+ || argacc->reverse != pacc->reverse)
return "propagated access types would not match existing ones";
exact_match = true;
copy->type = argacc->type;
copy->alias_ptr_type = argacc->alias_ptr_type;
copy->certain = true;
+ copy->reverse = argacc->reverse;
vec_safe_push (param_desc->accesses, copy);
}
else if (prop_kinds[j] == ACC_PROP_CERTAIN)
PREV_ADJUSTMENT. If the parent clone is the original function,
PREV_ADJUSTMENT is NULL and PREV_CLONE_INDEX is equal to BASE_INDEX. */
-
static void
push_param_adjustments_for_index (isra_func_summary *ifs, unsigned base_index,
unsigned prev_clone_index,