In current trunk (r170704), 4.4-branch and 4.5-branch I observe the
following optimization issue in IRA: It saves regs in the frame
instead of in callee-saved registers which would be much smarter.

In the following C source, foo2 is compiled as desired (push/pop r17
to save r24). In foo1 and foo3 r24 is saved in the frame. The old
lreg/greg allocator of 4.3-branch generates fine code for all functions.

Saving a reg in the frame should only be done if running out of hard
registers because setting up frame(pointer) and accessing frame is
very expensive on avr.

Maybe someone can give me a hint what's going wrong.

gcc configured

/gnu/source/gcc.gnu.org/trunk/configure --target=avr --prefix=...
--enable-languages=c,c++ --disable-libssp --disable-libada
--disable-nls --disable-shared

and sources compiled

with -Os -mmcu=atmega8 -c -dp -da -fira-verbose=100

/*****************************************************/
void bar0 (void);
void bar1 (char);

void foo1 (char x)
{
    bar0();
    bar1(x);
}


char foo2 (char x)
{
    bar1(x);

    return x;
}

char foo3 (char x)
{
    bar0();

    return x;
}
/*****************************************************/

FYI, I attached IRA dumps and asm output

As far I can see target avr gives appropriate costs for memory and
register moves.

IRA printout is as follows:

Thanks for any hints on that!

Johann

===========================================================

Building IRA IR

Pass 0 for finding pseudo/allocno costs

    a0 (r42,l0) best GENERAL_REGS, cover GENERAL_REGS

  a0(r42,l0) costs: POINTER_X_REGS:0,0 POINTER_Z_REGS:0,0
BASE_POINTER_REGS:0,0 POINTER_REGS:0,0 ADDW_REGS:0,0
SIMPLE_LD_REGS:0,0 LD_REGS:0,0 NO_LD_REGS:0,0 GENERAL_REGS:0,0 MEM:4000


Pass 1 for finding pseudo/allocno costs

    r42: preferred GENERAL_REGS, alternative NO_REGS, cover GENERAL_REGS

  a0(r42,l0) costs: POINTER_X_REGS:0,0 POINTER_Z_REGS:0,0
BASE_POINTER_REGS:0,0 POINTER_REGS:0,0 ADDW_REGS:0,0
SIMPLE_LD_REGS:0,0 LD_REGS:0,0 NO_LD_REGS:0,0 GENERAL_REGS:0,0 MEM:4000

   Insn 10(l0): point = 0
   Insn 9(l0): point = 2
   Insn 7(l0): point = 4
   Insn 2(l0): point = 6
 a0(r42): [3..6]
Compressing live ranges: from 9 to 2 - 22%
Ranges after the compression:
 a0(r42): [0..1]
+++Allocating 0 bytes for conflict table (uncompressed size 4)
;; a0(r42,l0) conflicts:  regions=1, blocks=3, points=2
    allocnos=1 (big 0), copies=0, conflicts=0, ranges=1

**** Allocnos coloring:


  Loop 0 (parent -1, header bb0, depth 0)
    bbs: 2
    all: 0r42
    modified regnos: 42
    border:
    Pressure: GENERAL_REGS=1
    Reg 42 of GENERAL_REGS has 6 regs less
      Pushing a0(r42,l0)
      Popping a0(r42,l0)  -- assign reg 24
Disposition:
    0:r42  l0    24
New iteration of spill/restore move
+++Costs: overall -4000, reg -4000, mem 0, ld 0, st 0, move 0
+++       move loops 0, new jumps 0

===========================================================

Building IRA IR

Pass 0 for finding pseudo/allocno costs

    a0 (r43,l0) best GENERAL_REGS, cover GENERAL_REGS

  a0(r43,l0) costs: POINTER_X_REGS:0,0 POINTER_Z_REGS:0,0
BASE_POINTER_REGS:0,0 POINTER_REGS:0,0 ADDW_REGS:0,0
SIMPLE_LD_REGS:0,0 LD_REGS:0,0 NO_LD_REGS:0,0 GENERAL_REGS:0,0 MEM:6000


