When a frame pointer is in use, we can optimize popping all queued parameters via a simple move from the frame pointer instead of an addition to the stack pointer.
The new sequence is 4 insns, the old sequence was 9 insns. Committed. r~
PR target/34888 * config/avr/avr.md: New splitter for REG_ARGS_SIZE 0. diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md index b8560df..b5aa73c 100644 --- a/gcc/config/avr/avr.md +++ b/gcc/config/avr/avr.md @@ -235,6 +235,17 @@ DONE; }) +;; Notice a special-case when adding N to SP where N results in a +;; zero REG_ARGS_SIZE. This is equivalent to a move from FP. +(define_split + [(set (reg:HI REG_SP) (match_operand:HI 0 "register_operand" ""))] + "reload_completed + && frame_pointer_needed + && !cfun->calls_alloca + && find_reg_note (insn, REG_ARGS_SIZE, const0_rtx)" + [(set (reg:HI REG_SP) (reg:HI REG_Y))] + "") + ;;======================================================================== ;; move byte ;; The last alternative (any immediate constant to any register) is