* Committed: Fix problems with RX sibcall patterns
@ 2009-11-26 11:29 Nick Clifton
2009-11-30 20:56 ` Richard Henderson
0 siblings, 1 reply; 4+ messages in thread
From: Nick Clifton @ 2009-11-26 11:29 UTC (permalink / raw)
To: gcc-patches
Hi Guys,
I am checking in the patch below to fix a couple of problems with
the RX sibcall patterns. The first was that they were being allowed
inside interrupt handlers, which does not work since these functions
need special return instructions.
The other problem was that the patterns contained a bogus USE
statement that was confusing the label checking code.
Cheers
Nick
gcc/ChangeLog
2009-11-26 Nick Clifton <nickc@redhat.com>
* config/rx/rx.c (rx_expand_epilogue): Add checks for sibcalls
being used incorrectly.
(rx_function_ok_for_sibcall): New function. Do not allow indirect
sibcalls, or sibcalls from interrupt functions.
(TARGET_FUNCTION_OK_FOR_SIBCALL): Define.
* config/rx/rx.md (sibcall): Convert to a define_expand. Check
for a MEM inside a MEM.
(sibcall_value): Likewise.
(sibcall_internal): New pattern containing old sibcall pattern.
(sibcall_value_internal): Likewise.
Index: gcc/config/rx/rx.md
===================================================================
--- gcc/config/rx/rx.md (revision 154669)
+++ gcc/config/rx/rx.md (working copy)
@@ -388,7 +388,7 @@
(match_operand:SI 1 "general_operand" "g,g"))]
""
"@
- jsr\t%A0
+ jsr\t%0
bsr\t%A0"
[(set_attr "length" "2,4")
(set_attr "timings" "33")]
@@ -415,32 +415,60 @@
(match_operand:SI 2 "general_operand" "g,g")))]
""
"@
- jsr\t%A1
+ jsr\t%1
bsr\t%A1"
[(set_attr "length" "2,4")
(set_attr "timings" "33")]
)
-(define_insn "sibcall"
- [(call (mem:QI (match_operand:SI 0 "rx_symbolic_call_operand" "Symbol"))
- (match_operand:SI 1 "general_operand" "g"))
- (return)
- (use (match_operand 2 "" ""))]
+;; Note - we do not allow indirect sibcalls (with the address
+;; held in a register) because we cannot guarantee that the register
+;; chosen will be a call-used one. If it is a call-saved register,
+;; then the epilogue code will corrupt it by popping the saved value
+;; off of the stack.
+(define_expand "sibcall"
+ [(parallel
+ [(call (mem:QI (match_operand:SI 0 "rx_symbolic_call_operand"))
+ (match_operand:SI 1 "general_operand"))
+ (return)])]
""
+ {
+ if (MEM_P (operands[0]))
+ operands[0] = XEXP (operands[0], 0);
+ }
+)
+
+(define_insn "sibcall_internal"
+ [(call (mem:QI (match_operand:SI 0 "rx_symbolic_call_operand" "Symbol"))
+ (match_operand:SI 1 "general_operand" "g"))
+ (return)]
+ ""
"bra\t%A0"
- [(set_attr "length" "4")
+ [(set_attr "length" "4")
(set_attr "timings" "33")]
)
-(define_insn "sibcall_value"
+(define_expand "sibcall_value"
+ [(parallel
+ [(set (match_operand 0 "register_operand")
+ (call (mem:QI (match_operand:SI 1 "rx_symbolic_call_operand"))
+ (match_operand:SI 2 "general_operand")))
+ (return)])]
+ ""
+ {
+ if (MEM_P (operands[1]))
+ operands[1] = XEXP (operands[1], 0);
+ }
+)
+
+(define_insn "sibcall_value_internal"
[(set (match_operand 0 "register_operand" "=r")
(call (mem:QI (match_operand:SI 1 "rx_symbolic_call_operand" "Symbol"))
(match_operand:SI 2 "general_operand" "g")))
- (return)
- (use (match_operand 3 "" ""))]
+ (return)]
""
"bra\t%A1"
- [(set_attr "length" "4")
+ [(set_attr "length" "4")
(set_attr "timings" "33")]
)
Index: gcc/config/rx/rx.c
===================================================================
--- gcc/config/rx/rx.c (revision 154669)
+++ gcc/config/rx/rx.c (working copy)
@@ -1190,7 +1190,7 @@
{
unsigned int i;
- for (i = 0; i < XVECLEN (insn, 0); i++)
+ for (i = 0; i < (unsigned) XVECLEN (insn, 0); i++)
RTX_FRAME_RELATED_P (XVECEXP (insn, 0, i)) = 1;
}
}
@@ -1454,8 +1454,26 @@
unsigned int reg;
unsigned HOST_WIDE_INT total_size;
+ /* FIXME: We do not support indirect sibcalls at the moment becaause we
+ cannot guarantee that the register holding the function address is a
+ call-used register. If it is a call-saved register then the stack
+ pop instructions generated in the epilogue will corrupt the address
+ before it is used.
+
+ Creating a new call-used-only register class works but then the
+ reload pass gets stuck because it cannot always find a call-used
+ register for spilling sibcalls.
+
+ The other possible solution is for this pass to scan forward for the
+ sibcall instruction (if it has been generated) and work out if it
+ is an indirect sibcall using a call-saved register. If it is then
+ the address can copied into a call-used register in this epilogue
+ code and the sibcall instruction modified to use that register. */
+
if (is_naked_func (NULL_TREE))
{
+ gcc_assert (! is_sibcall);
+
/* Naked functions use their own, programmer provided epilogues.
But, in order to keep gcc happy we have to generate some kind of
epilogue RTL. */
@@ -1547,9 +1565,15 @@
}
if (is_fast_interrupt_func (NULL_TREE))
- emit_jump_insn (gen_fast_interrupt_return ());
+ {
+ gcc_assert (! is_sibcall);
+ emit_jump_insn (gen_fast_interrupt_return ());
+ }
else if (is_interrupt_func (NULL_TREE))
- emit_jump_insn (gen_exception_return ());
+ {
+ gcc_assert (! is_sibcall);
+ emit_jump_insn (gen_exception_return ());
+ }
else if (! is_sibcall)
emit_jump_insn (gen_simple_return ());
@@ -2107,6 +2131,26 @@
&& ! is_naked_func (decl);
}
+/* Return nonzero if it is ok to make a tail-call to DECL,
+ a function_decl or NULL if this is an indirect call, using EXP */
+
+static bool
+rx_function_ok_for_sibcall (tree decl, tree exp)
+{
+ /* Do not allow indirect tailcalls. The
+ sibcall patterns do not support them. */
+ if (decl == NULL)
+ return false;
+
+ /* Never tailcall from inside interrupt handlers or naked functions. */
+ if (is_fast_interrupt_func (NULL_TREE)
+ || is_interrupt_func (NULL_TREE)
+ || is_naked_func (NULL_TREE))
+ return false;
+
+ return true;
+}
+
static void
rx_file_start (void)
{
@@ -2485,6 +2529,9 @@
#undef TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P
#define TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P rx_func_attr_inlinable
+#undef TARGET_FUNCTION_OK_FOR_SIBCALL
+#define TARGET_FUNCTION_OK_FOR_SIBCALL rx_function_ok_for_sibcall
+
#undef TARGET_SET_CURRENT_FUNCTION
#define TARGET_SET_CURRENT_FUNCTION rx_set_current_function
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: Committed: Fix problems with RX sibcall patterns
2009-11-26 11:29 Committed: Fix problems with RX sibcall patterns Nick Clifton
@ 2009-11-30 20:56 ` Richard Henderson
2009-12-01 10:58 ` Nick Clifton
0 siblings, 1 reply; 4+ messages in thread
From: Richard Henderson @ 2009-11-30 20:56 UTC (permalink / raw)
To: Nick Clifton; +Cc: gcc-patches
On 11/26/2009 02:44 AM, Nick Clifton wrote:
> +;; Note - we do not allow indirect sibcalls (with the address
> +;; held in a register) because we cannot guarantee that the register
> +;; chosen will be a call-used one. If it is a call-saved register,
> +;; then the epilogue code will corrupt it by popping the saved value
> +;; off of the stack.
Note that the x86 apporach here is to define a call-clobbered register
class.
r~
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: Committed: Fix problems with RX sibcall patterns
2009-11-30 20:56 ` Richard Henderson
@ 2009-12-01 10:58 ` Nick Clifton
2009-12-01 15:55 ` Richard Henderson
0 siblings, 1 reply; 4+ messages in thread
From: Nick Clifton @ 2009-12-01 10:58 UTC (permalink / raw)
To: Richard Henderson; +Cc: gcc-patches
Hi Richard,
>> +;; Note - we do not allow indirect sibcalls (with the address
>> +;; held in a register) because we cannot guarantee that the register
>> +;; chosen will be a call-used one. If it is a call-saved register,
>> +;; then the epilogue code will corrupt it by popping the saved value
>> +;; off of the stack.
>
> Note that the x86 apporach here is to define a call-clobbered register
> class.
I tried that - I ran into reload spill failures which I assume were
because there were not enough call-clobbered registers available. :-(
Cheers
Nick
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: Committed: Fix problems with RX sibcall patterns
2009-12-01 10:58 ` Nick Clifton
@ 2009-12-01 15:55 ` Richard Henderson
0 siblings, 0 replies; 4+ messages in thread
From: Richard Henderson @ 2009-12-01 15:55 UTC (permalink / raw)
To: Nick Clifton; +Cc: gcc-patches
On 12/01/2009 02:57 AM, Nick Clifton wrote:
> I tried that - I ran into reload spill failures which I assume were
> because there were not enough call-clobbered registers available. :-(
Presumably you also need to count the number of outgoing
register arguments and prevent the sibcall in that case too.
Like i386 does for regparm(3).
r~
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2009-12-01 15:42 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-11-26 11:29 Committed: Fix problems with RX sibcall patterns Nick Clifton
2009-11-30 20:56 ` Richard Henderson
2009-12-01 10:58 ` Nick Clifton
2009-12-01 15:55 ` Richard Henderson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).