c++ multithreading llvm llvm-ir lli

c++ - ¿Cómo emular thread_local en llvm-ir?



multithreading lli (1)

El siguiente código actualmente no funciona en lli:

//main.cpp extern thread_local int tls; int main() { tls = 42; return 0; } //clang++ -S -emit-llvm main.cpp && lli main.ll

llvm-ir:

; ModuleID = ''main.cpp'' target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-pc-linux-gnu" @tls = external thread_local global i32, align 4 ; Function Attrs: norecurse uwtable define i32 @main() #0 { %1 = alloca i32, align 4 store i32 0, i32* %1, align 4 %2 = call i32* @_ZTW3tls() store i32 42, i32* %2, align 4 ret i32 0 } define weak_odr hidden i32* @_ZTW3tls() { br i1 icmp ne (void ()* @_ZTH3tls, void ()* null), label %1, label %2 ; <label>:1 ; preds = %0 call void @_ZTH3tls() br label %2 ; <label>:2 ; preds = %1, %0 ret i32* @tls } declare extern_weak void @_ZTH3tls()

Causa el siguiente error:

LLVM ERROR: Cannot select: 0x55ec0e9c3a60: i64 = X86ISD::WrapperRIP TargetGlobalTLSAddress:i64<i32* @tls> 0 [TF=10] 0x55ec0e9c3858: i64 = TargetGlobalTLSAddress<i32* @tls> 0 [TF=10] In function: _ZTW3tls

¿Hay una manera de emular TLS y transformar el llvm-ir para hacer que esto funcione?

¿Sería factible utilizar un mapa global desde thread_id a punteros y reemplazar cada ocurrencia de subprocesos locales con asignador / desasignador / captador / configurador?

¿Son -femulated-tls y -ftls-model de cualquier uso?

preguntas relacionadas:

¿Cómo realizar TargetLowering en un pase de transformación IR?

http://lists.llvm.org/pipermail/llvm-dev/2017-February/109947.html


Ya que no ha dicho cuál es el error que está viendo, supongo que es algo de la forma LLVM ERROR: Program used external function ''_ZTH3tls'' which could not be resolved!

Este es un error de vinculación, que en realidad se refiere al hecho de que tls está declarado como que tiene una vinculación externa, pero no hay otra definición a la que vincular (al menos que hayas publicado).

Reemplazar

extern thread_local int tls;

con

thread_local int tls;

El compilador generará el siguiente IR

@tls = thread_local global i32 0, align 4

Si realmente necesita tener un enlace externo y usar lli , primero deberá vincular los archivos llvm-link con llvm-link ya que lli no tiene la capacidad de vincularse por sí mismo.

p.ej

ext.cpp

thread_local int tls = 0;

main.cpp

extern thread_local int tls; int main() { tls = 42; return 0; }

Compilar esto generará ext.ll y main.ll Ejecute llvm-link -S ext.ll main.ll > output.ll para obtener el archivo vinculado y luego lli output.ll también debería funcionar.

Déjame saber si eso lo resuelve.