Commit 748d71f3 by Jan Hubicka Committed by Jan Hubicka

Workaround binutils PR14342


	Workaround binutils PR14342
	* tree-profile.c (init_ic_make_global_vars): Add LTO path.
	(gimple_init_edge_profiler): Likewise.
	(gimple_gen_ic_func_profiler): Likewise.

	* Makefile.in: Add _gcov_indirect_call_profiler_v2 symbol.
	* libgcov.c (L_gcov_indirect_call_profiler): Restore original API.
	(L_gcov_indirect_call_profiler_v2): New.

From-SVN: r201648
parent 5979aa54
2013-08-10 Jan Hubicka <jh@suse.cz>
Workaround binutils PR14342
* tree-profile.c (init_ic_make_global_vars): Add LTO path.
(gimple_init_edge_profiler): Likewise.
(gimple_gen_ic_func_profiler): Likewise.
2013-08-09 Jan Hubicka <jh@suse.cz> 2013-08-09 Jan Hubicka <jh@suse.cz>
* cgraph.c (cgraph_create_edge_1): Clear speculative flag. * cgraph.c (cgraph_create_edge_1): Clear speculative flag.
......
...@@ -67,13 +67,28 @@ init_ic_make_global_vars (void) ...@@ -67,13 +67,28 @@ init_ic_make_global_vars (void)
ptr_void = build_pointer_type (void_type_node); ptr_void = build_pointer_type (void_type_node);
ic_void_ptr_var /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
= build_decl (UNKNOWN_LOCATION, VAR_DECL, if (flag_lto)
get_identifier ("__gcov_indirect_call_callee"), {
ptr_void); ic_void_ptr_var
= build_decl (UNKNOWN_LOCATION, VAR_DECL,
get_identifier ("__gcov_indirect_call_callee_ltopriv"),
ptr_void);
TREE_PUBLIC (ic_void_ptr_var) = 1;
DECL_COMMON (ic_void_ptr_var) = 1;
DECL_VISIBILITY (ic_void_ptr_var) = VISIBILITY_HIDDEN;
DECL_VISIBILITY_SPECIFIED (ic_void_ptr_var) = true;
}
else
{
ic_void_ptr_var
= build_decl (UNKNOWN_LOCATION, VAR_DECL,
get_identifier ("__gcov_indirect_call_callee"),
ptr_void);
TREE_PUBLIC (ic_void_ptr_var) = 1;
DECL_EXTERNAL (ic_void_ptr_var) = 1;
}
TREE_STATIC (ic_void_ptr_var) = 1; TREE_STATIC (ic_void_ptr_var) = 1;
TREE_PUBLIC (ic_void_ptr_var) = 1;
DECL_EXTERNAL (ic_void_ptr_var) = 1;
DECL_ARTIFICIAL (ic_void_ptr_var) = 1; DECL_ARTIFICIAL (ic_void_ptr_var) = 1;
DECL_INITIAL (ic_void_ptr_var) = NULL; DECL_INITIAL (ic_void_ptr_var) = NULL;
if (targetm.have_tls) if (targetm.have_tls)
...@@ -83,13 +98,28 @@ init_ic_make_global_vars (void) ...@@ -83,13 +98,28 @@ init_ic_make_global_vars (void)
varpool_finalize_decl (ic_void_ptr_var); varpool_finalize_decl (ic_void_ptr_var);
gcov_type_ptr = build_pointer_type (get_gcov_type ()); gcov_type_ptr = build_pointer_type (get_gcov_type ());
ic_gcov_type_ptr_var /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
= build_decl (UNKNOWN_LOCATION, VAR_DECL, if (flag_lto)
get_identifier ("__gcov_indirect_call_counters"), {
gcov_type_ptr); ic_gcov_type_ptr_var
= build_decl (UNKNOWN_LOCATION, VAR_DECL,
get_identifier ("__gcov_indirect_call_counters_ltopriv"),
gcov_type_ptr);
TREE_PUBLIC (ic_gcov_type_ptr_var) = 1;
DECL_COMMON (ic_gcov_type_ptr_var) = 1;
DECL_VISIBILITY (ic_gcov_type_ptr_var) = VISIBILITY_HIDDEN;
DECL_VISIBILITY_SPECIFIED (ic_gcov_type_ptr_var) = true;
}
else
{
ic_gcov_type_ptr_var
= build_decl (UNKNOWN_LOCATION, VAR_DECL,
get_identifier ("__gcov_indirect_call_counters"),
gcov_type_ptr);
TREE_PUBLIC (ic_gcov_type_ptr_var) = 1;
DECL_EXTERNAL (ic_gcov_type_ptr_var) = 1;
}
TREE_STATIC (ic_gcov_type_ptr_var) = 1; TREE_STATIC (ic_gcov_type_ptr_var) = 1;
TREE_PUBLIC (ic_gcov_type_ptr_var) = 1;
DECL_EXTERNAL (ic_gcov_type_ptr_var) = 1;
DECL_ARTIFICIAL (ic_gcov_type_ptr_var) = 1; DECL_ARTIFICIAL (ic_gcov_type_ptr_var) = 1;
DECL_INITIAL (ic_gcov_type_ptr_var) = NULL; DECL_INITIAL (ic_gcov_type_ptr_var) = NULL;
if (targetm.have_tls) if (targetm.have_tls)
...@@ -157,15 +187,31 @@ gimple_init_edge_profiler (void) ...@@ -157,15 +187,31 @@ gimple_init_edge_profiler (void)
init_ic_make_global_vars (); init_ic_make_global_vars ();
/* void (*) (gcov_type, void *) */ /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
ic_profiler_fn_type if (flag_lto)
= build_function_type_list (void_type_node, {
gcov_type_node, /* void (*) (gcov_type, void *) */
ptr_void, ic_profiler_fn_type
NULL_TREE); = build_function_type_list (void_type_node,
tree_indirect_call_profiler_fn gcov_type_ptr, gcov_type_node,
= build_fn_decl ("__gcov_indirect_call_profiler_v2", ptr_void, ptr_void,
ic_profiler_fn_type); NULL_TREE);
tree_indirect_call_profiler_fn
= build_fn_decl ("__gcov_indirect_call_profiler",
ic_profiler_fn_type);
}
else
{
/* void (*) (gcov_type, void *) */
ic_profiler_fn_type
= build_function_type_list (void_type_node,
gcov_type_node,
ptr_void,
NULL_TREE);
tree_indirect_call_profiler_fn
= build_fn_decl ("__gcov_indirect_call_profiler_v2",
ic_profiler_fn_type);
}
TREE_NOTHROW (tree_indirect_call_profiler_fn) = 1; TREE_NOTHROW (tree_indirect_call_profiler_fn) = 1;
DECL_ATTRIBUTES (tree_indirect_call_profiler_fn) DECL_ATTRIBUTES (tree_indirect_call_profiler_fn)
= tree_cons (get_identifier ("leaf"), NULL, = tree_cons (get_identifier ("leaf"), NULL,
...@@ -375,8 +421,25 @@ gimple_gen_ic_func_profiler (void) ...@@ -375,8 +421,25 @@ gimple_gen_ic_func_profiler (void)
true, GSI_SAME_STMT); true, GSI_SAME_STMT);
tree_uid = build_int_cst tree_uid = build_int_cst
(gcov_type_node, cgraph_get_node (current_function_decl)->profile_id); (gcov_type_node, cgraph_get_node (current_function_decl)->profile_id);
stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 2, /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
tree_uid, cur_func); if (flag_lto)
{
tree counter_ptr, ptr_var;
counter_ptr = force_gimple_operand_gsi (&gsi, ic_gcov_type_ptr_var,
true, NULL_TREE, true,
GSI_SAME_STMT);
ptr_var = force_gimple_operand_gsi (&gsi, ic_void_ptr_var,
true, NULL_TREE, true,
GSI_SAME_STMT);
stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 4,
counter_ptr, tree_uid, cur_func, ptr_var);
}
else
{
stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 2,
tree_uid, cur_func);
}
gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT); gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
/* Set __gcov_indirect_call_callee to 0, /* Set __gcov_indirect_call_callee to 0,
......
2013-08-10 Jan Hubicka <jh@suse.cz>
Work around binutils PR14342
* Makefile.in: Add _gcov_indirect_call_profiler_v2 symbol.
* libgcov.c (L_gcov_indirect_call_profiler): Restore original API.
(L_gcov_indirect_call_profiler_v2): New.
2013-08-06 Jan Hubicka <jh@suse.cz> 2013-08-06 Jan Hubicka <jh@suse.cz>
* libgcov.c (__gcov_indirect_call_callee, * libgcov.c (__gcov_indirect_call_callee,
......
...@@ -858,7 +858,7 @@ LIBGCOV = _gcov _gcov_merge_add _gcov_merge_single _gcov_merge_delta \ ...@@ -858,7 +858,7 @@ LIBGCOV = _gcov _gcov_merge_add _gcov_merge_single _gcov_merge_delta \
_gcov_execv _gcov_execvp _gcov_execve _gcov_reset _gcov_dump \ _gcov_execv _gcov_execvp _gcov_execve _gcov_reset _gcov_dump \
_gcov_interval_profiler _gcov_pow2_profiler _gcov_one_value_profiler \ _gcov_interval_profiler _gcov_pow2_profiler _gcov_one_value_profiler \
_gcov_indirect_call_profiler _gcov_average_profiler _gcov_ior_profiler \ _gcov_indirect_call_profiler _gcov_average_profiler _gcov_ior_profiler \
_gcov_merge_ior _gcov_merge_ior _gcov_indirect_call_profiler_v2
libgcov-objects = $(patsubst %,%$(objext),$(LIBGCOV)) libgcov-objects = $(patsubst %,%$(objext),$(LIBGCOV))
......
...@@ -1120,6 +1120,42 @@ __gcov_one_value_profiler (gcov_type *counters, gcov_type value) ...@@ -1120,6 +1120,42 @@ __gcov_one_value_profiler (gcov_type *counters, gcov_type value)
#endif #endif
#ifdef L_gcov_indirect_call_profiler #ifdef L_gcov_indirect_call_profiler
/* This function exist only for workaround of binutils bug 14342.
Once this compatibility hack is obsolette, it can be removed. */
/* By default, the C++ compiler will use function addresses in the
vtable entries. Setting TARGET_VTABLE_USES_DESCRIPTORS to nonzero
tells the compiler to use function descriptors instead. The value
of this macro says how many words wide the descriptor is (normally 2),
but it may be dependent on target flags. Since we do not have access
to the target flags here we just check to see if it is set and use
that to set VTABLE_USES_DESCRIPTORS to 0 or 1.
It is assumed that the address of a function descriptor may be treated
as a pointer to a function. */
#ifdef TARGET_VTABLE_USES_DESCRIPTORS
#define VTABLE_USES_DESCRIPTORS 1
#else
#define VTABLE_USES_DESCRIPTORS 0
#endif
/* Tries to determine the most common value among its inputs. */
void
__gcov_indirect_call_profiler (gcov_type* counter, gcov_type value,
void* cur_func, void* callee_func)
{
/* If the C++ virtual tables contain function descriptors then one
function may have multiple descriptors and we need to dereference
the descriptors to see if they point to the same function. */
if (cur_func == callee_func
|| (VTABLE_USES_DESCRIPTORS && callee_func
&& *(void **) cur_func == *(void **) callee_func))
__gcov_one_value_profiler_body (counter, value);
}
#endif
#ifdef L_gcov_indirect_call_profiler_v2
/* These two variables are used to actually track caller and callee. Keep /* These two variables are used to actually track caller and callee. Keep
them in TLS memory so races are not common (they are written to often). them in TLS memory so races are not common (they are written to often).
...@@ -1135,7 +1171,6 @@ __thread ...@@ -1135,7 +1171,6 @@ __thread
#endif #endif
gcov_type * __gcov_indirect_call_counters; gcov_type * __gcov_indirect_call_counters;
/* By default, the C++ compiler will use function addresses in the /* By default, the C++ compiler will use function addresses in the
vtable entries. Setting TARGET_VTABLE_USES_DESCRIPTORS to nonzero vtable entries. Setting TARGET_VTABLE_USES_DESCRIPTORS to nonzero
tells the compiler to use function descriptors instead. The value tells the compiler to use function descriptors instead. The value
...@@ -1167,7 +1202,6 @@ __gcov_indirect_call_profiler_v2 (gcov_type value, void* cur_func) ...@@ -1167,7 +1202,6 @@ __gcov_indirect_call_profiler_v2 (gcov_type value, void* cur_func)
} }
#endif #endif
#ifdef L_gcov_average_profiler #ifdef L_gcov_average_profiler
/* Increase corresponding COUNTER by VALUE. FIXME: Perhaps we want /* Increase corresponding COUNTER by VALUE. FIXME: Perhaps we want
to saturate up. */ to saturate up. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment