[llvm] b2f21b1 - [CodeGen][WebAssembly] Better lowering for WASM_SYMBOL_TYPE_GLOBAL symbols
Andy Wingo via llvm-commits
llvm-commits at lists.llvm.org
Tue May 11 02:48:39 PDT 2021
Author: Andy Wingo
Date: 2021-05-11T11:47:40+02:00
New Revision: b2f21b145aecbf5bc1af63b79de395897fc2e6f4
URL: https://github.com/llvm/llvm-project/commit/b2f21b145aecbf5bc1af63b79de395897fc2e6f4
DIFF: https://github.com/llvm/llvm-project/commit/b2f21b145aecbf5bc1af63b79de395897fc2e6f4.diff
LOG: [CodeGen][WebAssembly] Better lowering for WASM_SYMBOL_TYPE_GLOBAL symbols
As we have been missing support for WebAssembly globals on the IR level,
the lowering of WASM_SYMBOL_TYPE_GLOBAL to IR was incomplete. This
commit fleshes out the lowering support, lowering references to and
definitions of addrspace(1) values to correctly typed
WASM_SYMBOL_TYPE_GLOBAL symbols.
Depends on D101608.
Differential Revision: https://reviews.llvm.org/D101913
Added:
Modified:
llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.h
llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
llvm/test/CodeGen/WebAssembly/global-get.ll
llvm/test/CodeGen/WebAssembly/global-set.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
index 1391f2eee17a..d9e56e9dceeb 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
@@ -170,13 +170,54 @@ MCSymbolWasm *WebAssemblyAsmPrinter::getMCSymbolForFunction(
return WasmSym;
}
+void WebAssemblyAsmPrinter::emitGlobalVariable(const GlobalVariable *GV) {
+ if (!WebAssembly::isWasmVarAddressSpace(GV->getAddressSpace())) {
+ AsmPrinter::emitGlobalVariable(GV);
+ return;
+ }
+
+ assert(!GV->isThreadLocal());
+
+ MCSymbolWasm *Sym = cast<MCSymbolWasm>(getSymbol(GV));
+
+ if (!Sym->getType()) {
+ const WebAssemblyTargetLowering &TLI = *Subtarget->getTargetLowering();
+ SmallVector<EVT, 1> VTs;
+ ComputeValueVTs(TLI, GV->getParent()->getDataLayout(), GV->getValueType(),
+ VTs);
+ if (VTs.size() != 1 ||
+ TLI.getNumRegisters(GV->getParent()->getContext(), VTs[0]) != 1)
+ report_fatal_error("Aggregate globals not yet implemented");
+ MVT VT = TLI.getRegisterType(GV->getParent()->getContext(), VTs[0]);
+ bool Mutable = true;
+ wasm::ValType Type = WebAssembly::toValType(VT);
+ Sym->setType(wasm::WASM_SYMBOL_TYPE_GLOBAL);
+ Sym->setGlobalType(wasm::WasmGlobalType{uint8_t(Type), Mutable});
+ }
+
+ emitVisibility(Sym, GV->getVisibility(), !GV->isDeclaration());
+ if (GV->hasInitializer()) {
+ assert(getSymbolPreferLocal(*GV) == Sym);
+ emitLinkage(GV, Sym);
+ getTargetStreamer()->emitGlobalType(Sym);
+ OutStreamer->emitLabel(Sym);
+ // TODO: Actually emit the initializer value. Otherwise the global has the
+ // default value for its type (0, ref.null, etc).
+ OutStreamer->AddBlankLine();
+ }
+}
+
void WebAssemblyAsmPrinter::emitEndOfAsmFile(Module &M) {
for (auto &It : OutContext.getSymbols()) {
// Emit .globaltype, .eventtype, or .tabletype declarations.
auto Sym = cast<MCSymbolWasm>(It.getValue());
- if (Sym->getType() == wasm::WASM_SYMBOL_TYPE_GLOBAL)
- getTargetStreamer()->emitGlobalType(Sym);
- else if (Sym->getType() == wasm::WASM_SYMBOL_TYPE_EVENT)
+ if (Sym->getType() == wasm::WASM_SYMBOL_TYPE_GLOBAL) {
+ // .globaltype already handled by emitGlobalVariable for defined
+ // variables; here we make sure the types of external wasm globals get
+ // written to the file.
+ if (Sym->isUndefined())
+ getTargetStreamer()->emitGlobalType(Sym);
+ } else if (Sym->getType() == wasm::WASM_SYMBOL_TYPE_EVENT)
getTargetStreamer()->emitEventType(Sym);
else if (Sym->getType() == wasm::WASM_SYMBOL_TYPE_TABLE)
getTargetStreamer()->emitTableType(Sym);
@@ -262,12 +303,12 @@ void WebAssemblyAsmPrinter::emitEndOfAsmFile(Module &M) {
}
for (const auto &G : M.globals()) {
- if (!G.hasInitializer() && G.hasExternalLinkage()) {
- if (G.getValueType()->isSized()) {
- uint16_t Size = M.getDataLayout().getTypeAllocSize(G.getValueType());
- OutStreamer->emitELFSize(getSymbol(&G),
- MCConstantExpr::create(Size, OutContext));
- }
+ if (!G.hasInitializer() && G.hasExternalLinkage() &&
+ !WebAssembly::isWasmVarAddressSpace(G.getAddressSpace()) &&
+ G.getValueType()->isSized()) {
+ uint16_t Size = M.getDataLayout().getTypeAllocSize(G.getValueType());
+ OutStreamer->emitELFSize(getSymbol(&G),
+ MCConstantExpr::create(Size, OutContext));
}
}
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.h b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.h
index 7a6a3247a19f..99b6e1077f1d 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.h
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.h
@@ -65,6 +65,7 @@ class LLVM_LIBRARY_VISIBILITY WebAssemblyAsmPrinter final : public AsmPrinter {
void emitEndOfAsmFile(Module &M) override;
void EmitProducerInfo(Module &M);
void EmitTargetFeatures(Module &M);
+ void emitGlobalVariable(const GlobalVariable *GV) override;
void emitJumpTableInfo() override;
void emitConstantPool() override;
void emitFunctionBodyStart() override;
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
index 84b459b6997d..2383416d8a92 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
@@ -15,6 +15,7 @@
#include "WebAssemblyMCInstLower.h"
#include "TargetInfo/WebAssemblyTargetInfo.h"
#include "Utils/WebAssemblyTypeUtilities.h"
+#include "Utils/WebAssemblyUtilities.h"
#include "WebAssemblyAsmPrinter.h"
#include "WebAssemblyMachineFunctionInfo.h"
#include "WebAssemblyRuntimeLibcallSignatures.h"
@@ -46,8 +47,28 @@ static void removeRegisterOperands(const MachineInstr *MI, MCInst &OutMI);
MCSymbol *
WebAssemblyMCInstLower::GetGlobalAddressSymbol(const MachineOperand &MO) const {
const GlobalValue *Global = MO.getGlobal();
- if (!isa<Function>(Global))
- return cast<MCSymbolWasm>(Printer.getSymbol(Global));
+ if (!isa<Function>(Global)) {
+ auto *WasmSym = cast<MCSymbolWasm>(Printer.getSymbol(Global));
+ // If the symbol doesn't have an explicit WasmSymbolType yet and the
+ // GlobalValue is actually a WebAssembly global, then ensure the symbol is a
+ // WASM_SYMBOL_TYPE_GLOBAL.
+ if (WebAssembly::isWasmVarAddressSpace(Global->getAddressSpace()) &&
+ !WasmSym->getType()) {
+ const MachineFunction &MF = *MO.getParent()->getParent()->getParent();
+ const TargetMachine &TM = MF.getTarget();
+ const Function &CurrentFunc = MF.getFunction();
+ SmallVector<MVT, 1> VTs;
+ computeLegalValueVTs(CurrentFunc, TM, Global->getValueType(), VTs);
+ if (VTs.size() != 1)
+ report_fatal_error("Aggregate globals not yet implemented");
+
+ bool Mutable = true;
+ wasm::ValType Type = WebAssembly::toValType(VTs[0]);
+ WasmSym->setType(wasm::WASM_SYMBOL_TYPE_GLOBAL);
+ WasmSym->setGlobalType(wasm::WasmGlobalType{uint8_t(Type), Mutable});
+ }
+ return WasmSym;
+ }
const auto *FuncTy = cast<FunctionType>(Global->getValueType());
const MachineFunction &MF = *MO.getParent()->getParent()->getParent();
diff --git a/llvm/test/CodeGen/WebAssembly/global-get.ll b/llvm/test/CodeGen/WebAssembly/global-get.ll
index d683fe677864..a9b07657fbf5 100644
--- a/llvm/test/CodeGen/WebAssembly/global-get.ll
+++ b/llvm/test/CodeGen/WebAssembly/global-get.ll
@@ -5,6 +5,9 @@
@f32_global = local_unnamed_addr addrspace(1) global float undef
@f64_global = local_unnamed_addr addrspace(1) global double undef
+ at i32_external_used = external addrspace(1) global i32
+ at i32_external_unused = external addrspace(1) global i32
+
define i32 @return_i32_global() {
; CHECK-LABEL: return_i32_global:
; CHECK-NEXT: functype return_i32_global () -> (i32)
@@ -41,14 +44,36 @@ define double @return_f64_global() {
ret double %v
}
+define i32 @return_extern_i32_global() {
+; CHECK-LABEL: return_extern_i32_global:
+; CHECK-NEXT: functype return_extern_i32_global () -> (i32)
+; CHECK-NEXT: global.get i32_external_used
+; CHECK-NEXT: end_function
+ %v = load i32, i32 addrspace(1)* @i32_external_used
+ ret i32 %v
+}
+
+
+; CHECK: .globl i32_global
+; CHECK: .globaltype i32_global, i32
+; CHECK-LABEL: i32_global:
+
+; CHECK: .globl i64_global
+; CHECK: .globaltype i64_global, i64
+; CHECK-LABEL: i64_global:
+
+; CHECK: .globl f32_global
+; CHECK: .globaltype f32_global, f32
+; CHECK-LABEL: f32_global:
+
+; CHECK: .globl f64_global
+; CHECK: .globaltype f64_global, f64
+; CHECK-LABEL: f64_global:
+
+; CHECK-NOT: .global i32_external_used
+; CHECK: .globaltype i32_external_used, i32
+; CHECK-NOT: i32_external_used:
-;; LLVM doesn't yet declare proper WebAssembly globals for these values,
-;; instead placing them in linear memory. To fix in a followup.
-; FIXME-CHECK: .globl i32_global
-; FIXME-CHECK: .globaltype i32_global, i32
-; FIXME-CHECK: .globl i64_global
-; FIXME-CHECK: .globaltype i64_global, i64
-; FIXME-CHECK: .globl f32_global
-; FIXME-CHECK: .globaltype f32_global, f32
-; FIXME-CHECK: .globl f64_global
-; FIXME-CHECK: .globaltype f64_global, f64
+; CHECK-NOT: .global i32_external_unused
+; CHECK: .globaltype i32_external_unused, i32
+; CHECK-NOT: i32_external_unused:
diff --git a/llvm/test/CodeGen/WebAssembly/global-set.ll b/llvm/test/CodeGen/WebAssembly/global-set.ll
index 741fda632afd..54034e476fd6 100644
--- a/llvm/test/CodeGen/WebAssembly/global-set.ll
+++ b/llvm/test/CodeGen/WebAssembly/global-set.ll
@@ -45,13 +45,18 @@ define void @set_f64_global(double %v) {
ret void
}
-;; LLVM doesn't yet declare proper WebAssembly globals for these values,
-;; instead placing them in linear memory. To fix in a followup.
-; FIXME-CHECK: .globl i32_global
-; FIXME-CHECK: .globaltype i32_global, i32
-; FIXME-CHECK: .globl i64_global
-; FIXME-CHECK: .globaltype i64_global, i64
-; FIXME-CHECK: .globl f32_global
-; FIXME-CHECK: .globaltype f32_global, f32
-; FIXME-CHECK: .globl f64_global
-; FIXME-CHECK: .globaltype f64_global, f64
+; CHECK: .globl i32_global
+; CHECK: .globaltype i32_global, i32
+; CHECK-LABEL: i32_global:
+
+; CHECK: .globl i64_global
+; CHECK: .globaltype i64_global, i64
+; CHECK-LABEL: i64_global:
+
+; CHECK: .globl f32_global
+; CHECK: .globaltype f32_global, f32
+; CHECK-LABEL: f32_global:
+
+; CHECK: .globl f64_global
+; CHECK: .globaltype f64_global, f64
+; CHECK-LABEL: f64_global:
More information about the llvm-commits
mailing list