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
Daniel Jacobowitz <drow@false.org> writes:
> On Wed, Oct 17, 2007 at 04:19:35PM +0100, Richard Sandiford wrote:
>> 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.
>
> 10803 case HAZARD_DELAY:
> 10804 set = single_set (insn);
> 10805 gcc_assert (set != 0);
>
> Making loadsi into a parallel set means it is no longer single_set.
> I am testing this horrid adjustment:
>
> if (GET_CODE (PATTERN (insn)) == PARALLEL
> && XVECLEN (PATTERN (insn), 0) == 2
> && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == SET
> && GET_CODE (XVECEXP (PATTERN (insn), 0, 1)) == SET
> && GET_CODE (SET_DEST (XVECEXP (PATTERN (insn), 0, 1))) ==
> REG
> && (REGNO (SET_DEST (XVECEXP (PATTERN (insn), 0, 1)))
> == FAKE_CALL_REGNO))
> set = XVECEXP (PATTERN (insn), 0, 0);
> else
> set = single_set (insn);
Yeah, my build failed in the same way. I think the version below
is a little cleaner, so I'll test that.
It's probably more productive if I wait until I get a clean run with the
patch first, then post the version that seems to work. I only posted an
untested patch to avoid duplication of effort; sorry for wasting your
time here.
Richard
gcc/
* config/mips/mips.c (mips_expand_call): Use FAKE_CALL_REGNO.
(mips_avoid_hazard): Allow multiple sets for HAZARD_DELAY,
and pick the first.
* 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 22:59:11.000000000 +0100
+++ gcc/config/mips/mips.c 2007-10-17 22:59:30.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));
+ }
}
@@ -10793,8 +10797,10 @@ mips_avoid_hazard (rtx after, rtx insn,
break;
case HAZARD_DELAY:
- set = single_set (insn);
- gcc_assert (set != 0);
+ set = PATTERN (insn);
+ if (GET_CODE (set) == PARALLEL)
+ set = XVECEXP (set, 0, 0);
+ gcc_assert (GET_CODE (set) == SET);
*delayed_reg = SET_DEST (set);
break;
}
Index: gcc/config/mips/mips.md
===================================================================
--- gcc/config/mips/mips.md 2007-10-17 22:59:11.000000000 +0100
+++ gcc/config/mips/mips.md 2007-10-17 22:59:14.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")