Pass 1 for finding pseudo/allocno costs

    r43: preferred GENERAL_REGS, alternative NO_REGS, cover GENERAL_REGS

  a0(r43,l0) costs: POINTER_X_REGS:0,0 POINTER_Z_REGS:0,0
BASE_POINTER_REGS:0,0 POINTER_REGS:0,0 ADDW_REGS:0,0
SIMPLE_LD_REGS:0,0 LD_REGS:0,0 NO_LD_REGS:0,0 GENERAL_REGS:0,0 MEM:6000

   Insn 16(l0): point = 0
   Insn 13(l0): point = 2
   Insn 8(l0): point = 4
   Insn 7(l0): point = 6
   Insn 2(l0): point = 8
 a0(r43): [3..8]
Compressing live ranges: from 11 to 2 - 18%
Ranges after the compression:
 a0(r43): [0..1]
+++Allocating 0 bytes for conflict table (uncompressed size 4)
;; a0(r43,l0) conflicts:  regions=1, blocks=3, points=2
    allocnos=1 (big 0), copies=0, conflicts=0, ranges=1

**** Allocnos coloring:


  Loop 0 (parent -1, header bb0, depth 0)
    bbs: 2
    all: 0r43
    modified regnos: 43
    border:
    Pressure: GENERAL_REGS=2
    Reg 43 of GENERAL_REGS has 7 regs less
      Pushing a0(r43,l0)
      Popping a0(r43,l0)  -- assign reg 17
Disposition:
    0:r43  l0    17
New iteration of spill/restore move
+++Costs: overall 0, reg 0, mem 0, ld 0, st 0, move 0
+++       move loops 0, new jumps 0


===========================================================

Building IRA IR

Pass 0 for finding pseudo/allocno costs

    a0 (r43,l0) best GENERAL_REGS, cover GENERAL_REGS

  a0(r43,l0) costs: POINTER_X_REGS:0,0 POINTER_Z_REGS:0,0
BASE_POINTER_REGS:0,0 POINTER_REGS:0,0 ADDW_REGS:0,0
SIMPLE_LD_REGS:0,0 LD_REGS:0,0 NO_LD_REGS:0,0 GENERAL_REGS:0,0 MEM:4000


Pass 1 for finding pseudo/allocno costs

    r43: preferred GENERAL_REGS, alternative NO_REGS, cover GENERAL_REGS

  a0(r43,l0) costs: POINTER_X_REGS:0,0 POINTER_Z_REGS:0,0
BASE_POINTER_REGS:0,0 POINTER_REGS:0,0 ADDW_REGS:0,0
SIMPLE_LD_REGS:0,0 LD_REGS:0,0 NO_LD_REGS:0,0 GENERAL_REGS:0,0 MEM:4000

   Insn 15(l0): point = 0
   Insn 12(l0): point = 2
   Insn 7(l0): point = 4
   Insn 2(l0): point = 6
 a0(r43): [3..6]
Compressing live ranges: from 9 to 2 - 22%
Ranges after the compression:
 a0(r43): [0..1]
+++Allocating 0 bytes for conflict table (uncompressed size 4)
;; a0(r43,l0) conflicts:  regions=1, blocks=3, points=2
    allocnos=1 (big 0), copies=0, conflicts=0, ranges=1

**** Allocnos coloring:


  Loop 0 (parent -1, header bb0, depth 0)
    bbs: 2
    all: 0r43
    modified regnos: 43
    border:
    Pressure: GENERAL_REGS=1
    Reg 43 of GENERAL_REGS has 6 regs less
      Pushing a0(r43,l0)
      Popping a0(r43,l0)  -- assign reg 24
Disposition:
    0:r43  l0    24
New iteration of spill/restore move
+++Costs: overall -4000, reg -4000, mem 0, ld 0, st 0, move 0
+++       move loops 0, new jumps 0

;; Function foo1 (foo1)

