This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH ARM] RFC: PR69770 -mlong-calls does not affect calls to __gnu_mcount_nc generated by -pg
- From: Charles Baylis <charles dot baylis at linaro dot org>
- To: Kyrylo Tkachov <kyrylo dot tkachov at arm dot com>, Ramana Radhakrishnan <Ramana dot Radhakrishnan at arm dot com>, Richard Earnshaw <Richard dot Earnshaw at arm dot com>
- Cc: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Fri, 12 Feb 2016 14:56:30 +0000
- Subject: [PATCH ARM] RFC: PR69770 -mlong-calls does not affect calls to __gnu_mcount_nc generated by -pg
- Authentication-results: sourceware.org; auth=none
When compiling with -mlong-calls and -pg, calls to the __gnu_mcount_nc
function are not generated as long calls.
This is encountered when building an allyesconfig Linux kernel because
the Linux build system generates very large sections by partial
linking a large number of object files. This causes link failures,
which don't go away with -mlong-calls due to this bug. (However, with
this patch linking still fails due to calls in inline asm)
For example:
extern void g(void);
int f() { g(); return 0; }
compiles to:
push {r4, lr}
push {lr}
bl __gnu_mcount_nc ;// not a long call
ldr r3, .L2
blx r3 ;// a long call to g()
mov r0, #0
pop {r4, pc}
The call to __gnu_mcount_nc is generated from ARM_FUNCTION_PROFILER in
config/arm/bpabi.h.
For targets without MOVW/MOVT, the long call sequence requires a load
from the literal pool, and it is too late to set up a literal pool
entry from within ARM_FUNCTION_PROFILER. My approach to fix this is to
modify the prologue generation to load the address of __gnu_mcount_nc
into ip, so that it is ready when the call is generated.
This patch only implements the fix for ARM and Thumb-2. A similar fix
is possible for Thumb-1, but requires more slightly complex changes to
the prologue generation to make sure there is a low register
available.
This feels like a bit of a hack to me, so ideas for a cleaner solution
are welcome, if none, is this acceptable for trunk now, or should it
wait until GCC 7?
From 34993396a43fcfc263db5b02b2d1837c490f52ad Mon Sep 17 00:00:00 2001
From: Charles Baylis <charles.baylis@linaro.org>
Date: Thu, 11 Feb 2016 18:07:00 +0000
Subject: [PATCH] [ARM] PR69770 fix -mlong-calls with -pg
gcc/ChangeLog:
2016-02-12 Charles Baylis <charles.baylis@linaro.org>
* config/arm/arm.c (arm_expand_prologue): Load address of
__gnu_mcount_nc in r12 if profiling and long calls are enabled.
* config/arm/bpabi.h (ARM_FUNCTION_PROFILER): Emit long call to
__gnu_mcount_nc long calls are enabled.
(ARM_FUNCTION_PROFILER_SUPPORTS_LONG_CALLS): New define.
gcc/testsuite/ChangeLog:
2016-02-12 Charles Baylis <charles.baylis@linaro.org>
* gcc.target/arm/pr69770.c: New test.
Change-Id: I4c639a5edf32fa8c67324d37faee1cb4ddd57a5c
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 27aecf7..9ce9a58 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -21739,6 +21739,15 @@ arm_expand_prologue (void)
arm_load_pic_register (mask);
}
+ if (crtl->profile && TARGET_LONG_CALLS
+ && ARM_FUNCTION_PROFILER_SUPPORTS_LONG_CALLS)
+ {
+ rtx tmp = gen_rtx_SET (gen_rtx_REG (SImode, IP_REGNUM),
+ gen_rtx_SYMBOL_REF (Pmode, "__gnu_mcount_nc"));
+ emit_insn (tmp);
+ emit_insn (gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, IP_REGNUM)));
+ }
+
/* If we are profiling, make sure no instructions are scheduled before
the call to mcount. Similarly if the user has requested no
scheduling in the prolog. Similarly if we want non-call exceptions
diff --git a/gcc/config/arm/bpabi.h b/gcc/config/arm/bpabi.h
index 82128ef..b734a24 100644
--- a/gcc/config/arm/bpabi.h
+++ b/gcc/config/arm/bpabi.h
@@ -173,11 +173,21 @@
#undef NO_PROFILE_COUNTERS
#define NO_PROFILE_COUNTERS 1
+#undef ARM_FUNCTION_PROFILER_SUPPORTS_LONG_CALLS
+#define ARM_FUNCTION_PROFILER_SUPPORTS_LONG_CALLS 1
#undef ARM_FUNCTION_PROFILER
#define ARM_FUNCTION_PROFILER(STREAM, LABELNO) \
{ \
- fprintf (STREAM, "\tpush\t{lr}\n"); \
- fprintf (STREAM, "\tbl\t__gnu_mcount_nc\n"); \
+ if (TARGET_LONG_CALLS && TARGET_32BIT) \
+ { \
+ fprintf (STREAM, "\tpush\t{lr}\n"); \
+ /* arm_expand_prolog() has already set up ip to contain the */ \
+ /* address of __gnu_mcount_nc. */ \
+ fprintf (STREAM, "\tblx\tip\n"); \
+ } else { \
+ fprintf (STREAM, "\tpush\t{lr}\n"); \
+ fprintf (STREAM, "\tbl\t__gnu_mcount_nc\n"); \
+ } \
}
#undef SUBTARGET_FRAME_POINTER_REQUIRED
diff --git a/gcc/testsuite/gcc.target/arm/pr69770.c b/gcc/testsuite/gcc.target/arm/pr69770.c
new file mode 100644
index 0000000..61e5c6d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pr69770.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-pg -mlong-calls" } */
+
+extern void g(void);
+
+int f() { g(); return 0; }
+
+/* { dg-final { scan-assembler-not "bl\[ \t\]+__gnu_mcount_nc" } } */
+/* { dg-final { scan-assembler "__gnu_mcount_nc" } } */
--
1.9.1