mirror of https://github.com/WebAssembly/wasi-sdk
Sync LLVM patches with landed PRs (#650)
These PRs have now all landed in LLVM so update their corresponding `*.patch` files accordinglypull/651/head
parent
4d284af72e
commit
a70f9a8f10
@ -0,0 +1,94 @@
|
|||||||
|
diff --git a/lld/test/wasm/cooperative-threading.s b/lld/test/wasm/cooperative-threading.s
|
||||||
|
index 8b0f7eb1c256f..a4afb01dc2264 100644
|
||||||
|
--- a/lld/test/wasm/cooperative-threading.s
|
||||||
|
+++ b/lld/test/wasm/cooperative-threading.s
|
||||||
|
@@ -2,7 +2,7 @@
|
||||||
|
# thread-context globals (__init_stack_pointer, __init_tls_base, etc.) and
|
||||||
|
# works without --shared-memory and atomics.
|
||||||
|
|
||||||
|
-# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown -o %t.o %s
|
||||||
|
+# RUN: llvm-mc -mattr=+call-indirect-overlong -filetype=obj -triple=wasm32-unknown-unknown -o %t.o %s
|
||||||
|
# RUN: wasm-ld --cooperative-threading -no-gc-sections -o %t.wasm %t.o
|
||||||
|
# RUN: obj2yaml %t.wasm | FileCheck %s
|
||||||
|
# RUN: llvm-objdump -d --no-print-imm-hex --no-show-raw-insn %t.wasm | FileCheck %s --check-prefix=DIS
|
||||||
|
@@ -11,12 +11,22 @@
|
||||||
|
# RUN: not wasm-ld --cooperative-threading --shared-memory %t.o -o %t2.wasm 2>&1 | FileCheck %s --check-prefix=INCOMPAT
|
||||||
|
# INCOMPAT: --cooperative-threading is incompatible with --shared-memory
|
||||||
|
|
||||||
|
+.globl __indirect_function_table
|
||||||
|
+.tabletype __indirect_function_table, funcref
|
||||||
|
+
|
||||||
|
.globl __wasm_get_tls_base
|
||||||
|
__wasm_get_tls_base:
|
||||||
|
.functype __wasm_get_tls_base () -> (i32)
|
||||||
|
i32.const 0
|
||||||
|
end_function
|
||||||
|
|
||||||
|
+.globl do_call_indirect
|
||||||
|
+do_call_indirect:
|
||||||
|
+ .functype do_call_indirect () -> ()
|
||||||
|
+ i32.const 1
|
||||||
|
+ call_indirect __indirect_function_table, () -> ()
|
||||||
|
+ end_function
|
||||||
|
+
|
||||||
|
.globl _start
|
||||||
|
_start:
|
||||||
|
.functype _start () -> (i32)
|
||||||
|
@@ -66,12 +76,23 @@ foo:
|
||||||
|
.int8 7
|
||||||
|
.ascii "atomics"
|
||||||
|
|
||||||
|
+# CHECK: - Type: TABLE
|
||||||
|
+# CHECK-NEXT: Tables:
|
||||||
|
+# CHECK-NEXT: - Index: 0
|
||||||
|
+# CHECK-NEXT: ElemType: FUNCREF
|
||||||
|
+
|
||||||
|
# Memory must NOT be marked as shared.
|
||||||
|
# CHECK: - Type: MEMORY
|
||||||
|
# CHECK-NEXT: Memories:
|
||||||
|
# CHECK-NEXT: - Minimum: 0x2
|
||||||
|
# CHECK-NOT: Shared
|
||||||
|
|
||||||
|
+# The function table is exported by default.
|
||||||
|
+# CHECK: - Type: EXPORT
|
||||||
|
+# CHECK: - Name: __indirect_function_table
|
||||||
|
+# CHECK-NEXT: Kind: TABLE
|
||||||
|
+# CHECK-NEXT: Index: 0
|
||||||
|
+
|
||||||
|
# Only TLS needs a passive data segment; .data stays active and .bss gets no
|
||||||
|
# segment at all since memory is only instantiated once and starts zeroed.
|
||||||
|
# CHECK: - Type: DATACOUNT
|
||||||
|
@@ -118,3 +139,14 @@ foo:
|
||||||
|
# DIS-NEXT: i32.load 0
|
||||||
|
# DIS-NEXT: i32.add
|
||||||
|
# DIS-NEXT: end
|
||||||
|
+
|
||||||
|
+# When the table is imported instead there is no need to also export it.
|
||||||
|
+# RUN: wasm-ld --cooperative-threading --import-table -no-gc-sections -o %t3.wasm %t.o
|
||||||
|
+# RUN: obj2yaml %t3.wasm | FileCheck %s --check-prefix=IMPORT-TABLE
|
||||||
|
+
|
||||||
|
+# When the table is imported instead there is no need to also export it.
|
||||||
|
+# IMPORT-TABLE: - Type: IMPORT
|
||||||
|
+# IMPORT-TABLE: - Module: env
|
||||||
|
+# IMPORT-TABLE-NEXT: Field: __indirect_function_table
|
||||||
|
+# IMPORT-TABLE-NEXT: Kind: TABLE
|
||||||
|
+# IMPORT-TABLE-NOT: Kind: TABLE
|
||||||
|
diff --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp
|
||||||
|
index 9a2e3a82a9279..c213d7ca0b0f3 100644
|
||||||
|
--- a/lld/wasm/Driver.cpp
|
||||||
|
+++ b/lld/wasm/Driver.cpp
|
||||||
|
@@ -759,6 +759,14 @@ static void setConfigs() {
|
||||||
|
if (ctx.arg.sharedMemory)
|
||||||
|
error("--cooperative-threading is incompatible with --shared-memory");
|
||||||
|
ctx.arg.libcallThreadContext = true;
|
||||||
|
+
|
||||||
|
+ // Cooperative threading requires the table is either imported or exported
|
||||||
|
+ // or otherwise there's no way for embedders to read spawned functions from
|
||||||
|
+ // the table. If we've gotten this far and the table isn't otherwise
|
||||||
|
+ // imported (e.g in `isPic` mode) then export the table instead to ensure
|
||||||
|
+ // that it's visible to the outside world.
|
||||||
|
+ if (!ctx.arg.importTable)
|
||||||
|
+ ctx.arg.exportTable = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,172 @@
|
|||||||
|
diff --git a/lld/test/wasm/cooperative-threading.s b/lld/test/wasm/cooperative-threading.s
|
||||||
|
index 4ae4d464d1f90..af484b5e403d9 100644
|
||||||
|
--- a/lld/test/wasm/cooperative-threading.s
|
||||||
|
+++ b/lld/test/wasm/cooperative-threading.s
|
||||||
|
@@ -94,6 +94,28 @@ baz:
|
||||||
|
# CHECK-NEXT: - Minimum: 0x2
|
||||||
|
# CHECK-NOT: Shared
|
||||||
|
|
||||||
|
+# Ensure __init_stack_pointer, __init_tls_base, and __tls_size are all correct.
|
||||||
|
+# CHECK: - Type: GLOBAL
|
||||||
|
+# CHECK-NEXT: Globals:
|
||||||
|
+# CHECK-NEXT: - Index: 0
|
||||||
|
+# CHECK-NEXT: Type: I32
|
||||||
|
+# CHECK-NEXT: Mutable: false
|
||||||
|
+# CHECK-NEXT: InitExpr:
|
||||||
|
+# CHECK-NEXT: Opcode: I32_CONST
|
||||||
|
+# CHECK-NEXT: Value: 65536
|
||||||
|
+# CHECK-NEXT: - Index: 1
|
||||||
|
+# CHECK-NEXT: Type: I32
|
||||||
|
+# CHECK-NEXT: Mutable: true
|
||||||
|
+# CHECK-NEXT: InitExpr:
|
||||||
|
+# CHECK-NEXT: Opcode: I32_CONST
|
||||||
|
+# CHECK-NEXT: Value: 65544
|
||||||
|
+# CHECK-NEXT: - Index: 2
|
||||||
|
+# CHECK-NEXT: Type: I32
|
||||||
|
+# CHECK-NEXT: Mutable: false
|
||||||
|
+# CHECK-NEXT: InitExpr:
|
||||||
|
+# CHECK-NEXT: Opcode: I32_CONST
|
||||||
|
+# CHECK-NEXT: Value: 8
|
||||||
|
+
|
||||||
|
# The function table is exported by default.
|
||||||
|
# CHECK: - Type: EXPORT
|
||||||
|
# CHECK: - Name: __indirect_function_table
|
||||||
|
@@ -137,8 +159,14 @@ baz:
|
||||||
|
# CHECK-NEXT: Name: __tls_align
|
||||||
|
|
||||||
|
# DIS-LABEL: <__wasm_init_memory>:
|
||||||
|
-# DIS: memory.init 2, 0
|
||||||
|
-# DIS-NEXT: end
|
||||||
|
+# DIS-EMPTY:
|
||||||
|
+# DIS-NEXT: i32.const 65544
|
||||||
|
+# DIS-NEXT: i32.const 65544
|
||||||
|
+# DIS-NEXT: call 0
|
||||||
|
+# DIS-NEXT: i32.const 0
|
||||||
|
+# DIS-NEXT: i32.const 8
|
||||||
|
+# DIS-NEXT: memory.init 2, 0
|
||||||
|
+# DIS-NEXT: end
|
||||||
|
|
||||||
|
# DIS-LABEL: <_start>:
|
||||||
|
# DIS-EMPTY:
|
||||||
|
@@ -168,6 +196,35 @@ baz:
|
||||||
|
# RUN: obj2yaml %t.so | FileCheck %s --check-prefix=PIC
|
||||||
|
# RUN: llvm-objdump --disassemble-symbols=__wasm_init_memory --no-show-raw-insn --no-leading-addr %t.so | FileCheck %s --check-prefix=PIC-DIS
|
||||||
|
|
||||||
|
+# The stack pointer is imported under the libcall ABI name and
|
||||||
|
+# __wasm_set_tls_base is imported for TLS initialization.
|
||||||
|
+# PIC: - Type: IMPORT
|
||||||
|
+# PIC: Field: __init_stack_pointer
|
||||||
|
+# PIC-NEXT: Kind: GLOBAL
|
||||||
|
+# PIC-NEXT: GlobalType: I32
|
||||||
|
+# PIC-NEXT: GlobalMutable: false
|
||||||
|
+# PIC: Field: __memory_base
|
||||||
|
+# PIC: Field: __table_base
|
||||||
|
+# PIC: Field: __wasm_set_tls_base
|
||||||
|
+# PIC-NEXT: Kind: FUNCTION
|
||||||
|
+
|
||||||
|
+# The PIC `__init_tls_base` global (global 3) is mutable and initialized ot
|
||||||
|
+# 0 since its final value is calculated once `__memory_base` is provided.
|
||||||
|
+# PIC: - Type: GLOBAL
|
||||||
|
+# PIC-NEXT: Globals:
|
||||||
|
+# PIC-NEXT: - Index: 3
|
||||||
|
+# PIC-NEXT: Type: I32
|
||||||
|
+# PIC-NEXT: Mutable: true
|
||||||
|
+# PIC-NEXT: InitExpr:
|
||||||
|
+# PIC-NEXT: Opcode: I32_CONST
|
||||||
|
+# PIC-NEXT: Value: 0
|
||||||
|
+# PIC-NEXT: - Index: 4
|
||||||
|
+# PIC-NEXT: Type: I32
|
||||||
|
+# PIC-NEXT: Mutable: false
|
||||||
|
+# PIC-NEXT: InitExpr:
|
||||||
|
+# PIC-NEXT: Opcode: I32_CONST
|
||||||
|
+# PIC-NEXT: Value: 8
|
||||||
|
+
|
||||||
|
# In PIC mode the active .rodata and .data segments are combined into a single
|
||||||
|
# active segment at __memory_base; the TLS segment remains passive.
|
||||||
|
# PIC: - Type: DATACOUNT
|
||||||
|
@@ -185,15 +242,32 @@ baz:
|
||||||
|
# PIC-NEXT: Content: '0100000002000000'
|
||||||
|
# PIC-NEXT: - Type: CUSTOM
|
||||||
|
|
||||||
|
+# PIC: GlobalNames:
|
||||||
|
+# PIC-NEXT: - Index: 0
|
||||||
|
+# PIC-NEXT: Name: __init_stack_pointer
|
||||||
|
+# PIC-NEXT: - Index: 1
|
||||||
|
+# PIC-NEXT: Name: __memory_base
|
||||||
|
+# PIC-NEXT: - Index: 2
|
||||||
|
+# PIC-NEXT: Name: __table_base
|
||||||
|
+# PIC-NEXT: - Index: 3
|
||||||
|
+# PIC-NEXT: Name: __init_tls_base
|
||||||
|
+# PIC-NEXT: - Index: 4
|
||||||
|
+# PIC-NEXT: Name: __tls_size
|
||||||
|
+# PIC-NEXT: - Index: 5
|
||||||
|
+# PIC-NEXT: Name: __tls_align
|
||||||
|
+
|
||||||
|
# Memory initialization in PIC mode has a few responsibilities: it calculates
|
||||||
|
-# the TLS address and puts it in a local, `__wasm_set_tls_base` is called,
|
||||||
|
-# TLS is initialized, and then finally BSS is zero'd out.
|
||||||
|
+# the TLS address and puts it in a local, stores it into the __init_tls_base
|
||||||
|
+# global, `__wasm_set_tls_base` is called, TLS is initialized, and then finally
|
||||||
|
+# BSS is zero'd out.
|
||||||
|
# PIC-DIS: <__wasm_init_memory>:
|
||||||
|
# PIC-DIS-NEXT: .local i32
|
||||||
|
# PIC-DIS-NEXT: i32.const 8
|
||||||
|
-# PIC-DIS-NEXT: global.get {{[0-9]+}}
|
||||||
|
+# PIC-DIS-NEXT: global.get 1
|
||||||
|
# PIC-DIS-NEXT: i32.add
|
||||||
|
# PIC-DIS-NEXT: local.tee 0
|
||||||
|
+# PIC-DIS-NEXT: local.get 0
|
||||||
|
+# PIC-DIS-NEXT: global.set 3
|
||||||
|
# PIC-DIS-NEXT: call {{[0-9]+}}
|
||||||
|
# PIC-DIS-NEXT: local.get 0
|
||||||
|
# PIC-DIS-NEXT: i32.const 0
|
||||||
|
diff --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp
|
||||||
|
index 740e8878c6e03..4c2549b39def7 100644
|
||||||
|
--- a/lld/wasm/Driver.cpp
|
||||||
|
+++ b/lld/wasm/Driver.cpp
|
||||||
|
@@ -981,9 +981,8 @@ static void createSyntheticSymbols() {
|
||||||
|
// TLS symbols are all hidden/dso-local
|
||||||
|
auto tls_base_name =
|
||||||
|
ctx.arg.libcallThreadContext ? "__init_tls_base" : "__tls_base";
|
||||||
|
- ctx.sym.tlsBase =
|
||||||
|
- createGlobalVariable(tls_base_name, !ctx.arg.libcallThreadContext,
|
||||||
|
- WASM_SYMBOL_VISIBILITY_HIDDEN);
|
||||||
|
+ ctx.sym.tlsBase = createGlobalVariable(tls_base_name, true,
|
||||||
|
+ WASM_SYMBOL_VISIBILITY_HIDDEN);
|
||||||
|
ctx.sym.tlsSize = createGlobalVariable("__tls_size", false,
|
||||||
|
WASM_SYMBOL_VISIBILITY_HIDDEN);
|
||||||
|
ctx.sym.tlsAlign = createGlobalVariable("__tls_align", false,
|
||||||
|
diff --git a/lld/wasm/Writer.cpp b/lld/wasm/Writer.cpp
|
||||||
|
index 157af6a4ea9ac..1651134cbb607 100644
|
||||||
|
--- a/lld/wasm/Writer.cpp
|
||||||
|
+++ b/lld/wasm/Writer.cpp
|
||||||
|
@@ -1416,13 +1416,29 @@ void Writer::createInitMemoryFunction() {
|
||||||
|
// When we initialize the TLS segment we also set the TLS base.
|
||||||
|
// This allows the runtime to use this static copy of the TLS data
|
||||||
|
// for the first/main thread.
|
||||||
|
+ //
|
||||||
|
+ // Note that for `--cooperative-threading` this additionally configures
|
||||||
|
+ // the `__init_tls_base` global which is the initial TLS value that can
|
||||||
|
+ // be used for all new component model tasks. For non-PIC builds this
|
||||||
|
+ // global's statically known value is now calculated, so it's updated
|
||||||
|
+ // here. For PIC builds the result of the address computation above is
|
||||||
|
+ // what's stored into the global.
|
||||||
|
if (ctx.arg.isMultithreaded() && s->isTLS()) {
|
||||||
|
if (ctx.isPic) {
|
||||||
|
// Cache the result of the addition in the TLS address local
|
||||||
|
writeU8(os, WASM_OPCODE_LOCAL_TEE, "local.tee");
|
||||||
|
writeUleb128(os, tlsAddressLocal, "tls address local");
|
||||||
|
+ if (ctx.arg.libcallThreadContext) {
|
||||||
|
+ writeU8(os, WASM_OPCODE_LOCAL_GET, "local.get");
|
||||||
|
+ writeUleb128(os, tlsAddressLocal, "tls address local");
|
||||||
|
+ writeU8(os, WASM_OPCODE_GLOBAL_SET, "global.set");
|
||||||
|
+ writeUleb128(os, ctx.sym.tlsBase->getGlobalIndex(),
|
||||||
|
+ "__init_tls_base");
|
||||||
|
+ }
|
||||||
|
} else {
|
||||||
|
writePtrConst(os, s->startVA, is64, "destination address");
|
||||||
|
+ if (ctx.arg.libcallThreadContext)
|
||||||
|
+ ctx.sym.tlsBase->global->setPointerValue(s->startVA);
|
||||||
|
}
|
||||||
|
writeSetTLSBase(ctx, os);
|
||||||
|
if (ctx.isPic) {
|
||||||
Loading…
Reference in new issue