Thursday, July 26, 2018

Getting the Allegro CL Compiler to Inline

Many standard Common Lisp functions, particularly those which do simple calculations or access data from arrays or structures, can be compiled inline by the compiler. Inline compilation results in faster, often significantly faster run times as the function call and return overheads are saved.
But there are tricks to getting the compiler to inline, and there are tools which assist is expalining what the compiler is doing. In this note, we take a simple function with a call to the math function round, and try to get the call to round to inline. Here is the function:
(defun foo (x) 
   (declare (optimize (speed 3) (safety 0) (debug 0)) (double-float x)) 
   (round (* x x)))
round looks like a good candidate for inlining: the type of its argument is known and speed, safety, and debug have values calling for maximum speed. But when it is compiled and the compiled function is disassembled, we see that round was not inlined:
cl-user(10): (compile 'foo)
foo
nil
nil
cl-user(11): (disassemble 'foo)
;; disassembly of #<Function foo>
;; formals: x
;; constant vector:
0: round

;; code start: #x10003508c80:
   0: 48 83 ec 68    sub rsp,$104
   4: 4c 89 74 24 08 movq [rsp+8],r14
   9: f2 44 0f 10 6f movsd xmm13,[rdi-10]
      f6 
  15: f2 45 0f 59 ed mulsd xmm13,xmm13
  20: f2 45 0f 10 fd movsd xmm15,xmm13
  25: 31 c0          xorl eax,eax
  27: 41 ff 97 d7 03 call *[r15+983]   ; sys::new-double-float
      00 00 
  34: 4c 89 7c 24 18 movq [rsp+24],r15
  39: 48 8d 64 24 68 leaq rsp,[rsp+104]
  44: 49 8b 6e 36    movq rbp,[r14+54] ; round
  48: b0 08          movb al,$8
  50: ff e3          jmp *rbx
cl-user(11): 
The line labeled 44 is the jump to the round function.
So what went wrong? 

Read the rest of this post, and many more,  in the Tech Corner section of our website.