[LLVMdev] Using LLVM to serialize object state -- and performance

Kaylor, Andrew andrew.kaylor at intel.com
Tue Oct 30 09:25:50 PDT 2012

Hi Paul,

I had an additional thought with regard to the performance issue you are seeing.

As I understand it, you are generating a large number of functions that call other functions.  If the functions being called are externals from the perspective of the JITed code that need to be resolved against some static code within the running executable, that's probably where the slowdown is occurring.  Whenever the JIT engine (either the legacy JIT or MCJIT) needs to resolve an external function it calls JITMemoryManager::getPointerToNamedFunction to resolve the function address.

The default JITMemoryManager implementation uses sys::DynamicLibrary::SearchForAddressOfSymbol to find the function.  If you know all of the names and addresses of the functions that will need to be resolved, you can provide a custom memory manager implementation to optimize this external function resolution.


-----Original Message-----
From: llvmdev-bounces at cs.uiuc.edu [mailto:llvmdev-bounces at cs.uiuc.edu] On Behalf Of Paul J. Lucas
Sent: Friday, October 26, 2012 4:17 PM
To: llvmdev at cs.uiuc.edu List
Subject: [LLVMdev] Using LLVM to serialize object state -- and performance

I have a legacy C++ application that constructs a tree of C++ objects (an iterator tree to implement a query language).  I am trying to use LLVM to "serialize" the state of this tree to disk for later loading and execution (or "compile" it to disk, if you prefer).

Each of the C++ iterator objects now has a codegen() member function that adds to the LLVM code of an llvm::Function.  The LLVM code generated is a sequence of instructions to set up the arguments for and call the constructor of each C++ object.  (I am using C "thunks" that provide a C API to LLVM to make C++ class constructor calls.)  Hence, all the LLVM code taken together into a single "reconstitute" function are mostly a sequence of "call" instructions with a few "store" and "getelementptr" instructions here and there -- fairly straight-forward LLVM code.

I then write out the LLVM IR code to disk and, at some later time, read it back in with ParseIR(), do getPointerToFunction(), execute that function, and the C++ iterator tree has been reconstituted.

This all works, but the JIT compile step is *slow*.  For a sequence of about 8000 LLVM instructions (most of which are "call"), it takes several seconds to execute.

It occurred to me that I don't really want JIT compiling.  I really want to compile the LLVM code to machine code and write that to disk so that when I read it back, I can just run it. The "reconstitute" function is only ever run once per query invocation, so there's no benefit from JIT compiling it since it will never be run a second or subsequent time.


* Is what I'm doing with LLVM a "reasonable" thing to do with LLVM?
* If so, how can I speed it up?  By generating machine code?  If so, how?

I've looked at the source for llc, but that apparently only generates assembly source code, not object code.

- Paul

LLVM Developers mailing list
LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu

More information about the llvm-dev mailing list