[Bug gcov-profile/55734] [4.8 Regression] gcov-io.c uses builtins not available in non-GCC compilers
tejohnson at google dot com
gcc-bugzilla@gcc.gnu.org
Wed Dec 19 06:50:00 GMT 2012
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55734
--- Comment #13 from Teresa Johnson <tejohnson at google dot com> 2012-12-19 06:49:50 UTC ---
On Tue, Dec 18, 2012 at 2:48 PM, Teresa Johnson <tejohnson@google.com> wrote:
>
>
>
>
> On Tue, Dec 18, 2012 at 2:41 PM, aldyh at gcc dot gnu.org <gcc-bugzilla@gcc.gnu.org> wrote:
>>
>>
>> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55734
>>
>> --- Comment #11 from Aldy Hernandez <aldyh at gcc dot gnu.org> 2012-12-18 22:41:13 UTC ---
>> Teresa, I think this is what you were referring to, and the reason for my
>> original patch:
>>
>> houston:/build/trunkboot$ ./install/bin/gcc a.c -fprofile-generate
>> /home/build/trunkboot/install/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.8.0/libgcov.a(_gcov.o):
>> In function `gcov_histo_index':
>> libgcov.c:(.text+0x213): undefined reference to `clz_hwi'
>> /home/build/trunkboot/install/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.8.0/libgcov.a(_gcov.o):
>> In function `__gcov_read_summary':
>> libgcov.c:(.text+0x7f3): undefined reference to `popcount_hwi'
>> collect2: error: ld returned 1 exit status
>
>
> Yep. I've got a patch in the works that is a slightly simplified version of what you did. I'll send that a little later today once I get it tested.
Here is the patch. I am doing some final regression testing on it, but
earlier testing and my own testing looked good. It is similar to what
Aldy did, pulling some of the hwi routines into a new hwint-helper.c
file. However, in this case, it is included normally into hwint.c, and
the routines are only pulled in as static copies to gcov-io.c when we
are building libgcov.a (in other cases gcov-io.c is being built when
system.h is included, which includes hwint.h already). In the case of
libgcov.a, I also had to add support for the fact that the HOST_*
variables that were being used in the hwint routines are not defined.
Richard, let me know if this looks like a reasonable approach. The
only other solution I had was to simply inline copies of popcount_hwi
and clz_hwi into gcov-io.c when we are building libgcov.a.
Thanks,
Teresa
2012-12-18 Teresa Johnson <tejohnson@google.com>
Aldy Hernandez <aldyh@redhat.com>
* hwint-helper.c (floor_log2): Moved from hwint.c
(ceil_log2): Ditto.
(exact_log2): Ditto.
(ctz_hwi): Ditto.
(clz_hwi): Ditto.
(ffs_hwi): Ditto.
(popcount_hwi): Ditto.
* gcov-io.c (gcov_read_summary): Invoke popcount_hwi.
(gcov_histo_index): Invoke clz_hwi.
* Makefile.in (hwint.o): Depend on hwint-helper.c
* hwint.c (floor_log2): Moved to hwint-helper.c
(ceil_log2): Ditto.
(exact_log2): Ditto.
(ctz_hwi): Ditto.
(clz_hwi): Ditto.
(ffs_hwi): Ditto.
(popcount_hwi): Ditto.
Index: hwint-helper.c
===================================================================
--- hwint-helper.c (revision 0)
+++ hwint-helper.c (revision 0)
@@ -0,0 +1,130 @@
+/* Supporting bit functions for older versions of GCC, and non-GCC
+ bootstrap compilers.
+
+ Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+ 2012 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+<http://www.gnu.org/licenses/>. */
+
+#if GCC_VERSION < 3004
+
+/* The functions clz_hwi, ctz_hwi, ffs_hwi, floor_log2, ceil_log2,
+ and exact_log2 are defined as inline functions in hwint.h
+ if GCC_VERSION >= 3004.
+ The definitions here are used for older versions of GCC and
+ non-GCC bootstrap compilers. */
+
+/* Given X, an unsigned number, return the largest int Y such that 2**Y <= X.
+ If X is 0, return -1. */
+
+HWINT_LINKAGE int
+floor_log2 (HWINT_TYPE x)
+{
+ int t = 0;
+
+ if (x == 0)
+ return -1;
+
+ if (HWINT_TYPE_SIZE > 64)
+ if (x >= (HWINT_TYPE) 1 << (t + 64))
+ t += 64;
+ if (HWINT_TYPE_SIZE > 32)
+ if (x >= ((HWINT_TYPE) 1) << (t + 32))
+ t += 32;
+ if (x >= ((HWINT_TYPE) 1) << (t + 16))
+ t += 16;
+ if (x >= ((HWINT_TYPE) 1) << (t + 8))
+ t += 8;
+ if (x >= ((HWINT_TYPE) 1) << (t + 4))
+ t += 4;
+ if (x >= ((HWINT_TYPE) 1) << (t + 2))
+ t += 2;
+ if (x >= ((HWINT_TYPE) 1) << (t + 1))
+ t += 1;
+
+ return t;
+}
+
+/* Given X, an unsigned number, return the largest Y such that 2**Y >= X. */
+
+HWINT_LINKAGE int
+ceil_log2 (HWINT_TYPE x)
+{
+ return floor_log2 (x - 1) + 1;
+}
+
+/* Return the logarithm of X, base 2, considering X unsigned,
+ if X is a power of 2. Otherwise, returns -1. */
+
+HWINT_LINKAGE int
+exact_log2 (HWINT_TYPE x)
+{
+ if (x != (x & -x))
+ return -1;
+ return floor_log2 (x);
+}
+
+/* Given X, an unsigned number, return the number of least significant bits
+ that are zero. When X == 0, the result is the word size. */
+
+HWINT_LINKAGE int
+ctz_hwi (HWINT_TYPE x)
+{
+ return x ? floor_log2 (x & -x) : HWINT_TYPE_SIZE;
+}
+
+/* Similarly for most significant bits. */
+
+HWINT_LINKAGE int
+clz_hwi (HWINT_TYPE x)
+{
+ return HWINT_TYPE_SIZE - 1 - floor_log2 (x);
+}
+
+/* Similar to ctz_hwi, except that the least significant bit is numbered
+ starting from 1, and X == 0 yields 0. */
+
+HWINT_LINKAGE int
+ffs_hwi (HWINT_TYPE x)
+{
+ return 1 + floor_log2 (x & -x);
+}
+
+/* Return the number of set bits in X. */
+
+HWINT_LINKAGE int
+popcount_hwi (HWINT_TYPE x)
+{
+ int i, ret = 0;
+ size_t bits = sizeof (x) * CHAR_BIT;
+
+ for (i = 0; i < (int)bits; i += 1)
+ {
+ ret += x & 1;
+ x >>= 1;
+ }
+
+ return ret;
+}
+
+#endif /* GCC_VERSION < 3004 */
Index: gcov-io.c
===================================================================
--- gcov-io.c (revision 194585)
+++ gcov-io.c (working copy)
@@ -517,6 +517,18 @@ gcov_read_string (void)
}
#endif
+#if IN_LIBGCOV
+#if GCC_VERSION < 3004
+#define HWINT_LINKAGE inline static
+#define HWINT_TYPE gcov_type_unsigned
+#define HWINT_TYPE_SIZE LONG_LONG_TYPE_SIZE
+#include "hwint-helper.c"
+#else
+#define popcount_hwi __builtin_popcountll
+#define clz_hwi __builtin_clzll
+#endif
+#endif
+
GCOV_LINKAGE void
gcov_read_summary (struct gcov_summary *summary)
{
@@ -538,7 +550,7 @@ gcov_read_summary (struct gcov_summary *summary)
for (bv_ix = 0; bv_ix < GCOV_HISTOGRAM_BITVECTOR_SIZE; bv_ix++)
{
histo_bitvector[bv_ix] = gcov_read_unsigned ();
- h_cnt += __builtin_popcountll (histo_bitvector[bv_ix]);
+ h_cnt += popcount_hwi (histo_bitvector[bv_ix]);
}
bv_ix = 0;
h_ix = 0;
@@ -642,7 +654,7 @@ gcov_histo_index (gcov_type value)
/* Find the place of the most-significant bit set. */
if (v > 0)
- r = 63 - __builtin_clzll (v);
+ r = 63 - clz_hwi (v);
/* If at most the 2 least significant bits are set (value is
0 - 3) then that value is our index into the lowest set of
Index: Makefile.in
===================================================================
--- Makefile.in (revision 194585)
+++ Makefile.in (working copy)
@@ -2701,7 +2701,7 @@ toplev.o : toplev.c $(CONFIG_H) $(SYSTEM_H) corety
$(TREE_PRETTY_PRINT_H) opts-diagnostic.h $(COMMON_TARGET_H) \
tsan.h
-hwint.o : hwint.c $(CONFIG_H) $(SYSTEM_H) $(DIAGNOSTIC_CORE_H)
+hwint.o : hwint.c $(CONFIG_H) $(SYSTEM_H) $(DIAGNOSTIC_CORE_H) hwint-helper.c
passes.o : passes.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
$(RTL_H) $(FUNCTION_H) $(FLAGS_H) $(INPUT_H) $(INSN_ATTR_H) output.h \
Index: hwint.c
===================================================================
--- hwint.c (revision 194585)
+++ hwint.c (working copy)
@@ -23,109 +23,11 @@ along with GCC; see the file COPYING3. If not see
#include "system.h"
#include "diagnostic-core.h"
-#if GCC_VERSION < 3004
+#define HWINT_LINKAGE
+#define HWINT_TYPE unsigned HOST_WIDE_INT
+#define HWINT_TYPE_SIZE HOST_BITS_PER_WIDE_INT
+#include "hwint-helper.c"
-/* The functions clz_hwi, ctz_hwi, ffs_hwi, floor_log2, ceil_log2,
- and exact_log2 are defined as inline functions in hwint.h
- if GCC_VERSION >= 3004.
- The definitions here are used for older versions of GCC and
- non-GCC bootstrap compilers. */
-
-/* Given X, an unsigned number, return the largest int Y such that 2**Y <= X.
- If X is 0, return -1. */
-
-int
-floor_log2 (unsigned HOST_WIDE_INT x)
-{
- int t = 0;
-
- if (x == 0)
- return -1;
-
- if (HOST_BITS_PER_WIDE_INT > 64)
- if (x >= (unsigned HOST_WIDE_INT) 1 << (t + 64))
- t += 64;
- if (HOST_BITS_PER_WIDE_INT > 32)
- if (x >= ((unsigned HOST_WIDE_INT) 1) << (t + 32))
- t += 32;
- if (x >= ((unsigned HOST_WIDE_INT) 1) << (t + 16))
- t += 16;
- if (x >= ((unsigned HOST_WIDE_INT) 1) << (t + 8))
- t += 8;
- if (x >= ((unsigned HOST_WIDE_INT) 1) << (t + 4))
- t += 4;
- if (x >= ((unsigned HOST_WIDE_INT) 1) << (t + 2))
- t += 2;
- if (x >= ((unsigned HOST_WIDE_INT) 1) << (t + 1))
- t += 1;
-
- return t;
-}
-
-/* Given X, an unsigned number, return the largest Y such that 2**Y >= X. */
-
-int
-ceil_log2 (unsigned HOST_WIDE_INT x)
-{
- return floor_log2 (x - 1) + 1;
-}
-
-/* Return the logarithm of X, base 2, considering X unsigned,
- if X is a power of 2. Otherwise, returns -1. */
-
-int
-exact_log2 (unsigned HOST_WIDE_INT x)
-{
- if (x != (x & -x))
- return -1;
- return floor_log2 (x);
-}
-
-/* Given X, an unsigned number, return the number of least significant bits
- that are zero. When X == 0, the result is the word size. */
-
-int
-ctz_hwi (unsigned HOST_WIDE_INT x)
-{
- return x ? floor_log2 (x & -x) : HOST_BITS_PER_WIDE_INT;
-}
-
-/* Similarly for most significant bits. */
-
-int
-clz_hwi (unsigned HOST_WIDE_INT x)
-{
- return HOST_BITS_PER_WIDE_INT - 1 - floor_log2(x);
-}
-
-/* Similar to ctz_hwi, except that the least significant bit is numbered
- starting from 1, and X == 0 yields 0. */
-
-int
-ffs_hwi (unsigned HOST_WIDE_INT x)
-{
- return 1 + floor_log2 (x & -x);
-}
-
-/* Return the number of set bits in X. */
-
-int
-popcount_hwi (unsigned HOST_WIDE_INT x)
-{
- int i, ret = 0;
- size_t bits = sizeof (x) * CHAR_BIT;
-
- for (i = 0; i < bits; i += 1)
- {
- ret += x & 1;
- x >>= 1;
- }
-
- return ret;
-}
-
-#endif /* GCC_VERSION < 3004 */
-
/* Compute the absolute value of X. */
HOST_WIDE_INT
>
> Teresa
>>
>>
>> --
>> Configure bugmail: http://gcc.gnu.org/bugzilla/userprefs.cgi?tab=email
>> ------- You are receiving this mail because: -------
>> You are on the CC list for the bug.
>
>
>
>
> --
> Teresa Johnson | Software Engineer | tejohnson@google.com | 408-460-2413
>
--
Teresa Johnson | Software Engineer | tejohnson@google.com | 408-460-2413
More information about the Gcc-bugs
mailing list