Inline functions do not inline lambdas passed as arguments.

Bug #1762751 reported by Andrzej Walczak on 2018-04-10
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
SBCL
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
To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers