ipa.c (symbol_table::remove_unreachable_nodes): Don't remove instumentation thunks...
authorIlya Enkovich <ilya.enkovich@intel.com>
Wed, 3 Jun 2015 08:29:28 +0000 (08:29 +0000)
committerIlya Enkovich <ienkovich@gcc.gnu.org>
Wed, 3 Jun 2015 08:29:28 +0000 (08:29 +0000)
gcc/

* ipa.c (symbol_table::remove_unreachable_nodes): Don't
remove instumentation thunks calling reachable functions.
* lto-cgraph.c (output_refs): Always output IPA_REF_CHKP.
* lto/lto-partition.c (privatize_symbol_name_1): New.
(privatize_symbol_name): Privatize both decl and orig_decl
names for instrumented functions.
* cgraph.c (cgraph_node::verify_node): Add transparent
alias chain check for instrumented node.

gcc/testsuite/

* gcc.dg/lto/chkp-privatize-1_0.c: New.
* gcc.dg/lto/chkp-privatize-1_1.c: New.
* gcc.dg/lto/chkp-privatize-2_0.c: New.
* gcc.dg/lto/chkp-privatize-2_1.c: New.

From-SVN: r224063

gcc/ChangeLog
gcc/cgraph.c
gcc/ipa.c
gcc/lto-cgraph.c
gcc/lto/lto-partition.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/lto/chkp-privatize-1_0.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/chkp-privatize-1_1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/chkp-privatize-2_0.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/lto/chkp-privatize-2_1.c [new file with mode: 0644]

index ad33c67fa127118a74280dd11b5053dd756ab3d1..baeaef58e026fe7557a44ad2857003646c1ff2dd 100644 (file)
@@ -1,3 +1,14 @@
+2015-06-03  Ilya Enkovich  <ilya.enkovich@intel.com>
+
+       * ipa.c (symbol_table::remove_unreachable_nodes): Don't
+       remove instumentation thunks calling reachable functions.
+       * lto-cgraph.c (output_refs): Always output IPA_REF_CHKP.
+       * lto/lto-partition.c (privatize_symbol_name_1): New.
+       (privatize_symbol_name): Privatize both decl and orig_decl
+       names for instrumented functions.
+       * cgraph.c (cgraph_node::verify_node): Add transparent
+       alias chain check for instrumented node.
+
 2015-06-03  Marek Polacek  <polacek@redhat.com>
 
        PR c/64223
index 2ded5af546e1e499074642988fed12fef9ba0921..039ce150fd82bb22d9de2cda88abf308edb6366c 100644 (file)
@@ -3036,6 +3036,20 @@ cgraph_node::verify_node (void)
        }
     }
 
+  if (instrumentation_clone
+      && DECL_BUILT_IN_CLASS (decl) == NOT_BUILT_IN)
+    {
+      tree name = DECL_ASSEMBLER_NAME (decl);
+      tree orig_name = DECL_ASSEMBLER_NAME (orig_decl);
+
+      if (!IDENTIFIER_TRANSPARENT_ALIAS (name)
+         || TREE_CHAIN (name) != orig_name)
+       {
+         error ("Alias chain for instrumented node is broken");
+         error_found = true;
+       }
+    }
+
   if (analyzed && thunk.thunk_p)
     {
       if (!callees)
index eb6fd41a696f59904aae22a46b54f97cd02267c2..0b4010c33888c1cbac1945f36220231858dcc36b 100644 (file)
--- a/gcc/ipa.c
+++ b/gcc/ipa.c
@@ -476,6 +476,20 @@ symbol_table::remove_unreachable_nodes (FILE *file)
              if (cnode->global.inlined_to)
                body_needed_for_clonning.add (cnode->decl);
 
+             /* For instrumentation clones we always need original
+                function node for proper LTO privatization.  */
+             if (cnode->instrumentation_clone
+                 && cnode->definition)
+               {
+                 gcc_assert (cnode->instrumented_version || in_lto_p);
+                 if (cnode->instrumented_version)
+                   {
+                     enqueue_node (cnode->instrumented_version, &first,
+                                   &reachable);
+                     reachable.add (cnode->instrumented_version);
+                   }
+               }
+
              /* For non-inline clones, force their origins to the boundary and ensure
                 that body is not removed.  */
              while (cnode->clone_of)
@@ -492,7 +506,7 @@ symbol_table::remove_unreachable_nodes (FILE *file)
            }
          else if (cnode->thunk.thunk_p)
            enqueue_node (cnode->callees->callee, &first, &reachable);
