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
Log:
[WebAssembly] Implement thread-local storage (local-exec model)
Summary:
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:
__wasm_init_tls(malloc(__builtin_wasm_tls_size()));
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
cfe/trunk/lib/CodeGen/CGBuiltin.cpp
cfe/trunk/test/CodeGen/builtins-wasm.c
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