diff options
author | Derek Schuff <dschuff@google.com> | 2018-03-20 22:01:32 +0000 |
---|---|---|
committer | Derek Schuff <dschuff@google.com> | 2018-03-20 22:01:32 +0000 |
commit | 39b5367cba5d706ece4091cb33e850b68486b53a (patch) | |
tree | 240c607188f3726a15877299e1bef4a8dd501390 | |
parent | e28ff4d43fb2f48f0c679a2305ea50aef1e8a456 (diff) | |
download | bcm5719-llvm-39b5367cba5d706ece4091cb33e850b68486b53a.tar.gz bcm5719-llvm-39b5367cba5d706ece4091cb33e850b68486b53a.zip |
[WebAssembly] Strip threadlocal attribute from globals in single thread mode
The default thread model for wasm is single, and in this mode thread-local
global variables can be lowered identically to non-thread-local variables.
Differential Revision: https://reviews.llvm.org/D44703
llvm-svn: 328049
-rw-r--r-- | llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp | 22 | ||||
-rw-r--r-- | llvm/test/CodeGen/WebAssembly/tls.ll | 17 |
2 files changed, 37 insertions, 2 deletions
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp index a686e773cb5..c006df090de 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp @@ -126,6 +126,22 @@ WebAssemblyTargetMachine::getSubtargetImpl(const Function &F) const { } namespace { +class StripThreadLocal final : public ModulePass { + // The default thread model for wasm is single, where thread-local variables + // are identical to regular globals and should be treated the same. So this + // pass just converts all GlobalVariables to NotThreadLocal + static char ID; + + public: + StripThreadLocal() : ModulePass(ID) {} + bool runOnModule(Module &M) override { + for (auto &GV : M.globals()) + GV.setThreadLocalMode(GlobalValue::ThreadLocalMode::NotThreadLocal); + return true; + } +}; +char StripThreadLocal::ID = 0; + /// WebAssembly Code Generator Pass Configuration Options. class WebAssemblyPassConfig final : public TargetPassConfig { public: @@ -166,13 +182,15 @@ FunctionPass *WebAssemblyPassConfig::createTargetRegisterAllocator(bool) { //===----------------------------------------------------------------------===// void WebAssemblyPassConfig::addIRPasses() { - if (TM->Options.ThreadModel == ThreadModel::Single) + if (TM->Options.ThreadModel == ThreadModel::Single) { // In "single" mode, atomics get lowered to non-atomics. addPass(createLowerAtomicPass()); - else + addPass(new StripThreadLocal()); + } else { // Expand some atomic operations. WebAssemblyTargetLowering has hooks which // control specifically what gets lowered. addPass(createAtomicExpandPass()); + } // Lower .llvm.global_dtors into .llvm_global_ctors with __cxa_atexit calls. addPass(createWebAssemblyLowerGlobalDtors()); diff --git a/llvm/test/CodeGen/WebAssembly/tls.ll b/llvm/test/CodeGen/WebAssembly/tls.ll new file mode 100644 index 00000000000..1c02f490e29 --- /dev/null +++ b/llvm/test/CodeGen/WebAssembly/tls.ll @@ -0,0 +1,17 @@ +; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -thread-model=single | FileCheck --check-prefix=SINGLE %s +target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" +target triple = "wasm32-unknown-unknown-wasm" + +; SINGLE-LABEL: address_of_tls: +define i32 @address_of_tls() { + ; SINGLE: i32.const $push0=, tls + ; SINGLE-NEXT: return $pop0 + ret i32 ptrtoint(i32* @tls to i32) +} + +; SINGLE: .type tls,@object +; SINGLE-NEXT: .section .bss.tls,"",@ +; SINGLE-NEXT: .p2align 2 +; SINGLE-NEXT: tls: +; SINGLE-NEXT: .int32 0 +@tls = internal thread_local global i32 0 |