Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add bulk-memory-opt feature and ignore call-indirect-overlong #7139

Merged
merged 13 commits into from
Dec 6, 2024
4 changes: 2 additions & 2 deletions src/passes/LLVMMemoryCopyFillLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ struct LLVMMemoryCopyFillLowering
}

void run(Module* module) override {
if (!module->features.hasBulkMemory()) {
if (!module->features.hasBulkMemoryOpt()) {
return;
}
if (module->features.hasMemory64() || module->features.hasMultiMemory()) {
Expand Down Expand Up @@ -108,7 +108,7 @@ struct LLVMMemoryCopyFillLowering
} else {
module->removeFunction(memFillFuncName);
}
module->features.disable(FeatureSet::BulkMemory);
module->features.setBulkMemoryOpt(false);
}

void createMemoryCopyFunc(Module* module) {
Expand Down
4 changes: 2 additions & 2 deletions src/passes/OptimizeInstructions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1275,7 +1275,7 @@ struct OptimizeInstructions
if (curr->type == Type::unreachable) {
return;
}
assert(getModule()->features.hasBulkMemory());
assert(getModule()->features.hasBulkMemoryOpt());
if (auto* ret = optimizeMemoryCopy(curr)) {
return replaceCurrent(ret);
}
Expand All @@ -1285,7 +1285,7 @@ struct OptimizeInstructions
if (curr->type == Type::unreachable) {
return;
}
assert(getModule()->features.hasBulkMemory());
assert(getModule()->features.hasBulkMemoryOpt());
if (auto* ret = optimizeMemoryFill(curr)) {
return replaceCurrent(ret);
}
Expand Down
26 changes: 18 additions & 8 deletions src/tools/tool-options.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,15 @@ struct ToolOptions : public Options {
.addFeature(FeatureSet::MutableGlobals, "mutable globals")
.addFeature(FeatureSet::TruncSat, "nontrapping float-to-int operations")
.addFeature(FeatureSet::SIMD, "SIMD operations and types")
.addFeature(FeatureSet::BulkMemory, "bulk memory operations")
.addFeature(FeatureSet::BulkMemory,
"bulk memory operations",
FeatureSet(FeatureSet::BulkMemoryOpt))
.addFeature(FeatureSet::BulkMemoryOpt,
"memory.copy and memory.fill",
FeatureSet::None,
FeatureSet(FeatureSet::BulkMemoryOpt))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
FeatureSet(FeatureSet::BulkMemoryOpt))
FeatureSet(FeatureSet::BulkMemory))

Is this the intended behavior?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Er yes, done.

.addFeature(FeatureSet::CallIndirectOverlong,
"(ignored for compatibility)")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should write a little more here so the help message isn't "Enable (ignored for compatibility)" 😆

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, yeah it's a little unfortunate that the "Enable" and "Disable" bits are generated separately... how about "Enable call-indirect-overlong (ignored for compatibility as this has no effect on Binaryen)" with the idea that call-indirect-overlong can now be looked up in tool-conventions along with the rest?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sgtm 👍

.addFeature(FeatureSet::ExceptionHandling,
"exception handling operations")
.addFeature(FeatureSet::TailCall, "tail call operations")
Expand Down Expand Up @@ -200,26 +208,28 @@ struct ToolOptions : public Options {
}

ToolOptions& addFeature(FeatureSet::Feature feature,
const std::string& description) {
const std::string& description,
FeatureSet impliedEnable = FeatureSet::None,
FeatureSet impliedDisable = FeatureSet::None) {
(*this)
.add(std::string("--enable-") + FeatureSet::toString(feature),
"",
std::string("Enable ") + description,
ToolOptionsCategory,
Arguments::Zero,
[this, feature](Options*, const std::string&) {
enabledFeatures.set(feature, true);
disabledFeatures.set(feature, false);
[this, feature, impliedEnable](Options*, const std::string&) {
enabledFeatures.set(feature | impliedEnable, true);
disabledFeatures.set(feature | impliedEnable, false);
})

.add(std::string("--disable-") + FeatureSet::toString(feature),
"",
std::string("Disable ") + description,
ToolOptionsCategory,
Arguments::Zero,
[this, feature](Options*, const std::string&) {
enabledFeatures.set(feature, false);
disabledFeatures.set(feature, true);
[this, feature, impliedDisable](Options*, const std::string&) {
enabledFeatures.set(feature | impliedDisable, false);
disabledFeatures.set(feature | impliedDisable, true);
});
return *this;
}
Expand Down
2 changes: 2 additions & 0 deletions src/wasm-binary.h
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,8 @@ extern const char* MultiMemoryFeature;
extern const char* TypedContinuationsFeature;
extern const char* SharedEverythingFeature;
extern const char* FP16Feature;
extern const char* BulkMemoryOptFeature;
extern const char* CallIndirectOverlongFeature;

enum Subsection {
NameModule = 0,
Expand Down
19 changes: 18 additions & 1 deletion src/wasm-features.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ namespace wasm {

struct FeatureSet {
enum Feature : uint32_t {
// These features are intended to those documented in tool-conventions:
// https://github.com/WebAssembly/tool-conventions/blob/main/Linking.md#target-features-section
None = 0,
Atomics = 1 << 0,
MutableGlobals = 1 << 1,
Expand All @@ -47,11 +49,16 @@ struct FeatureSet {
TypedContinuations = 1 << 16,
SharedEverything = 1 << 17,
FP16 = 1 << 18,
BulkMemoryOpt = 1 << 19, // Just the memory.copy and fill operations
// This features is a no-op for compatibility. Having it in this list means
// that we can automatically generate tool flags that set it, but otherwise
// it does nothing. Binaryen always accepts LEB call-indirect encodings.
CallIndirectOverlong = 1 << 20,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please link to the tool-conventions doc that explains what these are, as all the other features are easily found on the main wasm website, but not these.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually these are missing from the tool-conventions doc, we should fix that.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MVP = None,
// Keep in sync with llvm default features:
// https://github.com/llvm/llvm-project/blob/c7576cb89d6c95f03968076e902d3adfd1996577/clang/lib/Basic/Targets/WebAssembly.cpp#L150-L153
Default = SignExt | MutableGlobals,
All = (1 << 19) - 1,
All = (1 << 21) - 1,
};

static std::string toString(Feature f) {
Expand Down Expand Up @@ -94,6 +101,10 @@ struct FeatureSet {
return "shared-everything";
case FP16:
return "fp16";
case BulkMemoryOpt:
return "bulk-memory-opt";
case CallIndirectOverlong:
return "call-indirect-overlong";
default:
WASM_UNREACHABLE("unexpected feature");
}
Expand Down Expand Up @@ -145,6 +156,11 @@ struct FeatureSet {
return (features & SharedEverything) != 0;
}
bool hasFP16() const { return (features & FP16) != 0; }
bool hasBulkMemoryOpt() const {
bool has = (features & BulkMemoryOpt) != 0;
assert(has || !hasBulkMemory());
return has;
}
bool hasAll() const { return (features & All) != 0; }

void set(FeatureSet f, bool v = true) {
Expand All @@ -169,6 +185,7 @@ struct FeatureSet {
void setTypedContinuations(bool v = true) { set(TypedContinuations, v); }
void setSharedEverything(bool v = true) { set(SharedEverything, v); }
void setFP16(bool v = true) { set(FP16, v); }
void setBulkMemoryOpt(bool v = true) { set(BulkMemoryOpt, v); }
void setMVP() { features = MVP; }
void setAll() { features = All; }

Expand Down
10 changes: 10 additions & 0 deletions src/wasm/wasm-binary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1354,6 +1354,10 @@ void WasmBinaryWriter::writeFeaturesSection() {
return BinaryConsts::CustomSections::SharedEverythingFeature;
case FeatureSet::FP16:
return BinaryConsts::CustomSections::FP16Feature;
case FeatureSet::BulkMemoryOpt:
return BinaryConsts::CustomSections::BulkMemoryOptFeature;
case FeatureSet::CallIndirectOverlong:
return BinaryConsts::CustomSections::CallIndirectOverlongFeature;
case FeatureSet::None:
case FeatureSet::Default:
case FeatureSet::All:
Expand Down Expand Up @@ -4795,6 +4799,12 @@ void WasmBinaryReader::readFeatures(size_t payloadLen) {
feature = FeatureSet::Atomics;
} else if (name == BinaryConsts::CustomSections::BulkMemoryFeature) {
feature = FeatureSet::BulkMemory;
if (used) {
// For backward compatibility, enable this dependent feature.
feature |= FeatureSet::BulkMemoryOpt;
}
} else if (name == BinaryConsts::CustomSections::BulkMemoryOptFeature) {
feature = FeatureSet::BulkMemoryOpt;
} else if (name == BinaryConsts::CustomSections::ExceptionHandlingFeature) {
feature = FeatureSet::ExceptionHandling;
} else if (name == BinaryConsts::CustomSections::MutableGlobalsFeature) {
Expand Down
12 changes: 6 additions & 6 deletions src/wasm/wasm-validator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1526,10 +1526,10 @@ void FunctionValidator::visitDataDrop(DataDrop* curr) {
}

void FunctionValidator::visitMemoryCopy(MemoryCopy* curr) {
shouldBeTrue(
getModule()->features.hasBulkMemory(),
curr,
"Bulk memory operations require bulk memory [--enable-bulk-memory]");
shouldBeTrue(getModule()->features.hasBulkMemoryOpt(),
curr,
"memory.copy operations require bulk memory operations "
"[--enable-bulk-memory-opt]");
shouldBeEqualOrFirstIsUnreachable(
curr->type, Type(Type::none), curr, "memory.copy must have type none");
auto* destMemory = getModule()->getMemoryOrNull(curr->destMemory);
Expand Down Expand Up @@ -1561,9 +1561,9 @@ void FunctionValidator::visitMemoryCopy(MemoryCopy* curr) {
void FunctionValidator::visitMemoryFill(MemoryFill* curr) {
auto* memory = getModule()->getMemoryOrNull(curr->memory);
shouldBeTrue(
getModule()->features.hasBulkMemory(),
getModule()->features.hasBulkMemoryOpt(),
curr,
"Bulk memory operations require bulk memory [--enable-bulk-memory]");
"memory.fill operations require bulk memory [--enable-bulk-memory-opt]");
shouldBeEqualOrFirstIsUnreachable(
curr->type, Type(Type::none), curr, "memory.fill must have type none");
shouldBeEqualOrFirstIsUnreachable(
Expand Down
2 changes: 2 additions & 0 deletions src/wasm/wasm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ const char* MultiMemoryFeature = "multimemory";
const char* TypedContinuationsFeature = "typed-continuations";
const char* SharedEverythingFeature = "shared-everything";
const char* FP16Feature = "fp16";
const char* BulkMemoryOptFeature = "bulk-memory-opt";
const char* CallIndirectOverlongFeature = "call-indirect-overlong";
} // namespace CustomSections
} // namespace BinaryConsts

Expand Down
2 changes: 1 addition & 1 deletion test/binaryen.js/kitchen-sink.js.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Features.RelaxedSIMD: 4096
Features.ExtendedConst: 8192
Features.Strings: 16384
Features.MultiMemory: 32768
Features.All: 524287
Features.All: 2097151
InvalidId: 0
BlockId: 1
IfId: 2
Expand Down
2 changes: 1 addition & 1 deletion test/example/c-api-kitchen-sink.txt
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ BinaryenFeatureMemory64: 2048
BinaryenFeatureRelaxedSIMD: 4096
BinaryenFeatureExtendedConst: 8192
BinaryenFeatureStrings: 16384
BinaryenFeatureAll: 524287
BinaryenFeatureAll: 2097151
(f32.neg
(f32.const -33.61199951171875)
)
Expand Down
8 changes: 8 additions & 0 deletions test/lit/help/wasm-as.test
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,14 @@
;; CHECK-NEXT:
;; CHECK-NEXT: --disable-bulk-memory Disable bulk memory operations
;; CHECK-NEXT:
;; CHECK-NEXT: --enable-bulk-memory-opt Enable memory.copy and memory.fill
;; CHECK-NEXT:
;; CHECK-NEXT: --disable-bulk-memory-opt Disable memory.copy and memory.fill
;; CHECK-NEXT:
;; CHECK-NEXT: --enable-call-indirect-overlong Enable (ignored for compatibility)
;; CHECK-NEXT:
;; CHECK-NEXT: --disable-call-indirect-overlong Disable (ignored for compatibility)
;; CHECK-NEXT:
;; CHECK-NEXT: --enable-exception-handling Enable exception handling operations
;; CHECK-NEXT:
;; CHECK-NEXT: --disable-exception-handling Disable exception handling operations
Expand Down
8 changes: 8 additions & 0 deletions test/lit/help/wasm-ctor-eval.test
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,14 @@
;; CHECK-NEXT:
;; CHECK-NEXT: --disable-bulk-memory Disable bulk memory operations
;; CHECK-NEXT:
;; CHECK-NEXT: --enable-bulk-memory-opt Enable memory.copy and memory.fill
;; CHECK-NEXT:
;; CHECK-NEXT: --disable-bulk-memory-opt Disable memory.copy and memory.fill
;; CHECK-NEXT:
;; CHECK-NEXT: --enable-call-indirect-overlong Enable (ignored for compatibility)
;; CHECK-NEXT:
;; CHECK-NEXT: --disable-call-indirect-overlong Disable (ignored for compatibility)
;; CHECK-NEXT:
;; CHECK-NEXT: --enable-exception-handling Enable exception handling operations
;; CHECK-NEXT:
;; CHECK-NEXT: --disable-exception-handling Disable exception handling operations
Expand Down
8 changes: 8 additions & 0 deletions test/lit/help/wasm-dis.test
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,14 @@
;; CHECK-NEXT:
;; CHECK-NEXT: --disable-bulk-memory Disable bulk memory operations
;; CHECK-NEXT:
;; CHECK-NEXT: --enable-bulk-memory-opt Enable memory.copy and memory.fill
;; CHECK-NEXT:
;; CHECK-NEXT: --disable-bulk-memory-opt Disable memory.copy and memory.fill
;; CHECK-NEXT:
;; CHECK-NEXT: --enable-call-indirect-overlong Enable (ignored for compatibility)
;; CHECK-NEXT:
;; CHECK-NEXT: --disable-call-indirect-overlong Disable (ignored for compatibility)
;; CHECK-NEXT:
;; CHECK-NEXT: --enable-exception-handling Enable exception handling operations
;; CHECK-NEXT:
;; CHECK-NEXT: --disable-exception-handling Disable exception handling operations
Expand Down
8 changes: 8 additions & 0 deletions test/lit/help/wasm-emscripten-finalize.test
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,14 @@
;; CHECK-NEXT:
;; CHECK-NEXT: --disable-bulk-memory Disable bulk memory operations
;; CHECK-NEXT:
;; CHECK-NEXT: --enable-bulk-memory-opt Enable memory.copy and memory.fill
;; CHECK-NEXT:
;; CHECK-NEXT: --disable-bulk-memory-opt Disable memory.copy and memory.fill
;; CHECK-NEXT:
;; CHECK-NEXT: --enable-call-indirect-overlong Enable (ignored for compatibility)
;; CHECK-NEXT:
;; CHECK-NEXT: --disable-call-indirect-overlong Disable (ignored for compatibility)
;; CHECK-NEXT:
;; CHECK-NEXT: --enable-exception-handling Enable exception handling operations
;; CHECK-NEXT:
;; CHECK-NEXT: --disable-exception-handling Disable exception handling operations
Expand Down
8 changes: 8 additions & 0 deletions test/lit/help/wasm-merge.test
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,14 @@
;; CHECK-NEXT:
;; CHECK-NEXT: --disable-bulk-memory Disable bulk memory operations
;; CHECK-NEXT:
;; CHECK-NEXT: --enable-bulk-memory-opt Enable memory.copy and memory.fill
;; CHECK-NEXT:
;; CHECK-NEXT: --disable-bulk-memory-opt Disable memory.copy and memory.fill
;; CHECK-NEXT:
;; CHECK-NEXT: --enable-call-indirect-overlong Enable (ignored for compatibility)
;; CHECK-NEXT:
;; CHECK-NEXT: --disable-call-indirect-overlong Disable (ignored for compatibility)
;; CHECK-NEXT:
;; CHECK-NEXT: --enable-exception-handling Enable exception handling operations
;; CHECK-NEXT:
;; CHECK-NEXT: --disable-exception-handling Disable exception handling operations
Expand Down
12 changes: 12 additions & 0 deletions test/lit/help/wasm-metadce.test
Original file line number Diff line number Diff line change
Expand Up @@ -699,6 +699,18 @@
;; CHECK-NEXT:
;; CHECK-NEXT: --disable-bulk-memory Disable bulk memory operations
;; CHECK-NEXT:
;; CHECK-NEXT: --enable-bulk-memory-opt Enable memory.copy and
;; CHECK-NEXT: memory.fill
;; CHECK-NEXT:
;; CHECK-NEXT: --disable-bulk-memory-opt Disable memory.copy and
;; CHECK-NEXT: memory.fill
;; CHECK-NEXT:
;; CHECK-NEXT: --enable-call-indirect-overlong Enable (ignored for
;; CHECK-NEXT: compatibility)
;; CHECK-NEXT:
;; CHECK-NEXT: --disable-call-indirect-overlong Disable (ignored for
;; CHECK-NEXT: compatibility)
;; CHECK-NEXT:
;; CHECK-NEXT: --enable-exception-handling Enable exception handling
;; CHECK-NEXT: operations
;; CHECK-NEXT:
Expand Down
12 changes: 12 additions & 0 deletions test/lit/help/wasm-opt.test
Original file line number Diff line number Diff line change
Expand Up @@ -708,6 +708,18 @@
;; CHECK-NEXT:
;; CHECK-NEXT: --disable-bulk-memory Disable bulk memory operations
;; CHECK-NEXT:
;; CHECK-NEXT: --enable-bulk-memory-opt Enable memory.copy and
;; CHECK-NEXT: memory.fill
;; CHECK-NEXT:
;; CHECK-NEXT: --disable-bulk-memory-opt Disable memory.copy and
;; CHECK-NEXT: memory.fill
;; CHECK-NEXT:
;; CHECK-NEXT: --enable-call-indirect-overlong Enable (ignored for
;; CHECK-NEXT: compatibility)
;; CHECK-NEXT:
;; CHECK-NEXT: --disable-call-indirect-overlong Disable (ignored for
;; CHECK-NEXT: compatibility)
;; CHECK-NEXT:
;; CHECK-NEXT: --enable-exception-handling Enable exception handling
;; CHECK-NEXT: operations
;; CHECK-NEXT:
Expand Down
8 changes: 8 additions & 0 deletions test/lit/help/wasm-reduce.test
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,14 @@
;; CHECK-NEXT:
;; CHECK-NEXT: --disable-bulk-memory Disable bulk memory operations
;; CHECK-NEXT:
;; CHECK-NEXT: --enable-bulk-memory-opt Enable memory.copy and memory.fill
;; CHECK-NEXT:
;; CHECK-NEXT: --disable-bulk-memory-opt Disable memory.copy and memory.fill
;; CHECK-NEXT:
;; CHECK-NEXT: --enable-call-indirect-overlong Enable (ignored for compatibility)
;; CHECK-NEXT:
;; CHECK-NEXT: --disable-call-indirect-overlong Disable (ignored for compatibility)
;; CHECK-NEXT:
;; CHECK-NEXT: --enable-exception-handling Enable exception handling operations
;; CHECK-NEXT:
;; CHECK-NEXT: --disable-exception-handling Disable exception handling operations
Expand Down
8 changes: 8 additions & 0 deletions test/lit/help/wasm-split.test
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,14 @@
;; CHECK-NEXT:
;; CHECK-NEXT: --disable-bulk-memory Disable bulk memory operations
;; CHECK-NEXT:
;; CHECK-NEXT: --enable-bulk-memory-opt Enable memory.copy and memory.fill
;; CHECK-NEXT:
;; CHECK-NEXT: --disable-bulk-memory-opt Disable memory.copy and memory.fill
;; CHECK-NEXT:
;; CHECK-NEXT: --enable-call-indirect-overlong Enable (ignored for compatibility)
;; CHECK-NEXT:
;; CHECK-NEXT: --disable-call-indirect-overlong Disable (ignored for compatibility)
;; CHECK-NEXT:
;; CHECK-NEXT: --enable-exception-handling Enable exception handling operations
;; CHECK-NEXT:
;; CHECK-NEXT: --disable-exception-handling Disable exception handling operations
Expand Down
12 changes: 12 additions & 0 deletions test/lit/help/wasm2js.test
Original file line number Diff line number Diff line change
Expand Up @@ -662,6 +662,18 @@
;; CHECK-NEXT:
;; CHECK-NEXT: --disable-bulk-memory Disable bulk memory operations
;; CHECK-NEXT:
;; CHECK-NEXT: --enable-bulk-memory-opt Enable memory.copy and
;; CHECK-NEXT: memory.fill
;; CHECK-NEXT:
;; CHECK-NEXT: --disable-bulk-memory-opt Disable memory.copy and
;; CHECK-NEXT: memory.fill
;; CHECK-NEXT:
;; CHECK-NEXT: --enable-call-indirect-overlong Enable (ignored for
;; CHECK-NEXT: compatibility)
;; CHECK-NEXT:
;; CHECK-NEXT: --disable-call-indirect-overlong Disable (ignored for
;; CHECK-NEXT: compatibility)
;; CHECK-NEXT:
;; CHECK-NEXT: --enable-exception-handling Enable exception handling
;; CHECK-NEXT: operations
;; CHECK-NEXT:
Expand Down
Loading
Loading