]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[PR 77333] Fixup fntypes of gimple calls of clones
authorMartin Jambor <mjambor@suse.cz>
Tue, 11 Apr 2017 13:31:16 +0000 (15:31 +0200)
committerMartin Jambor <jamborm@gcc.gnu.org>
Tue, 11 Apr 2017 13:31:16 +0000 (15:31 +0200)
2017-04-11  Martin Jambor  <mjambor@suse.cz>

Backport from mainline
2017-03-30  Martin Jambor  <mjambor@suse.cz>

        PR ipa/77333
        * cgraph.h (cgraph_build_function_type_skip_args): Declare.
        * cgraph.c (redirect_call_stmt_to_callee): Set gimple fntype so that
        it reflects the signature changes performed at the callee side.
        * cgraphclones.c (build_function_type_skip_args): Make public, renamed
        to cgraph_build_function_type_skip_args.
        (build_function_decl_skip_args): Adjust call to the above function.

testsuite/
        * g++.dg/ipa/pr77333.C: New test.

From-SVN: r246839

gcc/ChangeLog
gcc/cgraph.c
gcc/cgraph.h
gcc/cgraphclones.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ipa/pr77333.C [new file with mode: 0644]

index f5e533a35c4b5d80e5ba1a6f561bd2fae0fabf86..69ca2f75366c09dda3e42281c667c559d8e27466 100644 (file)
@@ -1,3 +1,16 @@
+2017-04-11  Martin Jambor  <mjambor@suse.cz>
+
+       Backport from mainline
+       2017-03-30  Martin Jambor  <mjambor@suse.cz>
+
+        PR ipa/77333
+        * cgraph.h (cgraph_build_function_type_skip_args): Declare.
+        * cgraph.c (redirect_call_stmt_to_callee): Set gimple fntype so that
+        it reflects the signature changes performed at the callee side.
+        * cgraphclones.c (build_function_type_skip_args): Make public, renamed
+        to cgraph_build_function_type_skip_args.
+        (build_function_decl_skip_args): Adjust call to the above function.
+
 2017-04-11  Bin Cheng  <bin.cheng@arm.com>
 
        Backport from mainline
index e25ecb3fb9607a5b63c65cbc59f212155cf14f36..448e940586fa4dbaa7a18fe8916be2992798d211 100644 (file)
@@ -1437,8 +1437,23 @@ cgraph_edge::redirect_call_stmt_to_callee (void)
       if (skip_bounds)
        new_stmt = chkp_copy_call_skip_bounds (new_stmt);
 
+      tree old_fntype = gimple_call_fntype (e->call_stmt);
       gimple_call_set_fndecl (new_stmt, e->callee->decl);
-      gimple_call_set_fntype (new_stmt, gimple_call_fntype (e->call_stmt));
+      cgraph_node *origin = e->callee;
+      while (origin->clone_of)
+       origin = origin->clone_of;
+
+      if ((origin->former_clone_of
+          && old_fntype == TREE_TYPE (origin->former_clone_of))
+         || old_fntype == TREE_TYPE (origin->decl))
+       gimple_call_set_fntype (new_stmt, TREE_TYPE (e->callee->decl));
+      else
+       {
+         bitmap skip = e->callee->clone.combined_args_to_skip;
+         tree t = cgraph_build_function_type_skip_args (old_fntype, skip,
+                                                        false);
+         gimple_call_set_fntype (new_stmt, t);
+       }
 
       if (gimple_vdef (new_stmt)
          && TREE_CODE (gimple_vdef (new_stmt)) == SSA_NAME)
index e3689968e96bf070068c159c86d3477f381aaae3..104b3bbc6db41420a9a11c4a3582da4221aec09c 100644 (file)
@@ -2238,6 +2238,8 @@ tree clone_function_name (tree decl, const char *);
 
 void tree_function_versioning (tree, tree, vec<ipa_replace_map *, va_gc> *,
                               bool, bitmap, bool, bitmap, basic_block);
