Inline functions do not inline lambdas passed as arguments.

Bug #1762751 reported by Andrzej Walczak
10
This bug affects 2 people
Affects Status Importance Assigned to Milestone
SBCL
Fix Released
Undecided
Unassigned

Bug Description

;; If we pass a lambda form to an inline function,
;; this does not get properly optimized by SBCL's compiler.
;; This maybe a recent regression, but I cannot pinpoint the SBCL version.

;; 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.

description: updated
summary: - Inlining and lambda arguments regression
+ Inlined functions do not inline lambdas passed as arguments.
summary: - Inlined functions do not inline lambdas passed as arguments.
+ Inline functions do not inline lambdas passed as arguments.
description: updated
description: updated
Revision history for this message
Stas Boukarev (stassats) wrote :

I think it was a23057a6fc95679d9c7e985c8989bc8d7c5a1507.

Changed in sbcl:
status: New → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.