tree-sra.c (ipa_sra_check_caller_data): New type.

2015-03-03  Martin Jambor  <mjambor@suse.cz>
            Eric Botcazou  <ebotcazou@adacore.com>

gcc/
        * tree-sra.c (ipa_sra_check_caller_data): New type.
        (has_caller_p): Removed.
        (ipa_sra_check_caller): New function.
        (ipa_sra_preliminary_function_checks): Use it.

gcc/changelog/
        * gnat.dg/specs/pack12.ads: New test.



Co-Authored-By: Eric Botcazou <ebotcazou@adacore.com>

From-SVN: r221148
This commit is contained in:
Martin Jambor 2015-03-03 14:58:15 +01:00 committed by Martin Jambor
parent 21ce14d309
commit ebde4f8e39
4 changed files with 98 additions and 12 deletions

View File

@ -1,3 +1,11 @@
2015-03-03 Martin Jambor <mjambor@suse.cz>
Eric Botcazou <ebotcazou@adacore.com>
* tree-sra.c (ipa_sra_check_caller_data): New type.
(has_caller_p): Removed.
(ipa_sra_check_caller): New function.
(ipa_sra_preliminary_function_checks): Use it.
2015-03-03 Martin Liska <mliska@suse.cz>
* ipa-icf.c (sem_item_optimizer::merge_classes): Use bit or

View File

@ -1,3 +1,8 @@
2015-03-03 Martin Jambor <mjambor@suse.cz>
Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/specs/pack12.ads: New test.
2015-03-03 Martin Liska <mliska@suse.cz>
* gcc.dg/ipa/PR65282.c: New test.

View File

@ -0,0 +1,21 @@
-- { dg-do compile }
-- { dg-options "-O2" }
package Pack12 is
type Rec1 is record
B : Boolean;
N : Natural;
end record;
type Rec2 is record
B : Boolean;
R : Rec1;
end record;
pragma Pack (Rec2);
type Rec3 is tagged record
R : Rec2;
end record;
end Pack12;

View File

@ -5009,13 +5009,54 @@ modify_function (struct cgraph_node *node, ipa_parm_adjustment_vec adjustments)
return cfg_changed;
}
/* If NODE has a caller, return true. */
/* Means of communication between ipa_sra_check_caller and
ipa_sra_preliminary_function_checks. */
struct ipa_sra_check_caller_data
{
bool has_callers;
bool bad_arg_alignment;
};
/* If NODE has a caller, mark that fact in DATA which is pointer to
ipa_sra_check_caller_data. Also check all aggregate arguments in all known
calls if they are unit aligned and if not, set the appropriate flag in DATA
too. */
static bool
has_caller_p (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
ipa_sra_check_caller (struct cgraph_node *node, void *data)
{
if (node->callers)
return true;
if (!node->callers)
return false;
struct ipa_sra_check_caller_data *iscc;
iscc = (struct ipa_sra_check_caller_data *) data;
iscc->has_callers = true;
for (cgraph_edge *cs = node->callers; cs; cs = cs->next_caller)
{
gimple call_stmt = cs->call_stmt;
unsigned count = gimple_call_num_args (call_stmt);
for (unsigned i = 0; i < count; i++)
{
tree arg = gimple_call_arg (call_stmt, i);
if (is_gimple_reg (arg))
continue;
tree offset;
HOST_WIDE_INT bitsize, bitpos;
machine_mode mode;
int unsignedp, volatilep = 0;
get_inner_reference (arg, &bitsize, &bitpos, &offset, &mode,
&unsignedp, &volatilep, false);
if (bitpos % BITS_PER_UNIT)
{
iscc->bad_arg_alignment = true;
return true;
}
}
}
return false;
}
@ -5070,14 +5111,6 @@ ipa_sra_preliminary_function_checks (struct cgraph_node *node)
return false;
}
if (!node->call_for_symbol_thunks_and_aliases (has_caller_p, NULL, true))
{
if (dump_file)
fprintf (dump_file,
"Function has no callers in this compilation unit.\n");
return false;
}
if (cfun->stdarg)
{
if (dump_file)
@ -5096,6 +5129,25 @@ ipa_sra_preliminary_function_checks (struct cgraph_node *node)
return false;
}
struct ipa_sra_check_caller_data iscc;
memset (&iscc, 0, sizeof(iscc));
node->call_for_symbol_thunks_and_aliases (ipa_sra_check_caller, &iscc, true);
if (!iscc.has_callers)
{
if (dump_file)
fprintf (dump_file,
"Function has no callers in this compilation unit.\n");
return false;
}
if (iscc.bad_arg_alignment)
{
if (dump_file)
fprintf (dump_file,
"A function call has an argument with non-unit alignemnt.\n");
return false;
}
return true;
}