|
From: Charles Z. <cha...@ya...> - 2020-01-14 04:54:33
|
Hi folks, A heads up that I've checked in block compilation support. I tried hard to make it a no-op, since most of the changes are guarded against actually using the feature, but there is a remote chance it might much something up (I did change the lifetime of the ir1-namespace hashtables and needed to hack around some cross-type ambiguity warnings deriving from some recent changes with another queued tlf mechanism that was recently added). Since as far as I can tell we have never supported it, we also don't have any user facing documentation for the feature. Can we lift the relevant sections of the CMUCL manual directly into our docs? A big omission is the CMUCL-style START-BLOCK END-BLOCK proclamations which specify the scope of block compilation and their entry points. I didn't want to open this can of worms because apparently it was the reason it was gutted out in the first place (i.e. the non-ANSI conformance of how these proclamations behaved in CMUCL). But the :block-compile and :entry-point keywords should work fine. Are the declarations something we would be interested supporting again, as a non-ANSI extension? I'd be interested in seeing if we can self host the compiler for delivery with it enabled to some extent, like CMUCL does. The re-implementation isn't perfect and I think source info and inlining may not interact with block compiling correctly., although I *think* compile-file should behave more or less entirely ANSI-compliant with this approach. Anyway, here is a quick demonstration: foo.lisp (defun foo (x y) (print (bar x y)) (bar x y)) (defun bar (x y) (+ x y)) (defun fact (n) (if (zerop n) 1 (* n (fact (1- n))))) > (compile-file "test.lisp" :block-compile t :entry-points nil)> (load "test.fasl") (sb-disassem:disassemble-code-component #'foo) ; Size: 210 bytes. Origin: #x52E63F90 (segment 1 of 4) ; (XEP BAR) ; 3F90: .ENTRY BAR(X Y) ; (SB-INT:SFUNCTION ; (T T) NUMBER) ; 3FA0: 8F4508 POP QWORD PTR [RBP+8] ; 3FA3: 4883F904 CMP RCX, 4 ; 3FA7: 0F85B1000000 JNE L2 ; 3FAD: 488D65D0 LEA RSP, [RBP-48] ; 3FB1: 4C8BC2 MOV R8, RDX ; 3FB4: 488BF7 MOV RSI, RDI ; 3FB7: EB03 JMP L1 ; 3FB9: L0: 8F4508 POP QWORD PTR [RBP+8] ; Origin #x52E63FBC (segment 2 of 4) ; BAR ; 3FBC: L1: 498B4510 MOV RAX, [R13+16] ; thread.binding-stack-pointer ; 3FC0: 488945F8 MOV [RBP-8], RAX ; 3FC4: 4C8945D8 MOV [RBP-40], R8 ; 3FC8: 488975D0 MOV [RBP-48], RSI ; 3FCC: 498BD0 MOV RDX, R8 ; 3FCF: 488BFE MOV RDI, RSI ; 3FD2: E8B9CB29FF CALL #x52100B90 ; GENERIC-+ ; 3FD7: 488B75D0 MOV RSI, [RBP-48] ; 3FDB: 4C8B45D8 MOV R8, [RBP-40] ; 3FDF: 488BE5 MOV RSP, RBP ; 3FE2: F8 CLC ; 3FE3: 5D POP RBP ; 3FE4: C3 RET ; Origin #x52E63FE5 (segment 3 of 4) ; (XEP FOO) ; 3FE5: .SKIP 11 ; 3FF0: .ENTRY FOO(X Y) ; (SB-INT:SFUNCTION ; (T T) NUMBER) ; 4000: 8F4508 POP QWORD PTR [RBP+8] ; 4003: 4883F904 CMP RCX, 4 ; 4007: 7557 JNE L3 ; 4009: 488D65D0 LEA RSP, [RBP-48] ; 400D: 488955E8 MOV [RBP-24], RDX ; 4011: 48897DE0 MOV [RBP-32], RDI ; Origin #x52E64015 (segment 4 of 4) ; FOO ; 4015: 498B4510 MOV RAX, [R13+16] ; thread.binding-stack-pointer ; 4019: 488945F0 MOV [RBP-16], RAX ; 401D: 4C8BCD MOV R9, RBP ; 4020: 488D4424F0 LEA RAX, [RSP-16] ; 4025: 4883EC40 SUB RSP, 64 ; 4029: 4C8B45E8 MOV R8, [RBP-24] ; 402D: 488B75E0 MOV RSI, [RBP-32] ; 4031: 4C8908 MOV [RAX], R9 ; 4034: 488BE8 MOV RBP, RAX ; 4037: E87DFFFFFF CALL L0 ; 403C: 4883EC10 SUB RSP, 16 ; 4040: B902000000 MOV ECX, 2 ; 4045: 48892C24 MOV [RSP], RBP ; 4049: 488BEC MOV RBP, RSP ; 404C: E8F1E163FD CALL #x504A2242 ; #<FDEFN PRINT> ; 4051: 4C8B45E8 MOV R8, [RBP-24] ; 4055: 488B75E0 MOV RSI, [RBP-32] ; 4059: E95EFFFFFF JMP L1 ; 405E: L2: CC10 INT3 16 ; Invalid argument count trap ; 4060: L3: CC10 INT3 16 ; Invalid argument count trap FOO and BAR are compiled into the same component (with local calls), and both have valid external entry points. > (compile-file "test.lisp" :block-compile t :entry-points '(bar fact)) FOO is removed for being unused. > (compile-file "test.lisp" :block-compile :specified) FOO, BAR, and FACT get entry points, and FACT calls itself directly and not through an FDEFN. Cheers. |