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:
Ilya Enkovich 2015-06-03 08:29:28 +00:00 committed by Ilya Enkovich
parent b2858c9f3e
commit 48de5d37c3
10 changed files with 174 additions and 37 deletions

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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;
}

View File

@ -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

View File

@ -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);
}

View File

@ -0,0 +1,11 @@
static int __attribute__((noinline))
f2 (int i)
{
return 2 * i;
}
int __attribute__((noinline))
f1 (int i)
{
return f2 (i) + 10;
}

View File

@ -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;
}

View File

@ -0,0 +1,8 @@
int func1 = 10;
int
func2 (int i)
{
func1++;
return i + func1;
}