[lld] r366624 - [WebAssembly] Compute and export TLS block alignment

Guanzhong Chen via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 19 16:34:16 PDT 2019


Author: quantum
Date: Fri Jul 19 16:34:16 2019
New Revision: 366624

URL: http://llvm.org/viewvc/llvm-project?rev=366624&view=rev
Log:
[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

Added:
    lld/trunk/test/wasm/tls-align.ll
Modified:
    lld/trunk/test/wasm/tls.ll
    lld/trunk/wasm/Driver.cpp
    lld/trunk/wasm/Symbols.cpp
    lld/trunk/wasm/Symbols.h
    lld/trunk/wasm/Writer.cpp

Added: lld/trunk/test/wasm/tls-align.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/wasm/tls-align.ll?rev=366624&view=auto
==============================================================================
--- lld/trunk/test/wasm/tls-align.ll (added)
+++ lld/trunk/test/wasm/tls-align.ll Fri Jul 19 16:34:16 2019
@@ -0,0 +1,51 @@
+; RUN: llc -mattr=+bulk-memory -filetype=obj %s -o %t.o
+
+target triple = "wasm32-unknown-unknown"
+
+ at no_tls = global i32 0, align 4
+ at tls1 = thread_local(localexec) global i32 1, align 4
+ at tls2 = thread_local(localexec) global i32 1, align 16
+
+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
+
+; 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:           66608
+
+; __tls_base
+; CHECK-NEXT:     - Index:           1
+; CHECK-NEXT:       Type:            I32
+; CHECK-NEXT:       Mutable:         true
+; CHECK-NEXT:       InitExpr:
+; CHECK-NEXT:         Opcode:          I32_CONST
+; CHECK-NEXT:         Value:           0
+
+; __tls_size
+; CHECK-NEXT:     - Index:           2
+; CHECK-NEXT:       Type:            I32
+; CHECK-NEXT:       Mutable:         false
+; CHECK-NEXT:       InitExpr:
+; CHECK-NEXT:         Opcode:          I32_CONST
+; CHECK-NEXT:         Value:           20
+
+; __tls_align
+; CHECK-NEXT:     - Index:           3
+; CHECK-NEXT:       Type:            I32
+; CHECK-NEXT:       Mutable:         false
+; CHECK-NEXT:       InitExpr:
+; CHECK-NEXT:         Opcode:          I32_CONST
+; CHECK-NEXT:         Value:           16

Modified: lld/trunk/test/wasm/tls.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/wasm/tls.ll?rev=366624&r1=366623&r2=366624&view=diff
==============================================================================
--- lld/trunk/test/wasm/tls.ll (original)
+++ lld/trunk/test/wasm/tls.ll Fri Jul 19 16:34:16 2019
@@ -14,6 +14,13 @@ define i32* @tls2_addr() {
   ret i32* @tls2
 }
 
+define i32 @tls_align() {
+  %1 = call i32 @llvm.wasm.tls.align.i32()
+  ret i32 %1
+}
+
+declare i32 @llvm.wasm.tls.align.i32()
+
 ; RUN: wasm-ld -no-gc-sections --shared-memory --max-memory=131072 --no-entry -o %t.wasm %t.o
 ; RUN: obj2yaml %t.wasm | FileCheck %s
 
@@ -28,12 +35,16 @@ define i32* @tls2_addr() {
 ; CHECK-NEXT:       InitExpr:
 ; CHECK-NEXT:         Opcode:          I32_CONST
 ; CHECK-NEXT:         Value:           66576
+
+; __tls_base
 ; CHECK-NEXT:     - Index:           1
 ; CHECK-NEXT:       Type:            I32
 ; CHECK-NEXT:       Mutable:         true
 ; CHECK-NEXT:       InitExpr:
 ; CHECK-NEXT:         Opcode:          I32_CONST
 ; CHECK-NEXT:         Value:           0
+
+; __tls_size
 ; CHECK-NEXT:     - Index:           2
 ; CHECK-NEXT:       Type:            I32
 ; CHECK-NEXT:       Mutable:         false
@@ -41,6 +52,14 @@ define i32* @tls2_addr() {
 ; CHECK-NEXT:         Opcode:          I32_CONST
 ; CHECK-NEXT:         Value:           8
 
+; __tls_align
+; CHECK-NEXT:     - Index:           3
+; CHECK-NEXT:       Type:            I32
+; CHECK-NEXT:       Mutable:         false
+; CHECK-NEXT:       InitExpr:
+; CHECK-NEXT:         Opcode:          I32_CONST
+; CHECK-NEXT:         Value:           4
+
 
 ; CHECK:      - Type:            CODE
 ; CHECK-NEXT:   Functions:
@@ -77,3 +96,11 @@ define i32* @tls2_addr() {
 ;   i32.const 4
 ;   i32.add
 ;   end
+
+; CHECK-NEXT:     - Index:           5
+; CHECK-NEXT:       Locals:          []
+; CHECK-NEXT:       Body:            2383808080000B
+
+; Expected body of tls1_addr:
+;   global.get 3
+;   end

Modified: lld/trunk/wasm/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/Driver.cpp?rev=366624&r1=366623&r2=366624&view=diff
==============================================================================
--- lld/trunk/wasm/Driver.cpp (original)
+++ lld/trunk/wasm/Driver.cpp Fri Jul 19 16:34:16 2019
@@ -450,6 +450,16 @@ createUndefinedGlobal(StringRef name, ll
   return sym;
 }
 
+static GlobalSymbol *createGlobalVariable(StringRef name, bool isMutable) {
+  llvm::wasm::WasmGlobal wasmGlobal;
+  wasmGlobal.Type = {WASM_TYPE_I32, isMutable};
+  wasmGlobal.InitExpr.Value.Int32 = 0;
+  wasmGlobal.InitExpr.Opcode = WASM_OPCODE_I32_CONST;
+  wasmGlobal.SymbolName = name;
+  return symtab->addSyntheticGlobal(name, WASM_SYMBOL_VISIBILITY_HIDDEN,
+                                    make<InputGlobal>(wasmGlobal, nullptr));
+}
+
 // Create ABI-defined synthetic symbols
 static void createSyntheticSymbols() {
   static WasmSignature nullSignature = {{}, {}};
@@ -517,24 +527,9 @@ static void createSyntheticSymbols() {
   }
 
   if (config->sharedMemory && !config->shared) {
-    llvm::wasm::WasmGlobal tlsBaseGlobal;
-    tlsBaseGlobal.Type = {WASM_TYPE_I32, true};
-    tlsBaseGlobal.InitExpr.Value.Int32 = 0;
-    tlsBaseGlobal.InitExpr.Opcode = WASM_OPCODE_I32_CONST;
-    tlsBaseGlobal.SymbolName = "__tls_base";
-    WasmSym::tlsBase =
-        symtab->addSyntheticGlobal("__tls_base", WASM_SYMBOL_VISIBILITY_HIDDEN,
-                                   make<InputGlobal>(tlsBaseGlobal, nullptr));
-
-    llvm::wasm::WasmGlobal tlsSizeGlobal;
-    tlsSizeGlobal.Type = {WASM_TYPE_I32, false};
-    tlsSizeGlobal.InitExpr.Value.Int32 = 0;
-    tlsSizeGlobal.InitExpr.Opcode = WASM_OPCODE_I32_CONST;
-    tlsSizeGlobal.SymbolName = "__tls_size";
-    WasmSym::tlsSize =
-        symtab->addSyntheticGlobal("__tls_size", WASM_SYMBOL_VISIBILITY_HIDDEN,
-                                   make<InputGlobal>(tlsSizeGlobal, nullptr));
-
+    WasmSym::tlsBase = createGlobalVariable("__tls_base", true);
+    WasmSym::tlsSize = createGlobalVariable("__tls_size", false);
+    WasmSym::tlsAlign = createGlobalVariable("__tls_align", false);
     WasmSym::initTLS = symtab->addSyntheticFunction(
         "__wasm_init_tls", WASM_SYMBOL_VISIBILITY_HIDDEN,
         make<SyntheticFunction>(i32ArgSignature, "__wasm_init_tls"));

Modified: lld/trunk/wasm/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/Symbols.cpp?rev=366624&r1=366623&r2=366624&view=diff
==============================================================================
--- lld/trunk/wasm/Symbols.cpp (original)
+++ lld/trunk/wasm/Symbols.cpp Fri Jul 19 16:34:16 2019
@@ -35,6 +35,7 @@ DefinedData *WasmSym::heapBase;
 GlobalSymbol *WasmSym::stackPointer;
 GlobalSymbol *WasmSym::tlsBase;
 GlobalSymbol *WasmSym::tlsSize;
+GlobalSymbol *WasmSym::tlsAlign;
 UndefinedGlobal *WasmSym::tableBase;
 UndefinedGlobal *WasmSym::memoryBase;
 

Modified: lld/trunk/wasm/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/Symbols.h?rev=366624&r1=366623&r2=366624&view=diff
==============================================================================
--- lld/trunk/wasm/Symbols.h (original)
+++ lld/trunk/wasm/Symbols.h Fri Jul 19 16:34:16 2019
@@ -435,6 +435,10 @@ struct WasmSym {
   // Symbol whose value is the size of the TLS block.
   static GlobalSymbol *tlsSize;
 
+  // __tls_size
+  // Symbol whose value is the alignment of the TLS block.
+  static GlobalSymbol *tlsAlign;
+
   // __data_end
   // Symbol marking the end of the data and bss.
   static DefinedData *dataEnd;

Modified: lld/trunk/wasm/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/Writer.cpp?rev=366624&r1=366623&r2=366624&view=diff
==============================================================================
--- lld/trunk/wasm/Writer.cpp (original)
+++ lld/trunk/wasm/Writer.cpp Fri Jul 19 16:34:16 2019
@@ -247,6 +247,9 @@ void Writer::layoutMemory() {
     if (WasmSym::tlsSize && seg->name == ".tdata") {
       auto *tlsSize = cast<DefinedGlobal>(WasmSym::tlsSize);
       tlsSize->global->global.InitExpr.Value.Int32 = seg->size;
+
+      auto *tlsAlign = cast<DefinedGlobal>(WasmSym::tlsAlign);
+      tlsAlign->global->global.InitExpr.Value.Int32 = 1U << seg->alignment;
     }
   }
 




More information about the llvm-commits mailing list