starting the processing of deferred insns
ending the processing of deferred insns
df_analyze called
starting the processing of deferred insns
ending the processing of deferred insns
df_analyze called
insn=2, live_throughout: 32, dead_or_set: 24, 42
insn=7, live_throughout: 32, 42, dead_or_set: 
insn=9, live_throughout: 32, dead_or_set: 24, 42
insn=10, live_throughout: 32, dead_or_set: 24
changing reg in insn 2
changing reg in insn 9
24 uses a new slot
24 uses a slot from prev iteration
Spilling for insn 16.
Using reg 30 for reload 0
Spilling for insn 17.
Using reg 30 for reload 0
deleting insn with uid = 16.
deleting insn with uid = 17.
24 uses a slot from prev iteration
Spilling for insn 18.
deleting insn with uid = 18.
deleting insn with uid = 19.
24 uses a slot from prev iteration
Spilling for insn 20.

Reloads for insn # 20
Reload 0: reload_out (QI) = (mem/c:QI (plus:HI (reg/f:HI 28 r28)
                                                        (const_int 1 [0x1])) [2 
S1 A8])
        NO_REGS, RELOAD_FOR_OUTPUT (opnum = 0), optional
        reload_out_reg: (mem/c:QI (plus:HI (reg/f:HI 28 r28)
                                                        (const_int 1 [0x1])) [2 
S1 A8])
deleting insn with uid = 2.
deleting insn with uid = 9.


try_optimize_cfg iteration 1

starting the processing of deferred insns
ending the processing of deferred insns
verify found no changes in insn with uid = 7.
verify found no changes in insn with uid = 10.
starting the processing of deferred insns
ending the processing of deferred insns
df_analyze called
df_worklist_dataflow_doublequeue:n_basic_blocks 3 n_edges 2 count 3 (    1)
df_worklist_dataflow_doublequeue:n_basic_blocks 3 n_edges 2 count 3 (    1)


foo1

Dataflow summary:
;;  invalidated by call          0 [r0] 1 [r1] 18 [r18] 19 [r19] 20 [r20] 21 
[r21] 22 [r22] 23 [r23] 24 [r24] 25 [r25] 26 [r26] 27 [r27] 30 [r30] 31 [r31] 
33 [__SP_H__] 35 [argH]
;;  hardware regs used   32 [__SP_L__]
;;  regular block artificial uses        28 [r28] 32 [__SP_L__]
;;  eh block artificial uses     28 [r28] 32 [__SP_L__] 34 [argL]
;;  entry block defs     8 [r8] 9 [r9] 10 [r10] 11 [r11] 12 [r12] 13 [r13] 14 
[r14] 15 [r15] 16 [r16] 17 [r17] 18 [r18] 19 [r19] 20 [r20] 21 [r21] 22 [r22] 
23 [r23] 24 [r24] 25 [r25] 28 [r28] 32 [__SP_L__]
;;  exit block uses      28 [r28] 32 [__SP_L__]
;;  regs ever live       24[r24] 28[r28] 29[r29] 30[r30] 31[r31] 32[__SP_L__]
;;  ref usage   r0={2d} r1={2d} r8={1d} r9={1d} r10={1d} r11={1d} r12={1d} 
r13={1d} r14={1d} r15={1d} r16={1d} r17={1d} r18={3d} r19={3d} r20={3d} 
r21={3d} r22={3d} r23={3d} r24={4d,2u} r25={3d} r26={2d} r27={2d} r28={1d,4u} 
r29={2u} r30={2d} r31={2d} r32={1d,4u} r33={2d} r35={2d} 
;;    total ref usage 65{53d,12u,0e} in 4{2 regular + 2 call} insns.
(note 1 0 4 NOTE_INSN_DELETED)

;; Start of basic block ( 0) -> 2
;; bb 2 artificial_defs: { }
;; bb 2 artificial_uses: { u-1(28){ }u-1(32){ }}
;; lr  in        24 [r24] 28 [r28] 29 [r29] 32 [__SP_L__]
;; lr  use       24 [r24] 28 [r28] 29 [r29] 32 [__SP_L__]
;; lr  def       0 [r0] 1 [r1] 18 [r18] 19 [r19] 20 [r20] 21 [r21] 22 [r22] 23 
[r23] 24 [r24] 25 [r25] 26 [r26] 27 [r27] 30 [r30] 31 [r31] 33 [__SP_H__] 35 
[argH]
;; live  in      24 [r24] 28 [r28] 32 [__SP_L__]
;; live  gen     24 [r24]
;; live  kill   

