【问题标题】:How to emulate thread_local in llvm-ir?如何在 llvm-ir 中模拟 thread_local?
【发布时间】:2017-02-07 16:59:02
【问题描述】:

以下代码目前在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()

它会导致以下错误:

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

有没有办法模拟 TLS 并转换 llvm-ir 以使其工作?

使用从 thread_id 到指针的全局映射并将每次出现的 thread-local 替换为 allocator/deallocator/getter/setter 是否可行?

-femulated-tls-ftls-model 有用吗?

相关问题:

how to perform TargetLowering in a IR-trasformation pass?

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

【问题讨论】:

  • 根据我对-femulated-tls 标志的理解,该标志基本上可以满足您的要求,使用与 GCC 相同的模型模拟 tls 以避免显式链接器和系统支持。
  • 不幸的是,它不会影响 IR。 -femulated-tls 在生成二进制文件时影响代码生成阶段的目标降低。我需要一个降低目标的转换应用于我的 IR,而不是我的机器代码。
  • @Gaetano - 任何解决方案?如果是这样,您可以发布作为您自己问题的答案吗?
  • @ago 不幸的是没有,看起来 LLVM 只在 TargetLowering 通行证中实现了 TLS 仿真。此通道正在从 IR 创建程序集,并且似乎不能作为 IR 转换使用。相关问题:stackoverflow.com/questions/42163796/…
  • @Gaetano – 您是否尝试在 IR 中明确指定任何受支持的 TLS 模型(例如 thread_local(localexec))?

标签: c++ multithreading llvm llvm-ir lli


【解决方案1】:

既然你没有说你看到的错误是什么,我假设它是某种形式 LLVM ERROR: Program used external function '_ZTH3tls' which could not be resolved!

这是一个链接错误,实际上是指tls 被声明为具有外部链接,但没有其他定义可链接(至少您已发布)。

替换

extern thread_local int tls;

thread_local int tls;

然后编译器会生成下面的 IR

@tls = thread_local global i32 0, align 4

如果您确实需要外部链接并使用lli,则需要先将llvm 文件与llvm-link 链接,因为lli 无法自行链接。

例如

ext.cpp

thread_local int tls = 0;

main.cpp

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

编译它将生成ext.llmain.ll。运行llvm-link -S ext.ll main.ll &gt; output.ll 以获取链接文件,然后lli output.ll 应该也可以工作。

如果解决了,请告诉我。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-09
    • 2014-01-13
    • 1970-01-01
    • 2016-12-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多