On 02/02/2017 02:18 PM, Martin Liška wrote: > 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:
After reading of the original thread, it's still unclear why 2 passes we introduced. As I read the original patch, there was just one. Having pre-approved patch by Honza, I'll install that after testing. Martin > > $ ./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 e2ff9bb3ebe8f005e7334780ede92dab6afb1a07 Mon Sep 17 00:00:00 2001 From: marxin <mli...@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 <mli...@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. gcc/testsuite/ChangeLog: 2017-01-24 Martin Liska <mli...@suse.cz> * gcc.target/i386/mvc9.c: New test. --- gcc/multiple_target.c | 71 +++++------------------------------- gcc/passes.def | 3 +- gcc/testsuite/gcc.target/i386/mvc9.c | 28 ++++++++++++++ 3 files changed, 39 insertions(+), 63 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/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