-             
+
          /* If any reachable function has simd clones, mark them as
             reachable as well.  */
          if (cnode->simd_clones)
index b306c28d37bdcdfb51bf561471fd99777e7e42d5..b5fd83ee7abe58067f4307fff141272af234121c 100644 (file)
@@ -806,8 +806,33 @@ output_refs (lto_symtab_encoder_t encoder)
     {
       symtab_node *node = lto_symtab_encoder_deref (encoder, i);
 
+      /* IPA_REF_ALIAS and IPA_REF_CHKP references are always preserved
+        in the boundary.  Alias node can't have other references and
+        can be always handled as if it's not in the boundary.  */
       if (!node->alias && !lto_symtab_encoder_in_partition_p (encoder, node))
-       continue;
+       {
+         cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
+         /* Output IPA_REF_CHKP reference.  */
+         if (cnode
+             && cnode->instrumented_version
+             && !cnode->instrumentation_clone)
+           {
+             for (int i = 0; node->iterate_reference (i, ref); i++)
+               if (ref->use == IPA_REF_CHKP)
+                 {
+                   if (lto_symtab_encoder_lookup (encoder, ref->referred)
+                       != LCC_NOT_FOUND)
+                     {
+                       int nref = lto_symtab_encoder_lookup (encoder, node);
+                       streamer_write_gcov_count_stream (ob->main_stream, 1);
+                       streamer_write_uhwi_stream (ob->main_stream, nref);
+                       lto_output_ref (ob, ref, encoder);
+                     }
+                   break;
+                 }
+           }
+         continue;
+       }
 
       count = node->ref_list.nreferences ();
       if (count)
index 8c72d9e9a41607ef0080f93210e1e38749566e9f..e7c22140802db57f3c86b1870aebc7c77004d0b8 100644 (file)
@@ -900,27 +900,13 @@ validize_symbol_for_target (symtab_node *node)
     }
 }
 
-/* Mangle NODE symbol name into a local name.  
-   This is necessary to do
-   1) if two or more static vars of same assembler name
-      are merged into single ltrans unit.
-   2) if previously static var was promoted hidden to avoid possible conflict
-      with symbols defined out of the LTO world.  */
+/* Helper for privatize_symbol_name.  Mangle NODE symbol name
+   represented by DECL.  */
 
 static bool
