This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Make multiple_target.c aware of LTO (PR lto/66295)
- From: Martin Liška <mliska at suse dot cz>
- To: Jan Hubicka <hubicka at ucw dot cz>
- Cc: GCC Patches <gcc-patches at gcc dot gnu dot org>, evstupac at gmail dot com
- Date: Thu, 2 Feb 2017 14:18:29 +0100
- Subject: Re: [PATCH] Make multiple_target.c aware of LTO (PR lto/66295)
- Authentication-results: sourceware.org; auth=none
- References: <3fc1a062-956e-ae18-21ff-296685d4f8c8@suse.cz> <20170117010319.GB34708@kam.mff.cuni.cz>
Ok, I spent more time with understanding how that pass works and I believe it can be
significantly simplified. I guess target_clones are very close to 'target' attribute
that is handled by C++ FE. It creates cgraph_function_version_info and function dispatcher
is generated.
I hope doing the very same by an early simple IPA pass should be the right approach.
Works fine apart from an assert it triggers:
$ ./xgcc -B. /home/marxin/Programming/gcc/gcc/testsuite/gcc.target/i386/mvc9.c -flto -O1
lto1: internal compiler error: in binds_to_current_def_p, at symtab.c:2239
0x8c580a symtab_node::binds_to_current_def_p(symtab_node*)
../../gcc/symtab.c:2239
0x18cb40b worse_state
../../gcc/ipa-pure-const.c:477
0x18cd61f propagate_pure_const
../../gcc/ipa-pure-const.c:1346
0x18ce304 execute
../../gcc/ipa-pure-const.c:1679
triggered for foo.ifunc:
foo.ifunc/6 (foo.ifunc) @0x7f9535b138a0
Type: function definition analyzed alias
Visibility: prevailing_def_ironly artificial
References: foo.resolver/7 (alias)
Referring:
Read from file: /tmp/ccdj2ikS.o
Availability: overwritable
First run: 0
Function flags:
Called by: main/2 (1.00 per call)
Calls:
The assert is removed in attached patch, but maybe there's a better approach?
Thanks,
Martin
>From 4dbaad270f77d3bf79d4d980371f120a19f7d3a3 Mon Sep 17 00:00:00 2001
From: marxin <mliska@suse.cz>
Date: Tue, 24 Jan 2017 13:41:25 +0100
Subject: [PATCH] Simplify creation of target_clones (PR lto/66295)
gcc/ChangeLog:
2017-01-24 Martin Liska <mliska@suse.cz>
* multiple_target.c (create_dispatcher_calls): Redirect edge
from a caller of a dispatcher.
(expand_target_clones): Make the clones local.
(ipa_target_clone): Do both target clones and resolvers.
(ipa_dispatcher_calls): Remove the pass.
(pass_dispatcher_calls::gate): Likewise.
(make_pass_dispatcher_calls): Likewise.
* passes.def (pass_target_clone): Put as very first IPA early
pass.
* symtab.c (symtab_node::binds_to_current_def_p): Remove assert.
gcc/testsuite/ChangeLog:
2017-01-24 Martin Liska <mliska@suse.cz>
* gcc.target/i386/mvc9.c: New test.
---
gcc/multiple_target.c | 71 +++++-------------------------------
gcc/passes.def | 3 +-
gcc/symtab.c | 2 -
gcc/testsuite/gcc.target/i386/mvc9.c | 28 ++++++++++++++
4 files changed, 39 insertions(+), 65 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/i386/mvc9.c
diff --git a/gcc/multiple_target.c b/gcc/multiple_target.c
index 5be3980db20..7b735ae81ae 100644
--- a/gcc/multiple_target.c
+++ b/gcc/multiple_target.c
@@ -87,6 +87,7 @@ create_dispatcher_calls (struct cgraph_node *node)
inode->resolve_alias (cgraph_node::get (resolver_decl));
e->redirect_callee (inode);
+ e->redirect_call_stmt_to_callee ();
/* Since REDIRECT_CALLEE modifies NEXT_CALLER field we move to
previously set NEXT_CALLER. */
e = NULL;
@@ -283,6 +284,7 @@ expand_target_clones (struct cgraph_node *node, bool definition)
create_new_asm_name (attr, suffix);
/* Create new target clone. */
cgraph_node *new_node = create_target_clone (node, definition, suffix);
+ new_node->local.local = false;
XDELETEVEC (suffix);
/* Set new attribute for the clone. */
@@ -334,17 +336,19 @@ expand_target_clones (struct cgraph_node *node, bool definition)
return ret;
}
-static bool target_clone_pass;
-
static unsigned int
ipa_target_clone (void)
{
struct cgraph_node *node;
- target_clone_pass = false;
+ bool target_clone_pass = false;
FOR_EACH_FUNCTION (node)
- if (node->definition)
- target_clone_pass |= expand_target_clones (node, true);
+ target_clone_pass |= expand_target_clones (node, node->definition);
+
+ if (target_clone_pass)
+ FOR_EACH_FUNCTION (node)
+ create_dispatcher_calls (node);
+
return 0;
}
@@ -360,7 +364,7 @@ const pass_data pass_data_target_clone =
0, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
- 0 /* todo_flags_finish */
+ TODO_update_ssa /* todo_flags_finish */
};
class pass_target_clone : public simple_ipa_opt_pass
@@ -388,58 +392,3 @@ make_pass_target_clone (gcc::context *ctxt)
{
return new pass_target_clone (ctxt);
}
-
-static unsigned int
-ipa_dispatcher_calls (void)
-{
- struct cgraph_node *node;
-
- FOR_EACH_FUNCTION (node)
- if (!node->definition)
- target_clone_pass |= expand_target_clones (node, false);
- if (target_clone_pass)
- FOR_EACH_FUNCTION (node)
- create_dispatcher_calls (node);
- return 0;
-}
-
-namespace {
-
-const pass_data pass_data_dispatcher_calls =
-{
- SIMPLE_IPA_PASS, /* type */
- "dispatchercalls", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- TV_NONE, /* tv_id */
- ( PROP_ssa | PROP_cfg ), /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
-};
-
-class pass_dispatcher_calls : public simple_ipa_opt_pass
-{
-public:
- pass_dispatcher_calls (gcc::context *ctxt)
- : simple_ipa_opt_pass (pass_data_dispatcher_calls, ctxt)
- {}
-
- /* opt_pass methods: */
- virtual bool gate (function *);
- virtual unsigned int execute (function *) { return ipa_dispatcher_calls (); }
-};
-
-bool
-pass_dispatcher_calls::gate (function *)
-{
- return true;
-}
-
-} // anon namespace
-
-simple_ipa_opt_pass *
-make_pass_dispatcher_calls (gcc::context *ctxt)
-{
- return new pass_dispatcher_calls (ctxt);
-}
diff --git a/gcc/passes.def b/gcc/passes.def
index 131d659e7a0..c09ec220d70 100644
--- a/gcc/passes.def
+++ b/gcc/passes.def
@@ -136,6 +136,7 @@ along with GCC; see the file COPYING3. If not see
POP_INSERT_PASSES ()
POP_INSERT_PASSES ()
+ NEXT_PASS (pass_target_clone);
NEXT_PASS (pass_ipa_chkp_produce_thunks);
NEXT_PASS (pass_ipa_auto_profile);
NEXT_PASS (pass_ipa_free_inline_summary);
@@ -155,7 +156,6 @@ along with GCC; see the file COPYING3. If not see
NEXT_PASS (pass_ipa_devirt);
NEXT_PASS (pass_ipa_cp);
NEXT_PASS (pass_ipa_cdtor_merge);
- NEXT_PASS (pass_target_clone);
NEXT_PASS (pass_ipa_hsa);
NEXT_PASS (pass_ipa_inline);
NEXT_PASS (pass_ipa_pure_const);
@@ -174,7 +174,6 @@ along with GCC; see the file COPYING3. If not see
INSERT_PASSES_AFTER (all_late_ipa_passes)
NEXT_PASS (pass_materialize_all_clones);
NEXT_PASS (pass_ipa_pta);
- NEXT_PASS (pass_dispatcher_calls);
NEXT_PASS (pass_omp_simd_clone);
TERMINATE_PASS_LIST (all_late_ipa_passes)
diff --git a/gcc/symtab.c b/gcc/symtab.c
index 0078896c8a8..3f43b07dac7 100644
--- a/gcc/symtab.c
+++ b/gcc/symtab.c
@@ -2236,8 +2236,6 @@ symtab_node::binds_to_current_def_p (symtab_node *ref)
if (DECL_EXTERNAL (decl))
return false;
- gcc_assert (externally_visible);
-
if (ref)
{
cgraph_node *cref = dyn_cast <cgraph_node *> (ref);
diff --git a/gcc/testsuite/gcc.target/i386/mvc9.c b/gcc/testsuite/gcc.target/i386/mvc9.c
new file mode 100644
index 00000000000..69e3cefb7d1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mvc9.c
@@ -0,0 +1,28 @@
+/* { dg-do run } */
+/* { dg-require-ifunc "" } */
+/* { dg-options "-flto -O2" { target lto } } */
+
+__attribute__((target_clones("avx","arch=slm","arch=core-avx2","default")))
+int
+foo ()
+{
+ return -2;
+}
+
+int
+bar ()
+{
+ return 2;
+}
+
+int
+main ()
+{
+ int r = 0;
+ r += bar ();
+ r += foo ();
+ r += bar ();
+ r += foo ();
+ r += bar ();
+ return r - 2;
+}
--
2.11.0