From ebde4f8e394d77663f500360e7f20a42cc471f85 Mon Sep 17 00:00:00 2001 From: Martin Jambor Date: Tue, 3 Mar 2015 14:58:15 +0100 Subject: [PATCH] tree-sra.c (ipa_sra_check_caller_data): New type. 2015-03-03 Martin Jambor Eric Botcazou 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 From-SVN: r221148 --- gcc/ChangeLog | 8 +++ gcc/testsuite/ChangeLog | 5 ++ gcc/testsuite/gnat.dg/specs/pack12.ads | 21 +++++++ gcc/tree-sra.c | 76 ++++++++++++++++++++++---- 4 files changed, 98 insertions(+), 12 deletions(-) create mode 100644 gcc/testsuite/gnat.dg/specs/pack12.ads diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 36aa08f0274..73854e0555b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2015-03-03 Martin Jambor + Eric Botcazou + + * 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 * ipa-icf.c (sem_item_optimizer::merge_classes): Use bit or diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 11ffd258d61..e242e595dc2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-03-03 Martin Jambor + Eric Botcazou + + * gnat.dg/specs/pack12.ads: New test. + 2015-03-03 Martin Liska * gcc.dg/ipa/PR65282.c: New test. diff --git a/gcc/testsuite/gnat.dg/specs/pack12.ads b/gcc/testsuite/gnat.dg/specs/pack12.ads new file mode 100644 index 00000000000..c5e962cf3d3 --- /dev/null +++ b/gcc/testsuite/gnat.dg/specs/pack12.ads @@ -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; diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index 023b8172300..a6cddafe44b 100644 --- a/gcc/tree-sra.c +++ b/gcc/tree-sra.c @@ -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; } -- 2.30.2