[prev in list] [next in list] [prev in thread] [next in thread]
List: cfe-commits
Subject: [PATCH] D66035: [WebAssembly] WIP: Add support for reference types
From: Valentin Churavy via Phabricator via cfe-commits <cfe-commits () lists ! llvm ! org>
Date: 2019-11-30 23:02:05
Message-ID: 90cb8ac9e4d9268ac4a1e4ccb3024975 () localhost ! localdomain
[Download RAW message or body]
vchuravy updated this revision to Diff 231601.
vchuravy added a comment.
- fix AS in anyref testfile
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D66035/new/
https://reviews.llvm.org/D66035
Files:
clang/lib/Basic/Targets/WebAssembly.h
lld/wasm/WriterUtils.cpp
llvm/include/llvm/BinaryFormat/Wasm.h
llvm/include/llvm/BinaryFormat/WasmRelocs.def
llvm/include/llvm/CodeGen/TargetLowering.h
llvm/include/llvm/CodeGen/ValueTypes.td
llvm/include/llvm/MC/MCExpr.h
llvm/include/llvm/MC/MCSymbolWasm.h
llvm/include/llvm/Object/Wasm.h
llvm/include/llvm/Support/MachineValueType.h
llvm/lib/BinaryFormat/Wasm.cpp
llvm/lib/CodeGen/CodeGenPrepare.cpp
llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
llvm/lib/CodeGen/ValueTypes.cpp
llvm/lib/MC/MCExpr.cpp
llvm/lib/MC/WasmObjectWriter.cpp
llvm/lib/Object/WasmObjectFile.cpp
llvm/lib/ObjectYAML/WasmEmitter.cpp
llvm/lib/ObjectYAML/WasmYAML.cpp
llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
llvm/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp
llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp
llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCCodeEmitter.cpp
llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.cpp
llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp
llvm/lib/Target/WebAssembly/WebAssembly.h
llvm/lib/Target/WebAssembly/WebAssembly.td
llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp
llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h
llvm/lib/Target/WebAssembly/WebAssemblyInstrCall.td
llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp
llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td
llvm/lib/Target/WebAssembly/WebAssemblyInstrTable.td
llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
llvm/lib/Target/WebAssembly/WebAssemblyPeephole.cpp
llvm/lib/Target/WebAssembly/WebAssemblyRegisterInfo.td
llvm/lib/Target/WebAssembly/WebAssemblySubtarget.h
llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
llvm/test/CodeGen/WebAssembly/anyref.ll
llvm/test/CodeGen/WebAssembly/reg-argument.mir
llvm/test/CodeGen/WebAssembly/reg-copy.mir
llvm/utils/TableGen/CodeGenTarget.cpp
["D66035.231601.patch" (text/x-patch)]
Index: llvm/utils/TableGen/CodeGenTarget.cpp
===================================================================
--- llvm/utils/TableGen/CodeGenTarget.cpp
+++ llvm/utils/TableGen/CodeGenTarget.cpp
@@ -196,6 +196,7 @@
case MVT::iPTRAny: return "MVT::iPTRAny";
case MVT::Untyped: return "MVT::Untyped";
case MVT::exnref: return "MVT::exnref";
+ case MVT::anyref: return "MVT::anyref";
default: llvm_unreachable("ILLEGAL VALUE TYPE!");
}
}
Index: llvm/test/CodeGen/WebAssembly/reg-copy.mir
===================================================================
--- llvm/test/CodeGen/WebAssembly/reg-copy.mir
+++ llvm/test/CodeGen/WebAssembly/reg-copy.mir
@@ -66,3 +66,14 @@
%0:exnref = COPY %1:exnref
RETURN implicit-def $arguments
...
+---
+name: copy_anyref
+# CHECK-LABEL: copy_anyref
+body: |
+ ; CHECK-LABEL: bb.0
+ ; CHECK-NEXT: %0:anyref = COPY_ANYREF %1:anyref
+ ; CHECK-NEXT: RETURN
+ bb.0:
+ %0:anyref = COPY %1:anyref
+ RETURN implicit-def $arguments
+...
Index: llvm/test/CodeGen/WebAssembly/reg-argument.mir
===================================================================
--- llvm/test/CodeGen/WebAssembly/reg-argument.mir
+++ llvm/test/CodeGen/WebAssembly/reg-argument.mir
@@ -57,3 +57,14 @@
%1:exnref = ARGUMENT_exnref 0, implicit $arguments
RETURN implicit-def $arguments
...
+---
+name: argument_anyref
+# CHECK-LABEL: argument_anyref
+body: |
+ ; CHECK-LABEL: bb.0:
+ ; CHECK-NEXT: %1:anyref = ARGUMENT_anyref 0
+ bb.0:
+ %0:i32 = CONST_I32 0, implicit-def $arguments
+ %1:anyref = ARGUMENT_anyref 0, implicit $arguments
+ RETURN implicit-def $arguments
+...
Index: llvm/test/CodeGen/WebAssembly/anyref.ll
===================================================================
--- /dev/null
+++ llvm/test/CodeGen/WebAssembly/anyref.ll
@@ -0,0 +1,29 @@
+; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt \
-wasm-disable-explicit-locals -wasm-keep-registers -mattr=+reference-types | \
FileCheck %s +
+target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128-ni:256"
+target triple = "wasm32-unknown-unknown"
+
+declare i8 addrspace(256)* @test(i8 addrspace(256)*)
+
+
+; CHECK-LABEL: call_test:
+; CHECK: .functype call_test (anyref) -> (anyref)
+define i8 addrspace(256)* @call_test(i8 addrspace(256)*) {
+; CHECK: anyref.call $push0=, test, $0
+ %a = call i8 addrspace(256)* @test(i8 addrspace(256)* %0)
+ ret i8 addrspace(256)* %a
+}
+
+; TODO: nullref?
+; define i8 addrspace(256)* @null_test() {
+; ret i8 addrspace(256)* null
+; }
+
+; TODO: Loading a anyref from a pointer
+; @glob = external global i8 addrspace(256)*, align 4
+; define i8 addrspace(256)* @global_test() {
+; %a = load i8 addrspace(256)*, i8 addrspace(256)** @glob
+; ret i8 addrspace(256)* %a
+; }
+
+; CHECK: .functype test (anyref) -> (anyref)
Index: llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
@@ -102,15 +102,45 @@
return *RM;
}
+static bool HasReferenceTypes(StringRef FS) {
+ bool ReferenceTypes = false;
+ SmallVector<StringRef, 3> Features;
+
+ FS.split(Features, ',', -1, false /* KeepEmpty */);
+ for (auto &Feature : Features) {
+ if (Feature == "reference-types" || Feature == "+reference-types")
+ ReferenceTypes = true;
+ if (Feature == "-reference-types")
+ ReferenceTypes = false;
+ }
+
+ return ReferenceTypes;
+}
+
+static std::string computeDataLayout(const Triple &TT, StringRef FS) {
+ std::string Ret = "e-m:e"; // little endian, mangling elf
+
+ if (TT.isArch64Bit()) {
+ Ret += "-p:64:64";
+ } else {
+ Ret += "-p:32:32";
+ }
+
+ Ret += "-i64:64-n32:64-S128";
+
+ if (HasReferenceTypes(FS)) {
+ Ret += "-ni:256"; // anyref
+ }
+ return Ret;
+}
+
/// Create an WebAssembly architecture model.
///
WebAssemblyTargetMachine::WebAssemblyTargetMachine(
const Target &T, const Triple &TT, StringRef CPU, StringRef FS,
const TargetOptions &Options, Optional<Reloc::Model> RM,
Optional<CodeModel::Model> CM, CodeGenOpt::Level OL, bool JIT)
- : LLVMTargetMachine(T,
- TT.isArch64Bit() ? "e-m:e-p:64:64-i64:64-n32:64-S128"
- : "e-m:e-p:32:32-i64:64-n32:64-S128",
+ : LLVMTargetMachine(T, computeDataLayout(TT, FS),
TT, CPU, FS, Options, getEffectiveRelocModel(RM, TT),
getEffectiveCodeModel(CM, CodeModel::Large), OL),
TLOF(new WebAssemblyTargetObjectFile()) {
Index: llvm/lib/Target/WebAssembly/WebAssemblySubtarget.h
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblySubtarget.h
+++ llvm/lib/Target/WebAssembly/WebAssemblySubtarget.h
@@ -47,6 +47,7 @@
bool HasMultivalue = false;
bool HasMutableGlobals = false;
bool HasTailCall = false;
+ bool HasReferenceTypes = false;
/// String name of used CPU.
std::string CPUString;
@@ -104,6 +105,7 @@
bool hasMultivalue() const { return HasMultivalue; }
bool hasMutableGlobals() const { return HasMutableGlobals; }
bool hasTailCall() const { return HasTailCall; }
+ bool hasReferenceTypes() const { return HasReferenceTypes; }
/// Parses features string setting specified subtarget options. Definition of
/// function is auto generated by tblgen.
Index: llvm/lib/Target/WebAssembly/WebAssemblyRegisterInfo.td
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyRegisterInfo.td
+++ llvm/lib/Target/WebAssembly/WebAssemblyRegisterInfo.td
@@ -44,6 +44,7 @@
def V128_0: WebAssemblyReg<"%v128">;
def EXNREF_0 : WebAssemblyReg<"%exnref.0">;
+def ANYREF_0 : WebAssemblyReg<"%anyref.0">;
// The value stack "register". This is an opaque entity which serves to order
// uses and defs that must remain in LIFO order.
@@ -65,3 +66,4 @@
def V128 : WebAssemblyRegClass<[v4f32, v2f64, v2i64, v4i32, v16i8, v8i16], 128,
(add V128_0)>;
def EXNREF : WebAssemblyRegClass<[exnref], 0, (add EXNREF_0)>;
+def ANYREF : WebAssemblyRegClass<[anyref], 0, (add ANYREF_0)>;
Index: llvm/lib/Target/WebAssembly/WebAssemblyPeephole.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyPeephole.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyPeephole.cpp
@@ -114,6 +114,9 @@
case WebAssembly::EXNREFRegClassID:
CopyLocalOpc = WebAssembly::COPY_EXNREF;
break;
+ case WebAssembly::ANYREFRegClassID:
+ CopyLocalOpc = WebAssembly::COPY_ANYREF;
+ break;
default:
llvm_unreachable("Unexpected register class for return operand");
}
Index: llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
@@ -64,6 +64,11 @@
WasmSym->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION);
}
+ unsigned TargetFlags = MO.getTargetFlags();
+ if (TargetFlags == WebAssemblyII::MO_TABLE_INDEX) {
+ WasmSym->setType(wasm::WASM_SYMBOL_TYPE_TABLE);
+ }
+
return WasmSym;
}
@@ -90,6 +95,12 @@
return WasmSym;
}
+ unsigned TargetFlags = MO.getTargetFlags();
+ if (TargetFlags == WebAssemblyII::MO_TABLE_INDEX) {
+ WasmSym->setType(wasm::WASM_SYMBOL_TYPE_TABLE);
+ return WasmSym;
+ }
+
SmallVector<wasm::ValType, 4> Returns;
SmallVector<wasm::ValType, 4> Params;
if (strcmp(Name, "__cpp_exception") == 0) {
@@ -130,6 +141,9 @@
switch (TargetFlags) {
case WebAssemblyII::MO_NO_FLAG:
break;
+ case WebAssemblyII::MO_TABLE_INDEX:
+ Kind = MCSymbolRefExpr::VK_WASM_TABLEINDEX;
+ break;
case WebAssemblyII::MO_GOT:
Kind = MCSymbolRefExpr::VK_GOT;
break;
Index: llvm/lib/Target/WebAssembly/WebAssemblyInstrTable.td
===================================================================
--- /dev/null
+++ llvm/lib/Target/WebAssembly/WebAssemblyInstrTable.td
@@ -0,0 +1,12 @@
+multiclass WebAssemblyTableGet<WebAssemblyRegClass rc, string Name, int Opcode> {
+ let mayLoad = 1, UseNamedOperandTable = 1 in
+ defm "": I<(outs rc:$dst),
+ (ins table_op: $table, I32:$offset),
+ (outs), (ins table_op: $table),
+ [], !strconcat(Name, "\t$dst, ${offset}(${table})"),
+ !strconcat(Name, "\t${table}"), Opcode>;
+}
+
+defm TABLE_GET : WebAssemblyTableGet<ANYREF, "table.get", 0x25>;
+
+def : Pat<(anyref (load (WebAssemblywrapper anyref:$addr))), (TABLE_GET \
anyref:$addr, (CONST_I32 0))>;
Index: llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td
+++ llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td
@@ -62,6 +62,10 @@
Predicate<"Subtarget->hasBulkMemory()">,
AssemblerPredicate<"FeatureBulkMemory", "bulk-memory">;
+def HasReferenceTypes :
+ Predicate<"Subtarget->hasReferenceTypes()">,
+ AssemblerPredicate<"FeatureReferenceTypes", "reference-types">;
+
//===----------------------------------------------------------------------===//
// WebAssembly-specific DAG Node Types.
//===----------------------------------------------------------------------===//
@@ -141,6 +145,9 @@
let OperandType = "OPERAND_GLOBAL" in
def global_op : Operand<i32>;
+let OperandType = "OPERAND_TABLE" in
+def table_op : Operand<anyref>;
+
let OperandType = "OPERAND_I32IMM" in
def i32imm_op : Operand<i32>;
@@ -226,6 +233,7 @@
defm "": ARGUMENT<F32, f32>;
defm "": ARGUMENT<F64, f64>;
defm "": ARGUMENT<EXNREF, exnref>;
+defm "": ARGUMENT<ANYREF, anyref>;
// local.get and local.set are not generated by instruction selection; they
// are implied by virtual register uses and defs.
@@ -296,6 +304,7 @@
defm "" : LOCAL<F64>;
defm "" : LOCAL<V128>, Requires<[HasSIMD128]>;
defm "" : LOCAL<EXNREF>, Requires<[HasExceptionHandling]>;
+defm "" : LOCAL<ANYREF>, Requires<[HasReferenceTypes]>;
let isMoveImm = 1, isAsCheapAsAMove = 1, isReMaterializable = 1 in {
defm CONST_I32 : I<(outs I32:$res), (ins i32imm_op:$imm),
@@ -348,3 +357,4 @@
include "WebAssemblyInstrSIMD.td"
include "WebAssemblyInstrRef.td"
include "WebAssemblyInstrBulkMemory.td"
+include "WebAssemblyInstrTable.td"
Index: llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp
@@ -77,6 +77,8 @@
CopyOpcode = WebAssembly::COPY_V128;
else if (RC == &WebAssembly::EXNREFRegClass)
CopyOpcode = WebAssembly::COPY_EXNREF;
+ else if (RC == &WebAssembly::ANYREFRegClass)
+ CopyOpcode = WebAssembly::COPY_ANYREF;
else
llvm_unreachable("Unexpected register class");
Index: llvm/lib/Target/WebAssembly/WebAssemblyInstrCall.td
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyInstrCall.td
+++ llvm/lib/Target/WebAssembly/WebAssemblyInstrCall.td
@@ -60,6 +60,7 @@
defm "" : CALL<f32, F32, "f32.">;
defm "" : CALL<f64, F64, "f64.">;
defm "" : CALL<exnref, EXNREF, "exnref.", [HasExceptionHandling]>;
+defm "" : CALL<anyref, ANYREF, "anyref.", [HasReferenceTypes]>;
defm "" : CALL<v16i8, V128, "v128.", [HasSIMD128]>;
defm "" : CALL<v8i16, V128, "v128.", [HasSIMD128]>;
defm "" : CALL<v4i32, V128, "v128.", [HasSIMD128]>;
@@ -142,6 +143,9 @@
def : Pat<(exnref (WebAssemblycall1 (WebAssemblywrapper tglobaladdr:$callee))),
(CALL_exnref tglobaladdr:$callee)>,
Requires<[HasExceptionHandling]>;
+def : Pat<(anyref (WebAssemblycall1 (WebAssemblywrapper tglobaladdr:$callee))),
+ (CALL_anyref tglobaladdr:$callee)>,
+ Requires<[HasReferenceTypes]>;
def : Pat<(WebAssemblycall0 (WebAssemblywrapper tglobaladdr:$callee)),
(CALL_VOID tglobaladdr:$callee)>;
def : Pat<(WebAssemblyretcall (WebAssemblywrapper tglobaladdr:$callee)),
@@ -171,6 +175,9 @@
def : Pat<(exnref (WebAssemblycall1 (WebAssemblywrapper texternalsym:$callee))),
(CALL_exnref texternalsym:$callee)>,
Requires<[HasExceptionHandling]>;
+def : Pat<(anyref (WebAssemblycall1 (WebAssemblywrapper texternalsym:$callee))),
+ (CALL_anyref texternalsym:$callee)>,
+ Requires<[HasReferenceTypes]>;
def : Pat<(WebAssemblycall0 (WebAssemblywrapper texternalsym:$callee)),
(CALL_VOID texternalsym:$callee)>;
def : Pat<(WebAssemblyretcall (WebAssemblywrapper texternalsym:$callee)),
Index: llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h
+++ llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.h
@@ -15,6 +15,7 @@
#ifndef LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYISELLOWERING_H
#define LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYISELLOWERING_H
+#include "WebAssembly.h"
#include "llvm/CodeGen/TargetLowering.h"
namespace llvm {
@@ -51,6 +52,18 @@
/// right decision when generating code for different targets.
const WebAssemblySubtarget *Subtarget;
+ MVT getPointerTy(const DataLayout &DL, uint32_t AS = 0) const override {
+ return AS == WebAssemblyAS::ANYREF_ADDRESS
+ ? MVT::anyref
+ : MVT::getIntegerVT(DL.getPointerSizeInBits(AS));
+ }
+
+ MVT getPointerMemTy(const DataLayout &DL, uint32_t AS = 0) const override {
+ return AS == WebAssemblyAS::ANYREF_ADDRESS
+ ? MVT::anyref
+ : MVT::getIntegerVT(DL.getPointerSizeInBits(AS));
+ }
+
AtomicExpansionKind shouldExpandAtomicRMWInIR(AtomicRMWInst *) const override;
FastISel *createFastISel(FunctionLoweringInfo &FuncInfo,
const TargetLibraryInfo *LibInfo) const override;
@@ -96,6 +109,7 @@
void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue> &Results,
SelectionDAG &DAG) const override;
+ bool isNoopAddrSpaceCast(unsigned SrcAS, unsigned DestAS) const override;
const char *getClearCacheBuiltinName() const override {
report_fatal_error("llvm.clear_cache is not supported on wasm");
Index: llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
@@ -13,6 +13,7 @@
#include "WebAssemblyISelLowering.h"
#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
+#include "WebAssembly.h"
#include "WebAssemblyMachineFunctionInfo.h"
#include "WebAssemblySubtarget.h"
#include "WebAssemblyTargetMachine.h"
@@ -65,6 +66,10 @@
addRegisterClass(MVT::v2i64, &WebAssembly::V128RegClass);
addRegisterClass(MVT::v2f64, &WebAssembly::V128RegClass);
}
+ if (Subtarget->hasReferenceTypes()) {
+ addRegisterClass(MVT::anyref, &WebAssembly::ANYREFRegClass);
+ setOperationAction(ISD::GlobalAddress, MVT::anyref, Custom);
+ }
// Compute derived properties from the register classes.
computeRegisterProperties(Subtarget->getRegisterInfo());
@@ -958,6 +963,14 @@
return Chain;
}
+bool WebAssemblyTargetLowering::isNoopAddrSpaceCast(unsigned SrcAS,
+ unsigned DestAS) const {
+ assert(SrcAS != DestAS && "Expected different address spaces!");
+
+ return SrcAS <= WebAssemblyAS::MAX_CUSTOM_ADDRESS &&
+ DestAS <= WebAssemblyAS::MAX_CUSTOM_ADDRESS;
+}
+
void WebAssemblyTargetLowering::ReplaceNodeResults(
SDNode *N, SmallVectorImpl<SDValue> &Results, SelectionDAG &DAG) const {
switch (N->getOpcode()) {
@@ -1103,8 +1116,9 @@
EVT VT = Op.getValueType();
assert(GA->getTargetFlags() == 0 &&
"Unexpected target flags on generic GlobalAddressSDNode");
- if (GA->getAddressSpace() != 0)
- fail(DL, DAG, "WebAssembly only expects the 0 address space");
+ if (GA->getAddressSpace() != 0 &&
+ GA->getAddressSpace() != WebAssemblyAS::ANYREF_ADDRESS)
+ fail(DL, DAG, "WebAssembly only expects the 0 or 256 (anyref) address space");
unsigned OperandFlags = 0;
if (isPositionIndependent()) {
@@ -1136,6 +1150,10 @@
}
}
+ if (GA->getAddressSpace() == WebAssemblyAS::ANYREF_ADDRESS) {
+ OperandFlags = WebAssemblyII::MO_TABLE_INDEX;
+ }
+
return DAG.getNode(WebAssemblyISD::Wrapper, DL, VT,
DAG.getTargetGlobalAddress(GA->getGlobal(), DL, VT,
GA->getOffset(), OperandFlags));
Index: llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
@@ -130,6 +130,7 @@
case MVT::f32:
case MVT::f64:
case MVT::exnref:
+ case MVT::anyref:
return VT;
case MVT::f16:
return MVT::f32;
@@ -706,6 +707,10 @@
Opc = WebAssembly::ARGUMENT_exnref;
RC = &WebAssembly::EXNREFRegClass;
break;
+ case MVT::anyref:
+ Opc = WebAssembly::ARGUMENT_anyref;
+ RC = &WebAssembly::ANYREFRegClass;
+ break;
default:
return false;
}
@@ -824,6 +829,11 @@
: WebAssembly::PCALL_INDIRECT_exnref;
ResultReg = createResultReg(&WebAssembly::EXNREFRegClass);
break;
+ case MVT::anyref:
+ Opc = IsDirect ? WebAssembly::CALL_anyref
+ : WebAssembly::PCALL_INDIRECT_anyref;
+ ResultReg = createResultReg(&WebAssembly::ANYREFRegClass);
+ break;
default:
return false;
}
@@ -1329,6 +1339,7 @@
case MVT::v4f32:
case MVT::v2f64:
case MVT::exnref:
+ case MVT::anyref:
break;
default:
return false;
Index: llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp
@@ -92,6 +92,8 @@
return WebAssembly::DROP_V128;
if (RC == &WebAssembly::EXNREFRegClass)
return WebAssembly::DROP_EXNREF;
+ if (RC == &WebAssembly::ANYREFRegClass)
+ return WebAssembly::DROP_ANYREF;
llvm_unreachable("Unexpected register class");
}
@@ -109,6 +111,8 @@
return WebAssembly::LOCAL_GET_V128;
if (RC == &WebAssembly::EXNREFRegClass)
return WebAssembly::LOCAL_GET_EXNREF;
+ if (RC == &WebAssembly::ANYREFRegClass)
+ return WebAssembly::LOCAL_GET_ANYREF;
llvm_unreachable("Unexpected register class");
}
@@ -126,6 +130,8 @@
return WebAssembly::LOCAL_SET_V128;
if (RC == &WebAssembly::EXNREFRegClass)
return WebAssembly::LOCAL_SET_EXNREF;
+ if (RC == &WebAssembly::EXNREFRegClass)
+ return WebAssembly::LOCAL_SET_ANYREF;
llvm_unreachable("Unexpected register class");
}
@@ -143,6 +149,8 @@
return WebAssembly::LOCAL_TEE_V128;
if (RC == &WebAssembly::EXNREFRegClass)
return WebAssembly::LOCAL_TEE_EXNREF;
+ if (RC == &WebAssembly::ANYREFRegClass)
+ return WebAssembly::LOCAL_TEE_ANYREF;
llvm_unreachable("Unexpected register class");
}
@@ -160,6 +168,8 @@
return MVT::v16i8;
if (RC == &WebAssembly::EXNREFRegClass)
return MVT::exnref;
+ if (RC == &WebAssembly::ANYREFRegClass)
+ return MVT::anyref;
llvm_unreachable("unrecognized register class");
}
Index: llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
@@ -329,6 +329,7 @@
case WebAssembly::ARGUMENT_v4f32_S:
case WebAssembly::ARGUMENT_v2f64:
case WebAssembly::ARGUMENT_v2f64_S:
+ case WebAssembly::ARGUMENT_anyref:
// These represent values which are live into the function entry, so there's
// no instruction to emit.
break;
Index: llvm/lib/Target/WebAssembly/WebAssembly.td
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssembly.td
+++ llvm/lib/Target/WebAssembly/WebAssembly.td
@@ -66,6 +66,10 @@
SubtargetFeature<"mutable-globals", "HasMutableGlobals", "true",
"Enable mutable globals">;
+def FeatureReferenceTypes :
+ SubtargetFeature<"reference-types", "HasReferenceTypes", "true",
+ "Enable referenceTypes">;
+
//===----------------------------------------------------------------------===//
// Architectures.
//===----------------------------------------------------------------------===//
Index: llvm/lib/Target/WebAssembly/WebAssembly.h
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssembly.h
+++ llvm/lib/Target/WebAssembly/WebAssembly.h
@@ -81,4 +81,12 @@
} // end namespace llvm
+namespace WebAssemblyAS {
+enum : unsigned {
+ // The maxium value for custom address-spaces.
+ MAX_CUSTOM_ADDRESS = 255,
+ ANYREF_ADDRESS = 256, // Address space for anyref
+};
+}
+
#endif
Index: llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp
+++ llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp
@@ -73,6 +73,8 @@
switch (Modifier) {
case MCSymbolRefExpr::VK_GOT:
return wasm::R_WASM_GLOBAL_INDEX_LEB;
+ case MCSymbolRefExpr::VK_WASM_TABLEINDEX:
+ return wasm::R_WASM_TABLE_INDEX_LEB;
case MCSymbolRefExpr::VK_WASM_TBREL:
assert(SymA.isFunction());
return wasm::R_WASM_TABLE_INDEX_REL_SLEB;
@@ -99,6 +101,8 @@
return wasm::R_WASM_FUNCTION_INDEX_LEB;
if (SymA.isEvent())
return wasm::R_WASM_EVENT_INDEX_LEB;
+ if (SymA.isTable())
+ return wasm::R_WASM_TABLE_INDEX_LEB;
return wasm::R_WASM_MEMORY_ADDR_LEB;
case FK_Data_4:
if (SymA.isFunction())
Index: llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
===================================================================
--- llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
+++ llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
@@ -48,6 +48,8 @@
OPERAND_LOCAL,
/// Global index.
OPERAND_GLOBAL,
+ /// Table index.
+ OPERAND_TABLE,
/// 32-bit integer immediates.
OPERAND_I32IMM,
/// 64-bit integer immediates.
@@ -102,6 +104,9 @@
// address relative the __table_base wasm global.
// Only applicable to function symbols.
MO_TABLE_BASE_REL,
+
+ // On a symbol operand this indicates that this operand is a table index.
+ MO_TABLE_INDEX,
};
} // end namespace WebAssemblyII
@@ -132,6 +137,7 @@
F64 = unsigned(wasm::ValType::F64),
V128 = unsigned(wasm::ValType::V128),
Exnref = unsigned(wasm::ValType::EXNREF),
+ Anyref = unsigned(wasm::ValType::ANYREF),
// Multivalue blocks (and other non-void blocks) are only emitted when the
// blocks will never be exited and are at the ends of functions (see
// WebAssemblyCFGStackify::fixEndsAtEndOfFunction). They also are never made
@@ -393,6 +399,8 @@
case WebAssembly::ARGUMENT_v2f64_S:
case WebAssembly::ARGUMENT_exnref:
case WebAssembly::ARGUMENT_exnref_S:
+ case WebAssembly::ARGUMENT_anyref:
+ case WebAssembly::ARGUMENT_anyref_S:
return true;
default:
return false;
@@ -413,6 +421,8 @@
case WebAssembly::COPY_V128_S:
case WebAssembly::COPY_EXNREF:
case WebAssembly::COPY_EXNREF_S:
+ case WebAssembly::COPY_ANYREF:
+ case WebAssembly::COPY_ANYREF_S:
return true;
default:
return false;
@@ -433,6 +443,8 @@
case WebAssembly::TEE_V128_S:
case WebAssembly::TEE_EXNREF:
case WebAssembly::TEE_EXNREF_S:
+ case WebAssembly::TEE_ANYREF:
+ case WebAssembly::TEE_ANYREF_S:
return true;
default:
return false;
@@ -465,6 +477,8 @@
case WebAssembly::CALL_v2f64_S:
case WebAssembly::CALL_exnref:
case WebAssembly::CALL_exnref_S:
+ case WebAssembly::CALL_anyref:
+ case WebAssembly::CALL_anyref_S:
case WebAssembly::RET_CALL:
case WebAssembly::RET_CALL_S:
return true;
@@ -499,6 +513,8 @@
case WebAssembly::CALL_INDIRECT_v2f64_S:
case WebAssembly::CALL_INDIRECT_exnref:
case WebAssembly::CALL_INDIRECT_exnref_S:
+ case WebAssembly::CALL_INDIRECT_anyref:
+ case WebAssembly::CALL_INDIRECT_anyref_S:
case WebAssembly::RET_CALL_INDIRECT:
case WebAssembly::RET_CALL_INDIRECT_S:
return true;
@@ -542,6 +558,8 @@
case WebAssembly::CALL_v2f64_S:
case WebAssembly::CALL_exnref:
case WebAssembly::CALL_exnref_S:
+ case WebAssembly::CALL_anyref:
+ case WebAssembly::CALL_anyref_S:
case WebAssembly::CALL_INDIRECT_i32:
case WebAssembly::CALL_INDIRECT_i32_S:
case WebAssembly::CALL_INDIRECT_i64:
@@ -562,6 +580,8 @@
case WebAssembly::CALL_INDIRECT_v4f32_S:
case WebAssembly::CALL_INDIRECT_v2f64:
case WebAssembly::CALL_INDIRECT_v2f64_S:
+ case WebAssembly::CALL_INDIRECT_anyref:
+ case WebAssembly::CALL_INDIRECT_anyref_S:
case WebAssembly::CALL_INDIRECT_exnref:
case WebAssembly::CALL_INDIRECT_exnref_S:
return 1;
Index: llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.cpp
+++ llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.cpp
@@ -149,6 +149,8 @@
return wasm::ValType::V128;
case MVT::exnref:
return wasm::ValType::EXNREF;
+ case MVT::anyref:
+ return wasm::ValType::ANYREF;
default:
llvm_unreachable("unexpected type");
}
Index: llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCCodeEmitter.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCCodeEmitter.cpp
+++ llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCCodeEmitter.cpp
@@ -155,6 +155,7 @@
case WebAssembly::OPERAND_SIGNATURE:
case WebAssembly::OPERAND_TYPEINDEX:
case WebAssembly::OPERAND_GLOBAL:
+ case WebAssembly::OPERAND_TABLE:
case WebAssembly::OPERAND_EVENT:
FixupKind = MCFixupKind(WebAssembly::fixup_uleb128_i32);
break;
Index: llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp
+++ llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp
@@ -305,6 +305,8 @@
return "v128";
case wasm::WASM_TYPE_FUNCREF:
return "funcref";
+ case wasm::WASM_TYPE_ANYREF:
+ return "anyref";
case wasm::WASM_TYPE_FUNC:
return "func";
case wasm::WASM_TYPE_EXNREF:
Index: llvm/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp
+++ llvm/lib/Target/WebAssembly/Disassembler/WebAssemblyDisassembler.cpp
@@ -197,6 +197,7 @@
case WebAssembly::OPERAND_BASIC_BLOCK:
case WebAssembly::OPERAND_LOCAL:
case WebAssembly::OPERAND_GLOBAL:
+ case WebAssembly::OPERAND_TABLE:
case WebAssembly::OPERAND_FUNCTION32:
case WebAssembly::OPERAND_OFFSET32:
case WebAssembly::OPERAND_P2ALIGN:
Index: llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
+++ llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
@@ -310,6 +310,8 @@
return wasm::ValType::V128;
if (Type == "exnref")
return wasm::ValType::EXNREF;
+ if (Type == "anyref")
+ return wasm::ValType::ANYREF;
return Optional<wasm::ValType>();
}
@@ -322,6 +324,7 @@
.Case("f64", WebAssembly::BlockType::F64)
.Case("v128", WebAssembly::BlockType::V128)
.Case("exnref", WebAssembly::BlockType::Exnref)
+ .Case("anyref", WebAssembly::BlockType::Anyref)
.Case("void", WebAssembly::BlockType::Void)
.Default(WebAssembly::BlockType::Invalid);
}
Index: llvm/lib/ObjectYAML/WasmYAML.cpp
===================================================================
--- llvm/lib/ObjectYAML/WasmYAML.cpp
+++ llvm/lib/ObjectYAML/WasmYAML.cpp
@@ -493,6 +493,8 @@
IO.mapRequired("Global", Info.ElementIndex);
} else if (Info.Kind == wasm::WASM_SYMBOL_TYPE_EVENT) {
IO.mapRequired("Event", Info.ElementIndex);
+ } else if (Info.Kind == wasm::WASM_SYMBOL_TYPE_TABLE) {
+ IO.mapRequired("Table", Info.ElementIndex);
} else if (Info.Kind == wasm::WASM_SYMBOL_TYPE_DATA) {
if ((Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0) {
IO.mapRequired("Segment", Info.DataRef.Segment);
@@ -547,6 +549,7 @@
ECase(GLOBAL);
ECase(SECTION);
ECase(EVENT);
+ ECase(TABLE);
#undef ECase
}
@@ -559,6 +562,7 @@
ECase(F64);
ECase(V128);
ECase(FUNCREF);
+ ECase(ANYREF);
ECase(FUNC);
#undef ECase
}
@@ -590,6 +594,7 @@
IO &IO, WasmYAML::TableType &Type) {
#define ECase(X) IO.enumCase(Type, #X, wasm::WASM_TYPE_##X);
ECase(FUNCREF);
+ ECase(ANYREF);
#undef ECase
}
Index: llvm/lib/ObjectYAML/WasmEmitter.cpp
===================================================================
--- llvm/lib/ObjectYAML/WasmEmitter.cpp
+++ llvm/lib/ObjectYAML/WasmEmitter.cpp
@@ -188,6 +188,7 @@
case wasm::WASM_SYMBOL_TYPE_FUNCTION:
case wasm::WASM_SYMBOL_TYPE_GLOBAL:
case wasm::WASM_SYMBOL_TYPE_EVENT:
+ case wasm::WASM_SYMBOL_TYPE_TABLE:
encodeULEB128(Info.ElementIndex, SubSection.getStream());
if ((Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0 ||
(Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0)
Index: llvm/lib/Object/WasmObjectFile.cpp
===================================================================
--- llvm/lib/Object/WasmObjectFile.cpp
+++ llvm/lib/Object/WasmObjectFile.cpp
@@ -470,9 +470,11 @@
std::vector<wasm::WasmImport *> ImportedGlobals;
std::vector<wasm::WasmImport *> ImportedFunctions;
std::vector<wasm::WasmImport *> ImportedEvents;
+ std::vector<wasm::WasmImport *> ImportedTables;
ImportedGlobals.reserve(Imports.size());
ImportedFunctions.reserve(Imports.size());
ImportedEvents.reserve(Imports.size());
+ ImportedTables.reserve(Imports.size());
for (auto &I : Imports) {
if (I.Kind == wasm::WASM_EXTERNAL_FUNCTION)
ImportedFunctions.emplace_back(&I);
@@ -480,6 +482,8 @@
ImportedGlobals.emplace_back(&I);
else if (I.Kind == wasm::WASM_EXTERNAL_EVENT)
ImportedEvents.emplace_back(&I);
+ else if (I.Kind == wasm::WASM_EXTERNAL_TABLE)
+ ImportedTables.emplace_back(&I);
}
while (Count--) {
@@ -609,6 +613,27 @@
break;
}
+ case wasm::WASM_SYMBOL_TYPE_TABLE: {
+ Info.ElementIndex = readVaruint32(Ctx);
+ if (!isValidTableIndex(Info.ElementIndex) ||
+ IsDefined != isDefinedTableIndex(Info.ElementIndex))
+ return make_error<GenericBinaryError>("invalid table symbol index",
+ object_error::parse_failed);
+ if (IsDefined) {
+ Info.Name = readString(Ctx);
+ unsigned TableIndex = Info.ElementIndex - NumImportedTables;
+ } else {
+ wasm::WasmImport &Import = *ImportedTables[Info.ElementIndex];
+ if ((Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0)
+ Info.Name = readString(Ctx);
+ else
+ Info.Name = Import.Field;
+ Info.ImportName = Import.Field;
+ Info.ImportModule = Import.Module;
+ }
+ break;
+ }
+
default:
return make_error<GenericBinaryError>("Invalid symbol type",
object_error::parse_failed);
@@ -793,6 +818,11 @@
return make_error<GenericBinaryError>("Bad relocation event index",
object_error::parse_failed);
break;
+ case wasm::R_WASM_TABLE_INDEX_LEB:
+ if (!isValidTableSymbol(Reloc.Index))
+ return make_error<GenericBinaryError>("Bad relocation table index",
+ object_error::parse_failed);
+ break;
case wasm::R_WASM_MEMORY_ADDR_LEB:
case wasm::R_WASM_MEMORY_ADDR_SLEB:
case wasm::R_WASM_MEMORY_ADDR_I32:
@@ -915,8 +945,10 @@
Im.Memory = readLimits(Ctx);
break;
case wasm::WASM_EXTERNAL_TABLE:
+ NumImportedTables++;
Im.Table = readTable(Ctx);
- if (Im.Table.ElemType != wasm::WASM_TYPE_FUNCREF)
+ if (Im.Table.ElemType != wasm::WASM_TYPE_FUNCREF &&
+ Im.Table.ElemType != wasm::WASM_TYPE_ANYREF)
return make_error<GenericBinaryError>("Invalid table element type",
object_error::parse_failed);
break;
@@ -959,7 +991,9 @@
Tables.reserve(Count);
while (Count--) {
Tables.push_back(readTable(Ctx));
- if (Tables.back().ElemType != wasm::WASM_TYPE_FUNCREF) {
+ if (Tables.back().ElemType != wasm::WASM_TYPE_FUNCREF &&
+ // TODO: Only allow anyref here when reference-types is enabled?
+ Tables.back().ElemType != wasm::WASM_TYPE_ANYREF) {
return make_error<GenericBinaryError>("Invalid table element type",
object_error::parse_failed);
}
@@ -1082,6 +1116,14 @@
return Index >= NumImportedEvents && isValidEventIndex(Index);
}
+bool WasmObjectFile::isValidTableIndex(uint32_t Index) const {
+ return Index < NumImportedTables + Tables.size();
+}
+
+bool WasmObjectFile::isDefinedTableIndex(uint32_t Index) const {
+ return Index >= NumImportedTables && isValidTableIndex(Index);
+}
+
bool WasmObjectFile::isValidFunctionSymbol(uint32_t Index) const {
return Index < Symbols.size() && Symbols[Index].isTypeFunction();
}
@@ -1094,6 +1136,10 @@
return Index < Symbols.size() && Symbols[Index].isTypeEvent();
}
+bool WasmObjectFile::isValidTableSymbol(uint32_t Index) const {
+ return Index < Symbols.size() && Symbols[Index].isTypeTable();
+}
+
bool WasmObjectFile::isValidDataSymbol(uint32_t Index) const {
return Index < Symbols.size() && Symbols[Index].isTypeData();
}
Index: llvm/lib/MC/WasmObjectWriter.cpp
===================================================================
--- llvm/lib/MC/WasmObjectWriter.cpp
+++ llvm/lib/MC/WasmObjectWriter.cpp
@@ -254,6 +254,7 @@
unsigned NumFunctionImports = 0;
unsigned NumGlobalImports = 0;
unsigned NumEventImports = 0;
+ unsigned NumTableImports = 0;
uint32_t SectionCount = 0;
// TargetObjectWriter wrappers.
@@ -555,6 +556,7 @@
case wasm::R_WASM_FUNCTION_INDEX_LEB:
case wasm::R_WASM_GLOBAL_INDEX_LEB:
case wasm::R_WASM_EVENT_INDEX_LEB:
+ case wasm::R_WASM_TABLE_INDEX_LEB:
// Provisional value is function/global/event Wasm index
assert(WasmIndices.count(RelEntry.Symbol) > 0 && "symbol not found in wasm index \
space"); return WasmIndices[RelEntry.Symbol];
@@ -652,6 +654,7 @@
case wasm::R_WASM_GLOBAL_INDEX_LEB:
case wasm::R_WASM_MEMORY_ADDR_LEB:
case wasm::R_WASM_EVENT_INDEX_LEB:
+ case wasm::R_WASM_TABLE_INDEX_LEB:
writePatchableLEB(Stream, Value, Offset);
break;
case wasm::R_WASM_TABLE_INDEX_I32:
@@ -945,6 +948,7 @@
case wasm::WASM_SYMBOL_TYPE_FUNCTION:
case wasm::WASM_SYMBOL_TYPE_GLOBAL:
case wasm::WASM_SYMBOL_TYPE_EVENT:
+ case wasm::WASM_SYMBOL_TYPE_TABLE:
encodeULEB128(Sym.ElementIndex, W.OS);
if ((Sym.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0 ||
(Sym.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0)
@@ -1137,6 +1141,7 @@
TableImport.Kind = wasm::WASM_EXTERNAL_TABLE;
TableImport.Table.ElemType = wasm::WASM_TYPE_FUNCREF;
Imports.push_back(TableImport);
+ NumTableImports++;
// Populate SignatureIndices, and Imports and WasmIndices for undefined
// symbols. This must be done before populating WasmIndices for defined
@@ -1191,6 +1196,15 @@
Imports.push_back(Import);
assert(WasmIndices.count(&WS) == 0);
WasmIndices[&WS] = NumEventImports++;
+ } else if (WS.isTable()) {
+ wasm::WasmImport Import;
+ Import.Module = WS.getImportModule();
+ Import.Field = WS.getImportName();
+ Import.Kind = wasm::WASM_EXTERNAL_TABLE;
+ Import.Table.ElemType = wasm::WASM_TYPE_ANYREF;
+ Imports.push_back(Import);
+ assert(WasmIndices.count(&WS) == 0);
+ WasmIndices[&WS] = NumTableImports++;
}
}
}
@@ -1389,7 +1403,15 @@
}
LLVM_DEBUG(dbgs() << " -> event index: " << WasmIndices.find(&WS)->second
<< "\n");
-
+ } else if (WS.isTable()) {
+ if (WS.isDefined()) {
+ report_fatal_error("Defined tables are not supported yet");
+ } else {
+ // An import; the index was assigned above.
+ assert(WasmIndices.count(&WS) > 0);
+ }
+ LLVM_DEBUG(dbgs() << " -> table index: " << WasmIndices.find(&WS)->second
+ << "\n");
} else {
assert(WS.isSection());
}
Index: llvm/lib/MC/MCExpr.cpp
===================================================================
--- llvm/lib/MC/MCExpr.cpp
+++ llvm/lib/MC/MCExpr.cpp
@@ -312,6 +312,7 @@
case VK_Hexagon_IE: return "IE";
case VK_Hexagon_IE_GOT: return "IEGOT";
case VK_WASM_TYPEINDEX: return "TYPEINDEX";
+ case VK_WASM_TABLEINDEX: return "TABLEINDEX";
case VK_WASM_MBREL: return "MBREL";
case VK_WASM_TBREL: return "TBREL";
case VK_AMDGPU_GOTPCREL32_LO: return "gotpcrel32@lo";
@@ -431,6 +432,7 @@
.Case("hi8", VK_AVR_HI8)
.Case("hlo8", VK_AVR_HLO8)
.Case("typeindex", VK_WASM_TYPEINDEX)
+ .Case("tableindex", VK_WASM_TABLEINDEX)
.Case("tbrel", VK_WASM_TBREL)
.Case("mbrel", VK_WASM_MBREL)
.Case("gotpcrel32@lo", VK_AMDGPU_GOTPCREL32_LO)
Index: llvm/lib/CodeGen/ValueTypes.cpp
===================================================================
--- llvm/lib/CodeGen/ValueTypes.cpp
+++ llvm/lib/CodeGen/ValueTypes.cpp
@@ -256,6 +256,7 @@
case MVT::Metadata:return "Metadata";
case MVT::Untyped: return "Untyped";
case MVT::exnref : return "exnref";
+ case MVT::anyref : return "anyref";
}
}
@@ -355,91 +356,94 @@
case MVT::v2f64: return VectorType::get(Type::getDoubleTy(Context), 2);
case MVT::v4f64: return VectorType::get(Type::getDoubleTy(Context), 4);
case MVT::v8f64: return VectorType::get(Type::getDoubleTy(Context), 8);
- case MVT::nxv1i1:
+ case MVT::nxv1i1:
return VectorType::get(Type::getInt1Ty(Context), 1, /*Scalable=*/ true);
- case MVT::nxv2i1:
+ case MVT::nxv2i1:
return VectorType::get(Type::getInt1Ty(Context), 2, /*Scalable=*/ true);
- case MVT::nxv4i1:
+ case MVT::nxv4i1:
return VectorType::get(Type::getInt1Ty(Context), 4, /*Scalable=*/ true);
- case MVT::nxv8i1:
+ case MVT::nxv8i1:
return VectorType::get(Type::getInt1Ty(Context), 8, /*Scalable=*/ true);
- case MVT::nxv16i1:
+ case MVT::nxv16i1:
return VectorType::get(Type::getInt1Ty(Context), 16, /*Scalable=*/ true);
- case MVT::nxv32i1:
+ case MVT::nxv32i1:
return VectorType::get(Type::getInt1Ty(Context), 32, /*Scalable=*/ true);
- case MVT::nxv1i8:
+ case MVT::nxv1i8:
return VectorType::get(Type::getInt8Ty(Context), 1, /*Scalable=*/ true);
- case MVT::nxv2i8:
+ case MVT::nxv2i8:
return VectorType::get(Type::getInt8Ty(Context), 2, /*Scalable=*/ true);
- case MVT::nxv4i8:
+ case MVT::nxv4i8:
return VectorType::get(Type::getInt8Ty(Context), 4, /*Scalable=*/ true);
- case MVT::nxv8i8:
+ case MVT::nxv8i8:
return VectorType::get(Type::getInt8Ty(Context), 8, /*Scalable=*/ true);
- case MVT::nxv16i8:
+ case MVT::nxv16i8:
return VectorType::get(Type::getInt8Ty(Context), 16, /*Scalable=*/ true);
- case MVT::nxv32i8:
+ case MVT::nxv32i8:
return VectorType::get(Type::getInt8Ty(Context), 32, /*Scalable=*/ true);
- case MVT::nxv1i16:
+ case MVT::nxv1i16:
return VectorType::get(Type::getInt16Ty(Context), 1, /*Scalable=*/ true);
- case MVT::nxv2i16:
+ case MVT::nxv2i16:
return VectorType::get(Type::getInt16Ty(Context), 2, /*Scalable=*/ true);
- case MVT::nxv4i16:
+ case MVT::nxv4i16:
return VectorType::get(Type::getInt16Ty(Context), 4, /*Scalable=*/ true);
- case MVT::nxv8i16:
+ case MVT::nxv8i16:
return VectorType::get(Type::getInt16Ty(Context), 8, /*Scalable=*/ true);
case MVT::nxv16i16:
return VectorType::get(Type::getInt16Ty(Context), 16, /*Scalable=*/ true);
case MVT::nxv32i16:
return VectorType::get(Type::getInt16Ty(Context), 32, /*Scalable=*/ true);
- case MVT::nxv1i32:
+ case MVT::nxv1i32:
return VectorType::get(Type::getInt32Ty(Context), 1, /*Scalable=*/ true);
- case MVT::nxv2i32:
+ case MVT::nxv2i32:
return VectorType::get(Type::getInt32Ty(Context), 2, /*Scalable=*/ true);
- case MVT::nxv4i32:
+ case MVT::nxv4i32:
return VectorType::get(Type::getInt32Ty(Context), 4, /*Scalable=*/ true);
- case MVT::nxv8i32:
+ case MVT::nxv8i32:
return VectorType::get(Type::getInt32Ty(Context), 8, /*Scalable=*/ true);
case MVT::nxv16i32:
return VectorType::get(Type::getInt32Ty(Context), 16,/*Scalable=*/ true);
case MVT::nxv32i32:
return VectorType::get(Type::getInt32Ty(Context), 32,/*Scalable=*/ true);
- case MVT::nxv1i64:
+ case MVT::nxv1i64:
return VectorType::get(Type::getInt64Ty(Context), 1, /*Scalable=*/ true);
- case MVT::nxv2i64:
+ case MVT::nxv2i64:
return VectorType::get(Type::getInt64Ty(Context), 2, /*Scalable=*/ true);
- case MVT::nxv4i64:
+ case MVT::nxv4i64:
return VectorType::get(Type::getInt64Ty(Context), 4, /*Scalable=*/ true);
- case MVT::nxv8i64:
+ case MVT::nxv8i64:
return VectorType::get(Type::getInt64Ty(Context), 8, /*Scalable=*/ true);
case MVT::nxv16i64:
return VectorType::get(Type::getInt64Ty(Context), 16, /*Scalable=*/ true);
case MVT::nxv32i64:
return VectorType::get(Type::getInt64Ty(Context), 32, /*Scalable=*/ true);
- case MVT::nxv2f16:
+ case MVT::nxv2f16:
return VectorType::get(Type::getHalfTy(Context), 2, /*Scalable=*/ true);
- case MVT::nxv4f16:
+ case MVT::nxv4f16:
return VectorType::get(Type::getHalfTy(Context), 4, /*Scalable=*/ true);
- case MVT::nxv8f16:
+ case MVT::nxv8f16:
return VectorType::get(Type::getHalfTy(Context), 8, /*Scalable=*/ true);
- case MVT::nxv1f32:
+ case MVT::nxv1f32:
return VectorType::get(Type::getFloatTy(Context), 1, /*Scalable=*/ true);
- case MVT::nxv2f32:
+ case MVT::nxv2f32:
return VectorType::get(Type::getFloatTy(Context), 2, /*Scalable=*/ true);
- case MVT::nxv4f32:
+ case MVT::nxv4f32:
return VectorType::get(Type::getFloatTy(Context), 4, /*Scalable=*/ true);
- case MVT::nxv8f32:
+ case MVT::nxv8f32:
return VectorType::get(Type::getFloatTy(Context), 8, /*Scalable=*/ true);
case MVT::nxv16f32:
return VectorType::get(Type::getFloatTy(Context), 16, /*Scalable=*/ true);
- case MVT::nxv1f64:
+ case MVT::nxv1f64:
return VectorType::get(Type::getDoubleTy(Context), 1, /*Scalable=*/ true);
- case MVT::nxv2f64:
+ case MVT::nxv2f64:
return VectorType::get(Type::getDoubleTy(Context), 2, /*Scalable=*/ true);
- case MVT::nxv4f64:
+ case MVT::nxv4f64:
return VectorType::get(Type::getDoubleTy(Context), 4, /*Scalable=*/ true);
- case MVT::nxv8f64:
+ case MVT::nxv8f64:
return VectorType::get(Type::getDoubleTy(Context), 8, /*Scalable=*/ true);
case MVT::Metadata: return Type::getMetadataTy(Context);
+ case MVT::anyref:
+ return PointerType::get(Type::getInt8Ty(Context),
+ 256); // TODO: Fix AS for Webassembly
}
}
Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
===================================================================
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -4086,10 +4086,12 @@
Root = Chain;
ChainI = 0;
}
- SDValue A = DAG.getNode(ISD::ADD, dl,
- PtrVT, Ptr,
- DAG.getConstant(Offsets[i], dl, PtrVT),
- Flags);
+ SDValue A = Ptr;
+ if (Offsets[i] != 0)
+ A = DAG.getNode(ISD::ADD, dl,
+ PtrVT, Ptr,
+ DAG.getConstant(Offsets[i], dl, PtrVT),
+ Flags);
auto MMOFlags = MachineMemOperand::MONone;
if (isVolatile)
MMOFlags |= MachineMemOperand::MOVolatile;
Index: llvm/lib/CodeGen/CodeGenPrepare.cpp
===================================================================
--- llvm/lib/CodeGen/CodeGenPrepare.cpp
+++ llvm/lib/CodeGen/CodeGenPrepare.cpp
@@ -1952,7 +1952,7 @@
case Intrinsic::experimental_widenable_condition: {
// Give up on future widening oppurtunties so that we can fold away dead
// paths and merge blocks before going into block-local instruction
- // selection.
+ // selection.
if (II->use_empty()) {
II->eraseFromParent();
return true;
@@ -5812,6 +5812,9 @@
EVT LoadResultVT = TLI->getValueType(*DL, Load->getType());
unsigned BitWidth = LoadResultVT.getSizeInBits();
+ if (!BitWidth)
+ return false;
+
APInt DemandBits(BitWidth, 0);
APInt WidestAndBits(BitWidth, 0);
Index: llvm/lib/BinaryFormat/Wasm.cpp
===================================================================
--- llvm/lib/BinaryFormat/Wasm.cpp
+++ llvm/lib/BinaryFormat/Wasm.cpp
@@ -20,6 +20,8 @@
return "WASM_SYMBOL_TYPE_SECTION";
case wasm::WASM_SYMBOL_TYPE_EVENT:
return "WASM_SYMBOL_TYPE_EVENT";
+ case wasm::WASM_SYMBOL_TYPE_TABLE:
+ return "WASM_SYMBOL_TYPE_TABLE";
}
llvm_unreachable("unknown symbol type");
}
Index: llvm/include/llvm/Support/MachineValueType.h
===================================================================
--- llvm/include/llvm/Support/MachineValueType.h
+++ llvm/include/llvm/Support/MachineValueType.h
@@ -218,9 +218,10 @@
// will be determined by the opcode.
exnref = 134, // WebAssembly's exnref type
+ anyref = 135, // WebAssembly's anyref type
FIRST_VALUETYPE = 1, // This is always the beginning of the list.
- LAST_VALUETYPE = 135, // This always remains at the end of the list.
+ LAST_VALUETYPE = 136, // This always remains at the end of the list.
// This is the current maximum for LAST_VALUETYPE.
// MVT::MAX_ALLOWED_VALUETYPE is used for asserts and to size bit vectors
@@ -824,6 +825,7 @@
case v1024f32: return TypeSize::Fixed(32768);
case v2048i32:
case v2048f32: return TypeSize::Fixed(65536);
+ case anyref:
case exnref: return TypeSize::Fixed(0); // opaque type
}
}
Index: llvm/include/llvm/Object/Wasm.h
===================================================================
--- llvm/include/llvm/Object/Wasm.h
+++ llvm/include/llvm/Object/Wasm.h
@@ -63,6 +63,8 @@
bool isTypeEvent() const { return Info.Kind == wasm::WASM_SYMBOL_TYPE_EVENT; }
+ bool isTypeTable() const { return Info.Kind == wasm::WASM_SYMBOL_TYPE_TABLE; }
+
bool isDefined() const { return !isUndefined(); }
bool isUndefined() const {
@@ -217,9 +219,12 @@
bool isDefinedGlobalIndex(uint32_t Index) const;
bool isValidEventIndex(uint32_t Index) const;
bool isDefinedEventIndex(uint32_t Index) const;
+ bool isValidTableIndex(uint32_t Index) const;
+ bool isDefinedTableIndex(uint32_t Index) const;
bool isValidFunctionSymbol(uint32_t Index) const;
bool isValidGlobalSymbol(uint32_t Index) const;
bool isValidEventSymbol(uint32_t Index) const;
+ bool isValidTableSymbol(uint32_t Index) const;
bool isValidDataSymbol(uint32_t Index) const;
bool isValidSectionSymbol(uint32_t Index) const;
wasm::WasmFunction &getDefinedFunction(uint32_t Index);
@@ -284,6 +289,7 @@
uint32_t NumImportedGlobals = 0;
uint32_t NumImportedFunctions = 0;
uint32_t NumImportedEvents = 0;
+ uint32_t NumImportedTables = 0;
uint32_t CodeSection = 0;
uint32_t DataSection = 0;
uint32_t GlobalSection = 0;
Index: llvm/include/llvm/MC/MCSymbolWasm.h
===================================================================
--- llvm/include/llvm/MC/MCSymbolWasm.h
+++ llvm/include/llvm/MC/MCSymbolWasm.h
@@ -44,6 +44,7 @@
bool isGlobal() const { return Type == wasm::WASM_SYMBOL_TYPE_GLOBAL; }
bool isSection() const { return Type == wasm::WASM_SYMBOL_TYPE_SECTION; }
bool isEvent() const { return Type == wasm::WASM_SYMBOL_TYPE_EVENT; }
+ bool isTable() const { return Type == wasm::WASM_SYMBOL_TYPE_TABLE; }
wasm::WasmSymbolType getType() const { return Type; }
void setType(wasm::WasmSymbolType type) { Type = type; }
Index: llvm/include/llvm/MC/MCExpr.h
===================================================================
--- llvm/include/llvm/MC/MCExpr.h
+++ llvm/include/llvm/MC/MCExpr.h
@@ -290,9 +290,10 @@
VK_Hexagon_IE,
VK_Hexagon_IE_GOT,
- VK_WASM_TYPEINDEX, // Reference to a symbol's type (signature)
- VK_WASM_MBREL, // Memory address relative to memory base
- VK_WASM_TBREL, // Table index relative to table bare
+ VK_WASM_TYPEINDEX, // Reference to a symbol's type (signature)
+ VK_WASM_TABLEINDEX, // Reference to a table
+ VK_WASM_MBREL, // Memory address relative to memory base
+ VK_WASM_TBREL, // Table index relative to table bare
VK_AMDGPU_GOTPCREL32_LO, // symbol@gotpcrel32@lo
VK_AMDGPU_GOTPCREL32_HI, // symbol@gotpcrel32@hi
Index: llvm/include/llvm/CodeGen/ValueTypes.td
===================================================================
--- llvm/include/llvm/CodeGen/ValueTypes.td
+++ llvm/include/llvm/CodeGen/ValueTypes.td
@@ -166,6 +166,7 @@
def isVoid : ValueType<0 , 132>; // Produces no value
def untyped: ValueType<8 , 133>; // Produces an untyped value
def exnref: ValueType<0, 134>; // WebAssembly's exnref type
+def anyref: ValueType<0, 135>; // WebAssembly's anyref type
def token : ValueType<0 , 248>; // TokenTy
def MetadataVT: ValueType<0, 249>; // Metadata
Index: llvm/include/llvm/CodeGen/TargetLowering.h
===================================================================
--- llvm/include/llvm/CodeGen/TargetLowering.h
+++ llvm/include/llvm/CodeGen/TargetLowering.h
@@ -255,7 +255,7 @@
/// Return the in-memory pointer type for the given address space, defaults to
/// the pointer type from the data layout. FIXME: The default needs to be
/// removed once all the code is updated.
- MVT getPointerMemTy(const DataLayout &DL, uint32_t AS = 0) const {
+ virtual MVT getPointerMemTy(const DataLayout &DL, uint32_t AS = 0) const {
return MVT::getIntegerVT(DL.getPointerSizeInBits(AS));
}
Index: llvm/include/llvm/BinaryFormat/WasmRelocs.def
===================================================================
--- llvm/include/llvm/BinaryFormat/WasmRelocs.def
+++ llvm/include/llvm/BinaryFormat/WasmRelocs.def
@@ -15,3 +15,4 @@
WASM_RELOC(R_WASM_EVENT_INDEX_LEB, 10)
WASM_RELOC(R_WASM_MEMORY_ADDR_REL_SLEB, 11)
WASM_RELOC(R_WASM_TABLE_INDEX_REL_SLEB, 12)
+WASM_RELOC(R_WASM_TABLE_INDEX_LEB, 13)
Index: llvm/include/llvm/BinaryFormat/Wasm.h
===================================================================
--- llvm/include/llvm/BinaryFormat/Wasm.h
+++ llvm/include/llvm/BinaryFormat/Wasm.h
@@ -225,6 +225,7 @@
WASM_TYPE_F64 = 0x7C,
WASM_TYPE_V128 = 0x7B,
WASM_TYPE_FUNCREF = 0x70,
+ WASM_TYPE_ANYREF = 0x6F,
WASM_TYPE_EXNREF = 0x68,
WASM_TYPE_FUNC = 0x60,
WASM_TYPE_NORESULT = 0x40, // for blocks with no result values
@@ -313,6 +314,7 @@
WASM_SYMBOL_TYPE_GLOBAL = 0x2,
WASM_SYMBOL_TYPE_SECTION = 0x3,
WASM_SYMBOL_TYPE_EVENT = 0x4,
+ WASM_SYMBOL_TYPE_TABLE = 0x5,
};
// Kinds of event attributes.
@@ -348,6 +350,8 @@
F32 = WASM_TYPE_F32,
F64 = WASM_TYPE_F64,
V128 = WASM_TYPE_V128,
+ FUNCREF = WASM_TYPE_FUNCREF,
+ ANYREF = WASM_TYPE_ANYREF,
EXNREF = WASM_TYPE_EXNREF,
};
Index: lld/wasm/WriterUtils.cpp
===================================================================
--- lld/wasm/WriterUtils.cpp
+++ lld/wasm/WriterUtils.cpp
@@ -30,6 +30,10 @@
return "f64";
case ValType::V128:
return "v128";
+ case ValType::FUNCREF:
+ return "funcref";
+ case ValType::ANYREF:
+ return "anyref";
case ValType::EXNREF:
return "exnref";
}
Index: clang/lib/Basic/Targets/WebAssembly.h
===================================================================
--- clang/lib/Basic/Targets/WebAssembly.h
+++ clang/lib/Basic/Targets/WebAssembly.h
@@ -38,6 +38,7 @@
bool HasMutableGlobals = false;
bool HasMultivalue = false;
bool HasTailCall = false;
+ bool HasReferenceTypes = false;
public:
explicit WebAssemblyTargetInfo(const llvm::Triple &T, const TargetOptions &)
[Attachment #4 (text/plain)]
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic