Richard Henderson schrieb: > 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 explained.
Thanks for the explanation. Here is the new patch for review with the new option -mjump-to-noreturn Ok for trunk? Johann * doc/invoke.texi (AVR Options): Document -mjump-to-noreturn. * 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. * common/config/avr/avr-common.c (-mjump-to-noreturn): Turn on for -O and higher.
Index: doc/invoke.texi =================================================================== --- doc/invoke.texi (revision 179993) +++ doc/invoke.texi (working copy) @@ -487,7 +487,7 @@ Objective-C and Objective-C++ Dialects}. @emph{AVR Options} @gccoptlist{-mmcu=@var{mcu} -mno-interrupts @gol --mcall-prologues -mtiny-stack -mint8 -mstrict-X} +-mcall-prologues -mtiny-stack -mint8 -mstrict-X -mjump-to-noreturn} @emph{Blackfin Options} @gccoptlist{-mcpu=@var{cpu}@r{[}-@var{sirevision}@r{]} @gol @@ -10690,6 +10690,13 @@ and long long will be 4 bytes. Please n comply to the C standards, but it will provide you with smaller code size. +@item -mjump-to-noreturn +@opindex mjump-to-noreturn +Use a jump instruction instead of a call instruction when calling a +no-return functions. This option is active if optimization is turned +on and just affects the way a call instruction is printed out. +Besides that, it has no effect on code generation or debug information. + @item -mstrict-X @opindex mstrict-X Use register @code{X} in a way proposed by the hardware. This means Index: config/avr/avr.md =================================================================== --- config/avr/avr.md (revision 179992) +++ 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.opt =================================================================== --- config/avr/avr.opt (revision 179993) +++ config/avr/avr.opt (working copy) @@ -65,3 +65,7 @@ Make the linker relaxation machine assum mstrict-X Target Report Var(avr_strict_X) Init(0) When accessing RAM, use X as imposed by the hardware, i.e. just use pre-decrement, post-increment and indirect addressing with the X register. Without this option, the compiler may assume that there is an addressing mode X+const similar to Y+const and Z+const and emit instructions to emulate such an addressing mode for X. + +mjump-to-noreturn +Target Report Var(avr_jump_to_noreturn) Init(0) +Jump to no-return functions instead of calling them. Index: config/avr/avr-protos.h =================================================================== --- config/avr/avr-protos.h (revision 179992) +++ 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 179993) +++ config/avr/avr.c (working copy) @@ -4928,6 +4928,28 @@ 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 (avr_jump_to_noreturn + && 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]: @@ -5334,6 +5356,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(); Index: common/config/avr/avr-common.c =================================================================== --- common/config/avr/avr-common.c (revision 179765) +++ common/config/avr/avr-common.c (working copy) @@ -29,6 +29,7 @@ static const struct default_options avr_option_optimization_table[] = { { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, + { OPT_LEVELS_1_PLUS, OPT_mjump_to_noreturn, NULL, 1 }, { OPT_LEVELS_NONE, 0, NULL, 0 } };