-fno-inline オプション

R5RS の例を最適化抑制 (インライン化しない?) なオプションで disasm してみる。

 gosh -fno-inline -E  '(disasm (lambda () (let ((x 5)) (letrec ((foo (lambda (y) (bar x y))) (bar (lambda (a b) (+ (* a b) a)))) (foo (+ x 3))))))'
main_code (name=#f, code=0x80f7ea0, size=12, const=2, stack=17):
args: #f
     0 LOCAL-ENV-CLOSURES(2) (#<lambda 0>#<lambda 1>); (letrec ((foo (lambda (y) (bar x y))) (b ...
     2 PRE-CALL(2) 8
     4 CONSTI-PUSH(5) 
     5 CONSTI-PUSH(3) 
     6 GREF-CALL(2) #<identifier user#+>; (+ x 3)
     8 PUSH 
     9 LREF1                    ; foo
    10 TAIL-CALL(1)             ; (foo (+ x 3))
    11 RET 
internal_closure_1 (name=bar, code=0x80f8fa0, size=10, const=2 stack=12):
args: #f
     0 PRE-CALL(2) 5
     2 LREF1-PUSH               ; a
     3 LREF0-PUSH-GREF-CALL(2) #<identifier user#*>; (* a b)
     5 PUSH 
     6 LREF1-PUSH               ; a
     7 GREF-TAIL-CALL(2) #<identifier user#+>; (+ (* a b) a)
     9 RET 
internal_closure_0 (name=foo, code=0x80d7db0, size=5, const=0 stack=5):
args: #f
     0 CONSTI-PUSH(5) 
     1 LREF0-PUSH               ; y
     2 LREF10                   ; bar
     3 TAIL-CALL(2)             ; (bar x y)
     4 RET 
*** ERROR: invalid application: (#<undef>)
Stack Trace:
_______________________________________
$

最後らへんが微妙ですが、最適化具合がもの凄い事は分かります。オプション略したら以下ですもの。

$ gosh -E  '(disasm (lambda () (let ((x 5)) (letrec ((foo (lambda (y) (bar x y))) (bar (lambda (a b) (+ (* a b) a)))) (foo (+ x 3))))))'
main_code (name=#f, code=0x80f6f40, size=8, const=0, stack=5):
args: #f
     0 CONSTI(3) 
     1 NUMADDI(5)               ; (+ x 3)
     2 PUSH-LOCAL-ENV(1)        ; (foo (+ x 3))
     3 CONSTI-PUSH(5) 
     4 LREF0                    ; y
     5 NUMMUL2                  ; (* a b)
     6 NUMADDI(5)               ; (+ (* a b) a)
     7 RET 
*** ERROR: invalid application: (#<undef>)
Stack Trace:
_______________________________________
$

ちょっと控えておいて別途時間があるときに眺めてみる方向で。