-privatize_symbol_name (symtab_node *node)
+privatize_symbol_name_1 (symtab_node *node, tree decl)
 {
-  tree decl = node->decl;
-  const char *name;
-  cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
-
-  /* If we want to privatize instrumentation clone
-     then we need to change original function name
-     which is used via transparent alias chain.  */
-  if (cnode && cnode->instrumentation_clone)
-    decl = cnode->orig_decl;
-
-  name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
+  const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
 
   if (must_not_rename (node, name))
     return false;
@@ -929,31 +915,57 @@ privatize_symbol_name (symtab_node *node)
   symtab->change_decl_assembler_name (decl,
                                      clone_function_name_1 (name,
                                                             "lto_priv"));
+
   if (node->lto_file_data)
     lto_record_renamed_decl (node->lto_file_data, name,
                             IDENTIFIER_POINTER
                             (DECL_ASSEMBLER_NAME (decl)));
+
+  if (symtab->dump_file)
+    fprintf (symtab->dump_file,
+            "Privatizing symbol name: %s -> %s\n",
+            name, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
+
+  return true;
+}
+
+/* Mangle NODE symbol name into a local name.
+   This is necessary to do
+   1) if two or more static vars of same assembler name
+      are merged into single ltrans unit.
+   2) if previously static var was promoted hidden to avoid possible conflict
+      with symbols defined out of the LTO world.  */
+
+static bool
+privatize_symbol_name (symtab_node *node)
+{
+  if (!privatize_symbol_name_1 (node, node->decl))
+    return false;
+
   /* We could change name which is a target of transparent alias
      chain of instrumented function name.  Fix alias chain if so  .*/
-  if (cnode)
+  if (cgraph_node *cnode = dyn_cast <cgraph_node *> (node))
     {
       tree iname = NULL_TREE;
       if (cnode->instrumentation_clone)
-       iname = DECL_ASSEMBLER_NAME (cnode->decl);
+       {
+         /* If we want to privatize instrumentation clone
+            then we also need to privatize original function.  */
+         if (cnode->instrumented_version)
+           privatize_symbol_name (cnode->instrumented_version);
+         else
+           privatize_symbol_name_1 (cnode, cnode->orig_decl);
+         iname = DECL_ASSEMBLER_NAME (cnode->decl);
+         TREE_CHAIN (iname) = DECL_ASSEMBLER_NAME (cnode->orig_decl);
+       }
       else if (cnode->instrumented_version
-              && cnode->instrumented_version->orig_decl == decl)
-       iname = DECL_ASSEMBLER_NAME (cnode->instrumented_version->decl);
-
-      if (iname)
+              && cnode->instrumented_version->orig_decl == cnode->decl)
        {
-         gcc_assert (IDENTIFIER_TRANSPARENT_ALIAS (iname));
-         TREE_CHAIN (iname) = DECL_ASSEMBLER_NAME (decl);
+         iname = DECL_ASSEMBLER_NAME (cnode->instrumented_version->decl);
+         TREE_CHAIN (iname) = DECL_ASSEMBLER_NAME (cnode->decl);
        }
     }
-  if (symtab->dump_file)
-    fprintf (symtab->dump_file,
-           "Privatizing symbol name: %s -> %s\n",
-           name, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
+
   return true;
 }
 
index d3280fc20f34bd94e9d4bdd9df4d8bf9a82b5b84..12bf61c614e7c3d6cee8246eed816a8d57342027 100644 (file)
@@ -1,3 +1,10 @@
+2015-06-03  Ilya Enkovich  <ilya.enkovich@intel.com>
+
+       * gcc.dg/lto/chkp-privatize-1_0.c: New.
+       * gcc.dg/lto/chkp-privatize-1_1.c: New.
+       * gcc.dg/lto/chkp-privatize-2_0.c: New.
+       * gcc.dg/lto/chkp-privatize-2_1.c: New.
+
 2015-06-03  Marek Polacek  <polacek@redhat.com>
 
        PR c/64223
diff --git a/gcc/testsuite/gcc.dg/lto/chkp-privatize-1_0.c b/gcc/testsuite/gcc.dg/lto/chkp-privatize-1_0.c
new file mode 100644 (file)
index 0000000..2054aa1
--- /dev/null
@@ -0,0 +1,17 @@
+/* { dg-lto-do link } */
+/* { dg-require-effective-target mpx } */
+/* { dg-lto-options { { -Ofast -flto -fcheck-pointer-bounds -mmpx } } } */
+
+extern int __attribute__((noinline)) f1 (int i);
+
+static int __attribute__((noinline))
+f2 (int i)
+{
+  return i + 6;
+}
+
+int
+main (int argc, char **argv)
+{
+  return f1 (argc) + f2 (argc);
+}
diff --git a/gcc/testsuite/gcc.dg/lto/chkp-privatize-1_1.c b/gcc/testsuite/gcc.dg/lto/chkp-privatize-1_1.c
new file mode 100644 (file)
index 0000000..4fa8656
--- /dev/null
@@ -0,0 +1,11 @@
+static int __attribute__((noinline))
+f2 (int i)
+{
+  return 2 * i;
+}
+
+int __attribute__((noinline))
+f1 (int i)
+{
+  return f2 (i) + 10;
+}
diff --git a/gcc/testsuite/gcc.dg/lto/chkp-privatize-2_0.c b/gcc/testsuite/gcc.dg/lto/chkp-privatize-2_0.c
new file mode 100644 (file)
index 0000000..be7f601
--- /dev/null
@@ -0,0 +1,18 @@
+/* { dg-lto-do link } */
+/* { dg-require-effective-target mpx } */
+/* { dg-lto-options { { -Ofast -flto -fcheck-pointer-bounds -mmpx } } } */
+
+static int
+__attribute__ ((noinline))
+func1 (int i)
+{
+  return i + 2;
+}
+
+extern int func2 (int i);
+
+int
+main (int argc, char **argv)
+{
+  return func1 (argc) + func2 (argc) + 1;
+}
diff --git a/gcc/testsuite/gcc.dg/lto/chkp-privatize-2_1.c b/gcc/testsuite/gcc.dg/lto/chkp-privatize-2_1.c
new file mode 100644 (file)
index 0000000..db39e7f
--- /dev/null
@@ -0,0 +1,8 @@
+int func1 = 10;
+
+int
+func2 (int i)
+{
+  func1++;
+  return i + func1;
+}