ipa.c (symtab_remove_unreachable_nodes): Fix up comment typos.
* ipa.c (symtab_remove_unreachable_nodes): Fix up comment typos. * ipa-prop.c (get_vector_of_formal_parm_types): Renamed to ... (ipa_get_vector_of_formal_parm_types): ... this. No longer static. (ipa_modify_formal_parameters): Adjust caller. Remove synth_parm_prefix argument. Use operator enum instead of bit fields. Add assert for properly handling vector of references. Handle creating brand new parameters. (ipa_modify_call_arguments): Use operator enum instead of bit fields. (ipa_combine_adjustments): Same. Assert that IPA_PARM_OP_NEW is not used. (ipa_modify_expr, get_ssa_base_param, ipa_get_adjustment_candidate): New functions. (ipa_dump_param_adjustments): Rename reduction to new_decl. Use operator enum instead of bit fields. * ipa-prop.h (enum ipa_parm_op): New. (struct ipa_parm_adjustment): New field op. Rename reduction to new_decl, new_arg_prefix to arg_prefix and remove remove_param and copy_param. (ipa_modify_formal_parameters): Remove last argument. (ipa_get_vector_of_formal_parm_types, ipa_modify_expr, ipa_get_adjustment_candidate): New prototypes. * tree-sra.c (turn_representatives_into_adjustments): Use operator enum. Set arg_prefix. (get_adjustment_for_base): Use operator enum. (sra_ipa_modify_expr): Rename to ipa_modify_expr and move to ipa-prop.c. (sra_ipa_modify_assign): Rename sra_ipa_modify_expr to ipa_modify_expr. (ipa_sra_modify_function_body): Same. No longer static. (sra_ipa_reset_debug_stmts): Use operator enum. (modify_function): Do not pass prefix argument. Co-Authored-By: Jakub Jelinek <jakub@redhat.com> From-SVN: r205284
This commit is contained in:
parent
0a508bb66b
commit
31519c3863
|
@ -1,3 +1,39 @@
|
|||
2013-11-22 Aldy Hernandez <aldyh@redhat.com>
|
||||
Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* ipa.c (symtab_remove_unreachable_nodes): Fix up comment typos.
|
||||
* ipa-prop.c (get_vector_of_formal_parm_types): Renamed to ...
|
||||
(ipa_get_vector_of_formal_parm_types): ... this. No longer static.
|
||||
(ipa_modify_formal_parameters): Adjust caller. Remove
|
||||
synth_parm_prefix argument. Use operator enum instead of bit fields.
|
||||
Add assert for properly handling vector of references. Handle
|
||||
creating brand new parameters.
|
||||
(ipa_modify_call_arguments): Use operator enum instead of bit
|
||||
fields.
|
||||
(ipa_combine_adjustments): Same. Assert that IPA_PARM_OP_NEW is not
|
||||
used.
|
||||
(ipa_modify_expr, get_ssa_base_param, ipa_get_adjustment_candidate):
|
||||
New functions.
|
||||
(ipa_dump_param_adjustments): Rename reduction to new_decl.
|
||||
Use operator enum instead of bit fields.
|
||||
* ipa-prop.h (enum ipa_parm_op): New.
|
||||
(struct ipa_parm_adjustment): New field op. Rename reduction
|
||||
to new_decl, new_arg_prefix to arg_prefix and remove remove_param
|
||||
and copy_param.
|
||||
(ipa_modify_formal_parameters): Remove last argument.
|
||||
(ipa_get_vector_of_formal_parm_types, ipa_modify_expr,
|
||||
ipa_get_adjustment_candidate): New prototypes.
|
||||
* tree-sra.c (turn_representatives_into_adjustments): Use operator
|
||||
enum. Set arg_prefix.
|
||||
(get_adjustment_for_base): Use operator enum.
|
||||
(sra_ipa_modify_expr): Rename to ipa_modify_expr and move to
|
||||
ipa-prop.c.
|
||||
(sra_ipa_modify_assign): Rename sra_ipa_modify_expr to
|
||||
ipa_modify_expr.
|
||||
(ipa_sra_modify_function_body): Same. No longer static.
|
||||
(sra_ipa_reset_debug_stmts): Use operator enum.
|
||||
(modify_function): Do not pass prefix argument.
|
||||
|
||||
2013-11-22 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* ubsan.c (ubsan_source_location): Don't crash on
|
||||
|
|
226
gcc/ipa-prop.c
226
gcc/ipa-prop.c
|
@ -3361,8 +3361,8 @@ ipa_get_vector_of_formal_parms (tree fndecl)
|
|||
/* Return a heap allocated vector containing types of formal parameters of
|
||||
function type FNTYPE. */
|
||||
|
||||
static inline vec<tree>
|
||||
get_vector_of_formal_parm_types (tree fntype)
|
||||
vec<tree>
|
||||
ipa_get_vector_of_formal_parm_types (tree fntype)
|
||||
{
|
||||
vec<tree> types;
|
||||
int count = 0;
|
||||
|
@ -3384,32 +3384,22 @@ get_vector_of_formal_parm_types (tree fntype)
|
|||
base_index field. */
|
||||
|
||||
void
|
||||
ipa_modify_formal_parameters (tree fndecl, ipa_parm_adjustment_vec adjustments,
|
||||
const char *synth_parm_prefix)
|
||||
ipa_modify_formal_parameters (tree fndecl, ipa_parm_adjustment_vec adjustments)
|
||||
{
|
||||
vec<tree> oparms, otypes;
|
||||
tree orig_type, new_type = NULL;
|
||||
tree old_arg_types, t, new_arg_types = NULL;
|
||||
tree parm, *link = &DECL_ARGUMENTS (fndecl);
|
||||
int i, len = adjustments.length ();
|
||||
tree new_reversed = NULL;
|
||||
bool care_for_types, last_parm_void;
|
||||
|
||||
if (!synth_parm_prefix)
|
||||
synth_parm_prefix = "SYNTH";
|
||||
|
||||
oparms = ipa_get_vector_of_formal_parms (fndecl);
|
||||
orig_type = TREE_TYPE (fndecl);
|
||||
old_arg_types = TYPE_ARG_TYPES (orig_type);
|
||||
vec<tree> oparms = ipa_get_vector_of_formal_parms (fndecl);
|
||||
tree orig_type = TREE_TYPE (fndecl);
|
||||
tree old_arg_types = TYPE_ARG_TYPES (orig_type);
|
||||
|
||||
/* The following test is an ugly hack, some functions simply don't have any
|
||||
arguments in their type. This is probably a bug but well... */
|
||||
care_for_types = (old_arg_types != NULL_TREE);
|
||||
bool care_for_types = (old_arg_types != NULL_TREE);
|
||||
bool last_parm_void;
|
||||
vec<tree> otypes;
|
||||
if (care_for_types)
|
||||
{
|
||||
last_parm_void = (TREE_VALUE (tree_last (old_arg_types))
|
||||
== void_type_node);
|
||||
otypes = get_vector_of_formal_parm_types (orig_type);
|
||||
otypes = ipa_get_vector_of_formal_parm_types (orig_type);
|
||||
if (last_parm_void)
|
||||
gcc_assert (oparms.length () + 1 == otypes.length ());
|
||||
else
|
||||
|
@ -3421,16 +3411,23 @@ ipa_modify_formal_parameters (tree fndecl, ipa_parm_adjustment_vec adjustments,
|
|||
otypes.create (0);
|
||||
}
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
int len = adjustments.length ();
|
||||
tree *link = &DECL_ARGUMENTS (fndecl);
|
||||
tree new_arg_types = NULL;
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
struct ipa_parm_adjustment *adj;
|
||||
gcc_assert (link);
|
||||
|
||||
adj = &adjustments[i];
|
||||
parm = oparms[adj->base_index];
|
||||
tree parm;
|
||||
if (adj->op == IPA_PARM_OP_NEW)
|
||||
parm = NULL;
|
||||
else
|
||||
parm = oparms[adj->base_index];
|
||||
adj->base = parm;
|
||||
|
||||
if (adj->copy_param)
|
||||
if (adj->op == IPA_PARM_OP_COPY)
|
||||
{
|
||||
if (care_for_types)
|
||||
new_arg_types = tree_cons (NULL_TREE, otypes[adj->base_index],
|
||||
|
@ -3438,7 +3435,7 @@ ipa_modify_formal_parameters (tree fndecl, ipa_parm_adjustment_vec adjustments,
|
|||
*link = parm;
|
||||
link = &DECL_CHAIN (parm);
|
||||
}
|
||||
else if (!adj->remove_param)
|
||||
else if (adj->op != IPA_PARM_OP_REMOVE)
|
||||
{
|
||||
tree new_parm;
|
||||
tree ptype;
|
||||
|
@ -3453,8 +3450,8 @@ ipa_modify_formal_parameters (tree fndecl, ipa_parm_adjustment_vec adjustments,
|
|||
|
||||
new_parm = build_decl (UNKNOWN_LOCATION, PARM_DECL, NULL_TREE,
|
||||
ptype);
|
||||
DECL_NAME (new_parm) = create_tmp_var_name (synth_parm_prefix);
|
||||
|
||||
const char *prefix = adj->arg_prefix ? adj->arg_prefix : "SYNTH";
|
||||
DECL_NAME (new_parm) = create_tmp_var_name (prefix);
|
||||
DECL_ARTIFICIAL (new_parm) = 1;
|
||||
DECL_ARG_TYPE (new_parm) = ptype;
|
||||
DECL_CONTEXT (new_parm) = fndecl;
|
||||
|
@ -3462,17 +3459,20 @@ ipa_modify_formal_parameters (tree fndecl, ipa_parm_adjustment_vec adjustments,
|
|||
DECL_IGNORED_P (new_parm) = 1;
|
||||
layout_decl (new_parm, 0);
|
||||
|
||||
adj->base = parm;
|
||||
adj->reduction = new_parm;
|
||||
if (adj->op == IPA_PARM_OP_NEW)
|
||||
adj->base = NULL;
|
||||
else
|
||||
adj->base = parm;
|
||||
adj->new_decl = new_parm;
|
||||
|
||||
*link = new_parm;
|
||||
|
||||
link = &DECL_CHAIN (new_parm);
|
||||
}
|
||||
}
|
||||
|
||||
*link = NULL_TREE;
|
||||
|
||||
tree new_reversed = NULL;
|
||||
if (care_for_types)
|
||||
{
|
||||
new_reversed = nreverse (new_arg_types);
|
||||
|
@ -3490,8 +3490,9 @@ ipa_modify_formal_parameters (tree fndecl, ipa_parm_adjustment_vec adjustments,
|
|||
Exception is METHOD_TYPEs must have THIS argument.
|
||||
When we are asked to remove it, we need to build new FUNCTION_TYPE
|
||||
instead. */
|
||||
tree new_type = NULL;
|
||||
if (TREE_CODE (orig_type) != METHOD_TYPE
|
||||
|| (adjustments[0].copy_param
|
||||
|| (adjustments[0].op == IPA_PARM_OP_COPY
|
||||
&& adjustments[0].base_index == 0))
|
||||
{
|
||||
new_type = build_distinct_type_copy (orig_type);
|
||||
|
@ -3515,7 +3516,7 @@ ipa_modify_formal_parameters (tree fndecl, ipa_parm_adjustment_vec adjustments,
|
|||
|
||||
/* This is a new type, not a copy of an old type. Need to reassociate
|
||||
variants. We can handle everything except the main variant lazily. */
|
||||
t = TYPE_MAIN_VARIANT (orig_type);
|
||||
tree t = TYPE_MAIN_VARIANT (orig_type);
|
||||
if (orig_type != t)
|
||||
{
|
||||
TYPE_MAIN_VARIANT (new_type) = t;
|
||||
|
@ -3564,13 +3565,13 @@ ipa_modify_call_arguments (struct cgraph_edge *cs, gimple stmt,
|
|||
|
||||
adj = &adjustments[i];
|
||||
|
||||
if (adj->copy_param)
|
||||
if (adj->op == IPA_PARM_OP_COPY)
|
||||
{
|
||||
tree arg = gimple_call_arg (stmt, adj->base_index);
|
||||
|
||||
vargs.quick_push (arg);
|
||||
}
|
||||
else if (!adj->remove_param)
|
||||
else if (adj->op != IPA_PARM_OP_REMOVE)
|
||||
{
|
||||
tree expr, base, off;
|
||||
location_t loc;
|
||||
|
@ -3689,7 +3690,7 @@ ipa_modify_call_arguments (struct cgraph_edge *cs, gimple stmt,
|
|||
NULL, true, GSI_SAME_STMT);
|
||||
vargs.quick_push (expr);
|
||||
}
|
||||
if (!adj->copy_param && MAY_HAVE_DEBUG_STMTS)
|
||||
if (adj->op != IPA_PARM_OP_COPY && MAY_HAVE_DEBUG_STMTS)
|
||||
{
|
||||
unsigned int ix;
|
||||
tree ddecl = NULL_TREE, origin = DECL_ORIGIN (adj->base), arg;
|
||||
|
@ -3764,6 +3765,124 @@ ipa_modify_call_arguments (struct cgraph_edge *cs, gimple stmt,
|
|||
free_dominance_info (CDI_DOMINATORS);
|
||||
}
|
||||
|
||||
/* If the expression *EXPR should be replaced by a reduction of a parameter, do
|
||||
so. ADJUSTMENTS is a pointer to a vector of adjustments. CONVERT
|
||||
specifies whether the function should care about type incompatibility the
|
||||
current and new expressions. If it is false, the function will leave
|
||||
incompatibility issues to the caller. Return true iff the expression
|
||||
was modified. */
|
||||
|
||||
bool
|
||||
ipa_modify_expr (tree *expr, bool convert,
|
||||
ipa_parm_adjustment_vec adjustments)
|
||||
{
|
||||
struct ipa_parm_adjustment *cand
|
||||
= ipa_get_adjustment_candidate (&expr, &convert, adjustments, false);
|
||||
if (!cand)
|
||||
return false;
|
||||
|
||||
tree src;
|
||||
if (cand->by_ref)
|
||||
src = build_simple_mem_ref (cand->new_decl);
|
||||
else
|
||||
src = cand->new_decl;
|
||||
|
||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||
{
|
||||
fprintf (dump_file, "About to replace expr ");
|
||||
print_generic_expr (dump_file, *expr, 0);
|
||||
fprintf (dump_file, " with ");
|
||||
print_generic_expr (dump_file, src, 0);
|
||||
fprintf (dump_file, "\n");
|
||||
}
|
||||
|
||||
if (convert && !useless_type_conversion_p (TREE_TYPE (*expr), cand->type))
|
||||
{
|
||||
tree vce = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (*expr), src);
|
||||
*expr = vce;
|
||||
}
|
||||
else
|
||||
*expr = src;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* If T is an SSA_NAME, return NULL if it is not a default def or
|
||||
return its base variable if it is. If IGNORE_DEFAULT_DEF is true,
|
||||
the base variable is always returned, regardless if it is a default
|
||||
def. Return T if it is not an SSA_NAME. */
|
||||
|
||||
static tree
|
||||
get_ssa_base_param (tree t, bool ignore_default_def)
|
||||
{
|
||||
if (TREE_CODE (t) == SSA_NAME)
|
||||
{
|
||||
if (ignore_default_def || SSA_NAME_IS_DEFAULT_DEF (t))
|
||||
return SSA_NAME_VAR (t);
|
||||
else
|
||||
return NULL_TREE;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
/* Given an expression, return an adjustment entry specifying the
|
||||
transformation to be done on EXPR. If no suitable adjustment entry
|
||||
was found, returns NULL.
|
||||
|
||||
If IGNORE_DEFAULT_DEF is set, consider SSA_NAMEs which are not a
|
||||
default def, otherwise bail on them.
|
||||
|
||||
If CONVERT is non-NULL, this function will set *CONVERT if the
|
||||
expression provided is a component reference. ADJUSTMENTS is the
|
||||
adjustments vector. */
|
||||
|
||||
ipa_parm_adjustment *
|
||||
ipa_get_adjustment_candidate (tree **expr, bool *convert,
|
||||
ipa_parm_adjustment_vec adjustments,
|
||||
bool ignore_default_def)
|
||||
{
|
||||
if (TREE_CODE (**expr) == BIT_FIELD_REF
|
||||
|| TREE_CODE (**expr) == IMAGPART_EXPR
|
||||
|| TREE_CODE (**expr) == REALPART_EXPR)
|
||||
{
|
||||
*expr = &TREE_OPERAND (**expr, 0);
|
||||
if (convert)
|
||||
*convert = true;
|
||||
}
|
||||
|
||||
HOST_WIDE_INT offset, size, max_size;
|
||||
tree base = get_ref_base_and_extent (**expr, &offset, &size, &max_size);
|
||||
if (!base || size == -1 || max_size == -1)
|
||||
return NULL;
|
||||
|
||||
if (TREE_CODE (base) == MEM_REF)
|
||||
{
|
||||
offset += mem_ref_offset (base).low * BITS_PER_UNIT;
|
||||
base = TREE_OPERAND (base, 0);
|
||||
}
|
||||
|
||||
base = get_ssa_base_param (base, ignore_default_def);
|
||||
if (!base || TREE_CODE (base) != PARM_DECL)
|
||||
return NULL;
|
||||
|
||||
struct ipa_parm_adjustment *cand = NULL;
|
||||
unsigned int len = adjustments.length ();
|
||||
for (unsigned i = 0; i < len; i++)
|
||||
{
|
||||
struct ipa_parm_adjustment *adj = &adjustments[i];
|
||||
|
||||
if (adj->base == base
|
||||
&& (adj->offset == offset || adj->op == IPA_PARM_OP_REMOVE))
|
||||
{
|
||||
cand = adj;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!cand || cand->op == IPA_PARM_OP_COPY || cand->op == IPA_PARM_OP_REMOVE)
|
||||
return NULL;
|
||||
return cand;
|
||||
}
|
||||
|
||||
/* Return true iff BASE_INDEX is in ADJUSTMENTS more than once. */
|
||||
|
||||
static bool
|
||||
|
@ -3809,10 +3928,14 @@ ipa_combine_adjustments (ipa_parm_adjustment_vec inner,
|
|||
struct ipa_parm_adjustment *n;
|
||||
n = &inner[i];
|
||||
|
||||
if (n->remove_param)
|
||||
if (n->op == IPA_PARM_OP_REMOVE)
|
||||
removals++;
|
||||
else
|
||||
tmp.quick_push (*n);
|
||||
{
|
||||
/* FIXME: Handling of new arguments are not implemented yet. */
|
||||
gcc_assert (n->op != IPA_PARM_OP_NEW);
|
||||
tmp.quick_push (*n);
|
||||
}
|
||||
}
|
||||
|
||||
adjustments.create (outlen + removals);
|
||||
|
@ -3823,27 +3946,32 @@ ipa_combine_adjustments (ipa_parm_adjustment_vec inner,
|
|||
struct ipa_parm_adjustment *in = &tmp[out->base_index];
|
||||
|
||||
memset (&r, 0, sizeof (r));
|
||||
gcc_assert (!in->remove_param);
|
||||
if (out->remove_param)
|
||||
gcc_assert (in->op != IPA_PARM_OP_REMOVE);
|
||||
if (out->op == IPA_PARM_OP_REMOVE)
|
||||
{
|
||||
if (!index_in_adjustments_multiple_times_p (in->base_index, tmp))
|
||||
{
|
||||
r.remove_param = true;
|
||||
r.op = IPA_PARM_OP_REMOVE;
|
||||
adjustments.quick_push (r);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* FIXME: Handling of new arguments are not implemented yet. */
|
||||
gcc_assert (out->op != IPA_PARM_OP_NEW);
|
||||
}
|
||||
|
||||
r.base_index = in->base_index;
|
||||
r.type = out->type;
|
||||
|
||||
/* FIXME: Create nonlocal value too. */
|
||||
|
||||
if (in->copy_param && out->copy_param)
|
||||
r.copy_param = true;
|
||||
else if (in->copy_param)
|
||||
if (in->op == IPA_PARM_OP_COPY && out->op == IPA_PARM_OP_COPY)
|
||||
r.op = IPA_PARM_OP_COPY;
|
||||
else if (in->op == IPA_PARM_OP_COPY)
|
||||
r.offset = out->offset;
|
||||
else if (out->copy_param)
|
||||
else if (out->op == IPA_PARM_OP_COPY)
|
||||
r.offset = in->offset;
|
||||
else
|
||||
r.offset = in->offset + out->offset;
|
||||
|
@ -3854,7 +3982,7 @@ ipa_combine_adjustments (ipa_parm_adjustment_vec inner,
|
|||
{
|
||||
struct ipa_parm_adjustment *n = &inner[i];
|
||||
|
||||
if (n->remove_param)
|
||||
if (n->op == IPA_PARM_OP_REMOVE)
|
||||
adjustments.quick_push (*n);
|
||||
}
|
||||
|
||||
|
@ -3891,10 +4019,10 @@ ipa_dump_param_adjustments (FILE *file, ipa_parm_adjustment_vec adjustments,
|
|||
fprintf (file, ", base: ");
|
||||
print_generic_expr (file, adj->base, 0);
|
||||
}
|
||||
if (adj->reduction)
|
||||
if (adj->new_decl)
|
||||
{
|
||||
fprintf (file, ", reduction: ");
|
||||
print_generic_expr (file, adj->reduction, 0);
|
||||
fprintf (file, ", new_decl: ");
|
||||
print_generic_expr (file, adj->new_decl, 0);
|
||||
}
|
||||
if (adj->new_ssa_base)
|
||||
{
|
||||
|
@ -3902,9 +4030,9 @@ ipa_dump_param_adjustments (FILE *file, ipa_parm_adjustment_vec adjustments,
|
|||
print_generic_expr (file, adj->new_ssa_base, 0);
|
||||
}
|
||||
|
||||
if (adj->copy_param)
|
||||
if (adj->op == IPA_PARM_OP_COPY)
|
||||
fprintf (file, ", copy_param");
|
||||
else if (adj->remove_param)
|
||||
else if (adj->op == IPA_PARM_OP_REMOVE)
|
||||
fprintf (file, ", remove_param");
|
||||
else
|
||||
fprintf (file, ", offset %li", (long) adj->offset);
|
||||
|
|
|
@ -609,6 +609,27 @@ extern alloc_pool ipcp_values_pool;
|
|||
extern alloc_pool ipcp_sources_pool;
|
||||
extern alloc_pool ipcp_agg_lattice_pool;
|
||||
|
||||
/* Operation to be performed for the parameter in ipa_parm_adjustment
|
||||
below. */
|
||||
enum ipa_parm_op {
|
||||
IPA_PARM_OP_NONE,
|
||||
|
||||
/* This describes a brand new parameter.
|
||||
|
||||
The field `type' should be set to the new type, `arg_prefix'
|
||||
should be set to the string prefix for the new DECL_NAME, and
|
||||
`new_decl' will ultimately hold the newly created argument. */
|
||||
IPA_PARM_OP_NEW,
|
||||
|
||||
/* This new parameter is an unmodified parameter at index base_index. */
|
||||
IPA_PARM_OP_COPY,
|
||||
|
||||
/* This adjustment describes a parameter that is about to be removed
|
||||
completely. Most users will probably need to book keep those so that they
|
||||
don't leave behinfd any non default def ssa names belonging to them. */
|
||||
IPA_PARM_OP_REMOVE
|
||||
};
|
||||
|
||||
/* Structure to describe transformations of formal parameters and actual
|
||||
arguments. Each instance describes one new parameter and they are meant to
|
||||
be stored in a vector. Additionally, most users will probably want to store
|
||||
|
@ -632,10 +653,11 @@ struct ipa_parm_adjustment
|
|||
arguments. */
|
||||
tree alias_ptr_type;
|
||||
|
||||
/* The new declaration when creating/replacing a parameter. Created by
|
||||
ipa_modify_formal_parameters, useful for functions modifying the body
|
||||
accordingly. */
|
||||
tree reduction;
|
||||
/* The new declaration when creating/replacing a parameter. Created
|
||||
by ipa_modify_formal_parameters, useful for functions modifying
|
||||
the body accordingly. For brand new arguments, this is the newly
|
||||
created argument. */
|
||||
tree new_decl;
|
||||
|
||||
/* New declaration of a substitute variable that we may use to replace all
|
||||
non-default-def ssa names when a parm decl is going away. */
|
||||
|
@ -645,22 +667,19 @@ struct ipa_parm_adjustment
|
|||
is NULL), this is going to be its nonlocalized vars value. */
|
||||
tree nonlocal_value;
|
||||
|
||||
/* This holds the prefix to be used for the new DECL_NAME. */
|
||||
const char *arg_prefix;
|
||||
|
||||
/* Offset into the original parameter (for the cases when the new parameter
|
||||
is a component of an original one). */
|
||||
HOST_WIDE_INT offset;
|
||||
|
||||
/* Zero based index of the original parameter this one is based on. (ATM
|
||||
there is no way to insert a new parameter out of the blue because there is
|
||||
no need but if it arises the code can be easily exteded to do so.) */
|
||||
/* Zero based index of the original parameter this one is based on. */
|
||||
int base_index;
|
||||
|
||||
/* This new parameter is an unmodified parameter at index base_index. */
|
||||
unsigned copy_param : 1;
|
||||
|
||||
/* This adjustment describes a parameter that is about to be removed
|
||||
completely. Most users will probably need to book keep those so that they
|
||||
don't leave behinfd any non default def ssa names belonging to them. */
|
||||
unsigned remove_param : 1;
|
||||
/* Whether this parameter is a new parameter, a copy of an old one,
|
||||
or one about to be removed. */
|
||||
enum ipa_parm_op op;
|
||||
|
||||
/* The parameter is to be passed by reference. */
|
||||
unsigned by_ref : 1;
|
||||
|
@ -671,8 +690,8 @@ typedef struct ipa_parm_adjustment ipa_parm_adjustment_t;
|
|||
typedef vec<ipa_parm_adjustment_t> ipa_parm_adjustment_vec;
|
||||
|
||||
vec<tree> ipa_get_vector_of_formal_parms (tree fndecl);
|
||||
void ipa_modify_formal_parameters (tree fndecl, ipa_parm_adjustment_vec,
|
||||
const char *);
|
||||
vec<tree> ipa_get_vector_of_formal_parm_types (tree fntype);
|
||||
void ipa_modify_formal_parameters (tree fndecl, ipa_parm_adjustment_vec);
|
||||
void ipa_modify_call_arguments (struct cgraph_edge *, gimple,
|
||||
ipa_parm_adjustment_vec);
|
||||
ipa_parm_adjustment_vec ipa_combine_adjustments (ipa_parm_adjustment_vec,
|
||||
|
@ -690,6 +709,10 @@ tree ipa_value_from_jfunc (struct ipa_node_params *info,
|
|||
struct ipa_jump_func *jfunc);
|
||||
unsigned int ipcp_transform_function (struct cgraph_node *node);
|
||||
void ipa_dump_param (FILE *, struct ipa_node_params *info, int i);
|
||||
bool ipa_modify_expr (tree *, bool, ipa_parm_adjustment_vec);
|
||||
ipa_parm_adjustment *ipa_get_adjustment_candidate (tree **, bool *,
|
||||
ipa_parm_adjustment_vec,
|
||||
bool);
|
||||
|
||||
|
||||
/* From tree-sra.c: */
|
||||
|
|
|
@ -246,7 +246,7 @@ walk_polymorphic_call_targets (pointer_set_t *reachable_call_targets,
|
|||
hope calls to them will be devirtualized.
|
||||
|
||||
Again we remove them after inlining. In late optimization some
|
||||
devirtualization may happen, but it is not importnat since we won't inline
|
||||
devirtualization may happen, but it is not important since we won't inline
|
||||
the call. In theory early opts and IPA should work out all important cases.
|
||||
|
||||
- virtual clones needs bodies of their origins for later materialization;
|
||||
|
@ -274,7 +274,7 @@ walk_polymorphic_call_targets (pointer_set_t *reachable_call_targets,
|
|||
by reachable symbols or origins of clones). The queue is represented
|
||||
as linked list by AUX pointer terminated by 1.
|
||||
|
||||
A the end we keep all reachable symbols. For symbols in boundary we always
|
||||
At the end we keep all reachable symbols. For symbols in boundary we always
|
||||
turn definition into a declaration, but we may keep function body around
|
||||
based on body_needed_for_clonning
|
||||
|
||||
|
|
106
gcc/tree-sra.c
106
gcc/tree-sra.c
|
@ -4281,9 +4281,10 @@ turn_representatives_into_adjustments (vec<access_p> representatives,
|
|||
adj.base_index = get_param_index (parm, parms);
|
||||
adj.base = parm;
|
||||
if (!repr)
|
||||
adj.copy_param = 1;
|
||||
adj.op = IPA_PARM_OP_COPY;
|
||||
else
|
||||
adj.remove_param = 1;
|
||||
adj.op = IPA_PARM_OP_REMOVE;
|
||||
adj.arg_prefix = "ISRA";
|
||||
adjustments.quick_push (adj);
|
||||
}
|
||||
else
|
||||
|
@ -4303,6 +4304,7 @@ turn_representatives_into_adjustments (vec<access_p> representatives,
|
|||
adj.by_ref = (POINTER_TYPE_P (TREE_TYPE (repr->base))
|
||||
&& (repr->grp_maybe_modified
|
||||
|| repr->grp_not_necessarilly_dereferenced));
|
||||
adj.arg_prefix = "ISRA";
|
||||
adjustments.quick_push (adj);
|
||||
}
|
||||
}
|
||||
|
@ -4433,7 +4435,7 @@ get_adjustment_for_base (ipa_parm_adjustment_vec adjustments, tree base)
|
|||
struct ipa_parm_adjustment *adj;
|
||||
|
||||
adj = &adjustments[i];
|
||||
if (!adj->copy_param && adj->base == base)
|
||||
if (adj->op != IPA_PARM_OP_COPY && adj->base == base)
|
||||
return adj;
|
||||
}
|
||||
|
||||
|
@ -4497,84 +4499,6 @@ replace_removed_params_ssa_names (gimple stmt,
|
|||
return true;
|
||||
}
|
||||
|
||||
/* If the expression *EXPR should be replaced by a reduction of a parameter, do
|
||||
so. ADJUSTMENTS is a pointer to a vector of adjustments. CONVERT
|
||||
specifies whether the function should care about type incompatibility the
|
||||
current and new expressions. If it is false, the function will leave
|
||||
incompatibility issues to the caller. Return true iff the expression
|
||||
was modified. */
|
||||
|
||||
static bool
|
||||
sra_ipa_modify_expr (tree *expr, bool convert,
|
||||
ipa_parm_adjustment_vec adjustments)
|
||||
{
|
||||
int i, len;
|
||||
struct ipa_parm_adjustment *adj, *cand = NULL;
|
||||
HOST_WIDE_INT offset, size, max_size;
|
||||
tree base, src;
|
||||
|
||||
len = adjustments.length ();
|
||||
|
||||
if (TREE_CODE (*expr) == BIT_FIELD_REF
|
||||
|| TREE_CODE (*expr) == IMAGPART_EXPR
|
||||
|| TREE_CODE (*expr) == REALPART_EXPR)
|
||||
{
|
||||
expr = &TREE_OPERAND (*expr, 0);
|
||||
convert = true;
|
||||
}
|
||||
|
||||
base = get_ref_base_and_extent (*expr, &offset, &size, &max_size);
|
||||
if (!base || size == -1 || max_size == -1)
|
||||
return false;
|
||||
|
||||
if (TREE_CODE (base) == MEM_REF)
|
||||
{
|
||||
offset += mem_ref_offset (base).low * BITS_PER_UNIT;
|
||||
base = TREE_OPERAND (base, 0);
|
||||
}
|
||||
|
||||
base = get_ssa_base_param (base);
|
||||
if (!base || TREE_CODE (base) != PARM_DECL)
|
||||
return false;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
adj = &adjustments[i];
|
||||
|
||||
if (adj->base == base
|
||||
&& (adj->offset == offset || adj->remove_param))
|
||||
{
|
||||
cand = adj;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!cand || cand->copy_param || cand->remove_param)
|
||||
return false;
|
||||
|
||||
if (cand->by_ref)
|
||||
src = build_simple_mem_ref (cand->reduction);
|
||||
else
|
||||
src = cand->reduction;
|
||||
|
||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||
{
|
||||
fprintf (dump_file, "About to replace expr ");
|
||||
print_generic_expr (dump_file, *expr, 0);
|
||||
fprintf (dump_file, " with ");
|
||||
print_generic_expr (dump_file, src, 0);
|
||||
fprintf (dump_file, "\n");
|
||||
}
|
||||
|
||||
if (convert && !useless_type_conversion_p (TREE_TYPE (*expr), cand->type))
|
||||
{
|
||||
tree vce = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (*expr), src);
|
||||
*expr = vce;
|
||||
}
|
||||
else
|
||||
*expr = src;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* If the statement pointed to by STMT_PTR contains any expressions that need
|
||||
to replaced with a different one as noted by ADJUSTMENTS, do so. Handle any
|
||||
potential type incompatibilities (GSI is used to accommodate conversion
|
||||
|
@ -4595,8 +4519,8 @@ sra_ipa_modify_assign (gimple *stmt_ptr, gimple_stmt_iterator *gsi,
|
|||
rhs_p = gimple_assign_rhs1_ptr (stmt);
|
||||
lhs_p = gimple_assign_lhs_ptr (stmt);
|
||||
|
||||
any = sra_ipa_modify_expr (rhs_p, false, adjustments);
|
||||
any |= sra_ipa_modify_expr (lhs_p, false, adjustments);
|
||||
any = ipa_modify_expr (rhs_p, false, adjustments);
|
||||
any |= ipa_modify_expr (lhs_p, false, adjustments);
|
||||
if (any)
|
||||
{
|
||||
tree new_rhs = NULL_TREE;
|
||||
|
@ -4642,7 +4566,7 @@ sra_ipa_modify_assign (gimple *stmt_ptr, gimple_stmt_iterator *gsi,
|
|||
/* Traverse the function body and all modifications as described in
|
||||
ADJUSTMENTS. Return true iff the CFG has been changed. */
|
||||
|
||||
static bool
|
||||
bool
|
||||
ipa_sra_modify_function_body (ipa_parm_adjustment_vec adjustments)
|
||||
{
|
||||
bool cfg_changed = false;
|
||||
|
@ -4668,7 +4592,7 @@ ipa_sra_modify_function_body (ipa_parm_adjustment_vec adjustments)
|
|||
case GIMPLE_RETURN:
|
||||
t = gimple_return_retval_ptr (stmt);
|
||||
if (*t != NULL_TREE)
|
||||
modified |= sra_ipa_modify_expr (t, true, adjustments);
|
||||
modified |= ipa_modify_expr (t, true, adjustments);
|
||||
break;
|
||||
|
||||
case GIMPLE_ASSIGN:
|
||||
|
@ -4681,13 +4605,13 @@ ipa_sra_modify_function_body (ipa_parm_adjustment_vec adjustments)
|
|||
for (i = 0; i < gimple_call_num_args (stmt); i++)
|
||||
{
|
||||
t = gimple_call_arg_ptr (stmt, i);
|
||||
modified |= sra_ipa_modify_expr (t, true, adjustments);
|
||||
modified |= ipa_modify_expr (t, true, adjustments);
|
||||
}
|
||||
|
||||
if (gimple_call_lhs (stmt))
|
||||
{
|
||||
t = gimple_call_lhs_ptr (stmt);
|
||||
modified |= sra_ipa_modify_expr (t, false, adjustments);
|
||||
modified |= ipa_modify_expr (t, false, adjustments);
|
||||
modified |= replace_removed_params_ssa_names (stmt,
|
||||
adjustments);
|
||||
}
|
||||
|
@ -4697,12 +4621,12 @@ ipa_sra_modify_function_body (ipa_parm_adjustment_vec adjustments)
|
|||
for (i = 0; i < gimple_asm_ninputs (stmt); i++)
|
||||
{
|
||||
t = &TREE_VALUE (gimple_asm_input_op (stmt, i));
|
||||
modified |= sra_ipa_modify_expr (t, true, adjustments);
|
||||
modified |= ipa_modify_expr (t, true, adjustments);
|
||||
}
|
||||
for (i = 0; i < gimple_asm_noutputs (stmt); i++)
|
||||
{
|
||||
t = &TREE_VALUE (gimple_asm_output_op (stmt, i));
|
||||
modified |= sra_ipa_modify_expr (t, false, adjustments);
|
||||
modified |= ipa_modify_expr (t, false, adjustments);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -4748,7 +4672,7 @@ sra_ipa_reset_debug_stmts (ipa_parm_adjustment_vec adjustments)
|
|||
use_operand_p use_p;
|
||||
|
||||
adj = &adjustments[i];
|
||||
if (adj->copy_param || !is_gimple_reg (adj->base))
|
||||
if (adj->op == IPA_PARM_OP_COPY || !is_gimple_reg (adj->base))
|
||||
continue;
|
||||
name = ssa_default_def (cfun, adj->base);
|
||||
vexpr = NULL;
|
||||
|
@ -4931,7 +4855,7 @@ modify_function (struct cgraph_node *node, ipa_parm_adjustment_vec adjustments)
|
|||
redirect_callers.release ();
|
||||
|
||||
push_cfun (DECL_STRUCT_FUNCTION (new_node->decl));
|
||||
ipa_modify_formal_parameters (current_function_decl, adjustments, "ISRA");
|
||||
ipa_modify_formal_parameters (current_function_decl, adjustments);
|
||||
cfg_changed = ipa_sra_modify_function_body (adjustments);
|
||||
sra_ipa_reset_debug_stmts (adjustments);
|
||||
convert_callers (new_node, node->decl, adjustments);
|
||||
|
|
Loading…
Reference in New Issue