This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: RFA: Prevent double execution of MIPS call stubs
"Maciej W. Rozycki" <macro@linux-mips.org> writes:
> On Wed, 17 Oct 2007, Richard Sandiford wrote:
>
>> This isn't a full fix though: const functions don't clobber memory,
>> so loads of their address can still be hoisted. E.g. for:
>
> Just a thought from a GCC non-expert -- can't the address of the function
> itself be marked as clobbered with a call somehow?
Not directly: the address itself is always considered to be constant,
and is assumed to be the canonical function address. We're therefore
using an UNSPEC wrapper around the address to expose the fact that the
value we're loading is not always the canonical address. Dan and I were
trying to find some way of making that UNSPEC call-clobbered. The old
code did this by including a call-clobbered register as an operand to
the UNSPEC, but that no longer works.
FWIW, one alternative would be to switch the sense of FAKE_CALL_REGNO
around: make the load_call* patterns set it and the calls use it.
We've giving up on the idea of making the UNSPEC itself call-clobbered,
and instead just relying on the fact that load_call* is the only way
of setting FAKE_CALL_REGNO to the correct value.
What about the patch below (which is missing changes to the commentary
above load_call*; I'd fix that before committing)? It seems to work
with the example I posted earlier. I'll give it a spin to see how
things go.
Richard
gcc/
* config/mips/mips.c (mips_expand_call): Use FAKE_CALL_REGNO.
* config/mips/mips.md (load_call<mode>): Don't make the unspec
depend on FAKE_CALL_REGNO. Set FAKE_CALL_REGNO.
Index: gcc/config/mips/mips.c
===================================================================
--- gcc/config/mips/mips.c 2007-10-17 16:01:31.000000000 +0100
+++ gcc/config/mips/mips.c 2007-10-17 16:01:50.000000000 +0100
@@ -4208,7 +4208,11 @@ mips_expand_call (rtx result, rtx addr,
/* Lazy-binding stubs require $gp to be valid on entry. */
if (mips_ok_for_lazy_binding_p (orig_addr))
- use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
+ {
+ use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx);
+ use_reg (&CALL_INSN_FUNCTION_USAGE (insn),
+ gen_rtx_REG (Pmode, FAKE_CALL_REGNO));
+ }
}
Index: gcc/config/mips/mips.md
===================================================================
--- gcc/config/mips/mips.md 2007-10-17 16:01:25.000000000 +0100
+++ gcc/config/mips/mips.md 2007-10-17 16:08:17.000000000 +0100
@@ -5612,9 +5612,10 @@ (define_insn_and_split "nonlocal_goto_re
(define_insn "load_call<mode>"
[(set (match_operand:P 0 "register_operand" "=d")
(unspec:P [(match_operand:P 1 "register_operand" "r")
- (match_operand:P 2 "immediate_operand" "")
- (reg:P FAKE_CALL_REGNO)]
- UNSPEC_LOAD_CALL))]
+ (match_operand:P 2 "immediate_operand" "")]
+ UNSPEC_LOAD_CALL))
+ (set (reg:P FAKE_CALL_REGNO)
+ (unspec:P [(match_dup 2)] UNSPEC_LOAD_CALL))]
"TARGET_USE_GOT"
"<load>\t%0,%R2(%1)"
[(set_attr "type" "load")