;; Pred edge  ENTRY [100.0%]  (fallthru)
(note 4 1 3 2 [bb 2] NOTE_INSN_BASIC_BLOCK)

(note 3 4 20 2 NOTE_INSN_FUNCTION_BEG)

(insn 20 3 7 2 (set (mem/c:QI (plus:HI (reg/f:HI 28 r28)
                (const_int 1 [0x1])) [2 S1 A8])
        (reg:QI 24 r24)) sib.c:6 4 {*movqi}
     (nil))

(call_insn 7 20 21 2 (call (mem:HI (symbol_ref:HI ("bar0") [flags 0x41]  
<function_decl 0xb753e680 bar0>) [0 S2 A8])
        (const_int 0 [0])) sib.c:6 122 {call_insn}
     (nil)
    (nil))

(insn 21 7 10 2 (set (reg:QI 24 r24)
        (mem/c:QI (plus:HI (reg/f:HI 28 r28)
                (const_int 1 [0x1])) [2 S1 A8])) sib.c:7 4 {*movqi}
     (nil))

(call_insn 10 21 15 2 (call (mem:HI (symbol_ref:HI ("bar1") [flags 0x41]  
<function_decl 0xb753e700 bar1>) [0 S2 A8])
        (const_int 0 [0])) sib.c:7 122 {call_insn}
     (nil)
    (expr_list:REG_DEP_TRUE (use (reg:QI 24 r24))
        (nil)))
;; End of basic block 2 -> ( 1)
;; lr  out       28 [r28] 32 [__SP_L__]
;; live  out     28 [r28] 32 [__SP_L__]


;; Succ edge  EXIT [100.0%]  (fallthru)

(note 15 10 0 NOTE_INSN_DELETED)


;; Function foo2 (foo2)

starting the processing of deferred insns
ending the processing of deferred insns
df_analyze called
starting the processing of deferred insns
ending the processing of deferred insns
df_analyze called
insn=2, live_throughout: 32, dead_or_set: 24, 43
insn=7, live_throughout: 32, 43, dead_or_set: 24
insn=8, live_throughout: 32, 43, dead_or_set: 24
insn=13, live_throughout: 32, dead_or_set: 24, 43
insn=16, live_throughout: 24, 32, dead_or_set: 
changing reg in insn 2
changing reg in insn 13
changing reg in insn 7


try_optimize_cfg iteration 1

starting the processing of deferred insns
ending the processing of deferred insns
verify found no changes in insn with uid = 8.
starting the processing of deferred insns
ending the processing of deferred insns
df_analyze called
df_worklist_dataflow_doublequeue:n_basic_blocks 3 n_edges 2 count 3 (    1)
df_worklist_dataflow_doublequeue:n_basic_blocks 3 n_edges 2 count 3 (    1)


foo2

Dataflow summary:
;;  invalidated by call          0 [r0] 1 [r1] 18 [r18] 19 [r19] 20 [r20] 21 
[r21] 22 [r22] 23 [r23] 24 [r24] 25 [r25] 26 [r26] 27 [r27] 30 [r30] 31 [r31] 
33 [__SP_H__] 35 [argH]
;;  hardware regs used   32 [__SP_L__]
;;  regular block artificial uses        32 [__SP_L__]
;;  eh block artificial uses     32 [__SP_L__] 34 [argL]
;;  entry block defs     8 [r8] 9 [r9] 10 [r10] 11 [r11] 12 [r12] 13 [r13] 14 
[r14] 15 [r15] 16 [r16] 17 [r17] 18 [r18] 19 [r19] 20 [r20] 21 [r21] 22 [r22] 
23 [r23] 24 [r24] 25 [r25] 32 [__SP_L__]
;;  exit block uses      24 [r24] 32 [__SP_L__]
;;  regs ever live       17[r17] 24[r24] 32[__SP_L__]
;;  ref usage   r0={1d} r1={1d} r8={1d} r9={1d} r10={1d} r11={1d} r12={1d} 
r13={1d} r14={1d} r15={1d} r16={1d} r17={2d,2u} r18={2d} r19={2d} r20={2d} 
r21={2d} r22={2d} r23={2d} r24={4d,4u} r25={2d} r26={1d} r27={1d} r30={1d} 
r31={1d} r32={1d,3u} r33={1d} r35={1d} 
;;    total ref usage 47{38d,9u,0e} in 5{4 regular + 1 call} insns.
(note 1 0 4 NOTE_INSN_DELETED)

