tree-sra.c (ipa_sra_check_caller_data): New type.
authorMartin Jambor <mjambor@suse.cz>
Tue, 3 Mar 2015 13:58:15 +0000 (14:58 +0100)
committerMartin Jambor <jamborm@gcc.gnu.org>
Tue, 3 Mar 2015 13:58:15 +0000 (14:58 +0100)
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

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gnat.dg/specs/pack12.ads [new file with mode: 0644]
gcc/tree-sra.c

index 36aa08f02747ffb7496ee250ea4929f5a04f6168..73854e0555b60886e65094c4d9f52dc5d5cd6f45 100644 (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
index 11ffd258d6179b10ac2833f856f250bddaac1723..e242e595dc288fc1008163c9580f4ec07f9559ad 100644 (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.
diff --git a/gcc/testsuite/gnat.dg/specs/pack12.ads b/gcc/testsuite/gnat.dg/specs/pack12.ads
new file mode 100644 (file)
index 0000000..c5e962c
--- /dev/null
@@ -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;
index 023b8172300415bf9f5e775823c7d85fa6ef1df0..a6cddafe44bf8a2c4411c1fa102583afb230fa8d 100644 (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;
 }