[WebAssembly] Lower global syms representing tables with .tabletype
authorPaulo Matos <pmatos@igalia.com>
Mon, 13 Dec 2021 16:45:51 +0000 (17:45 +0100)
committerPaulo Matos <pmatos@igalia.com>
Mon, 13 Dec 2021 17:17:03 +0000 (18:17 +0100)
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

llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
llvm/test/CodeGen/WebAssembly/externref-tableget.ll
llvm/test/CodeGen/WebAssembly/externref-tableset.ll
llvm/test/CodeGen/WebAssembly/funcref-table_call.ll
llvm/test/CodeGen/WebAssembly/funcref-tableget.ll
llvm/test/CodeGen/WebAssembly/funcref-tableset.ll

index 0d3f516..69911cb 100644 (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);
index f315b63..d3490e9 100644 (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;
   }
index e54e9e8..1161b6e 100644 (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
index 2066123..025fb03 100644 (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
index a9a3171..4b5a9b4 100644 (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
index c374da7..63cd69a 100644 (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
index 1bb50d1..ddc6c3e 100644 (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