Skip to content

Commit b8f33cd

Browse files
committed
[WebAssembly] Define a new "Trail1" CPU
First, define some new target features. These are subsets of existing features that reflect implemenetation concerns: - "call-indirect-overlong" - implied by "reference-types"; just the overlong encoding for the `call_indirect` immediate, and not the actual reference types. - "bulk-memory-opt" - implied by "bulk-memory": just `memory.copy` and `memory.fill`, and not the other instructions in the bulk-memory proposal. Next, define a new target CPU, "Trail1", which enables mutable-globals, bulk-memory-opt, multivalue, sign-ext, nontrapping-fptoint, extended-const, and call-indirect-overlong. Unlike the default "generic" CPU, "trail1" is meant to be frozen, and followed up by "trail2" and so on when new features are desired.
1 parent 14705a9 commit b8f33cd

18 files changed

+110
-33
lines changed

clang/lib/Basic/Targets/WebAssembly.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ bool WebAssemblyTargetInfo::hasFeature(StringRef Feature) const {
4747
return llvm::StringSwitch<bool>(Feature)
4848
.Case("atomics", HasAtomics)
4949
.Case("bulk-memory", HasBulkMemory)
50+
.Case("bulk-memory-opt", HasBulkMemoryOpt)
5051
.Case("exception-handling", HasExceptionHandling)
5152
.Case("extended-const", HasExtendedConst)
5253
.Case("fp16", HasFP16)
@@ -55,6 +56,7 @@ bool WebAssemblyTargetInfo::hasFeature(StringRef Feature) const {
5556
.Case("mutable-globals", HasMutableGlobals)
5657
.Case("nontrapping-fptoint", HasNontrappingFPToInt)
5758
.Case("reference-types", HasReferenceTypes)
59+
.Case("call-indirect-overlong", HasCallIndirectOverlong)
5860
.Case("relaxed-simd", SIMDLevel >= RelaxedSIMD)
5961
.Case("sign-ext", HasSignExt)
6062
.Case("simd128", SIMDLevel >= SIMD128)
@@ -78,6 +80,8 @@ void WebAssemblyTargetInfo::getTargetDefines(const LangOptions &Opts,
7880
Builder.defineMacro("__wasm_atomics__");
7981
if (HasBulkMemory)
8082
Builder.defineMacro("__wasm_bulk_memory__");
83+
if (HasBulkMemoryOpt)
84+
Builder.defineMacro("__wasm_bulk_memory_opt__");
8185
if (HasExceptionHandling)
8286
Builder.defineMacro("__wasm_exception_handling__");
8387
if (HasExtendedConst)
@@ -154,12 +158,23 @@ bool WebAssemblyTargetInfo::initFeatureMap(
154158
Features["multivalue"] = true;
155159
Features["mutable-globals"] = true;
156160
Features["reference-types"] = true;
161+
Features["call-indirect-overlong"] = true;
157162
Features["sign-ext"] = true;
158163
};
164+
auto addTrail1Features = [&]() {
165+
Features["multivalue"] = true;
166+
Features["mutable-globals"] = true;
167+
Features["call-indirect-overlong"] = true;
168+
Features["sign-ext"] = true;
169+
Features["bulk-memory-opt"] = true;
170+
Features["nontrapping-fptoint"] = true;
171+
Features["extended-const"] = true;
172+
};
159173
auto addBleedingEdgeFeatures = [&]() {
160174
addGenericFeatures();
161175
Features["atomics"] = true;
162176
Features["bulk-memory"] = true;
177+
Features["bulk-memory-opt"] = true;
163178
Features["exception-handling"] = true;
164179
Features["extended-const"] = true;
165180
Features["fp16"] = true;
@@ -170,6 +185,8 @@ bool WebAssemblyTargetInfo::initFeatureMap(
170185
};
171186
if (CPU == "generic") {
172187
addGenericFeatures();
188+
} else if (CPU == "trail1") {
189+
addTrail1Features();
173190
} else if (CPU == "bleeding-edge") {
174191
addBleedingEdgeFeatures();
175192
}
@@ -196,6 +213,14 @@ bool WebAssemblyTargetInfo::handleTargetFeatures(
196213
HasBulkMemory = false;
197214
continue;
198215
}
216+
if (Feature == "+bulk-memory-opt") {
217+
HasBulkMemoryOpt = true;
218+
continue;
219+
}
220+
if (Feature == "-bulk-memory-opt") {
221+
HasBulkMemoryOpt = false;
222+
continue;
223+
}
199224
if (Feature == "+exception-handling") {
200225
HasExceptionHandling = true;
201226
continue;
@@ -261,6 +286,14 @@ bool WebAssemblyTargetInfo::handleTargetFeatures(
261286
HasReferenceTypes = false;
262287
continue;
263288
}
289+
if (Feature == "+call-indirect-overlong") {
290+
HasCallIndirectOverlong = true;
291+
continue;
292+
}
293+
if (Feature == "-call-indirect-overlong") {
294+
HasCallIndirectOverlong = false;
295+
continue;
296+
}
264297
if (Feature == "+relaxed-simd") {
265298
SIMDLevel = std::max(SIMDLevel, RelaxedSIMD);
266299
continue;
@@ -298,6 +331,18 @@ bool WebAssemblyTargetInfo::handleTargetFeatures(
298331
<< Feature << "-target-feature";
299332
return false;
300333
}
334+
335+
// The reference-types feature included the change to `call_indirect`
336+
// encodings to support overlong immediates.
337+
if (HasReferenceTypes) {
338+
HasCallIndirectOverlong = true;
339+
}
340+
341+
// bulk-memory-opt is a subset of bulk-memory.
342+
if (HasBulkMemory) {
343+
HasBulkMemoryOpt = true;
344+
}
345+
301346
return true;
302347
}
303348

clang/lib/Basic/Targets/WebAssembly.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ class LLVM_LIBRARY_VISIBILITY WebAssemblyTargetInfo : public TargetInfo {
5555

5656
bool HasAtomics = false;
5757
bool HasBulkMemory = false;
58+
bool HasBulkMemoryOpt = false;
5859
bool HasExceptionHandling = false;
5960
bool HasExtendedConst = false;
6061
bool HasFP16 = false;
@@ -63,6 +64,7 @@ class LLVM_LIBRARY_VISIBILITY WebAssemblyTargetInfo : public TargetInfo {
6364
bool HasMutableGlobals = false;
6465
bool HasNontrappingFPToInt = false;
6566
bool HasReferenceTypes = false;
67+
bool HasCallIndirectOverlong = false;
6668
bool HasSignExt = false;
6769
bool HasTailCall = false;
6870

lld/test/wasm/compress-relocs.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
; RUN: llc -filetype=obj %s -o %t.o
2-
; RUN: llvm-mc -mattr=+reference-types -filetype=obj -triple=wasm32-unknown-unknown %p/Inputs/call-indirect.s -o %t2.o
2+
; RUN: llvm-mc -mattr=+call-indirect-overlong -filetype=obj -triple=wasm32-unknown-unknown %p/Inputs/call-indirect.s -o %t2.o
33
; RUN: wasm-ld --export-dynamic -o %t.wasm %t2.o %t.o
44
; RUN: obj2yaml %t.wasm | FileCheck %s
55
; RUN: wasm-ld --export-dynamic -O2 -o %t-opt.wasm %t2.o %t.o

lld/test/wasm/import-table-explicit.s

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# RUN: llvm-mc -mattr=+reference-types -filetype=obj -triple=wasm32-unknown-unknown %s -o %t.o
1+
# RUN: llvm-mc -mattr=+call-indirect-overlong -filetype=obj -triple=wasm32-unknown-unknown %s -o %t.o
22
# RUN: wasm-ld --import-table -o %t.wasm %t.o
33
# RUN: obj2yaml %t.wasm | FileCheck %s
44

lld/test/wasm/invalid-mvp-table-use.s

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown -o %t.o %s
22
#
33
# If any table is defined or declared besides the __indirect_function_table,
4-
# the compilation unit should be compiled with -mattr=+reference-types,
4+
# the compilation unit should be compiled with -mattr=+call-indirect-overlong,
55
# causing symbol table entries to be emitted for all tables.
66
# RUN: not wasm-ld --no-entry %t.o -o %t.wasm 2>&1 | FileCheck -check-prefix=CHECK-ERR %s
77

lld/wasm/InputFiles.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -247,10 +247,11 @@ static void setRelocs(const std::vector<T *> &chunks,
247247
}
248248
}
249249

250-
// An object file can have two approaches to tables. With the reference-types
251-
// feature enabled, input files that define or use tables declare the tables
252-
// using symbols, and record each use with a relocation. This way when the
253-
// linker combines inputs, it can collate the tables used by the inputs,
250+
// An object file can have two approaches to tables. With the
251+
// call-indirect-overlong feature enabled (explicitly, or implied by the
252+
// reference-types feature), input files that define or use tables declare the
253+
// tables using symbols, and record each use with a relocation. This way when
254+
// the linker combines inputs, it can collate the tables used by the inputs,
254255
// assigning them distinct table numbers, and renumber all the uses as
255256
// appropriate. At the same time, the linker has special logic to build the
256257
// indirect function table if it is needed.
@@ -276,7 +277,7 @@ void ObjFile::addLegacyIndirectFunctionTableIfNeeded(
276277
return;
277278

278279
// It's possible for an input to define tables and also use the indirect
279-
// function table, but forget to compile with -mattr=+reference-types.
280+
// function table, but forget to compile with -mattr=+call-indirect-overlong.
280281
// For these newer files, we require symbols for all tables, and
281282
// relocations for all of their uses.
282283
if (tableSymbolCount != 0) {

lld/wasm/SyntheticSections.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,7 @@ void TableSection::addTable(InputTable *table) {
326326
// to assign table number 0 to the indirect function table.
327327
for (const auto *culprit : out.importSec->importedSymbols) {
328328
if (isa<UndefinedTable>(culprit)) {
329-
error("object file not built with 'reference-types' feature "
329+
error("object file not built with 'call-indirect-overlong' feature "
330330
"conflicts with import of table " +
331331
culprit->getName() + " by file " +
332332
toString(culprit->getFile()));

llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser {
292292

293293
DefaultFunctionTable = getOrCreateFunctionTableSymbol(
294294
getContext(), "__indirect_function_table", Is64);
295-
if (!STI->checkFeatures("+reference-types"))
295+
if (!STI->checkFeatures("+call-indirect-overlong"))
296296
DefaultFunctionTable->setOmitFromLinkingSection();
297297
}
298298

@@ -532,11 +532,11 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser {
532532
}
533533

534534
bool parseFunctionTableOperand(std::unique_ptr<WebAssemblyOperand> *Op) {
535-
if (STI->checkFeatures("+reference-types")) {
536-
// If the reference-types feature is enabled, there is an explicit table
537-
// operand. To allow the same assembly to be compiled with or without
538-
// reference types, we allow the operand to be omitted, in which case we
539-
// default to __indirect_function_table.
535+
if (STI->checkFeatures("+call-indirect-overlong")) {
536+
// If the call-indirect-overlong feature is enabled, there is an explicit
537+
// table operand. To allow the same assembly to be compiled with or
538+
// without call-indirect overlong, we allow the operand to be omitted, in
539+
// which case we default to __indirect_function_table.
540540
auto &Tok = Lexer.getTok();
541541
if (Tok.is(AsmToken::Identifier)) {
542542
auto *Sym =

llvm/lib/Target/WebAssembly/WebAssembly.td

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ def FeatureBulkMemory :
2929
SubtargetFeature<"bulk-memory", "HasBulkMemory", "true",
3030
"Enable bulk memory operations">;
3131

32+
def FeatureBulkMemoryOpt :
33+
SubtargetFeature<"bulk-memory-opt", "HasBulkMemoryOpt", "true",
34+
"Enable bulk memory optimization operations">;
35+
3236
def FeatureExceptionHandling :
3337
SubtargetFeature<"exception-handling", "HasExceptionHandling", "true",
3438
"Enable Wasm exception handling">;
@@ -63,6 +67,10 @@ def FeatureReferenceTypes :
6367
SubtargetFeature<"reference-types", "HasReferenceTypes", "true",
6468
"Enable reference types">;
6569

70+
def FeatureCallIndirectOverlong :
71+
SubtargetFeature<"call-indirect-overlong", "HasCallIndirectOverlong", "true",
72+
"Enable overlong encoding for call_indirect immediates">;
73+
6674
def FeatureRelaxedSIMD :
6775
SubtargetFeature<"relaxed-simd", "SIMDLevel", "RelaxedSIMD",
6876
"Enable relaxed-simd instructions">;
@@ -113,6 +121,12 @@ def : ProcessorModel<"generic", NoSchedModel,
113121
[FeatureMultivalue, FeatureMutableGlobals,
114122
FeatureReferenceTypes, FeatureSignExt]>;
115123

124+
def : ProcessorModel<"trail1", NoSchedModel,
125+
[FeatureMultivalue, FeatureMutableGlobals,
126+
FeatureCallIndirectOverlong, FeatureSignExt,
127+
FeatureBulkMemoryOpt, FeatureNontrappingFPToInt,
128+
FeatureExtendedConst]>;
129+
116130
// Latest and greatest experimental version of WebAssembly. Bugs included!
117131
def : ProcessorModel<"bleeding-edge", NoSchedModel,
118132
[FeatureAtomics, FeatureBulkMemory,

llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -899,7 +899,7 @@ bool WebAssemblyFastISel::selectCall(const Instruction *I) {
899899
// The table into which this call_indirect indexes.
900900
MCSymbolWasm *Table = WebAssembly::getOrCreateFunctionTableSymbol(
901901
MF->getContext(), Subtarget);
902-
if (Subtarget->hasReferenceTypes()) {
902+
if (Subtarget->hasCallIndirectOverlong()) {
903903
MIB.addSym(Table);
904904
} else {
905905
// Otherwise for the MVP there is at most one table whose number is 0, but

0 commit comments

Comments
 (0)