[llvm] c9801db - [WebAssembly][MC] Record limit constraints for table sizes
Andy Wingo via llvm-commits
llvm-commits at lists.llvm.org
Wed Mar 24 01:47:41 PDT 2021
Author: Andy Wingo
Date: 2021-03-24T09:44:22+01:00
New Revision: c9801db2eb4b273ccf4b793784911b4465366f68
URL: https://github.com/llvm/llvm-project/commit/c9801db2eb4b273ccf4b793784911b4465366f68
DIFF: https://github.com/llvm/llvm-project/commit/c9801db2eb4b273ccf4b793784911b4465366f68.diff
LOG: [WebAssembly][MC] Record limit constraints for table sizes
This commit adds a full WasmTableType to MCSymbolWasm, differing from
the current situation (just an ElemType) in that it additionally records
a WasmLimits.
We add support for specifying the limits in .S files also, via the
following syntax variations:
.tabletype SYM, ELEMTYPE
.tabletype SYM, ELEMTYPE, MINSIZE
.tabletype SYM, ELEMTYPE, MINSIZE, MAXSIZE
Depends on D99186.
Differential Revision: https://reviews.llvm.org/D99191
Added:
Modified:
llvm/include/llvm/MC/MCSymbolWasm.h
llvm/lib/MC/WasmObjectWriter.cpp
llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp
llvm/test/MC/WebAssembly/tables.s
Removed:
################################################################################
diff --git a/llvm/include/llvm/MC/MCSymbolWasm.h b/llvm/include/llvm/MC/MCSymbolWasm.h
index 49d57919f6f3..14b3a5d8e941 100644
--- a/llvm/include/llvm/MC/MCSymbolWasm.h
+++ b/llvm/include/llvm/MC/MCSymbolWasm.h
@@ -26,7 +26,7 @@ class MCSymbolWasm : public MCSymbol {
Optional<StringRef> ExportName;
wasm::WasmSignature *Signature = nullptr;
Optional<wasm::WasmGlobalType> GlobalType;
- Optional<wasm::ValType> TableType;
+ Optional<wasm::WasmTableType> TableType;
Optional<wasm::WasmEventType> EventType;
/// An expression describing how to calculate the size of a symbol. If a
@@ -108,7 +108,7 @@ class MCSymbolWasm : public MCSymbol {
bool isFunctionTable() const {
return isTable() && hasTableType() &&
- getTableType() == wasm::ValType::FUNCREF;
+ getTableType().ElemType == wasm::WASM_TYPE_FUNCREF;
}
void setFunctionTable() {
setType(wasm::WASM_SYMBOL_TYPE_TABLE);
@@ -131,11 +131,17 @@ class MCSymbolWasm : public MCSymbol {
void setGlobalType(wasm::WasmGlobalType GT) { GlobalType = GT; }
bool hasTableType() const { return TableType.hasValue(); }
- wasm::ValType getTableType() const {
+ const wasm::WasmTableType &getTableType() const {
assert(hasTableType());
return TableType.getValue();
}
- void setTableType(wasm::ValType TT) { TableType = TT; }
+ void setTableType(wasm::WasmTableType TT) { TableType = TT; }
+ void setTableType(wasm::ValType VT) {
+ // Declare a table with element type VT and no limits (min size 0, no max
+ // size).
+ wasm::WasmLimits Limits = {wasm::WASM_LIMITS_FLAG_NONE, 0, 0};
+ setTableType({uint8_t(VT), Limits});
+ }
const wasm::WasmEventType &getEventType() const {
assert(EventType.hasValue());
diff --git a/llvm/lib/MC/WasmObjectWriter.cpp b/llvm/lib/MC/WasmObjectWriter.cpp
index 2a679ca687d4..0eda8b5a3234 100644
--- a/llvm/lib/MC/WasmObjectWriter.cpp
+++ b/llvm/lib/MC/WasmObjectWriter.cpp
@@ -1338,12 +1338,7 @@ void WasmObjectWriter::prepareImports(
Import.Module = WS.getImportModule();
Import.Field = WS.getImportName();
Import.Kind = wasm::WASM_EXTERNAL_TABLE;
- wasm::ValType ElemType = WS.getTableType();
- Import.Table.ElemType = uint8_t(ElemType);
- // FIXME: Extend table type to include limits? For now we don't specify
- // a min or max which does not place any restrictions on the size of the
- // imported table.
- Import.Table.Limits = {wasm::WASM_LIMITS_FLAG_NONE, 0, 0};
+ Import.Table = WS.getTableType();
Imports.push_back(Import);
assert(WasmIndices.count(&WS) == 0);
WasmIndices[&WS] = NumTableImports++;
@@ -1626,9 +1621,7 @@ uint64_t WasmObjectWriter::writeOneObject(MCAssembler &Asm,
if (WS.isDefined()) {
wasm::WasmTable Table;
Table.Index = NumTableImports + Tables.size();
- Table.Type.ElemType = static_cast<uint8_t>(WS.getTableType());
- // FIXME: Work on custom limits is ongoing
- Table.Type.Limits = {wasm::WASM_LIMITS_FLAG_NONE, 0, 0};
+ Table.Type = WS.getTableType();
assert(WasmIndices.count(&WS) == 0);
WasmIndices[&WS] = Table.Index;
Tables.push_back(Table);
diff --git a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
index c17067351154..d57c7ec17187 100644
--- a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
+++ b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
@@ -169,6 +169,11 @@ struct WebAssemblyOperand : public MCParsedAsmOperand {
}
};
+// Perhaps this should go somewhere common.
+static wasm::WasmLimits DefaultLimits() {
+ return {wasm::WASM_LIMITS_FLAG_NONE, 0, 0};
+}
+
static MCSymbolWasm *GetOrCreateFunctionTableSymbol(MCContext &Ctx,
const StringRef &Name) {
MCSymbolWasm *Sym = cast_or_null<MCSymbolWasm>(Ctx.lookupSymbol(Name));
@@ -487,6 +492,28 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser {
WebAssemblyOperand::IntOp{static_cast<int64_t>(BT)}));
}
+ bool parseLimits(wasm::WasmLimits *Limits) {
+ auto Tok = Lexer.getTok();
+ if (!Tok.is(AsmToken::Integer))
+ return error("Expected integer constant, instead got: ", Tok);
+ int64_t Val = Tok.getIntVal();
+ assert(Val >= 0);
+ Limits->Minimum = Val;
+ Parser.Lex();
+
+ if (isNext(AsmToken::Comma)) {
+ Limits->Flags |= wasm::WASM_LIMITS_FLAG_HAS_MAX;
+ auto Tok = Lexer.getTok();
+ if (!Tok.is(AsmToken::Integer))
+ return error("Expected integer constant, instead got: ", Tok);
+ int64_t Val = Tok.getIntVal();
+ assert(Val >= 0);
+ Limits->Maximum = Val;
+ Parser.Lex();
+ }
+ return false;
+ }
+
bool parseFunctionTableOperand(std::unique_ptr<WebAssemblyOperand> *Op) {
if (STI->checkFeatures("+reference-types")) {
// If the reference-types feature is enabled, there is an explicit table
@@ -819,24 +846,31 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser {
}
if (DirectiveID.getString() == ".tabletype") {
+ // .tabletype SYM, ELEMTYPE[, MINSIZE[, MAXSIZE]]
auto SymName = expectIdent();
if (SymName.empty())
return true;
if (expect(AsmToken::Comma, ","))
return true;
- auto TypeTok = Lexer.getTok();
- auto TypeName = expectIdent();
- if (TypeName.empty())
+
+ auto ElemTypeTok = Lexer.getTok();
+ auto ElemTypeName = expectIdent();
+ if (ElemTypeName.empty())
+ return true;
+ Optional<wasm::ValType> ElemType = parseType(ElemTypeName);
+ if (!ElemType)
+ return error("Unknown type in .tabletype directive: ", ElemTypeTok);
+
+ wasm::WasmLimits Limits = DefaultLimits();
+ if (isNext(AsmToken::Comma) && parseLimits(&Limits))
return true;
- auto Type = parseType(TypeName);
- if (!Type)
- return error("Unknown type in .tabletype directive: ", TypeTok);
// Now that we have the name and table type, we can actually create the
// symbol
auto WasmSym = cast<MCSymbolWasm>(Ctx.getOrCreateSymbol(SymName));
WasmSym->setType(wasm::WASM_SYMBOL_TYPE_TABLE);
- WasmSym->setTableType(Type.getValue());
+ wasm::WasmTableType Type = {uint8_t(ElemType.getValue()), Limits};
+ WasmSym->setTableType(Type);
TOut.emitTableType(WasmSym);
return expect(AsmToken::EndOfStatement, "EOL");
}
diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp
index 652d7a00a63c..3dd961efca42 100644
--- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp
+++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyTargetStreamer.cpp
@@ -79,8 +79,15 @@ void WebAssemblyTargetAsmStreamer::emitGlobalType(const MCSymbolWasm *Sym) {
void WebAssemblyTargetAsmStreamer::emitTableType(const MCSymbolWasm *Sym) {
assert(Sym->isTable());
+ const wasm::WasmTableType &Type = Sym->getTableType();
OS << "\t.tabletype\t" << Sym->getName() << ", "
- << WebAssembly::typeToString(Sym->getTableType());
+ << WebAssembly::typeToString(static_cast<wasm::ValType>(Type.ElemType));
+ bool HasMaximum = Type.Limits.Flags & wasm::WASM_LIMITS_FLAG_HAS_MAX;
+ if (Type.Limits.Minimum != 0 || HasMaximum) {
+ OS << ", " << Type.Limits.Minimum;
+ if (HasMaximum)
+ OS << ", " << Type.Limits.Maximum;
+ }
OS << '\n';
}
diff --git a/llvm/test/MC/WebAssembly/tables.s b/llvm/test/MC/WebAssembly/tables.s
index b1bf1a988646..a682a738445b 100644
--- a/llvm/test/MC/WebAssembly/tables.s
+++ b/llvm/test/MC/WebAssembly/tables.s
@@ -16,9 +16,9 @@ bar:
.tabletype bar, funcref
table1:
- .tabletype table1, funcref
+ .tabletype table1, funcref, 42
table2:
- .tabletype table2, funcref
+ .tabletype table2, funcref, 42, 100
# Table instructions
@@ -132,11 +132,13 @@ table_fill:
# BIN-NEXT: - Index: 2
# BIN-NEXT: ElemType: FUNCREF
# BIN-NEXT: Limits:
-# BIN-NEXT: Minimum: 0x0
+# BIN-NEXT: Minimum: 0x2A
# BIN-NEXT: - Index: 3
# BIN-NEXT: ElemType: FUNCREF
# BIN-NEXT: Limits:
-# BIN-NEXT: Minimum: 0x0
+# BIN-NEXT: Flags: [ HAS_MAX ]
+# BIN-NEXT: Minimum: 0x2A
+# BIN-NEXT: Maximum: 0x64
# BIN: - Type: CODE
# BIN-NEXT: Relocations:
More information about the llvm-commits
mailing list