aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
diff options
context:
space:
mode:
authorGuanzhong Chen <gzchen@google.com>2019-07-16 22:00:45 +0000
committerGuanzhong Chen <gzchen@google.com>2019-07-16 22:00:45 +0000
commit42bba4b852b1a63db4043798bba7d9fcea61cbaf (patch)
tree6d17f3ede350dc96c647deda73fdbe78a44c6071 /llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
parent21f2858dcf3a556f01f6ae151bf7638b70f01c02 (diff)
downloadllvm-42bba4b852b1a63db4043798bba7d9fcea61cbaf.zip
llvm-42bba4b852b1a63db4043798bba7d9fcea61cbaf.tar.gz
llvm-42bba4b852b1a63db4043798bba7d9fcea61cbaf.tar.bz2
[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 llvm-svn: 366272
Diffstat (limited to 'llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp')
-rw-r--r--llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp23
1 files changed, 16 insertions, 7 deletions
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
index a75df34..7e65368 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
@@ -186,13 +186,21 @@ public:
for (auto &F : M)
replaceFeatures(F, FeatureStr);
- bool Stripped = false;
- if (!Features[WebAssembly::FeatureAtomics]) {
- Stripped |= stripAtomics(M);
- Stripped |= stripThreadLocals(M);
- }
+ bool StrippedAtomics = false;
+ bool StrippedTLS = false;
+
+ if (!Features[WebAssembly::FeatureAtomics])
+ StrippedAtomics = stripAtomics(M);
+
+ if (!Features[WebAssembly::FeatureBulkMemory])
+ StrippedTLS = stripThreadLocals(M);
+
+ if (StrippedAtomics && !StrippedTLS)
+ stripThreadLocals(M);
+ else if (StrippedTLS && !StrippedAtomics)
+ stripAtomics(M);
- recordFeatures(M, Features, Stripped);
+ recordFeatures(M, Features, StrippedAtomics || StrippedTLS);
// Conservatively assume we have made some change
return true;
@@ -271,7 +279,8 @@ private:
// "atomics" is special: code compiled without atomics may have had its
// atomics lowered to nonatomic operations. In that case, atomics is
// disallowed to prevent unsafe linking with atomics-enabled objects.
- assert(!Features[WebAssembly::FeatureAtomics]);
+ assert(!Features[WebAssembly::FeatureAtomics] ||
+ !Features[WebAssembly::FeatureBulkMemory]);
M.addModuleFlag(Module::ModFlagBehavior::Error, MDKey,
wasm::WASM_FEATURE_PREFIX_DISALLOWED);
} else if (Features[KV.Value]) {