From: Tobias C. R. <tc...@fr...> - 2009-05-16 16:33:11
|
Currently: (disassemble (defun bar (x y) (funcall (lambda (a b) (+ a b)) x y))) ; disassembly for BAR ; 0B56FCBC: 8BD6 MOV EDX, ESI ; no-arg-parsing entry point ; BE: 8B7DFC MOV EDI, [EBP-4] ; C1: 8B0588FC560B MOV EAX, [#xB56FC88] ; #<FUNCTION (LAMBDA ; #) {B56FA2D}> ; C7: B908000000 MOV ECX, 8 ; CC: FF7504 PUSH DWORD PTR [EBP+4] ; CF: FF60FF JMP DWORD PTR [EAX-1] ; D2: CC0A BREAK 10 ; error trap ; D4: 02 BYTE #X02 ; D5: 18 BYTE #X18 ; INVALID-ARG-COUNT-ERROR ; D6: 4D BYTE #X4D ; ECX With the patch of this mail: ; disassembly for BAR ; 0BA33475: 8B55FC MOV EDX, [EBP-4] ; no-arg-parsing entry point ; 78: 8B7DF8 MOV EDI, [EBP-8] ; 7B: E8D0CC5CF5 CALL #x1000150 ; GENERIC-+ ; 80: 7302 JNB L0 ; 82: 8BE3 MOV ESP, EBX ; 84: L0: 8BE5 MOV ESP, EBP ; 86: F8 CLC ; 87: 5D POP EBP ; 88: C3 RET ; 89: CC0A BREAK 10 ; error trap ; 8B: 02 BYTE #X02 ; 8C: 18 BYTE #X18 ; INVALID-ARG-COUNT-ERROR ; 8D: 4D BYTE #X4D ; ECX How can one write a test case for this? -T. diff --git a/src/compiler/ir1-translators.lisp b/src/compiler/ir1-translators.lisp index 7556b7e..8cef527 100644 --- a/src/compiler/ir1-translators.lisp +++ b/src/compiler/ir1-translators.lisp @@ -587,18 +587,20 @@ be a lambda expression." `(%funcall ,(ensure-lvar-fun-form function 'function) ,@arg-names)))) (def-ir1-translator %funcall ((function &rest args) start next result) - (let ((op (when (consp function) (car function)))) - (cond ((eq op 'function) - (with-fun-name-leaf (leaf (second function) start) - (ir1-convert start next result `(,leaf ,@args)))) - ((eq op 'global-function) - (with-fun-name-leaf (leaf (second function) start :global-function t) - (ir1-convert start next result `(,leaf ,@args)))) - (t - (let ((ctran (make-ctran)) - (fun-lvar (make-lvar))) - (ir1-convert start ctran fun-lvar `(the function ,function)) - (ir1-convert-combination-args fun-lvar ctran next result args)))))) + (flet ((ir1-convert-function-form (fn &optional globalp) + (with-fun-name-leaf (leaf (second fn) start :global-function globalp) + (ir1-convert start next result `(,leaf ,@args))))) + (let ((op (when (consp function) (car function)))) + (cond ((eq op 'function) (ir1-convert-function-form function)) + ((eq op 'global-function) (ir1-convert-function-form function t)) + ((member op '(lambda named-lambda)) + ;; N.B. Give *MACROEXPAND-HOOK* chance to run. + (ir1-convert-function-form (macroexpand-1 function *lexenv*))) + (t + (let ((ctran (make-ctran)) + (fun-lvar (make-lvar))) + (ir1-convert start ctran fun-lvar `(the function ,function)) + (ir1-convert-combination-args fun-lvar ctran next result args))))))) ;;; This source transform exists to reduce the amount of work for the ;;; compiler. If the called function is a FUNCTION form, then convert |
From: Tobias C. R. <tc...@fr...> - 2009-05-16 16:56:24
|
"Tobias C. Rittweiler" <tc...@fr...> writes: > (def-ir1-translator %funcall ((function &rest args) start next result) > - .... > + (flet ((ir1-convert-function-form (fn &optional globalp) > + (with-fun-name-leaf (leaf (second fn) start :global-function globalp) > + (ir1-convert start next result `(,leaf ,@args))))) > + (let ((op (when (consp function) (car function)))) > + (cond ((eq op 'function) (ir1-convert-function-form function)) > + ((eq op 'global-function) (ir1-convert-function-form function t)) > + ((member op '(lambda named-lambda)) > + ;; N.B. Give *MACROEXPAND-HOOK* chance to run. > + (ir1-convert-function-form (macroexpand-1 function *lexenv*))) Sorry this is wrong. It's right to give *MACROEXPAND-HOOK* a chance to run, but it may return something else than (FUNCTION FOO). I'll come up with something else tomorrow if none has fixed it till then. -T. |
From: Nikodemus S. <nik...@ra...> - 2009-05-17 18:06:57
|
2009/5/16 Tobias C. Rittweiler <tc...@fr...>: > > Currently: > > (disassemble (defun bar (x y) > (funcall (lambda (a b) (+ a b)) x y))) > > ; disassembly for BAR > ; 0B56FCBC: 8BD6 MOV EDX, ESI ; no-arg-parsing entry point > ; BE: 8B7DFC MOV EDI, [EBP-4] > ; C1: 8B0588FC560B MOV EAX, [#xB56FC88] ; #<FUNCTION (LAMBDA > ; #) {B56FA2D}> > ; C7: B908000000 MOV ECX, 8 > ; CC: FF7504 PUSH DWORD PTR [EBP+4] > ; CF: FF60FF JMP DWORD PTR [EAX-1] > ; D2: CC0A BREAK 10 ; error trap > ; D4: 02 BYTE #X02 > ; D5: 18 BYTE #X18 ; INVALID-ARG-COUNT-ERROR > ; D6: 4D BYTE #X4D ; ECX I don't see this: CL-USER> (disassemble (defun bar (x y) (funcall (lambda (a b) (+ a b)) x y))) STYLE-WARNING: redefining BAR in DEFUN ; disassembly for BAR ; 158E57F5: 8B55FC MOV EDX, [EBP-4] ; no-arg-parsing entry point ; 7F8: 8B7DF8 MOV EDI, [EBP-8] ; 7FB: E848A971EE CALL #x4000148 ; GENERIC-+ ; 800: 0F42E3 CMOVB ESP, EBX ; 803: 8BE5 MOV ESP, EBP ; 805: F8 CLC ; 806: 5D POP EBP ; 807: C3 RET ; 808: 0F0B0A BREAK 10 ; error trap ; 80B: 02 BYTE #X02 ; 80C: 18 BYTE #X18 ; INVALID-ARG-COUNT-ERROR ; 80D: 4D BYTE #X4D ; ECX NIL CL-USER> (describe-compiler-policy) Basic qualities: COMPILATION-SPEED = 1 DEBUG = 1 SAFETY = 1 SPACE = 1 SPEED = 1 INHIBIT-WARNINGS = 1 Cheers, -- Nikodemus |
From: Tobias C. R. <tc...@fr...> - 2009-05-17 18:47:13
|
Nikodemus Siivola <nik...@ra...> writes: > 2009/5/16 Tobias C. Rittweiler <tc...@fr...>: > > > > Currently: > > > > (disassemble (defun bar (x y) > > (funcall (lambda (a b) (+ a b)) x y))) > > > > .... no inlining ... > > I don't see this: I'm on .28.43, linux x86-32. Notice that the lambda is correctly inlined for #'(lambda (a b) (+ a b)). -T. |
From: Nikodemus S. <nik...@ra...> - 2009-05-18 13:05:57
|
2009/5/17 Tobias C. Rittweiler <tc...@fr...>: > I'm on .28.43, linux x86-32. Notice that the lambda is correctly inlined > for #'(lambda (a b) (+ a b)). Turns out this the difference between COMPILE and COMPILE-FILE. I don't yet quite understand why what happens happens, but (SB-C::MAKE-FUNCTIONAL-FROM-TOPLEVEL-LAMBDA (SB-INT:NAMED-LAMBDA BAR (X Y) (BLOCK BAR (FUNCALL (LAMBDA (A B) (+ A B)) X Y))) ...) versus (SB-C::MAKE-FUNCTIONAL-FROM-TOPLEVEL-LAMBDA (LAMBDA () (SB-INT:NAMED-LAMBDA BAR (X Y) (BLOCK BAR (FUNCALL (LAMBDA (A B) (+ A B)) X Y))) ...)) is the core difference. (Latter from produces better code -- obviously the produced function needs to be called to get the function we want.) Cheers, -- Nikodemus |