;; Start of basic block ( 0) -> 2
;; bb 2 artificial_defs: { }
;; bb 2 artificial_uses: { u-1(32){ }}
;; lr  in        24 [r24] 32 [__SP_L__]
;; lr  use       24 [r24] 32 [__SP_L__]
;; lr  def       0 [r0] 1 [r1] 17 [r17] 18 [r18] 19 [r19] 20 [r20] 21 [r21] 22 
[r22] 23 [r23] 24 [r24] 25 [r25] 26 [r26] 27 [r27] 30 [r30] 31 [r31] 33 
[__SP_H__] 35 [argH]
;; live  in      24 [r24] 32 [__SP_L__]
;; live  gen     17 [r17] 24 [r24]
;; live  kill   

;; Pred edge  ENTRY [100.0%]  (fallthru)
(note 4 1 2 2 [bb 2] NOTE_INSN_BASIC_BLOCK)

(insn 2 4 3 2 (set (reg/v:QI 17 r17 [orig:43 x ] [43])
        (reg:QI 24 r24 [ x ])) sib.c:12 4 {*movqi}
     (nil))

(note 3 2 7 2 NOTE_INSN_FUNCTION_BEG)

(insn 7 3 8 2 (set (reg:QI 24 r24)
        (reg/v:QI 17 r17 [orig:43 x ] [43])) sib.c:13 4 {*movqi}
     (nil))

(call_insn 8 7 13 2 (call (mem:HI (symbol_ref:HI ("bar1") [flags 0x41]  
<function_decl 0xb753e700 bar1>) [0 S2 A8])
        (const_int 0 [0])) sib.c:13 122 {call_insn}
     (nil)
    (expr_list:REG_DEP_TRUE (use (reg:QI 24 r24))
        (nil)))

(insn 13 8 16 2 (set (reg/i:QI 24 r24)
        (reg/v:QI 17 r17 [orig:43 x ] [43])) sib.c:16 4 {*movqi}
     (nil))

(insn 16 13 20 2 (use (reg/i:QI 24 r24)) sib.c:16 -1
     (nil))
;; End of basic block 2 -> ( 1)
;; lr  out       24 [r24] 32 [__SP_L__]
;; live  out     24 [r24] 32 [__SP_L__]


;; Succ edge  EXIT [100.0%]  (fallthru)

(note 20 16 0 NOTE_INSN_DELETED)


;; Function foo3 (foo3)

starting the processing of deferred insns
ending the processing of deferred insns
df_analyze called
starting the processing of deferred insns
ending the processing of deferred insns
df_analyze called
insn=2, live_throughout: 32, dead_or_set: 24, 43
insn=7, live_throughout: 32, 43, dead_or_set: 
insn=12, live_throughout: 32, dead_or_set: 24, 43
insn=15, live_throughout: 24, 32, dead_or_set: 
changing reg in insn 2
changing reg in insn 12
24 uses a new slot
24 uses a slot from prev iteration
Spilling for insn 20.
Using reg 30 for reload 0
Spilling for insn 21.
Using reg 30 for reload 0
deleting insn with uid = 20.
deleting insn with uid = 21.
24 uses a slot from prev iteration
Spilling for insn 22.
deleting insn with uid = 22.
deleting insn with uid = 23.
24 uses a slot from prev iteration
Spilling for insn 24.

