ipa.c (symbol_table::remove_unreachable_nodes): Don't remove instumentation thunks calling reachable functions.
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
This commit is contained in:
parent
b2858c9f3e
commit
48de5d37c3
|
@ -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
|
||||
|
|
14
gcc/cgraph.c
14
gcc/cgraph.c
|
@ -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)
|
||||
|
|
16
gcc/ipa.c
16
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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -900,7 +900,36 @@ validize_symbol_for_target (symtab_node *node)
|
|||
}
|
||||
}
|
||||
|
||||
/* Mangle NODE symbol name into a local name.
|
||||
/* Helper for privatize_symbol_name. Mangle NODE symbol name
|
||||
represented by DECL. */
|
||||
|
||||
static bool
|
||||
privatize_symbol_name_1 (symtab_node *node, tree decl)
|
||||
{
|
||||
const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
|
||||
|
||||
if (must_not_rename (node, name))
|
||||
return false;
|
||||
|
||||
name = maybe_rewrite_identifier (name);
|
||||
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.
|
||||
|
@ -910,50 +939,33 @@ validize_symbol_for_target (symtab_node *node)
|
|||
static bool
|
||||
privatize_symbol_name (symtab_node *node)
|
||||
{
|
||||
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));
|
||||
|
||||
if (must_not_rename (node, name))
|
||||
if (!privatize_symbol_name_1 (node, node->decl))
|
||||
return false;
|
||||
|
||||
name = maybe_rewrite_identifier (name);
|
||||
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)));
|
||||
/* 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);
|
||||
else if (cnode->instrumented_version
|
||||
&& cnode->instrumented_version->orig_decl == decl)
|
||||
iname = DECL_ASSEMBLER_NAME (cnode->instrumented_version->decl);
|
||||
|
||||
if (iname)
|
||||
{
|
||||
gcc_assert (IDENTIFIER_TRANSPARENT_ALIAS (iname));
|
||||
TREE_CHAIN (iname) = DECL_ASSEMBLER_NAME (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 == cnode->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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
static int __attribute__((noinline))
|
||||
f2 (int i)
|
||||
{
|
||||
return 2 * i;
|
||||
}
|
||||
|
||||
int __attribute__((noinline))
|
||||
f1 (int i)
|
||||
{
|
||||
return f2 (i) + 10;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
int func1 = 10;
|
||||
|
||||
int
|
||||
func2 (int i)
|
||||
{
|
||||
func1++;
|
||||
return i + func1;
|
||||
}
|
Loading…
Reference in New Issue