Ping
2015-05-05 11:06 GMT+03:00 Ilya Enkovich <enkovich....@gmail.com>: > Ping > > 2015-04-14 12:14 GMT+03:00 Ilya Enkovich <enkovich....@gmail.com>: >> On 10 Apr 03:15, Jan Hubicka wrote: >>> > >>> > References are not streamed out for nodes which are referenced in a >>> > partition but don't belong to it ('continue' condition in output_refs >>> > loop). >>> >>> Yeah, but it already special cases aliases (because we now always preserve >>> IPA_REF_ALIAS link >>> in the boundary, so I think making IPA_REF_CHKP to be rpeserved should go >>> the same path) >>> so we can special case the instrumentation thunks too? >> >> Any cgraph_node having instrumented clone should have it, not only >> instrumentation thunks. Surely we can make an exception for IPA_REF_CHKP. >> >>> > >>> > > >>> > > I suppose we still need to >>> > > 1) write_symbol and lto-symtab should know that transparent aliases >>> > > are not real >>> > > symbols and ignore them. We have predicate >>> > > symtab_node::real_symbol_p, >>> > > I suppose it should return true. >>> > > >>> > > I think cgraph_merge and varpool_merge in lto-symtab needs to know >>> > > what to do >>> > > when merging two symbols with transparent aliases. >>> > > 2) At some point we need to populate transparent alias links as >>> > > discussed in the >>> > > other thread. >>> > > 3) For safety, I guess we want >>> > > symbol_table::change_decl_assembler_name to either >>> > > sanity check there are no trasparent alias links pointing to old >>> > > assembler >>> > > names or update it. >>> > >>> > Wouldn't search for possible referring via transparent aliases nodes >>> > be too expensive? >>> >>> Changing of decl_assembler_name is not very common and if we set up the >>> links >>> only after renaming of statics, i think we are safe. But it would be better >>> to >>> keep verify it at some point. >>> >>> I suppose verify_node check that there is no transparent alias link on >>> symbols >>> were it is not supposed to be and that there is link when it is supposed to >>> be (i.e. >>> symtab_state is >=EXPANSION and symbol is either weakref on tragets w/o >>> native weakrefs >>> or instrumentation cone. >>> >>> Would you please mind adding the test and making sure it triggers when >>> things are >>> out of sync? >>> >> >> OK, but I suppose it should be a part of transparent alias links rework >> discussed in another thread. BTW are you going to intoroduce transparent >> aliases in cgraph soon? >> >>> > >>> > > 4) I think we want verify_node to check that transparent alias links >>> > > and chkp points >>> > > as intended and only on those symbols where they need to be >>> > > >>> > > There is also logic in lto-partition to always insert alias target >>> > >> > OK, so you have the chkp references that links to >>> > >> > instrumented_version. >>> > >> > You do not stream them for boundary symbols but for some reason they >>> > >> > are needed, >>> > >> > but when you can end up with wrong CHKP link? >>> > >> >>> > >> Wrong links may appear when cgraph nodes are merged. >>> > > >>> > > I see, I think you really want to fix these at merging time as sugested >>> > > in 1). >>> > > In this case even the node->instrumented_version pointer may be out of >>> > > date and >>> > > point to a node that lost in merging? >>> > >>> > node->instrumented_version is redirected and never points to lost >>> > symbol. But during merge we may have situations when >>> > (node->instrumented_version->instrumented_version != node) because of >>> > multiple not merged (yet) symbols referencing the same merged target. >>> >>> OK, which should not be a problem if we stream the links instead of >>> rebuilding them, right? >> >> IPA_REF_CHKP refs don't affect instrumented_version merging. And I actually >> don't see here any problems, instrumented_version links always come into >> consistent state when symbol merging finishes. >> >> >> Here is a new patch version. It has no chkp_maybe_fix_chkp_ref function, >> IPA_REF_CHKP references are streamed out instead. Bootstrapped and tested >> on x86_64-unknown-linux-gnu. OK for trunk? I also want to port it to GCC 5 >> branch after release. >> >> Thanks, >> Ilya >> -- >> gcc/ >> >> 2015-04-14 Ilya Enkovich <ilya.enkov...@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. >> >> gcc/testsuite/ >> >> 2015-04-14 Ilya Enkovich <ilya.enkov...@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.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 ac50e4b..ea352f1 100644 >> --- a/gcc/lto-cgraph.c >> +++ b/gcc/lto-cgraph.c >> @@ -805,8 +805,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) >> 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/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; >> +}