r366272 - [WebAssembly] Implement thread-local storage (local-exec model)

Guanzhong Chen via cfe-commits cfe-commits at lists.llvm.org
Tue Jul 16 15:00:46 PDT 2019

Author: quantum
Date: Tue Jul 16 15:00:45 2019
New Revision: 366272

URL: http://llvm.org/viewvc/llvm-project?rev=366272&view=rev
[WebAssembly] Implement thread-local storage (local-exec model)

Thread local variables are placed inside a `.tdata` segment. Their symbols are
offsets from the start of the segment. The address of a thread local variable
is computed as `__tls_base` + the offset from the start of the segment.

`.tdata` segment is a passive segment and `memory.init` is used once per thread
to initialize the thread local storage.

`__tls_base` is a wasm global. Since each thread has its own wasm instance,
it is effectively thread local. Currently, `__tls_base` must be initialized
at thread startup, and so cannot be used with dynamic libraries.

`__tls_base` is to be initialized with a new linker-synthesized function,
`__wasm_init_tls`, which takes as an argument a block of memory to use as the
storage for thread locals. It then initializes the block of memory and sets
`__tls_base`. As `__wasm_init_tls` will handle the memory initialization,
the memory does not have to be zeroed.

To help allocating memory for thread-local storage, a new compiler intrinsic
is introduced: `__builtin_wasm_tls_size()`. This instrinsic function returns
the size of the thread-local storage for the current function.

The expected usage is to run something like the following upon thread startup:


Reviewers: tlively, aheejin, kripken, sbc100

Subscribers: dschuff, jgravelle-google, hiraditya, sunfish, jfb, cfe-commits, llvm-commits

Tags: #clang, #llvm

Differential Revision: https://reviews.llvm.org/D64537


Modified: cfe/trunk/include/clang/Basic/BuiltinsWebAssembly.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/BuiltinsWebAssembly.def?rev=366272&r1=366271&r2=366272&view=diff
--- cfe/trunk/include/clang/Basic/BuiltinsWebAssembly.def (original)
+++ cfe/trunk/include/clang/Basic/BuiltinsWebAssembly.def Tue Jul 16 15:00:45 2019
@@ -29,6 +29,9 @@ BUILTIN(__builtin_wasm_memory_grow, "zIi
 TARGET_BUILTIN(__builtin_wasm_memory_init, "vIUiIUiv*UiUi", "", "bulk-memory")
 TARGET_BUILTIN(__builtin_wasm_data_drop, "vIUi", "", "bulk-memory")
+// Thread-local storage
+TARGET_BUILTIN(__builtin_wasm_tls_size, "z", "nc", "bulk-memory")
 // Floating point min/max
 BUILTIN(__builtin_wasm_min_f32, "fff", "nc")
 BUILTIN(__builtin_wasm_max_f32, "fff", "nc")

Modified: cfe/trunk/lib/CodeGen/CGBuiltin.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBuiltin.cpp?rev=366272&r1=366271&r2=366272&view=diff
--- cfe/trunk/lib/CodeGen/CGBuiltin.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGBuiltin.cpp Tue Jul 16 15:00:45 2019
@@ -13913,6 +13913,11 @@ Value *CodeGenFunction::EmitWebAssemblyB
     Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_data_drop);
     return Builder.CreateCall(Callee, {Arg});
+  case WebAssembly::BI__builtin_wasm_tls_size: {
+    llvm::Type *ResultType = ConvertType(E->getType());
+    Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_tls_size, ResultType);
+    return Builder.CreateCall(Callee);
+  }
   case WebAssembly::BI__builtin_wasm_throw: {
     Value *Tag = EmitScalarExpr(E->getArg(0));
     Value *Obj = EmitScalarExpr(E->getArg(1));

Modified: cfe/trunk/test/CodeGen/builtins-wasm.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/builtins-wasm.c?rev=366272&r1=366271&r2=366272&view=diff
--- cfe/trunk/test/CodeGen/builtins-wasm.c (original)
+++ cfe/trunk/test/CodeGen/builtins-wasm.c Tue Jul 16 15:00:45 2019
@@ -38,6 +38,12 @@ void data_drop() {
   // WEBASSEMBLY64: call void @llvm.wasm.data.drop(i32 3)
+__SIZE_TYPE__ tls_size() {
+  return __builtin_wasm_tls_size();
+  // WEBASSEMBLY32: call i32 @llvm.wasm.tls.size.i32()
+  // WEBASSEMBLY64: call i64 @llvm.wasm.tls.size.i64()
 void throw(void *obj) {
   return __builtin_wasm_throw(0, obj);
   // WEBASSEMBLY32: call void @llvm.wasm.throw(i32 0, i8* %{{.*}})

More information about the cfe-commits mailing list