summaryrefslogtreecommitdiffstats
path: root/lld/test/wasm/tls.ll
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 /lld/test/wasm/tls.ll
parent21f2858dcf3a556f01f6ae151bf7638b70f01c02 (diff)
downloadbcm5719-llvm-42bba4b852b1a63db4043798bba7d9fcea61cbaf.tar.gz
bcm5719-llvm-42bba4b852b1a63db4043798bba7d9fcea61cbaf.zip
[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 'lld/test/wasm/tls.ll')
-rw-r--r--lld/test/wasm/tls.ll81
1 files changed, 81 insertions, 0 deletions
diff --git a/lld/test/wasm/tls.ll b/lld/test/wasm/tls.ll
new file mode 100644
index 00000000000..b570d467568
--- /dev/null
+++ b/lld/test/wasm/tls.ll
@@ -0,0 +1,81 @@
+; RUN: llc -mattr=+bulk-memory -filetype=obj %s -o %t.o
+
+target triple = "wasm32-unknown-unknown"
+
+@tls1 = thread_local(localexec) global i32 1, align 4
+@no_tls = global i32 0, align 4
+@tls2 = thread_local(localexec) global i32 1, align 4
+
+define i32* @tls1_addr() {
+ ret i32* @tls1
+}
+
+define i32* @tls2_addr() {
+ ret i32* @tls2
+}
+
+; RUN: wasm-ld -no-gc-sections --shared-memory --max-memory=131072 --no-entry -o %t.wasm %t.o
+; RUN: obj2yaml %t.wasm | FileCheck %s
+
+; RUN: wasm-ld -no-gc-sections --shared-memory --max-memory=131072 --no-merge-data-segments --no-entry -o %t.wasm %t.o
+; RUN: obj2yaml %t.wasm | FileCheck %s
+
+; CHECK: - Type: GLOBAL
+; CHECK-NEXT: Globals:
+; CHECK-NEXT: - Index: 0
+; CHECK-NEXT: Type: I32
+; CHECK-NEXT: Mutable: true
+; CHECK-NEXT: InitExpr:
+; CHECK-NEXT: Opcode: I32_CONST
+; CHECK-NEXT: Value: 66576
+; CHECK-NEXT: - Index: 1
+; CHECK-NEXT: Type: I32
+; CHECK-NEXT: Mutable: true
+; CHECK-NEXT: InitExpr:
+; CHECK-NEXT: Opcode: I32_CONST
+; CHECK-NEXT: Value: 0
+; CHECK-NEXT: - Index: 2
+; CHECK-NEXT: Type: I32
+; CHECK-NEXT: Mutable: false
+; CHECK-NEXT: InitExpr:
+; CHECK-NEXT: Opcode: I32_CONST
+; CHECK-NEXT: Value: 8
+
+
+; CHECK: - Type: CODE
+; CHECK-NEXT: Functions:
+; CHECK-NEXT: - Index: 0
+; CHECK-NEXT: Locals: []
+; CHECK-NEXT: Body: 0B
+; CHECK-NEXT: - Index: 1
+; CHECK-NEXT: Locals: []
+; CHECK-NEXT: Body: 20002401200041004108FC0800000B
+
+; Expected body of __wasm_init_tls:
+; local.get 0
+; global.set 1
+; local.get 0
+; i32.const 0
+; i32.const 8
+; memory.init 0, 0
+; end
+
+; CHECK-NEXT: - Index: 2
+; CHECK-NEXT: Locals: []
+; CHECK-NEXT: Body: 2381808080004180808080006A0B
+
+; Expected body of tls1_addr:
+; global.get 1
+; i32.const 0
+; i32.add
+; end
+
+; CHECK-NEXT: - Index: 3
+; CHECK-NEXT: Locals: []
+; CHECK-NEXT: Body: 2381808080004184808080006A0B
+
+; Expected body of tls1_addr:
+; global.get 1
+; i32.const 4
+; i32.add
+; end
OpenPOWER on IntegriCloud