Last active
August 28, 2019 18:31
-
-
Save fouric/867cd3fb4d86fec991c63ebbf3c08317 to your computer and use it in GitHub Desktop.
the SBCL compiler is available at runtime; how much can we optimize compilation of a function if we have information about its parameters?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; example code to test out "JIT compilation" in (SBCL) CL | |
(defun foo (x f n) | |
"call f(f(f(...f(x)))) with f being called n times" | |
(dotimes (i n) | |
(setf x (funcall f x))) | |
x) | |
;; no type declarations | |
; Size: 186 bytes. Origin: #x1004C502AC | |
; 2AC: 498B4C2458 MOV RCX, [R12+88] ; no-arg-parsing entry point | |
; thread.binding-stack-pointer | |
; 2B1: 48894DF8 MOV [RBP-8], RCX | |
; 2B5: 488B4DE8 MOV RCX, [RBP-24] | |
; 2B9: 8D41F1 LEA EAX, [RCX-15] | |
; 2BC: A801 TEST AL, 1 | |
; 2BE: 7512 JNE L0 | |
; 2C0: A80F TEST AL, 15 | |
; 2C2: 0F8595000000 JNE L4 | |
; 2C8: 8079F111 CMP BYTE PTR [RCX-15], 17 | |
; 2CC: 0F858B000000 JNE L4 | |
; 2D2: L0: 31F6 XOR ESI, ESI | |
; 2D4: EB5E JMP L3 | |
; 2D6: 660F1F840000000000 NOP | |
; 2DF: 90 NOP | |
; 2E0: L1: 488BD3 MOV RDX, RBX | |
; 2E3: 4883EC10 SUB RSP, 16 | |
; 2E7: 488975E0 MOV [RBP-32], RSI | |
; 2EB: 488B45F0 MOV RAX, [RBP-16] | |
; 2EF: B902000000 MOV ECX, 2 | |
; 2F4: 48892C24 MOV [RSP], RBP | |
; 2F8: 488BEC MOV RBP, RSP | |
; 2FB: 8D58F5 LEA EBX, [RAX-11] | |
; 2FE: F6C30F TEST BL, 15 | |
; 301: 7407 JEQ L2 | |
; 303: BB1004B021 MOV EBX, #x21B00410 ; CALL-SYMBOL | |
; 308: FFD3 CALL RBX | |
; 30A: L2: FF50FD CALL QWORD PTR [RAX-3] | |
; 30D: 480F42E3 CMOVB RSP, RBX | |
; 311: 488B75E0 MOV RSI, [RBP-32] | |
; 315: 488BDA MOV RBX, RDX | |
; 318: 48895DD8 MOV [RBP-40], RBX | |
; 31C: BF02000000 MOV EDI, 2 | |
; 321: 488BD6 MOV RDX, RSI | |
; 324: 41BB7005B021 MOV R11D, #x21B00570 ; GENERIC-+ | |
; 32A: 41FFD3 CALL R11 | |
; 32D: 488B5DD8 MOV RBX, [RBP-40] | |
; 331: 488BF2 MOV RSI, RDX | |
; 334: L3: 48895DD8 MOV [RBP-40], RBX | |
; 338: 488975E0 MOV [RBP-32], RSI | |
; 33C: 488B7DE8 MOV RDI, [RBP-24] | |
; 340: 488BD6 MOV RDX, RSI | |
; 343: B97007B021 MOV ECX, #x21B00770 ; GENERIC-< | |
; 348: FFD1 CALL RCX | |
; 34A: 488B75E0 MOV RSI, [RBP-32] | |
; 34E: 488B5DD8 MOV RBX, [RBP-40] | |
; 352: 7C8C JL L1 | |
; 354: 488BD3 MOV RDX, RBX | |
; 357: 488BE5 MOV RSP, RBP | |
; 35A: F8 CLC | |
; 35B: 5D POP RBP | |
; 35C: C3 RET | |
; 35D: L4: 488B45E8 MOV RAX, [RBP-24] | |
; 361: CC53 BREAK 83 ; OBJECT-NOT-INTEGER-ERROR | |
; 363: 00 BYTE #X00 ; RAX | |
; 364: CC0F BREAK 15 ; Invalid argument count trap | |
;; type declarations for f and n | |
; Size: 132 bytes. Origin: #x1004C5078C | |
; 78C: 498B4C2458 MOV RCX, [R12+88] ; no-arg-parsing entry point | |
; thread.binding-stack-pointer | |
; 791: 48894DF8 MOV [RBP-8], RCX | |
; 795: 31F6 XOR ESI, ESI | |
; 797: EB4C JMP L1 | |
; 799: 0F1F8000000000 NOP | |
; 7A0: L0: 488BD3 MOV RDX, RBX | |
; 7A3: 4883EC10 SUB RSP, 16 | |
; 7A7: 488975E0 MOV [RBP-32], RSI | |
; 7AB: 488B45F0 MOV RAX, [RBP-16] | |
; 7AF: B902000000 MOV ECX, 2 | |
; 7B4: 48892C24 MOV [RSP], RBP | |
; 7B8: 488BEC MOV RBP, RSP | |
; 7BB: FF50FD CALL QWORD PTR [RAX-3] | |
; 7BE: 480F42E3 CMOVB RSP, RBX | |
; 7C2: 488B75E0 MOV RSI, [RBP-32] | |
; 7C6: 488BDA MOV RBX, RDX | |
; 7C9: 48895DD8 MOV [RBP-40], RBX | |
; 7CD: BF02000000 MOV EDI, 2 | |
; 7D2: 488BD6 MOV RDX, RSI | |
; 7D5: 41BB7005B021 MOV R11D, #x21B00570 ; GENERIC-+ | |
; 7DB: 41FFD3 CALL R11 | |
; 7DE: 488B5DD8 MOV RBX, [RBP-40] | |
; 7E2: 488BF2 MOV RSI, RDX | |
; 7E5: L1: 48895DD8 MOV [RBP-40], RBX | |
; 7E9: 488975E0 MOV [RBP-32], RSI | |
; 7ED: 488B7DE8 MOV RDI, [RBP-24] | |
; 7F1: 488BD6 MOV RDX, RSI | |
; 7F4: B97007B021 MOV ECX, #x21B00770 ; GENERIC-< | |
; 7F9: FFD1 CALL RCX | |
; 7FB: 488B75E0 MOV RSI, [RBP-32] | |
; 7FF: 488B5DD8 MOV RBX, [RBP-40] | |
; 803: 7C9B JL L0 | |
; 805: 488BD3 MOV RDX, RBX | |
; 808: 488BE5 MOV RSP, RBP | |
; 80B: F8 CLC | |
; 80C: 5D POP RBP | |
; 80D: C3 RET | |
; 80E: CC0F BREAK 15 ; Invalid argument count trap | |
;; substitute (funcall #'1+ x) | |
; Size: 135 bytes. Origin: #x1004C51088 | |
; 088: 498B4C2458 MOV RCX, [R12+88] ; no-arg-parsing entry point | |
; thread.binding-stack-pointer | |
; 08D: 48894DF8 MOV [RBP-8], RCX | |
; 091: 31F6 XOR ESI, ESI | |
; 093: EB4F JMP L1 | |
; 095: 660F1F840000000000 NOP | |
; 09E: 6690 NOP | |
; 0A0: L0: 488BD3 MOV RDX, RBX | |
; 0A3: 4883EC10 SUB RSP, 16 | |
; 0A7: 488975E8 MOV [RBP-24], RSI | |
; 0AB: 488B055EFFFFFF MOV RAX, [RIP-162] ; #<FUNCTION 1+> | |
; 0B2: B902000000 MOV ECX, 2 | |
; 0B7: 48892C24 MOV [RSP], RBP | |
; 0BB: 488BEC MOV RBP, RSP | |
; 0BE: FF50FD CALL QWORD PTR [RAX-3] | |
; 0C1: 488B75E8 MOV RSI, [RBP-24] | |
; 0C5: 488BDA MOV RBX, RDX | |
; 0C8: 48895DE0 MOV [RBP-32], RBX | |
; 0CC: BF02000000 MOV EDI, 2 | |
; 0D1: 488BD6 MOV RDX, RSI | |
; 0D4: 41BB7005B021 MOV R11D, #x21B00570 ; GENERIC-+ | |
; 0DA: 41FFD3 CALL R11 | |
; 0DD: 488B5DE0 MOV RBX, [RBP-32] | |
; 0E1: 488BF2 MOV RSI, RDX | |
; 0E4: L1: 48895DE0 MOV [RBP-32], RBX | |
; 0E8: 488975E8 MOV [RBP-24], RSI | |
; 0EC: 488B7DF0 MOV RDI, [RBP-16] | |
; 0F0: 488BD6 MOV RDX, RSI | |
; 0F3: B97007B021 MOV ECX, #x21B00770 ; GENERIC-< | |
; 0F8: FFD1 CALL RCX | |
; 0FA: 488B75E8 MOV RSI, [RBP-24] | |
; 0FE: 488B5DE0 MOV RBX, [RBP-32] | |
; 102: 7C9C JL L0 | |
; 104: 488BD3 MOV RDX, RBX | |
; 107: 488BE5 MOV RSP, RBP | |
; 10A: F8 CLC | |
; 10B: 5D POP RBP | |
; 10C: C3 RET | |
; 10D: CC0F BREAK 15 ; Invalid argument count trap | |
;; substitute (1+ x) | |
; Size: 123 bytes. Origin: #x1004C51528 | |
; 28: 498B4C2458 MOV RCX, [R12+88] ; no-arg-parsing entry point | |
; thread.binding-stack-pointer | |
; 2D: 48894DF8 MOV [RBP-8], RCX | |
; 31: 31DB XOR EBX, EBX | |
; 33: EB43 JMP L1 | |
; 35: 660F1F840000000000 NOP | |
; 3E: 6690 NOP | |
; 40: L0: 48895DE8 MOV [RBP-24], RBX | |
; 44: BF02000000 MOV EDI, 2 | |
; 49: 498BD0 MOV RDX, R8 | |
; 4C: 41BB7005B021 MOV R11D, #x21B00570 ; GENERIC-+ | |
; 52: 41FFD3 CALL R11 | |
; 55: 488B5DE8 MOV RBX, [RBP-24] | |
; 59: 4C8BC2 MOV R8, RDX | |
; 5C: 4C8945E0 MOV [RBP-32], R8 | |
; 60: BF02000000 MOV EDI, 2 | |
; 65: 488BD3 MOV RDX, RBX | |
; 68: 41BB7005B021 MOV R11D, #x21B00570 ; GENERIC-+ | |
; 6E: 41FFD3 CALL R11 | |
; 71: 4C8B45E0 MOV R8, [RBP-32] | |
; 75: 488BDA MOV RBX, RDX | |
; 78: L1: 4C8945E0 MOV [RBP-32], R8 | |
; 7C: 48895DE8 MOV [RBP-24], RBX | |
; 80: 488B7DF0 MOV RDI, [RBP-16] | |
; 84: 488BD3 MOV RDX, RBX | |
; 87: B97007B021 MOV ECX, #x21B00770 ; GENERIC-< | |
; 8C: FFD1 CALL RCX | |
; 8E: 488B5DE8 MOV RBX, [RBP-24] | |
; 92: 4C8B45E0 MOV R8, [RBP-32] | |
; 96: 7CA8 JL L0 | |
; 98: 498BD0 MOV RDX, R8 | |
; 9B: 488BE5 MOV RSP, RBP | |
; 9E: F8 CLC | |
; 9F: 5D POP RBP | |
; A0: C3 RET | |
; A1: CC0F BREAK 15 ; Invalid argument count trap | |
;; (declare (optimize (speed 3))) | |
; Size: 107 bytes. Origin: #x1004C51858 | |
; 58: 31F6 XOR ESI, ESI ; no-arg-parsing entry point | |
; 5A: EB3C JMP L1 | |
; 5C: 0F1F4000 NOP | |
; 60: L0: 488975F0 MOV [RBP-16], RSI | |
; 64: BF02000000 MOV EDI, 2 | |
; 69: 488BD3 MOV RDX, RBX | |
; 6C: 41BB7005B021 MOV R11D, #x21B00570 ; GENERIC-+ | |
; 72: 41FFD3 CALL R11 | |
; 75: 488B75F0 MOV RSI, [RBP-16] | |
; 79: 488BDA MOV RBX, RDX | |
; 7C: 48895DE8 MOV [RBP-24], RBX | |
; 80: BF02000000 MOV EDI, 2 | |
; 85: 488BD6 MOV RDX, RSI | |
; 88: 41BB7005B021 MOV R11D, #x21B00570 ; GENERIC-+ | |
; 8E: 41FFD3 CALL R11 | |
; 91: 488B5DE8 MOV RBX, [RBP-24] | |
; 95: 488BF2 MOV RSI, RDX | |
; 98: L1: 488975F0 MOV [RBP-16], RSI | |
; 9C: 48895DE8 MOV [RBP-24], RBX | |
; A0: 488B7DF8 MOV RDI, [RBP-8] | |
; A4: 488BD6 MOV RDX, RSI | |
; A7: B97007B021 MOV ECX, #x21B00770 ; GENERIC-< | |
; AC: FFD1 CALL RCX | |
; AE: 488B5DE8 MOV RBX, [RBP-24] | |
; B2: 488B75F0 MOV RSI, [RBP-16] | |
; B6: 7CA8 JL L0 | |
; B8: 488BD3 MOV RDX, RBX | |
; BB: 488BE5 MOV RSP, RBP | |
; BE: F8 CLC | |
; BF: 5D POP RBP | |
; C0: C3 RET | |
; C1: CC0F BREAK 15 ; Invalid argument count trap | |
;; declare x to also be an integer - somehow larger than when it wasn't??? (oh, and also remove the argument f) | |
; Size: 113 bytes. Origin: #x1004C529D2 | |
; 9D2: 31F6 XOR ESI, ESI ; no-arg-parsing entry point | |
; 9D4: EB42 JMP L1 | |
; 9D6: 660F1F840000000000 NOP | |
; 9DF: 90 NOP | |
; 9E0: L0: 488975F0 MOV [RBP-16], RSI | |
; 9E4: BF02000000 MOV EDI, 2 | |
; 9E9: 488BD3 MOV RDX, RBX | |
; 9EC: 41BB7005B021 MOV R11D, #x21B00570 ; GENERIC-+ | |
; 9F2: 41FFD3 CALL R11 | |
; 9F5: 488B75F0 MOV RSI, [RBP-16] | |
; 9F9: 488BDA MOV RBX, RDX | |
; 9FC: 48895DE8 MOV [RBP-24], RBX | |
; A00: BF02000000 MOV EDI, 2 | |
; A05: 488BD6 MOV RDX, RSI | |
; A08: 41BB7005B021 MOV R11D, #x21B00570 ; GENERIC-+ | |
; A0E: 41FFD3 CALL R11 | |
; A11: 488B5DE8 MOV RBX, [RBP-24] | |
; A15: 488BF2 MOV RSI, RDX | |
; A18: L1: 488975F0 MOV [RBP-16], RSI | |
; A1C: 48895DE8 MOV [RBP-24], RBX | |
; A20: 488B7DF8 MOV RDI, [RBP-8] | |
; A24: 488BD6 MOV RDX, RSI | |
; A27: B97007B021 MOV ECX, #x21B00770 ; GENERIC-< | |
; A2C: FFD1 CALL RCX | |
; A2E: 488B5DE8 MOV RBX, [RBP-24] | |
; A32: 488B75F0 MOV RSI, [RBP-16] | |
; A36: 7CA8 JL L0 | |
; A38: 488BD3 MOV RDX, RBX | |
; A3B: 488BE5 MOV RSP, RBP | |
; A3E: F8 CLC | |
; A3F: 5D POP RBP | |
; A40: C3 RET | |
; A41: CC0F BREAK 15 ; Invalid argument count trap | |
;; declare n and x to be fixnum | |
; Size: 55 bytes. Origin: #x10030CCB21 | |
; 21: 31D2 XOR EDX, EDX ; no-arg-parsing entry point | |
; 23: EB20 JMP L1 | |
; 25: 660F1F840000000000 NOP | |
; 2E: 6690 NOP | |
; 30: L0: 48D1F8 SAR RAX, 1 | |
; 33: 48FFC0 INC RAX | |
; 36: 488BC8 MOV RCX, RAX | |
; 39: 48D1E1 SHL RCX, 1 | |
; 3C: 7015 JO L2 | |
; 3E: 48D1E0 SHL RAX, 1 | |
; 41: 4883C202 ADD RDX, 2 | |
; 45: L1: 4839FA CMP RDX, RDI | |
; 48: 7CE6 JL L0 | |
; 4A: 488BD0 MOV RDX, RAX | |
; 4D: 488BE5 MOV RSP, RBP | |
; 50: F8 CLC | |
; 51: 5D POP RBP | |
; 52: C3 RET | |
; 53: L2: CC47 BREAK 71 ; OBJECT-NOT-FIXNUM-ERROR | |
; 55: 02 BYTE #X02 ; RAX | |
; 56: CC0F BREAK 15 ; Invalid argument count trap | |
;; declare safety 0 | |
; Size: 32 bytes. Origin: #x10030CCC49 | |
; 49: 31C9 XOR ECX, ECX ; no-arg-parsing entry point | |
; 4B: EB0E JMP L1 | |
; 4D: 0F1F00 NOP | |
; 50: L0: 488D4302 LEA RAX, [RBX+2] | |
; 54: 488BD8 MOV RBX, RAX | |
; 57: 4883C102 ADD RCX, 2 | |
; 5B: L1: 4839F9 CMP RCX, RDI | |
; 5E: 7CF0 JL L0 | |
; 60: 488BD3 MOV RDX, RBX | |
; 63: 488BE5 MOV RSP, RBP | |
; 66: F8 CLC | |
; 67: 5D POP RBP | |
; 68: C3 RET | |
;; final code: | |
(let ((f '1+)) | |
(eval `(defun foo (x n) | |
"call f(f(f(...f(x)))) with f being called n times" | |
(declare (optimize (speed 3) (safety 0)) | |
(type fixnum n) | |
(type fixnum x)) | |
(dotimes (i n x) | |
(setf x (,f x)))))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
What happens if we turn the loop + assign into a recursive call with a depth/count parameter?