title: Running GHC's LLVM output through the LLVM bitcode linker first
body: <p>I want to be able to call LLVM code from Haskell without the overhead of a full function call. For example:</p>
  
  <pre><code>-- Main.hs --
  
  {-# LANGUAGE MagicHash #-}
  {-# LANGUAGE UnboxedTuples #-}
  {-# LANGUAGE GHCForeignImportPrim #-}
  {-# LANGUAGE ForeignFunctionInterface #-}
  {-# LANGUAGE UnliftedFFITypes #-}
  {-# LANGUAGE BangPatterns #-}
  
  import GHC.Exts(Word(W#))
  import GHC.Prim(Word#)
  
  foreign import ccall llvminc :: Word# -&gt; Word#
  
  main = do
    line1 &lt;- getLine
    let !(W# x1) = read line1
    let !r1 = llvminc x1
    print (W# r1)
  
  
  -- funcs.ll --
  
  define fastcc i64 @llvminc(i64 inreg %x) {
    %r = add i64 %x, 1
    ret i64 %r
  }
  </code></pre>
  
  <p>I can compile and link this to produce a functioning executable by running:</p>
  
  <pre><code>ghc -O2 -fllvm Main.hs funcs.ll
  </code></pre>
  
  <p>Indeed, even removing <code>-fllvm</code> still results in a functioning executable, e.g. </p>
  
  <pre><code>ghc -O2 Main.hs funcs.ll
  </code></pre>
  
  <p>Which leads me to strongly suspect GHC is linking these files separately in both cases using ordinary C linkage.</p>
  
  <p>Indeed, when I investigate the intermediate output using:</p>
  
  <pre><code>ghc -O2 -fllvm -keep-s-files Main.hs funcs.ll
  </code></pre>
  
  <p>I see the following in Main.s:</p>
  
  <pre><code>callq   suspendThread
  movq    %rax, %rbp
  movq    %rbx, %rdi
  callq   llvminc
  movq    %rax, %rbx
  movq    %rbp, %rdi
  callq   resumeThread
  </code></pre>
  
  <p>Which again suggests that GHC is just asking LLVM to compile the files separately and it then just sending the results to the system linker, which wouldn't inline the calls.</p>
  
  <p>Instead, I'd like GHC to send the initial LLVM files (both from GHC and user specified) to the <a href="http://llvm.org/docs/CommandGuide/llvm-link.html" rel="noreferrer">llvm-link</a>, which unlike a system linker, simply combines multiple LLVM bitcode files into one LLVM bitcode file. It would be best if this result was then compiled to native code object file and sent to the system linker, instead of multiple object files being sent to the system linker.</p>
  
  <p>Indeed, when I tried this manually, assembling the <code>.ll</code> human readable files to LLVM <code>.bc</code> bitcode, <code>llvm-link</code>ing the resulting bitcode, then disassembling the bitcode like so:</p>
  
  <pre><code>llvm-as Main.ll
  llvm-as funcs.ll
  llvm-link funcs.bc Main.bc -o combined.bc
  llvm-dis combined.bc
  </code></pre>
  
  <p>I found the following in the resulting LLVM code</p>
  
  <pre><code>%ln59M = add i64 %ln59L, 1
  </code></pre>
  
  <p>directly after the call to read, with no "call" or return. The actual function is still in the LLVM, but is uncalled.</p>
  
  <p>So I tried instructing GHC to link with the LLVM linker by adding <code>-pgml llvm-link</code> to the command line, but this failed spectacularly, with <code>llvm-link</code> throwing back many errors about unknown options. This is unsurprising, as <code>llvm-link</code> isn't a real linker, it just combines LLVM files.</p>
  
  <p>So, is there anyway to get GHC to send all it's intermediate LLVM files through the LLVM linker to enable intermodule optimisations at the LLVM level?</p>