diff mbox

[AVR] Print no-return functions as JMP

Message ID 4E972AEF.1020802@gjlay.de
State New
Headers show

Commit Message

Georg-Johann Lay Oct. 13, 2011, 6:16 p.m. UTC
This patch saves some ticks and bytes on stack by JUMPing to no-return
functions instead of CALLing them.

Passes without regression.

Ok for trunk?

Johann

	* config/avr/avr-protos.h (avr_out_call): New prototype.
	* config/avr/avr.md (adjust_len): Add alternative "call".
	(call_insn, call_calue_insn): Use it.  Use avr_out_call to print
	assembler.
	* config/avr/avr.c (avr_out_call): New function.
	(adjust_insn_length): Handle ADJUST_LEN_CALL.

Comments

Richard Henderson Oct. 13, 2011, 6:38 p.m. UTC | #1
On 10/13/2011 11:16 AM, Georg-Johann Lay wrote:
> This patch saves some ticks and bytes on stack by JUMPing to no-return
> functions instead of CALLing them.
> 
> Passes without regression.
> 
> Ok for trunk?
> 
> Johann
> 
> 	* config/avr/avr-protos.h (avr_out_call): New prototype.
> 	* config/avr/avr.md (adjust_len): Add alternative "call".
> 	(call_insn, call_calue_insn): Use it.  Use avr_out_call to print
> 	assembler.
> 	* config/avr/avr.c (avr_out_call): New function.
> 	(adjust_insn_length): Handle ADJUST_LEN_CALL.

You should have a way to turn this off.  Otherwise this makes debugging
the call to abort impossible.


r~
Georg-Johann Lay Oct. 13, 2011, 7 p.m. UTC | #2
Richard Henderson schrieb:
> On 10/13/2011 11:16 AM, Georg-Johann Lay wrote:
>> This patch saves some ticks and bytes on stack by JUMPing to no-return
>> functions instead of CALLing them.
>>
>> Passes without regression.
>>
>> Ok for trunk?
>>
>> Johann
>>
>> 	* config/avr/avr-protos.h (avr_out_call): New prototype.
>> 	* config/avr/avr.md (adjust_len): Add alternative "call".
>> 	(call_insn, call_calue_insn): Use it.  Use avr_out_call to print
>> 	assembler.
>> 	* config/avr/avr.c (avr_out_call): New function.
>> 	(adjust_insn_length): Handle ADJUST_LEN_CALL.
> 
> You should have a way to turn this off.  Otherwise this makes debugging
> the call to abort impossible.
> 
> r~

What do you propose?

o A command line option that is on per default like
  -mnoreturn-tail-calls or -mjmp-noreturn

o Hard-coded factor out some function names like "abort",
  "exit", "_exit"

Johann
Richard Henderson Oct. 13, 2011, 7:05 p.m. UTC | #3
On 10/13/2011 12:00 PM, Georg-Johann Lay wrote:
> What do you propose?
> 
> o A command line option that is on per default like
>   -mnoreturn-tail-calls or -mjmp-noreturn

The command-line-option.  I think I prefer -mjump-noreturn,
as the inverse -mno-noreturn-tail-calls is too awkward.


r~
Paul Koning Oct. 13, 2011, 7:07 p.m. UTC | #4
>> You should have a way to turn this off.  Otherwise this makes 

>> debugging the call to abort impossible.

>

>What do you propose?

>

>o A command line option that is on per default like

>  -mnoreturn-tail-calls or -mjmp-noreturn

>

>o Hard-coded factor out some function names like "abort",

>  "exit", "_exit"


I'd suggest the first option.  That way you can do this for other similar functions like panic().

	paul
Georg-Johann Lay Oct. 14, 2011, 6:31 a.m. UTC | #5
Richard Henderson schrieb:
> On 10/13/2011 12:00 PM, Georg-Johann Lay wrote:
> 
>>What do you propose?
>>
>>o A command line option that is on per default like
>>  -mnoreturn-tail-calls or -mjmp-noreturn
> 
> The command-line-option.  I think I prefer -mjump-noreturn,
> as the inverse -mno-noreturn-tail-calls is too awkward.

What about flag_optimize_sibling_calls?
What wa are seeing here is actually a tail call.

Johann

> 
> r~
>
Richard Henderson Oct. 14, 2011, 3:14 p.m. UTC | #6
On 10/13/2011 11:31 PM, Georg-Johann Lay wrote:
> Richard Henderson schrieb:
>> On 10/13/2011 12:00 PM, Georg-Johann Lay wrote:
>>
>>> What do you propose?
>>>
>>> o A command line option that is on per default like
>>>  -mnoreturn-tail-calls or -mjmp-noreturn
>>
>> The command-line-option.  I think I prefer -mjump-noreturn,
>> as the inverse -mno-noreturn-tail-calls is too awkward.
> 
> What about flag_optimize_sibling_calls?
> What wa are seeing here is actually a tail call.

Because we explicitly don't tail call noreturn for the
reason previously explainted.


r~
diff mbox

Patch

