summaryrefslogtreecommitdiff
path: root/libgcc
diff options
context:
space:
mode:
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2013-08-10 20:52:06 +0000
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2013-08-10 20:52:06 +0000
commit4771c0ac5aa3f5e2483d8ec651ce85a06684b5ec (patch)
treece0c2d8826c16bf6bbfa6330c50f8f407eb91463 /libgcc
parent136bc3b3d78303a8b8c6a30de715fcadd601c9fd (diff)
downloadlinaro-gcc-4771c0ac5aa3f5e2483d8ec651ce85a06684b5ec.tar.gz
linaro-gcc-4771c0ac5aa3f5e2483d8ec651ce85a06684b5ec.tar.bz2
linaro-gcc-4771c0ac5aa3f5e2483d8ec651ce85a06684b5ec.zip
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@201648 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgcc')
-rw-r--r--libgcc/ChangeLog7
-rw-r--r--libgcc/Makefile.in2
-rw-r--r--libgcc/libgcov.c38
3 files changed, 44 insertions, 3 deletions
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog
index f098a42ba6c..438514fae44 100644
--- a/libgcc/ChangeLog
+++ b/libgcc/ChangeLog
@@ -1,3 +1,10 @@
+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>
* libgcov.c (__gcov_indirect_call_callee,
diff --git a/libgcc/Makefile.in b/libgcc/Makefile.in
index 63fd626da40..354fb72d984 100644
--- a/libgcc/Makefile.in
+++ b/libgcc/Makefile.in
@@ -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_interval_profiler _gcov_pow2_profiler _gcov_one_value_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))
diff --git a/libgcc/libgcov.c b/libgcc/libgcov.c
index 93b8bd99963..d1a989274f4 100644
--- a/libgcc/libgcov.c
+++ b/libgcc/libgcov.c
@@ -1120,6 +1120,42 @@ __gcov_one_value_profiler (gcov_type *counters, gcov_type value)
#endif
#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
them in TLS memory so races are not common (they are written to often).
@@ -1135,7 +1171,6 @@ __thread
#endif
gcov_type * __gcov_indirect_call_counters;
-
/* 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
@@ -1167,7 +1202,6 @@ __gcov_indirect_call_profiler_v2 (gcov_type value, void* cur_func)
}
#endif
-
#ifdef L_gcov_average_profiler
/* Increase corresponding COUNTER by VALUE. FIXME: Perhaps we want
to saturate up. */