aboutsummaryrefslogtreecommitdiff
path: root/elf/dl-profile.c
diff options
context:
space:
mode:
Diffstat (limited to 'elf/dl-profile.c')
-rw-r--r--elf/dl-profile.c21
1 files changed, 18 insertions, 3 deletions
diff --git a/elf/dl-profile.c b/elf/dl-profile.c
index 83e849561a..19d1865c25 100644
--- a/elf/dl-profile.c
+++ b/elf/dl-profile.c
@@ -19,6 +19,7 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
+#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
@@ -217,9 +218,23 @@ _dl_start_profile (struct link_map *map, const char *output_dir)
kcountsize = textsize / HISTFRACTION;
hashfraction = HASHFRACTION;
if ((HASHFRACTION & (HASHFRACTION - 1)) == 0)
- /* If HASHFRACTION is a power of two, mcount can use shifting
- instead of integer division. Precompute shift amount. */
- log_hashfraction = __ffs (hashfraction * sizeof (*froms)) - 1;
+ {
+ /* If HASHFRACTION is a power of two, mcount can use shifting
+ instead of integer division. Precompute shift amount.
+
+ This is a constant but the compiler cannot compile the
+ expression away since the __ffs implementation is not known
+ to the compiler. Help the compiler by precomputing the
+ usual cases. */
+ assert (hashfraction == 2);
+
+ if (sizeof (*froms) == 8)
+ log_hashfraction = 4;
+ else if (sizeof (*froms) == 16)
+ log_hashfraction = 5;
+ else
+ log_hashfraction = __ffs (hashfraction * sizeof (*froms)) - 1;
+ }
else
log_hashfraction = -1;
tossize = textsize / HASHFRACTION;