Hello everyone,
I'm using the ORC JIT to load and execute some IR files which I compiled with Clang-Cl from some source files - the host is Windows 64bit. Apparently, clang decided to generate code using the thread local storage for some of the code. When now loading and jitting those files I get the following undefined references:
__emutls_get_address
__emutls_v._Init_thread_epoch
A while ago I was told, that those references are coming from compiler-rt - so I build that project and at least I found "__emutls_get_address" in the "clang_rt.builtins-x86_64.lib" file. However, I haven't found "__emutls_v._Init_thread_epoch" anyway and don't know what to do with this symbol.
Any ideas?
Also, in case you see double - I asked this question in the LLVM Discord already with no big success...
Kind greetings
Björn
_______________________________________________
LLVM Developers mailing list
llvm...@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Hey Geoff,
Sadly this didn’t changed the undefined symbols I encounter :c
I am no expert, so take anything I say with a pinch of salt, but my understanding is that Orc JIT does not support native thread-local storage, it just emulates it.
Hey Lang,
I can’t remember anymore but I think I haven’t tried with -femulated-tls.
I also forwarded the question to the Cling people because I think they got it running – but also haven’t heard back from there. I decided against emulated-tls
and tried resolving the Windows symbols myself by adding another IR file to it which was compiled as the following:
extern
"C"
{
void Sleep(unsigned long dwMilliseconds);
static constexpr int EpochStart = std::numeric_limits<int>::min();
unsigned int _tls_index = 0;
int _Init_global_epoch = EpochStart;
int _Init_thread_epoch = EpochStart;
void _Init_thread_header(volatile int* ptss)
{
while(true)
{
/* Try to acquire the first initialization lock */
int oldTss = _InterlockedCompareExchange(reinterpret_cast<volatile long*>(ptss), -1, 0);
if(oldTss == -1)
{
/* Busy, wait for the other thread to do the initialization */
Sleep(0);
continue;
}
/* Either we acquired the lock and the caller will do the initializaion
or the initialization is complete and the caller will skip it */
break;
}
}
void _Init_thread_footer(int *ptss)
{
*ptss = _InterlockedIncrement(reinterpret_cast<long*>(&_Init_global_epoch));
}
void _Init_thread_abort(volatile int* ptss)
{
/* Abort the initialization */
_InterlockedAnd(reinterpret_cast<volatile long*>(ptss), 0);
}
}
This was good enough for me until I hear a better way to do this – cause I got a feel that this is not really working? However my static variables were only initialized once no matter how many threads I threw at.
I haven’t mentioned that solution yet cause I’m not much confident about it’s reliability. Maybe I should show this to the cling people too…
Kind greetings
Björn
From: Lang Hames <lha...@gmail.com>
Sent: 02 March 2021 23:24
To: David Blaikie <dbla...@gmail.com>
Cc: Gaier, Bjoern <Bjoern...@horiba.com>; LLVM Developers Mailing List <llvm...@lists.llvm.org>
Subject: Re: [llvm-dev] How to use thread local storage with ORC JIT?
Hi All,
Hey Lang,
I can’t remember anymore but I think I haven’t tried with -femulated-tls.
<snip>
Sent: 03 March 2021 10:02
To: Gaier, Bjoern <Bjoern...@horiba.com>
Cc: Lang Hames <lha...@gmail.com>; David Blaikie <dbla...@gmail.com>; LLVM Developers Mailing List <llvm...@lists.llvm.org>
Subject: Re: [llvm-dev] How to use thread local storage with ORC JIT?
Bjoern,
In your 15 February email you said you tried that and it didn't help...?
>Ohhh right!
I did try it…. Thanks for the reminder >o<