]> granicus.if.org Git - llvm/commitdiff
[WebAssembly] Compute and export TLS block alignment
authorGuanzhong Chen <gzchen@google.com>
Fri, 19 Jul 2019 23:34:16 +0000 (23:34 +0000)
committerGuanzhong Chen <gzchen@google.com>
Fri, 19 Jul 2019 23:34:16 +0000 (23:34 +0000)
Summary:
Add immutable WASM global `__tls_align` which stores the alignment
requirements of the TLS segment.

Add `__builtin_wasm_tls_align()` intrinsic to get this alignment in Clang.

The expected usage has now changed to:

    __wasm_init_tls(memalign(__builtin_wasm_tls_align(),
                             __builtin_wasm_tls_size()));

Reviewers: tlively, aheejin, sbc100, sunfish, alexcrichton

Reviewed By: tlively

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

Tags: #clang, #llvm

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@366624 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/IR/IntrinsicsWebAssembly.td
lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp
lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
test/CodeGen/WebAssembly/tls-general-dynamic.ll

index 0dc68a5e0c029e8e5be27ead240eb400dd1e5e49..4750c315611c868071c340498a7c305c14ae2974 100644 (file)
@@ -133,6 +133,11 @@ def int_wasm_tls_size :
             [],
             [IntrNoMem, IntrSpeculatable]>;
 
+def int_wasm_tls_align :
+  Intrinsic<[llvm_anyint_ty],
+            [],
+            [IntrNoMem, IntrSpeculatable]>;
+
 def int_wasm_tls_base :
   Intrinsic<[llvm_ptr_ty],
             [],
index aaf3259e314d0d791deb11ca6ccec979057a093a..4de002ce487c3769a166833974cdf3d083d2b89b 100644 (file)
@@ -224,6 +224,16 @@ void WebAssemblyDAGToDAGISel::Select(SDNode *Node) {
       ReplaceNode(Node, TLSSize);
       return;
     }
+    case Intrinsic::wasm_tls_align: {
+      MVT PtrVT = TLI->getPointerTy(CurDAG->getDataLayout());
+      assert(PtrVT == MVT::i32 && "only wasm32 is supported for now");
+
+      MachineSDNode *TLSAlign = CurDAG->getMachineNode(
+          WebAssembly::GLOBAL_GET_I32, DL, PtrVT,
+          CurDAG->getTargetExternalSymbol("__tls_align", MVT::i32));
+      ReplaceNode(Node, TLSAlign);
+      return;
+    }
     }
     break;
   }
index 288b991ae2c54ce317124de49184f1c8a4860954..d9089deaa7b04b23c271e7ee77007bc2816fc055 100644 (file)
@@ -79,7 +79,7 @@ MCSymbol *WebAssemblyMCInstLower::GetExternalSymbolSymbol(
   // Clang-provided symbols.
   if (strcmp(Name, "__stack_pointer") == 0 || strcmp(Name, "__tls_base") == 0 ||
       strcmp(Name, "__memory_base") == 0 || strcmp(Name, "__table_base") == 0 ||
-      strcmp(Name, "__tls_size") == 0) {
+      strcmp(Name, "__tls_size") == 0 || strcmp(Name, "__tls_align") == 0) {
     bool Mutable =
         strcmp(Name, "__stack_pointer") == 0 || strcmp(Name, "__tls_base") == 0;
     WasmSym->setType(wasm::WASM_SYMBOL_TYPE_GLOBAL);
index f121d62346d0cf811fea92167adc5492ab30d19f..41dbd476b065023bac65ef71679753bf48cc9eba 100644 (file)
@@ -75,6 +75,15 @@ define i32 @tls_size() {
   ret i32 %1
 }
 
+; CHECK-LABEL: tls_align:
+; CHECK-NEXT: .functype tls_align () -> (i32)
+define i32 @tls_align() {
+; CHECK-NEXT: global.get __tls_align
+; CHECK-NEXT: return
+  %1 = call i32 @llvm.wasm.tls.align.i32()
+  ret i32 %1
+}
+
 ; CHECK-LABEL: tls_base:
 ; CHECK-NEXT: .functype tls_base () -> (i32)
 define i8* @tls_base() {
@@ -104,4 +113,5 @@ define void @tls_base_write(i8** %output) {
 @tls = internal thread_local global i32 0
 
 declare i32 @llvm.wasm.tls.size.i32()
+declare i32 @llvm.wasm.tls.align.i32()
 declare i8* @llvm.wasm.tls.base()