From: Ilya Enkovich <enkovich.gnu@gmail.com>
To: gcc-patches@gcc.gnu.org
Subject: Re: [CHKP, PATCH] Fix LTO cgraph merge for instrumented functions
Date: Thu, 19 Mar 2015 08:35:00 -0000 [thread overview]
Message-ID: <20150319083455.GD64546@msticlxl57.ims.intel.com> (raw)
In-Reply-To: <20150312102706.GL27860@msticlxl57.ims.intel.com>
On 12 Mar 13:27, Ilya Enkovich wrote:
> Hi,
>
> Currently cgraph merge has several issues with instrumented code:
> - original function node may be removed => no assembler name conflict is detected between function and variable
> - only orig_decl name is privatized for instrumented function => node still shares assembler name which causes infinite privatization loop
> - information about changed name is stored in file_data of instrumented node => original section name may be not found for original function
> - chkp reference is not fixed when nodes are merged
>
> This patch should fix theese problems by keeping instrumentation thunks reachable, privatizing both nodes and fixing chkp references. Bootstrapped and tested on x86_64-unknown-linux-gnu. OK for trunk?
>
>
> Thanks,
> Ilya
Here is an updated version where chkp_maybe_fix_chkp_ref also removes duplicating references which may appear during cgraph nodes merge. Bootstrapped and tested on x86_64-unknown-linux-gnu. OK for trunk?
Thanks,
Ilya
--
gcc/
2015-03-19 Ilya Enkovich <ilya.enkovich@intel.com>
* ipa-chkp.h (chkp_maybe_fix_chkp_ref): New.
* ipa-chkp.c (chkp_maybe_fix_chkp_ref): New.
* ipa.c (symbol_table::remove_unreachable_nodes): Don't
remove instumentation thunks calling reachable functions.
* lto-cgraph.c: Include ipa-chkp.h.
(input_symtab): Fix chkp references for boundary nodes.
* lto/lto-partition.c (privatize_symbol_name_1): New.
(privatize_symbol_name): Privatize both decl and orig_decl
names for instrumented functions.
* lto/lto-symtab.c: Include ipa-chkp.h.
(lto_cgraph_replace_node): Fix chkp references for merged
function nodes.
gcc/testsuite/
2015-03-19 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.
diff --git a/gcc/ipa-chkp.c b/gcc/ipa-chkp.c
index 0b857ff..7a7fc3c 100644
--- a/gcc/ipa-chkp.c
+++ b/gcc/ipa-chkp.c
@@ -414,6 +414,40 @@ chkp_instrumentable_p (tree fndecl)
&& (!fn || !copy_forbidden (fn, fndecl)));
}
+/* Check NODE has a correct IPA_REF_CHKP reference.
+ Create a new reference if required. */
+
+void
+chkp_maybe_fix_chkp_ref (cgraph_node *node)
+{
+ /* Firstly check node needs IPA_REF_CHKP. */
+ if (node->instrumentation_clone
+ || !node->instrumented_version)
+ return;
+
+ /* Check we already have a proper IPA_REF_CHKP.
+ Remove incorrect refs. */
+ int i;
+ ipa_ref *ref = NULL;
+ bool found = false;
+ for (i = 0; node->iterate_reference (i, ref); i++)
+ if (ref->use == IPA_REF_CHKP)
+ {
+ /* Found proper reference. */
+ if (ref->referred == node->instrumented_version
+ && !found)
+ found = true;
+ else
+ {
+ ref->remove_reference ();
+ i--;
+ }
+ }
+
+ if (!found)
+ node->create_reference (node->instrumented_version, IPA_REF_CHKP, NULL);
+}
+
/* Return clone created for instrumentation of NODE or NULL. */
cgraph_node *
diff --git a/gcc/ipa-chkp.h b/gcc/ipa-chkp.h
index 6708fe9..5fa7d88 100644
--- a/gcc/ipa-chkp.h
+++ b/gcc/ipa-chkp.h
@@ -24,5 +24,6 @@ extern tree chkp_copy_function_type_adding_bounds (tree orig_type);
extern tree chkp_maybe_clone_builtin_fndecl (tree fndecl);
extern cgraph_node *chkp_maybe_create_clone (tree fndecl);
extern bool chkp_instrumentable_p (tree fndecl);
+extern void chkp_maybe_fix_chkp_ref (cgraph_node *node);
#endif /* GCC_IPA_CHKP_H */
diff --git a/gcc/ipa.c b/gcc/ipa.c
index b3752de..3054afe 100644
--- a/gcc/ipa.c
+++ b/gcc/ipa.c
@@ -492,7 +492,22 @@ symbol_table::remove_unreachable_nodes (FILE *file)
}
else if (cnode->thunk.thunk_p)
enqueue_node (cnode->callees->callee, &first, &reachable);
-
+
+ /* For instrumentation clones we always need original
+ function node for proper LTO privatization. */
+ if (cnode->instrumentation_clone
+ && reachable.contains (cnode)
+ && 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);
+ }
+ }
+
/* If any reachable function has simd clones, mark them as
reachable as well. */
if (cnode->simd_clones)
diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c
index c875fed..b9196eb 100644
--- a/gcc/lto-cgraph.c
+++ b/gcc/lto-cgraph.c
@@ -80,6 +80,7 @@ along with GCC; see the file COPYING3. If not see
#include "pass_manager.h"
#include "ipa-utils.h"
#include "omp-low.h"
+#include "ipa-chkp.h"
/* True when asm nodes has been output. */
bool asm_nodes_output = false;
@@ -1888,6 +1889,10 @@ input_symtab (void)
context of the nested function. */
if (node->lto_file_data)
node->aux = NULL;
+
+ /* May need to fix chkp reference because we don't stream
+ them for boundary symbols. */
+ chkp_maybe_fix_chkp_ref (node);
}
}
diff --git a/gcc/lto/lto-partition.c b/gcc/lto/lto-partition.c
index 235b735..7d117e9 100644
--- a/gcc/lto/lto-partition.c
+++ b/gcc/lto/lto-partition.c
@@ -877,27 +877,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;
@@ -906,31 +892,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;
}
diff --git a/gcc/lto/lto-symtab.c b/gcc/lto/lto-symtab.c
index c00fd87..e0b9762 100644
--- a/gcc/lto/lto-symtab.c
+++ b/gcc/lto/lto-symtab.c
@@ -56,6 +56,7 @@ along with GCC; see the file COPYING3. If not see
#include "ipa-prop.h"
#include "ipa-inline.h"
#include "builtins.h"
+#include "ipa-chkp.h"
/* Replace the cgraph node NODE with PREVAILING_NODE in the cgraph, merging
all edges and removing the old node. */
@@ -116,7 +117,11 @@ lto_cgraph_replace_node (struct cgraph_node *node,
== prevailing_node->instrumentation_clone);
node->instrumented_version->instrumented_version = prevailing_node;
if (!prevailing_node->instrumented_version)
- prevailing_node->instrumented_version = node->instrumented_version;
+ {
+ prevailing_node->instrumented_version = node->instrumented_version;
+ chkp_maybe_fix_chkp_ref (prevailing_node);
+ }
+ chkp_maybe_fix_chkp_ref (node->instrumented_version);
/* Need to reset node->instrumented_version to NULL,
otherwise node removal code would reset
node->instrumented_version->instrumented_version. */
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
index 0000000..2054aa15
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lto/chkp-privatize-1_0.c
@@ -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
index 0000000..4fa8656
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lto/chkp-privatize-1_1.c
@@ -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
index 0000000..be7f601
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lto/chkp-privatize-2_0.c
@@ -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
index 0000000..db39e7f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lto/chkp-privatize-2_1.c
@@ -0,0 +1,8 @@
+int func1 = 10;
+
+int
+func2 (int i)
+{
+ func1++;
+ return i + func1;
+}
next prev parent reply other threads:[~2015-03-19 8:35 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-03-12 12:10 Ilya Enkovich
2015-03-19 8:35 ` Ilya Enkovich [this message]
2015-04-02 14:52 ` Ilya Enkovich
2015-04-02 17:01 ` Jan Hubicka
2015-04-03 7:54 ` Ilya Enkovich
2015-04-03 18:49 ` Jan Hubicka
2015-04-06 13:57 ` Ilya Enkovich
2015-04-10 1:15 ` Jan Hubicka
2015-04-14 9:16 ` Ilya Enkovich
2015-05-05 8:06 ` Ilya Enkovich
2015-05-19 9:40 ` Ilya Enkovich
2015-05-26 13:09 ` Ilya Enkovich
2015-05-29 6:33 ` Jan Hubicka
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20150319083455.GD64546@msticlxl57.ims.intel.com \
--to=enkovich.gnu@gmail.com \
--cc=gcc-patches@gcc.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).