From: Guanzhong Chen Date: Fri, 19 Jul 2019 23:34:16 +0000 (+0000) Subject: [WebAssembly] Compute and export TLS block alignment X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=adeb619f50bfcfa74fbfaf26538a69c86a7550b4;p=llvm [WebAssembly] Compute and export TLS block alignment 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 --- diff --git a/include/llvm/IR/IntrinsicsWebAssembly.td b/include/llvm/IR/IntrinsicsWebAssembly.td index 0dc68a5e0c0..4750c315611 100644 --- a/include/llvm/IR/IntrinsicsWebAssembly.td +++ b/include/llvm/IR/IntrinsicsWebAssembly.td @@ -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], [], diff --git a/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp b/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp index aaf3259e314..4de002ce487 100644 --- a/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp +++ b/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp @@ -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; } diff --git a/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp b/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp index 288b991ae2c..d9089deaa7b 100644 --- a/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp +++ b/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp @@ -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); diff --git a/test/CodeGen/WebAssembly/tls-general-dynamic.ll b/test/CodeGen/WebAssembly/tls-general-dynamic.ll index f121d62346d..41dbd476b06 100644 --- a/test/CodeGen/WebAssembly/tls-general-dynamic.ll +++ b/test/CodeGen/WebAssembly/tls-general-dynamic.ll @@ -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()