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:
Aldy Hernandez 2013-11-22 20:08:44 +00:00 committed by Jakub Jelinek
parent 0a508bb66b
commit 31519c3863
5 changed files with 269 additions and 158 deletions

View File

@ -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

View File

@ -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);

View File

@ -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: */

View File

@ -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

View File

@ -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);