LLVM's JIT Support for VTune

LLVM and VTune are awesome. LLVM's JIT Compiler already has integrated support with Intel VTune's JIT support. If you want to profile JIT compiled code in VTune with reasonable names instead of machine addresses, this is an essential feature. However, you really have to dig through LLVM's source code to figure out how to do it. Although it's not too bad.

First, you have to rebuild LLVM to enable the Intel JIT Event listener. When you configure LLVM, add this flag:

--with-intel-jitevents

Now rebuild LLVM and get a coffee. Next, in your JIT compiler, after you create the execution engine,  add a JITEventListener:

1
2
3
4
5
void JIT::addVtuneProfiling() {
  JITEventListener* vtuneProfiler = JITEventListener::createIntelJITEventListener();
  assert (vtuneProfiler != NULL);
  _executionEngine->RegisterJITEventListener(vtuneProfiler);
}

That's all the code you need! Finally, once you link your application, assuming you are using llvm-config, you need to link in the IntelJITEvents library. So this command:

llvm-config --ldflags --libs IntelJITEvents jit analysis .. etc etc

However, either I have a bug or my system is weird. I was still getting these errors at link time:

libLLVMIntelJITEvents.a(IntelJITEventListener.o): In function `IntelJITEventsWrapper':
IntelJITEventsWrapper.h:53: undefined reference to `iJIT_NotifyEvent'
IntelJITEventsWrapper.h:53: undefined reference to `iJIT_RegisterCallbackEx'
IntelJITEventsWrapper.h:53: undefined reference to `iJIT_IsProfilingActive'
IntelJITEventsWrapper.h:53: undefined reference to `FinalizeThread'
IntelJITEventsWrapper.h:53: undefined reference to `FinalizeProcess'
IntelJITEventsWrapper.h:53: undefined reference to `iJIT_GetNewMethodID'

What was going on!! Save yourself a few hours because the linker doesn't like the order of the VTune library supplied by llvm-config. llvm-config --ldflags correctly includes the -ljitprofiling library included with VTune. But the LLVMIntelJITEvents library can't seem to find it. You need to add -ljitprofiling to the linker flags AFTER LLVMIntelJitEvents is included like so:

llvm-config --ldflags --libs IntelJITEvents .... -ljitprofiling

The -ljitprofiling is included twice, but it works. You should see JIT compiled code in VTune reports.

Update:

Uhanov, Kirill from Intel has submitted a patch to LLVM which fixes this static linking issue.