Skip to content

Commit 4274deb

Browse files
committed
accumulate
1 parent 8cf214a commit 4274deb

1 file changed

Lines changed: 46 additions & 20 deletions

File tree

src/tools/wasm-merge.cpp

Lines changed: 46 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,11 @@ namespace {
117117
// have it as a global rather than pass it around all the time.
118118
Module merged;
119119

120+
// Everything we merge is accumulated into |merged|, aside from the start
121+
// functions. To avoid incrementally adding a call each time, which can end up
122+
// nested, we add them here and generate a series of flat calls at the end.
123+
std::vector<Name> startFunctions;
124+
120125
// Name conflicts on functions etc. are resolved by renaming things in a way
121126
// that only matters internally. Conflicting export names, however, are
122127
// observable, and so the user must decide how they want wasm-merge to handle
@@ -363,26 +368,9 @@ void copyModuleContents(Module& input, Name inputName) {
363368
merged.addExport(std::move(copy));
364369
}
365370

366-
// Start functions must be merged.
367-
if (input.start.is()) {
368-
if (!merged.start.is()) {
369-
// No previous start; just refer to the new one.
370-
merged.start = input.start;
371-
} else {
372-
// Merge them, keeping the order. We add a new function that calls the two
373-
// (leaving proper inlining, including handling of control flow etc., to
374-
// the optimizer).
375-
auto combinedName =
376-
Names::getValidFunctionName(merged, "merged.start.combined");
377-
Builder builder(merged);
378-
auto* callOld = builder.makeCall(merged.start, {}, Type::none);
379-
auto* callNew = builder.makeCall(input.start, {}, Type::none);
380-
auto* body = builder.makeSequence(callOld, callNew);
381-
auto combined = builder.makeFunction(
382-
combinedName, Signature(Type::none, Type::none), {}, body);
383-
merged.addFunction(std::move(combined));
384-
merged.start = combinedName;
385-
}
371+
// Start functions are accumulated til the end.
372+
if (input.start) {
373+
startFunctions.push_back(input.start);
386374
}
387375

388376
// TODO: type names, features, debug info, custom sections, dylink info, etc.
@@ -594,6 +582,34 @@ void updateTypes(Module& wasm) {
594582
updater.runOnModuleCode(&runner, &wasm);
595583
}
596584

585+
// Merge the start functions, keeping the order. We add a new function that
586+
// calls them in sequence (leaving proper inlining, including handling of
587+
// control flow etc., to the optimizer).
588+
void mergeStartFunctions() {
589+
if (startFunctions.empty()) {
590+
return;
591+
}
592+
593+
if (startFunctions.size() == 1) {
594+
// Avoid adding a call here.
595+
merged.start = startFunctions[0];
596+
return;
597+
}
598+
599+
auto combinedName =
600+
Names::getValidFunctionName(merged, "merged.start.combined");
601+
Builder builder(merged);
602+
std::vector<Expression*> calls;
603+
for (auto start : startFunctions) {
604+
calls.push_back(builder.makeCall(start, {}, Type::none));
605+
}
606+
auto* body = builder.makeBlock(calls);
607+
auto combined = builder.makeFunction(
608+
combinedName, Signature(Type::none, Type::none), {}, body);
609+
merged.addFunction(std::move(combined));
610+
merged.start = combinedName;
611+
}
612+
597613
// Merges an input module into an existing target module. The input module can
598614
// be modified, as it will no longer be needed (so it is intentionally not
599615
// marked as const here).
@@ -792,6 +808,13 @@ Input source maps can be specified by adding an -ism option right after the modu
792808
for (auto& curr : merged.exports) {
793809
exportModuleMap[curr.get()] = ExportInfo{inputFileName, curr->name};
794810
}
811+
812+
// Start functions are accumulated til the end.
813+
if (merged.start) {
814+
startFunctions.push_back(merged.start);
815+
merged.start = Name();
816+
}
817+
795818
} else {
796819
// This is a later module: do a full merge.
797820
mergeInto(*currModule, inputFileName);
@@ -825,6 +848,9 @@ Input source maps can be specified by adding an -ism option right after the modu
825848
// Update types after combing and linking everything.
826849
updateTypes(merged);
827850

851+
// Merge the start functions, after everything else is set up.
852+
mergeStartFunctions();
853+
828854
{
829855
PassRunner passRunner(&merged);
830856
// We might have made some globals read from others that now appear after

0 commit comments

Comments
 (0)