Reloads for insn # 24
Reload 0: reload_out (QI) = (mem/c:QI (plus:HI (reg/f:HI 28 r28)
                                                        (const_int 1 [0x1])) [2 
S1 A8])
        NO_REGS, RELOAD_FOR_OUTPUT (opnum = 0), optional
        reload_out_reg: (mem/c:QI (plus:HI (reg/f:HI 28 r28)
                                                        (const_int 1 [0x1])) [2 
S1 A8])
deleting insn with uid = 2.
deleting insn with uid = 12.


try_optimize_cfg iteration 1

starting the processing of deferred insns
ending the processing of deferred insns
verify found no changes in insn with uid = 7.
starting the processing of deferred insns
ending the processing of deferred insns
df_analyze called
df_worklist_dataflow_doublequeue:n_basic_blocks 3 n_edges 2 count 3 (    1)
df_worklist_dataflow_doublequeue:n_basic_blocks 3 n_edges 2 count 3 (    1)


foo3

Dataflow summary:
;;  invalidated by call          0 [r0] 1 [r1] 18 [r18] 19 [r19] 20 [r20] 21 
[r21] 22 [r22] 23 [r23] 24 [r24] 25 [r25] 26 [r26] 27 [r27] 30 [r30] 31 [r31] 
33 [__SP_H__] 35 [argH]
;;  hardware regs used   32 [__SP_L__]
;;  regular block artificial uses        28 [r28] 32 [__SP_L__]
;;  eh block artificial uses     28 [r28] 32 [__SP_L__] 34 [argL]
;;  entry block defs     8 [r8] 9 [r9] 10 [r10] 11 [r11] 12 [r12] 13 [r13] 14 
[r14] 15 [r15] 16 [r16] 17 [r17] 18 [r18] 19 [r19] 20 [r20] 21 [r21] 22 [r22] 
23 [r23] 24 [r24] 25 [r25] 28 [r28] 32 [__SP_L__]
;;  exit block uses      24 [r24] 28 [r28] 32 [__SP_L__]
;;  regs ever live       24[r24] 28[r28] 29[r29] 30[r30] 31[r31] 32[__SP_L__]
;;  ref usage   r0={1d} r1={1d} r8={1d} r9={1d} r10={1d} r11={1d} r12={1d} 
r13={1d} r14={1d} r15={1d} r16={1d} r17={1d} r18={2d} r19={2d} r20={2d} 
r21={2d} r22={2d} r23={2d} r24={3d,3u} r25={2d} r26={1d} r27={1d} r28={1d,4u} 
r29={2u} r30={1d} r31={1d} r32={1d,3u} r33={1d} r35={1d} 
;;    total ref usage 49{37d,12u,0e} in 4{3 regular + 1 call} insns.
(note 1 0 4 NOTE_INSN_DELETED)

;; Start of basic block ( 0) -> 2
;; bb 2 artificial_defs: { }
;; bb 2 artificial_uses: { u-1(28){ }u-1(32){ }}
;; lr  in        24 [r24] 28 [r28] 29 [r29] 32 [__SP_L__]
;; lr  use       24 [r24] 28 [r28] 29 [r29] 32 [__SP_L__]
;; lr  def       0 [r0] 1 [r1] 18 [r18] 19 [r19] 20 [r20] 21 [r21] 22 [r22] 23 
[r23] 24 [r24] 25 [r25] 26 [r26] 27 [r27] 30 [r30] 31 [r31] 33 [__SP_H__] 35 
[argH]
;; live  in      24 [r24] 28 [r28] 32 [__SP_L__]
;; live  gen     24 [r24]
;; live  kill   

;; Pred edge  ENTRY [100.0%]  (fallthru)
(note 4 1 3 2 [bb 2] NOTE_INSN_BASIC_BLOCK)

(note 3 4 24 2 NOTE_INSN_FUNCTION_BEG)