+tree cgraph_build_function_type_skip_args (tree orig_type, bitmap args_to_skip,
+                                          bool skip_return);
 
 /* In cgraphbuild.c  */
 int compute_call_stmt_bb_frequency (tree, basic_block bb);
index 546cac865640884939e494d6e0e5de9ad58b30e2..93668ab9981698ebbe4706b0fa7f39060133c88f 100644 (file)
@@ -191,9 +191,9 @@ cgraph_edge::clone (cgraph_node *n, gcall *call_stmt, unsigned stmt_uid,
 /* Build variant of function type ORIG_TYPE skipping ARGS_TO_SKIP and the
    return value if SKIP_RETURN is true.  */
 
-static tree
-build_function_type_skip_args (tree orig_type, bitmap args_to_skip,
-                              bool skip_return)
+tree
+cgraph_build_function_type_skip_args (tree orig_type, bitmap args_to_skip,
+                                     bool skip_return)
 {
   tree new_type = NULL;
   tree args, new_args = NULL;
@@ -258,7 +258,8 @@ build_function_decl_skip_args (tree orig_decl, bitmap args_to_skip,
   if (prototype_p (new_type)
       || (skip_return && !VOID_TYPE_P (TREE_TYPE (new_type))))
     new_type
-      = build_function_type_skip_args (new_type, args_to_skip, skip_return);
+      = cgraph_build_function_type_skip_args (new_type, args_to_skip,
+                                             skip_return);
   TREE_TYPE (new_decl) = new_type;
 
   /* For declarations setting DECL_VINDEX (i.e. methods)
index cab6462d171a74d86eed8c1649e48de4dc8e5d4d..6b737b69feb734f204677be9d02b31d9aa8a68c2 100644 (file)
@@ -1,3 +1,11 @@
+2017-04-11  Martin Jambor  <mjambor@suse.cz>
+
+       Backport from mainline
+       2017-03-30  Martin Jambor  <mjambor@suse.cz>
+
+        PR ipa/77333
+        * g++.dg/ipa/pr77333.C: New test.
+
 2017-04-11  Bin Cheng  <bin.cheng@arm.com>
 
        PR tree-optimization/80345
diff --git a/gcc/testsuite/g++.dg/ipa/pr77333.C b/gcc/testsuite/g++.dg/ipa/pr77333.C
new file mode 100644 (file)
index 0000000..1ef997f
--- /dev/null
@@ -0,0 +1,65 @@
+// { dg-do run }
+// { dg-options "-O2 -fno-ipa-sra" }
+
+volatile int global;
+int __attribute__((noinline, noclone))
+get_data (int i)
+{
+  global = i;
+  return i;
+}
+
+typedef int array[32];
+
+namespace {
+
+char buf[512];
+
+class A
+{
+public:
+  int field;
+  char *s;
+
+  A() : field(223344)
+  {
+    s = buf;
+  }
+
+  int __attribute__((noinline))
+  foo (int a, int b, int c, int d, int e, int f, int g, int h, int i, int j,
+       int k, int l, int m, int n, int o, int p, int q, int r, int s, int t)
+  {
+    global = a+b+c+d+e+f+g+h+i+j+k+l+m+n+o+p+q+r+s+t;
+    return global;
+  }
+
+  int __attribute__((noinline))
+  bar()
+  {
+    int r = foo (get_data (1), get_data (1), get_data (1), get_data (1),
+                get_data (1), get_data (1), get_data (1), get_data (1),
+                get_data (1), get_data (1), get_data (1), get_data (1),
+                get_data (1), get_data (1), get_data (1), get_data (1),
+                get_data (1), get_data (1), get_data (1), get_data (1));
+
+    if (field != 223344)
+      __builtin_abort ();
+    return 0;
+  }
+};
+
+}
+
+int main (int argc, char **argv)
+{
+  A a;
+  int r = a.bar();
+  r = a.bar ();
+  if (a.field != 223344)
+      __builtin_abort ();
+  if (global != 20)
+    __builtin_abort ();
+
+  return r;
+}