[WebAssembly] Lower global syms representing tables with .tabletype

This patch implements a fix to recognize global symbols that represent
WebAssembly appropriately and generate the necessary .tabletype
directives.

Reviewed By: sbc100

Differential Revision: https://reviews.llvm.org/D115511
This commit is contained in:
Paulo Matos 2021-12-13 17:45:51 +01:00
parent b18b2a01ef
commit b5b5f0ac77
7 changed files with 23 additions and 10 deletions

View File

@ -196,6 +196,13 @@ void WebAssemblyAsmPrinter::emitGlobalVariable(const GlobalVariable *GV) {
Sym->setGlobalType(wasm::WasmGlobalType{uint8_t(Type), Mutable});
}
// If the GlobalVariable refers to a table, we handle it here instead of
// in emitExternalDecls
if (Sym->isTable()) {
getTargetStreamer()->emitTableType(Sym);
return;
}
emitVisibility(Sym, GV->getVisibility(), !GV->isDeclaration());
if (GV->hasInitializer()) {
assert(getSymbolPreferLocal(*GV) == Sym);

View File

@ -66,9 +66,11 @@ WebAssemblyMCInstLower::GetGlobalAddressSymbol(const MachineOperand &MO) const {
// they reach this point as aggregate Array types with an element type
// that is a reference type.
wasm::ValType Type;
bool IsTable = false;
if (GlobalVT->isArrayTy() &&
WebAssembly::isRefType(GlobalVT->getArrayElementType())) {
MVT VT;
IsTable = true;
switch (GlobalVT->getArrayElementType()->getPointerAddressSpace()) {
case WebAssembly::WasmAddressSpace::WASM_ADDRESS_SPACE_FUNCREF:
VT = MVT::funcref;
@ -85,9 +87,14 @@ WebAssemblyMCInstLower::GetGlobalAddressSymbol(const MachineOperand &MO) const {
} else
report_fatal_error("Aggregate globals not yet implemented");
WasmSym->setType(wasm::WASM_SYMBOL_TYPE_GLOBAL);
WasmSym->setGlobalType(
wasm::WasmGlobalType{uint8_t(Type), /*Mutable=*/true});
if (IsTable) {
WasmSym->setType(wasm::WASM_SYMBOL_TYPE_TABLE);
WasmSym->setTableType(Type);
} else {
WasmSym->setType(wasm::WASM_SYMBOL_TYPE_GLOBAL);
WasmSym->setGlobalType(
wasm::WasmGlobalType{uint8_t(Type), /*Mutable=*/true});
}
}
return WasmSym;
}

View File

@ -73,4 +73,4 @@ define %externref @get_externref_from_table_with_var_offset2(i32 %i) {
ret %externref %ref
}
; CHECK: .globl externref_table
; CHECK: .tabletype externref_table, externref

View File

@ -79,4 +79,4 @@ define void @set_externref_table_with_var_offset2(%externref %g, i32 %i) {
ret void
}
; CHECK: .globl externref_table
; CHECK: .tabletype externref_table, externref

View File

@ -13,7 +13,7 @@ define void @call_funcref_from_table(i32 %i) {
ret void
}
; CHECK: .tabletype __funcref_call_table, funcref, 1
; CHECK: .tabletype __funcref_call_table, funcref, 1
; CHECK-LABEL: call_funcref_from_table:
; CHECK-NEXT: .functype call_funcref_from_table (i32) -> ()
@ -28,6 +28,5 @@ define void @call_funcref_from_table(i32 %i) {
; CHECK-NEXT: table.set __funcref_call_table
; CHECK-NEXT: end_function
; CHECK: .tabletype funcref_table, funcref
; CHECK: .globl funcref_table
; CHECK-NEXT .globaltype funcref_table, funcref

View File

@ -72,4 +72,4 @@ define %funcref @get_funcref_from_table_with_var_offset2(i32 %i) {
ret %funcref %ref
}
; CHECK: .globl funcref_table
; CHECK: .tabletype funcref_table, funcref

View File

@ -78,4 +78,4 @@ define void @set_funcref_table_with_var_offset2(%funcref %g, i32 %i) {
ret void
}
; CHECK: .globl funcref_table
; CHECK: .tabletype funcref_table, funcref