Skip to content

Commit 613ea88

Browse files
authored
Allow customizing the limit in LimitSegments (#7285)
The custom limit can be passed by e.g. --limit-segments --pass-arg=limit-segments@1024 Fixes #7229
1 parent 3339c1f commit 613ea88

File tree

3 files changed

+41
-9
lines changed

3 files changed

+41
-9
lines changed

src/ir/memory-utils.h

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,14 @@ inline void ensureExists(Module* wasm) {
4646
// Try to merge segments until they fit into web limitations.
4747
// Return true if successful.
4848
// Does not yet support multimemory
49-
inline bool ensureLimitedSegments(Module& module) {
49+
inline bool
50+
ensureLimitedSegments(Module& module,
51+
Index maxDataSegments = WebLimitations::MaxDataSegments) {
5052
if (module.memories.size() > 1) {
5153
return false;
5254
}
5355
auto& dataSegments = module.dataSegments;
54-
if (dataSegments.size() <= WebLimitations::MaxDataSegments) {
56+
if (dataSegments.size() <= maxDataSegments) {
5557
return true;
5658
}
5759

@@ -86,19 +88,19 @@ inline bool ensureLimitedSegments(Module& module) {
8688

8789
// check if we have too many dynamic data segments, which we can do nothing
8890
// about
89-
if (numDynamic + 1 >= WebLimitations::MaxDataSegments) {
91+
if (numDynamic + 1 >= maxDataSegments) {
9092
return false;
9193
}
9294

9395
// we'll merge constant segments if we must
94-
if (numConstant + numDynamic >= WebLimitations::MaxDataSegments) {
95-
numConstant = WebLimitations::MaxDataSegments - numDynamic - 1;
96+
if (numConstant + numDynamic >= maxDataSegments) {
97+
numConstant = maxDataSegments - numDynamic - 1;
9698
[[maybe_unused]] auto num = numConstant + numDynamic;
97-
assert(num == WebLimitations::MaxDataSegments - 1);
99+
assert(num == maxDataSegments - 1);
98100
}
99101

100102
std::vector<std::unique_ptr<wasm::DataSegment>> mergedSegments;
101-
mergedSegments.reserve(WebLimitations::MaxDataSegments);
103+
mergedSegments.reserve(maxDataSegments);
102104

103105
// drop empty segments and pass through dynamic-offset segments
104106
for (auto& segment : dataSegments) {
@@ -121,7 +123,7 @@ inline bool ensureLimitedSegments(Module& module) {
121123
if (!isRelevant(*segment)) {
122124
continue;
123125
}
124-
if (mergedSegments.size() + 2 < WebLimitations::MaxDataSegments) {
126+
if (mergedSegments.size() + 2 < maxDataSegments) {
125127
mergedSegments.push_back(std::move(segment));
126128
continue;
127129
}

src/passes/LimitSegments.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,28 @@
1818
#include "pass.h"
1919
#include "wasm.h"
2020

21+
//
22+
// Attempt to merge segments to fit within a specified limit.
23+
//
24+
// By default this limit is equal to the one commonly used by wasm VMs
25+
// (see wasm-limits.h), but it can be changed with the option below:
26+
//
27+
// --pass-arg=limit-segments@max-data-segments
28+
//
29+
// Specify a custom maximum number of data segments.
30+
//
31+
2132
namespace wasm {
2233

2334
struct LimitSegments : public Pass {
2435
void run(Module* module) override {
25-
if (!MemoryUtils::ensureLimitedSegments(*module)) {
36+
Index maxDataSegments;
37+
if (hasArgument("limit-segments")) {
38+
maxDataSegments = std::stoul(getArgument("limit-segments", ""));
39+
} else {
40+
maxDataSegments = WebLimitations::MaxDataSegments;
41+
}
42+
if (!MemoryUtils::ensureLimitedSegments(*module, maxDataSegments)) {
2643
std::cerr << "Unable to merge segments. "
2744
<< "wasm VMs may not accept this binary" << std::endl;
2845
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
;; RUN: wasm-opt %s --limit-segments --pass-arg=limit-segments@3 -S -o - | filecheck %s
2+
3+
;; Test that the data segments custom limit is respected.
4+
(module
5+
(memory 256 256)
6+
;; CHECK: (data $0 (i32.const 0) "A")
7+
(data (i32.const 0) "A")
8+
;; CHECK: (data $"" (i32.const 1) "AAAA")
9+
(data (i32.const 1) "A")
10+
(data (i32.const 2) "A")
11+
(data (i32.const 3) "A")
12+
(data (i32.const 4) "A")
13+
)

0 commit comments

Comments
 (0)