Comment 0 for bug 1762751

Revision history for this message
Andrzej Walczak (andrzejwalczak) wrote : Inlining and lambda arguments regression

;; If we pass a lambda form to an inline function,
;; this does not get properly optimized by SBCL's compiler.

;; Example code.

(declaim (inline nie))
(defun nie (fn) (declare (function fn))
   "A function that calls nie."
   (funcall fn :nie))

;;
;; NIE is fully inlined here and BAZ becomes (constantly T).
(defun baz ()
  (nie #'symbolp))

CL-USER> (disassemble 'baz)
; disassembly for BAZ
; Size: 11 bytes. Origin: #x1021287276
; 76: BA4F001050 MOV EDX, #x5010004F ; no-arg-parsing entry point
                                                              ; T
; 7B: 488BE5 MOV RSP, RBP
; 7E: F8 CLC
; 7F: 5D POP RBP
; 80: C3 RET

;;
;; Now the same with a LAMBDA. 12 - bytes more and a JMP.
(defun bar ()
  (nie (lambda (s) (symbolp s))))

CL-USER> (disassemble 'bar)
; disassembly for BAR
; Size: 23 bytes. Origin: #x1021287386
; 86: BA1F729C50 MOV EDX, #x509C721F ; no-arg-parsing entry point
                                                              ; :NIE
; 8B: 488B05AEFFFFFF MOV RAX, [RIP-82] ; #<FUNCTION (LAMBDA
                                                              ; # ..)>
; 92: B902000000 MOV ECX, 2
; 97: FF7508 PUSH QWORD PTR [RBP+8]
; 9A: FF60FD JMP QWORD PTR [RAX-3]

;; Just to check that:
;; (funcall (lambda ...)) still works like in the 60s'

(defun foo ()
  (funcall (lambda (x) (symbolp x)) :nie))

CL-USER> (disassemble 'foo)
; disassembly for FOO
; Size: 11 bytes. Origin: #x10212873F6
; 3F6: BA4F001050 MOV EDX, #x5010004F ; no-arg-parsing entry point
                                                              ; T
; 3FB: 488BE5 MOV RSP, RBP
; 3FE: F8 CLC
; 3FF: 5D POP RBP
; 400: C3 RET

;; As a consequence this forces one to use compiler-macros for folding and inlining
;; instead-of the default inline mechanism.