Orc JIT + STL = broken on Windows?

Given this C++ code (hello.cpp):

#include
int main()
{
std::cout << “Hi, mom.” << std::endl;
return 0;
}

On Linux (CentOS 7), no problem:

clang++ -c -emit-llvm hello.cpp
lli --jit-end=orc-lazy hello.bc
Hi, mom.

But on Windows (7):

clang++ -c -emit-llvm hello.cpp
lli --jit-end=orc-lazy hello.bc

LLVM ERROR: Associative COMDAT symbol ‘??_7_Iostream_error_category2@std@@6B@’ is not a key for its COMDAT.
PLEASE submit a bug report to https://bugs.llvm.org/ and include the crash backtrace.

I know Orc JIT lacks COMDAT support, but I thought that just caused duplicate symbols sometimes. Am I doing something stupid here? Or should I just give up now on porting our Orc-based application to Windows? (The application JIT-compiles C++ modules which rely heavily on STL.)

Geoff

Sorry, there is a typo in my previous message: read “jit-kind” where I typed “jit-end”.

Hi Geoff

LLVM ERROR: Associative COMDAT symbol ‘GVName’ is not a key for its COMDAT.

This is in CodeGen TargetLoweringObjectFileCOFF so this isn’t necessarily JIT specific. Maybe a backtrace would be helpful?

lli --jit-end=orc-lazy hello.bc

Greedy Orc mode recently landed in lli: You might want to retry with that in order to rule out the lazy-JIT-infrastructure as a cause for the error. I am not aware of anyone actively working on improved Orc Windows support right now.

Thanks for that, Stefan. I built the main branch of LLVM (I have been using the 11.1 release branch) and tried again with --jit-kind=orc. That does indeed fix the crash. But lli fails with unresolved symbols:

Symbols not found: [ __emutls_v._Init_thread_epoch, __emutls_get_address, _Init_thread_header, _Init_thread_footer, ??3@YAXPEAX_K@Z, ??_7type_info@@6B@, ?_Facet_Register@std@@YAXPEAV_Facet_base@1@@Z ]

Geoff

Thanks for that, Stefan. I built the main branch of LLVM (I have been using the 11.1 release branch) and tried again with --jit-kind=orc. That does indeed fix the crash.

Nice, so this issue originated from module splitting in orc-lazy mode. Your options are:
(1) Keep the --jit-kind=orc greedy mode, which materializes all reachable code upfront and can be fine if you deal with small amounts only.
(2) Go lazy but compile modules as a whole with --jit-kind=orc-lazy --per-module-lazy; it’s the most performant lazy flavor in my experience and it hopefully avoids the CodeGen error as well.
(3) Or go lazy and supply your own partitioning function. Then you could tune everything yourself in detail.

But lli fails with unresolved symbols:

Symbols not found: [ __emutls_v._Init_thread_epoch, __emutls_get_address, _Init_thread_header, _Init_thread_footer, ??3@YAXPEAX_K@Z, ??_7type_info@@6B@, ?_Facet_Register@std@@YAXPEAV_Facet_base@1@@Z ]

I think these are all Windows-specific issues that are not currently supported in RuntimeDyld and, honestly, I don’t know if it’s realistic to still expect it to happen. My understanding is that someone will have to write a COFF backend for JITLink to have a chance at solving all the Windows mysteries eventually.

In the meantime, you can try to compile with exceptions disabled and fake/provide a delete from the host process. The TLS ones you probably know. I guess the std::locale::facet one indicates you are missing a library, libcmt.lib or libcpmt.lib maybe?

Good luck.

Thanks for the info, Stefan. I will have a think about it. We may just give up on JITting on Windows for the time being. We are a small, private company, meaning we have to be at least a bit profitable, and I’m not sure that is reconcilable with trailblazing in JIT compilation for Windows.

Geoff