Index: config/avr/avr.md
===================================================================
--- config/avr/avr.md	(revision 179843)
+++ config/avr/avr.md	(working copy)
@@ -133,11 +133,10 @@  (define_attr "length" ""
 ;; Following insn attribute tells if and how the adjustment has to be
 ;; done:
 ;;     no     No adjustment needed; attribute "length" is fine.
-;;     yes    Analyse pattern in adjust_insn_length by hand.
 ;; Otherwise do special processing depending on the attribute.
 
 (define_attr "adjust_len"
-  "out_bitop, out_plus, addto_sp, tsthi, tstsi, compare,
+  "out_bitop, out_plus, addto_sp, tsthi, tstsi, compare, call,
    mov8, mov16, mov32, reload_in16, reload_in32,
    ashlqi, ashrqi, lshrqi,
    ashlhi, ashrhi, lshrhi,
@@ -3634,21 +3633,12 @@  (define_insn "call_insn"
   ;; Operand 1 not used on the AVR.
   ;; Operand 2 is 1 for tail-call, 0 otherwise.
   ""
-  "@
-    %!icall
-    %~call %x0
-    %!ijmp
-    %~jmp %x0"
+  {
+     return avr_out_call (insn, operands[0], 0 != INTVAL (operands[2]));
+  }
   [(set_attr "cc" "clobber")
-   (set_attr_alternative "length"
-                         [(const_int 1)
-                          (if_then_else (eq_attr "mcu_mega" "yes")
-                                        (const_int 2)
-                                        (const_int 1))
-                          (const_int 1)
-                          (if_then_else (eq_attr "mcu_mega" "yes")
-                                        (const_int 2)
-                                        (const_int 1))])])
+   (set_attr "length" "1,*,1,*")
+   (set_attr "adjust_len" "*,call,*,call")])
 
 (define_insn "call_value_insn"
   [(parallel[(set (match_operand 0 "register_operand"                   "=r,r,r,r")
@@ -3658,21 +3648,12 @@  (define_insn "call_value_insn"
   ;; Operand 2 not used on the AVR.
   ;; Operand 3 is 1 for tail-call, 0 otherwise.
   ""
-  "@
-    %!icall
-    %~call %x1
-    %!ijmp
-    %~jmp %x1"
+  {
+     return avr_out_call (insn, operands[1], 0 != INTVAL (operands[3]));
+  }
   [(set_attr "cc" "clobber")
-   (set_attr_alternative "length"
-                         [(const_int 1)
-                          (if_then_else (eq_attr "mcu_mega" "yes")
-                                        (const_int 2)
-                                        (const_int 1))
-                          (const_int 1)
-                          (if_then_else (eq_attr "mcu_mega" "yes")
-                                        (const_int 2)
-                                        (const_int 1))])])
+   (set_attr "length" "1,*,1,*")
+   (set_attr "adjust_len" "*,call,*,call")])
 
 (define_insn "nop"
   [(const_int 0)]
Index: config/avr/avr-protos.h
===================================================================
--- config/avr/avr-protos.h	(revision 179842)
+++ config/avr/avr-protos.h	(working copy)
@@ -84,6 +84,7 @@  extern const char *avr_out_sbxx_branch (
 extern const char* avr_out_bitop (rtx, rtx*, int*);
 extern const char* avr_out_plus (rtx*, int*, int*);
 extern const char* avr_out_addto_sp (rtx*, int*);
+extern const char* avr_out_call (rtx, rtx, bool);
 extern bool avr_popcount_each_byte (rtx, int, int);
 
 extern int extra_constraint_Q (rtx x);
Index: config/avr/avr.c
===================================================================
--- config/avr/avr.c	(revision 179843)
+++ config/avr/avr.c	(working copy)
@@ -4905,6 +4905,27 @@  avr_out_plus (rtx *xop, int *plen, int *
 }
 
 
+/* Print call insn INSN to the assembler file and return "".
+   ADDRESS is the target address.
+   If SIBCALL_P then INSN is a tail-call.  */
+   
+const char*
+avr_out_call (rtx insn, rtx address, bool sibcall_p)
+{
+  /* No need to waste stack or time for no-return calls.  */
+  
+  if (optimize && find_reg_note (insn, REG_NORETURN, NULL))
+    sibcall_p = true;
+
+  if (REG_P (address))
+    output_asm_insn (sibcall_p ? "%!ijmp" : "%!icall", &address);
+  else
+    output_asm_insn (sibcall_p ? "%~jmp %x0" : "%~call %x0", &address);
+
+  return "";
+}
+
+
 /* Output bit operation (IOR, AND, XOR) with register XOP[0] and compile
    time constant XOP[2]:
 
@@ -5311,6 +5332,8 @@  adjust_insn_length (rtx insn, int len)
     case ADJUST_LEN_ASHLQI: ashlqi3_out (insn, op, &len); break;
     case ADJUST_LEN_ASHLHI: ashlhi3_out (insn, op, &len); break;
     case ADJUST_LEN_ASHLSI: ashlsi3_out (insn, op, &len); break;
+
+    case ADJUST_LEN_CALL: len = AVR_HAVE_JMP_CALL ? 2 : 1; break;
       
     default:
       gcc_unreachable();