(insn 24 3 7 2 (set (mem/c:QI (plus:HI (reg/f:HI 28 r28)
                (const_int 1 [0x1])) [2 S1 A8])
        (reg:QI 24 r24)) sib.c:20 4 {*movqi}
     (nil))

(call_insn 7 24 25 2 (call (mem:HI (symbol_ref:HI ("bar0") [flags 0x41]  
<function_decl 0xb753e680 bar0>) [0 S2 A8])
        (const_int 0 [0])) sib.c:20 122 {call_insn}
     (nil)
    (nil))

(insn 25 7 15 2 (set (reg:QI 24 r24)
        (mem/c:QI (plus:HI (reg/f:HI 28 r28)
                (const_int 1 [0x1])) [2 S1 A8])) sib.c:23 4 {*movqi}
     (nil))

(insn 15 25 19 2 (use (reg/i:QI 24 r24)) sib.c:23 -1
     (nil))
;; End of basic block 2 -> ( 1)
;; lr  out       24 [r24] 28 [r28] 32 [__SP_L__]
;; live  out     24 [r24] 28 [r28] 32 [__SP_L__]


;; Succ edge  EXIT [100.0%]  (fallthru)

(note 19 15 0 NOTE_INSN_DELETED)

        .file   "sib.c"
__SREG__ = 0x3f
__SP_H__ = 0x3e
__SP_L__ = 0x3d
__tmp_reg__ = 0
__zero_reg__ = 1
        .global __do_copy_data
        .global __do_clear_bss
        .text
.global foo1
        .type   foo1, @function
foo1:
        push r29         ;  22  *pushhi/1       [length = 2]
        push r28
        push __tmp_reg__         ;  26  *addhi3_sp_R_pc2        [length = 1]
        in r28,__SP_L__  ;  27  *movhi_sp/2     [length = 2]
        in r29,__SP_H__
/* prologue: function */
/* frame size = 1 */
/* stack size = 3 */
.L__stack_usage = 3
        std Y+1,r24      ;  20  *movqi/3        [length = 1]
        rcall bar0       ;  7   call_insn/3     [length = 1]
        ldd r24,Y+1      ;  21  *movqi/4        [length = 1]
        rcall bar1       ;  10  call_insn/3     [length = 1]
/* epilogue start */
        pop __tmp_reg__  ;  32  *addhi3_sp_R_pc2        [length = 1]
        pop r28  ;  33  pophi   [length = 2]
        pop r29
        ret      ;  34  return_from_epilogue    [length = 1]
        .size   foo1, .-foo1
.global foo2
        .type   foo2, @function
foo2:
        push r17         ;  21  *pushqi/1       [length = 1]
/* prologue: function */
/* frame size = 0 */
/* stack size = 1 */
.L__stack_usage = 1
        mov r17,r24      ;  2   *movqi/1        [length = 1]
        rcall bar1       ;  8   call_insn/3     [length = 1]
        mov r24,r17      ;  13  *movqi/1        [length = 1]
/* epilogue start */
        pop r17  ;  24  popqi   [length = 1]
        ret      ;  25  return_from_epilogue    [length = 1]
        .size   foo2, .-foo2
.global foo3
        .type   foo3, @function
foo3:
        push r29         ;  26  *pushhi/1       [length = 2]
        push r28
        push __tmp_reg__         ;  30  *addhi3_sp_R_pc2        [length = 1]
        in r28,__SP_L__  ;  31  *movhi_sp/2     [length = 2]
        in r29,__SP_H__
/* prologue: function */
/* frame size = 1 */
/* stack size = 3 */
.L__stack_usage = 3
        std Y+1,r24      ;  24  *movqi/3        [length = 1]
        rcall bar0       ;  7   call_insn/3     [length = 1]
        ldd r24,Y+1      ;  25  *movqi/4        [length = 1]
/* epilogue start */
        pop __tmp_reg__  ;  36  *addhi3_sp_R_pc2        [length = 1]
        pop r28  ;  37  pophi   [length = 2]
        pop r29
        ret      ;  38  return_from_epilogue    [length = 1]
        .size   foo3, .-foo3

Reply via email to