summaryrefslogtreecommitdiff
path: root/src/passes
diff options
context:
space:
mode:
Diffstat (limited to 'src/passes')
-rw-r--r--src/passes/Asyncify.cpp51
-rw-r--r--src/passes/AvoidReinterprets.cpp4
-rw-r--r--src/passes/CoalesceLocals.cpp8
-rw-r--r--src/passes/CodeFolding.cpp4
-rw-r--r--src/passes/CodePushing.cpp4
-rw-r--r--src/passes/ConstHoisting.cpp4
-rw-r--r--src/passes/ConstantFieldPropagation.cpp11
-rw-r--r--src/passes/DWARF.cpp4
-rw-r--r--src/passes/DataFlowOpts.cpp4
-rw-r--r--src/passes/DeAlign.cpp4
-rw-r--r--src/passes/DeadArgumentElimination.cpp18
-rw-r--r--src/passes/DeadCodeElimination.cpp4
-rw-r--r--src/passes/Directize.cpp10
-rw-r--r--src/passes/DuplicateFunctionElimination.cpp8
-rw-r--r--src/passes/DuplicateImportElimination.cpp4
-rw-r--r--src/passes/ExtractFunction.cpp17
-rw-r--r--src/passes/Flatten.cpp4
-rw-r--r--src/passes/FuncCastEmulation.cpp12
-rw-r--r--src/passes/GUFA.cpp11
-rw-r--r--src/passes/GlobalEffects.cpp10
-rw-r--r--src/passes/GlobalRefining.cpp8
-rw-r--r--src/passes/GlobalStructInference.cpp8
-rw-r--r--src/passes/GlobalTypeOptimization.cpp23
-rw-r--r--src/passes/Heap2Local.cpp4
-rw-r--r--src/passes/I64ToI32Lowering.cpp4
-rw-r--r--src/passes/Inlining.cpp29
-rw-r--r--src/passes/Intrinsics.cpp4
-rw-r--r--src/passes/JSPI.cpp2
-rw-r--r--src/passes/LegalizeJSInterface.cpp14
-rw-r--r--src/passes/LimitSegments.cpp2
-rw-r--r--src/passes/LocalCSE.cpp4
-rw-r--r--src/passes/LocalSubtyping.cpp4
-rw-r--r--src/passes/LoopInvariantCodeMotion.cpp4
-rw-r--r--src/passes/MemoryPacking.cpp41
-rw-r--r--src/passes/MergeBlocks.cpp4
-rw-r--r--src/passes/MergeLocals.cpp4
-rw-r--r--src/passes/MergeSimilarFunctions.cpp2
-rw-r--r--src/passes/MinifyImportsAndExports.cpp2
-rw-r--r--src/passes/NameList.cpp2
-rw-r--r--src/passes/NameTypes.cpp2
-rw-r--r--src/passes/OnceReduction.cpp14
-rw-r--r--src/passes/OptimizeAddedConstants.cpp4
-rw-r--r--src/passes/OptimizeForJS.cpp4
-rw-r--r--src/passes/OptimizeInstructions.cpp4
-rw-r--r--src/passes/PickLoadSigns.cpp4
-rw-r--r--src/passes/Poppify.cpp11
-rw-r--r--src/passes/PostEmscripten.cpp24
-rw-r--r--src/passes/Precompute.cpp4
-rw-r--r--src/passes/Print.cpp23
-rw-r--r--src/passes/PrintCallGraph.cpp2
-rw-r--r--src/passes/PrintFeatures.cpp2
-rw-r--r--src/passes/PrintFunctionMap.cpp4
-rw-r--r--src/passes/ReReloop.cpp8
-rw-r--r--src/passes/RedundantSetElimination.cpp4
-rw-r--r--src/passes/RemoveMemory.cpp2
-rw-r--r--src/passes/RemoveNonJSOps.cpp8
-rw-r--r--src/passes/RemoveUnusedBrs.cpp4
-rw-r--r--src/passes/RemoveUnusedModuleElements.cpp2
-rw-r--r--src/passes/RemoveUnusedNames.cpp4
-rw-r--r--src/passes/ReorderFunctions.cpp8
-rw-r--r--src/passes/ReorderLocals.cpp4
-rw-r--r--src/passes/RoundTrip.cpp4
-rw-r--r--src/passes/SSAify.cpp7
-rw-r--r--src/passes/SafeHeap.cpp17
-rw-r--r--src/passes/SetGlobals.cpp4
-rw-r--r--src/passes/SignaturePruning.cpp10
-rw-r--r--src/passes/SignatureRefining.cpp10
-rw-r--r--src/passes/SimplifyGlobals.cpp36
-rw-r--r--src/passes/SimplifyLocals.cpp5
-rw-r--r--src/passes/SpillPointers.cpp4
-rw-r--r--src/passes/StackCheck.cpp11
-rw-r--r--src/passes/StackIR.cpp8
-rw-r--r--src/passes/Strip.cpp2
-rw-r--r--src/passes/StripTargetFeatures.cpp2
-rw-r--r--src/passes/TrapMode.cpp4
-rw-r--r--src/passes/TypeRefining.cpp29
-rw-r--r--src/passes/Untee.cpp2
-rw-r--r--src/passes/Vacuum.cpp2
-rw-r--r--src/passes/opt-utils.h4
-rw-r--r--src/passes/pass.cpp18
-rw-r--r--src/passes/test_passes.cpp5
81 files changed, 399 insertions, 292 deletions
diff --git a/src/passes/Asyncify.cpp b/src/passes/Asyncify.cpp
index b076c77d4..89e9a3ad5 100644
--- a/src/passes/Asyncify.cpp
+++ b/src/passes/Asyncify.cpp
@@ -839,12 +839,13 @@ struct AsyncifyFlow : public Pass {
ModuleAnalyzer* analyzer;
- AsyncifyFlow* create() override { return new AsyncifyFlow(analyzer); }
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<AsyncifyFlow>(analyzer);
+ }
AsyncifyFlow(ModuleAnalyzer* analyzer) : analyzer(analyzer) {}
- void
- runOnFunction(PassRunner* runner, Module* module_, Function* func_) override {
+ void runOnFunction(Module* module_, Function* func_) override {
module = module_;
func = func_;
builder = make_unique<AsyncifyBuilder>(*module);
@@ -1213,7 +1214,9 @@ struct AsyncifyLocals : public WalkerPass<PostWalker<AsyncifyLocals>> {
ModuleAnalyzer* analyzer;
- AsyncifyLocals* create() override { return new AsyncifyLocals(analyzer); }
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<AsyncifyLocals>(analyzer);
+ }
AsyncifyLocals(ModuleAnalyzer* analyzer) : analyzer(analyzer) {}
@@ -1491,52 +1494,49 @@ static std::string getFullImportName(Name module, Name base) {
}
struct Asyncify : public Pass {
- void run(PassRunner* runner, Module* module) override {
- bool optimize = runner->options.optimizeLevel > 0;
+ void run(Module* module) override {
+ auto& options = getPassOptions();
+ bool optimize = options.optimizeLevel > 0;
// Ensure there is a memory, as we need it.
MemoryUtils::ensureExists(module);
// Find which things can change the state.
auto stateChangingImports = String::trim(read_possible_response_file(
- runner->options.getArgumentOrDefault("asyncify-imports", "")));
+ options.getArgumentOrDefault("asyncify-imports", "")));
auto ignoreImports =
- runner->options.getArgumentOrDefault("asyncify-ignore-imports", "");
+ options.getArgumentOrDefault("asyncify-ignore-imports", "");
bool allImportsCanChangeState =
stateChangingImports == "" && ignoreImports == "";
String::Split listedImports(stateChangingImports, ",");
// TODO: consider renaming asyncify-ignore-indirect to
// asyncify-ignore-nondirect, but that could break users.
- auto ignoreNonDirect = runner->options.getArgumentOrDefault(
- "asyncify-ignore-indirect", "") == "";
+ auto ignoreNonDirect =
+ options.getArgumentOrDefault("asyncify-ignore-indirect", "") == "";
std::string removeListInput =
- runner->options.getArgumentOrDefault("asyncify-removelist", "");
+ options.getArgumentOrDefault("asyncify-removelist", "");
if (removeListInput.empty()) {
// Support old name for now to avoid immediate breakage TODO remove
- removeListInput =
- runner->options.getArgumentOrDefault("asyncify-blacklist", "");
+ removeListInput = options.getArgumentOrDefault("asyncify-blacklist", "");
}
String::Split removeList(
String::trim(read_possible_response_file(removeListInput)), ",");
String::Split addList(
String::trim(read_possible_response_file(
- runner->options.getArgumentOrDefault("asyncify-addlist", ""))),
+ options.getArgumentOrDefault("asyncify-addlist", ""))),
",");
std::string onlyListInput =
- runner->options.getArgumentOrDefault("asyncify-onlylist", "");
+ options.getArgumentOrDefault("asyncify-onlylist", "");
if (onlyListInput.empty()) {
// Support old name for now to avoid immediate breakage TODO remove
- onlyListInput =
- runner->options.getArgumentOrDefault("asyncify-whitelist", "");
+ onlyListInput = options.getArgumentOrDefault("asyncify-whitelist", "");
}
String::Split onlyList(
String::trim(read_possible_response_file(onlyListInput)), ",");
- auto asserts =
- runner->options.getArgumentOrDefault("asyncify-asserts", "") != "";
- auto verbose =
- runner->options.getArgumentOrDefault("asyncify-verbose", "") != "";
+ auto asserts = options.getArgumentOrDefault("asyncify-asserts", "") != "";
+ auto verbose = options.getArgumentOrDefault("asyncify-verbose", "") != "";
auto relocatable =
- runner->options.getArgumentOrDefault("asyncify-relocatable", "") != "";
+ options.getArgumentOrDefault("asyncify-relocatable", "") != "";
removeList = handleBracketingOperators(removeList);
addList = handleBracketingOperators(addList);
@@ -1716,8 +1716,9 @@ struct ModAsyncify
ModAsyncify<neverRewind, neverUnwind, importsAlwaysUnwind>>> {
bool isFunctionParallel() override { return true; }
- ModAsyncify* create() override {
- return new ModAsyncify<neverRewind, neverUnwind, importsAlwaysUnwind>();
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<
+ ModAsyncify<neverRewind, neverUnwind, importsAlwaysUnwind>>();
}
void doWalkFunction(Function* func) {
@@ -1840,7 +1841,7 @@ Pass* createModAsyncifyAlwaysOnlyUnwindPass() {
// Assume that we never unwind, but may still rewind.
//
struct ModAsyncifyNeverUnwind : public Pass {
- void run(PassRunner* runner, Module* module) override {}
+ void run(Module* module) override {}
};
Pass* createModAsyncifyNeverUnwindPass() {
diff --git a/src/passes/AvoidReinterprets.cpp b/src/passes/AvoidReinterprets.cpp
index feea4871f..3f4795303 100644
--- a/src/passes/AvoidReinterprets.cpp
+++ b/src/passes/AvoidReinterprets.cpp
@@ -76,7 +76,9 @@ static bool isReinterpret(Unary* curr) {
struct AvoidReinterprets : public WalkerPass<PostWalker<AvoidReinterprets>> {
bool isFunctionParallel() override { return true; }
- Pass* create() override { return new AvoidReinterprets; }
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<AvoidReinterprets>();
+ }
struct Info {
// Info used when analyzing.
diff --git a/src/passes/CoalesceLocals.cpp b/src/passes/CoalesceLocals.cpp
index edf142039..558be07ff 100644
--- a/src/passes/CoalesceLocals.cpp
+++ b/src/passes/CoalesceLocals.cpp
@@ -51,7 +51,9 @@ struct CoalesceLocals
// FIXME DWARF updating does not handle local changes yet.
bool invalidatesDWARF() override { return true; }
- Pass* create() override { return new CoalesceLocals; }
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<CoalesceLocals>();
+ }
// main entry point
@@ -580,7 +582,9 @@ void CoalesceLocals::applyIndices(std::vector<Index>& indices,
}
struct CoalesceLocalsWithLearning : public CoalesceLocals {
- virtual Pass* create() override { return new CoalesceLocalsWithLearning; }
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<CoalesceLocalsWithLearning>();
+ }
virtual void pickIndices(std::vector<Index>& indices) override;
};
diff --git a/src/passes/CodeFolding.cpp b/src/passes/CodeFolding.cpp
index 0323223e1..0e57a79a2 100644
--- a/src/passes/CodeFolding.cpp
+++ b/src/passes/CodeFolding.cpp
@@ -86,7 +86,9 @@ struct ExpressionMarker
struct CodeFolding : public WalkerPass<ControlFlowWalker<CodeFolding>> {
bool isFunctionParallel() override { return true; }
- Pass* create() override { return new CodeFolding; }
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<CodeFolding>();
+ }
// information about a "tail" - code that reaches a point that we can
// merge (e.g., a branch and some code leading up to it)
diff --git a/src/passes/CodePushing.cpp b/src/passes/CodePushing.cpp
index 5026773d4..c71078558 100644
--- a/src/passes/CodePushing.cpp
+++ b/src/passes/CodePushing.cpp
@@ -249,7 +249,9 @@ struct CodePushing : public WalkerPass<PostWalker<CodePushing>> {
// way), so validation will be preserved.
bool requiresNonNullableLocalFixups() override { return false; }
- Pass* create() override { return new CodePushing; }
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<CodePushing>();
+ }
LocalAnalyzer analyzer;
diff --git a/src/passes/ConstHoisting.cpp b/src/passes/ConstHoisting.cpp
index 3d9ac5e90..6463221f4 100644
--- a/src/passes/ConstHoisting.cpp
+++ b/src/passes/ConstHoisting.cpp
@@ -44,7 +44,9 @@ static const Index MIN_USES = 2;
struct ConstHoisting : public WalkerPass<PostWalker<ConstHoisting>> {
bool isFunctionParallel() override { return true; }
- Pass* create() override { return new ConstHoisting; }
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<ConstHoisting>();
+ }
InsertOrderedMap<Literal, std::vector<Expression**>> uses;
diff --git a/src/passes/ConstantFieldPropagation.cpp b/src/passes/ConstantFieldPropagation.cpp
index 0ec889e36..0f66fe28b 100644
--- a/src/passes/ConstantFieldPropagation.cpp
+++ b/src/passes/ConstantFieldPropagation.cpp
@@ -55,7 +55,9 @@ struct FunctionOptimizer : public WalkerPass<PostWalker<FunctionOptimizer>> {
// Only modifies struct.get operations.
bool requiresNonNullableLocalFixups() override { return false; }
- Pass* create() override { return new FunctionOptimizer(infos); }
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<FunctionOptimizer>(infos);
+ }
FunctionOptimizer(PCVStructValuesMap& infos) : infos(infos) {}
@@ -126,8 +128,8 @@ private:
struct PCVScanner
: public StructUtils::StructScanner<PossibleConstantValues, PCVScanner> {
- Pass* create() override {
- return new PCVScanner(functionNewInfos, functionSetGetInfos);
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<PCVScanner>(functionNewInfos, functionSetGetInfos);
}
PCVScanner(StructUtils::FunctionStructValuesMap<PossibleConstantValues>&
@@ -181,7 +183,7 @@ struct ConstantFieldPropagation : public Pass {
// Only modifies struct.get operations.
bool requiresNonNullableLocalFixups() override { return false; }
- void run(PassRunner* runner, Module* module) override {
+ void run(Module* module) override {
if (!module->features.hasGC()) {
return;
}
@@ -193,6 +195,7 @@ struct ConstantFieldPropagation : public Pass {
PCVFunctionStructValuesMap functionNewInfos(*module),
functionSetInfos(*module);
PCVScanner scanner(functionNewInfos, functionSetInfos);
+ auto* runner = getPassRunner();
scanner.run(runner, module);
scanner.runOnModuleCode(runner, module);
diff --git a/src/passes/DWARF.cpp b/src/passes/DWARF.cpp
index bc2af3292..efde51ad6 100644
--- a/src/passes/DWARF.cpp
+++ b/src/passes/DWARF.cpp
@@ -30,9 +30,7 @@
namespace wasm {
struct DWARFDump : public Pass {
- void run(PassRunner* runner, Module* module) override {
- Debug::dumpDWARF(*module);
- }
+ void run(Module* module) override { Debug::dumpDWARF(*module); }
};
Pass* createDWARFDumpPass() { return new DWARFDump(); }
diff --git a/src/passes/DataFlowOpts.cpp b/src/passes/DataFlowOpts.cpp
index 40e0c3c48..79878f4c9 100644
--- a/src/passes/DataFlowOpts.cpp
+++ b/src/passes/DataFlowOpts.cpp
@@ -39,7 +39,9 @@ namespace wasm {
struct DataFlowOpts : public WalkerPass<PostWalker<DataFlowOpts>> {
bool isFunctionParallel() override { return true; }
- Pass* create() override { return new DataFlowOpts; }
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<DataFlowOpts>();
+ }
DataFlow::Users nodeUsers;
diff --git a/src/passes/DeAlign.cpp b/src/passes/DeAlign.cpp
index 795b6a228..15adc2ed6 100644
--- a/src/passes/DeAlign.cpp
+++ b/src/passes/DeAlign.cpp
@@ -27,7 +27,9 @@ namespace wasm {
struct DeAlign : public WalkerPass<PostWalker<DeAlign>> {
bool isFunctionParallel() override { return true; }
- Pass* create() override { return new DeAlign(); }
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<DeAlign>();
+ }
void visitLoad(Load* curr) { curr->align = 1; }
diff --git a/src/passes/DeadArgumentElimination.cpp b/src/passes/DeadArgumentElimination.cpp
index 784aec31a..b84ebddd5 100644
--- a/src/passes/DeadArgumentElimination.cpp
+++ b/src/passes/DeadArgumentElimination.cpp
@@ -90,7 +90,9 @@ struct DAEScanner
: public WalkerPass<PostWalker<DAEScanner, Visitor<DAEScanner>>> {
bool isFunctionParallel() override { return true; }
- Pass* create() override { return new DAEScanner(infoMap); }
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<DAEScanner>(infoMap);
+ }
DAEScanner(DAEFunctionInfoMap* infoMap) : infoMap(infoMap) {}
@@ -172,16 +174,16 @@ struct DAE : public Pass {
bool optimize = false;
- void run(PassRunner* runner, Module* module) override {
+ void run(Module* module) override {
// Iterate to convergence.
while (1) {
- if (!iteration(runner, module)) {
+ if (!iteration(module)) {
break;
}
}
}
- bool iteration(PassRunner* runner, Module* module) {
+ bool iteration(Module* module) {
allDroppedCalls.clear();
DAEFunctionInfoMap infoMap;
@@ -198,7 +200,7 @@ struct DAE : public Pass {
}
}
// Scan all the functions.
- scanner.run(runner, module);
+ scanner.run(getPassRunner(), module);
// Combine all the info.
std::map<Name, std::vector<Call*>> allCalls;
std::unordered_set<Name> tailCallees;
@@ -245,7 +247,7 @@ struct DAE : public Pass {
// Changing a call expression's return type can propagate out to its
// parents, and so we must refinalize.
// TODO: We could track in which functions we actually make changes.
- ReFinalize().run(runner, module);
+ ReFinalize().run(getPassRunner(), module);
}
// Track which functions we changed, and optimize them later if necessary.
std::unordered_set<Function*> changed;
@@ -260,7 +262,7 @@ struct DAE : public Pass {
continue;
}
auto removedIndexes = ParamUtils::removeParameters(
- {func}, infoMap[name].unusedParams, calls, {}, module, runner);
+ {func}, infoMap[name].unusedParams, calls, {}, module, getPassRunner());
if (!removedIndexes.empty()) {
// Success!
changed.insert(func);
@@ -304,7 +306,7 @@ struct DAE : public Pass {
}
}
if (optimize && !changed.empty()) {
- OptUtils::optimizeAfterInlining(changed, module, runner);
+ OptUtils::optimizeAfterInlining(changed, module, getPassRunner());
}
return !changed.empty() || refinedReturnTypes;
}
diff --git a/src/passes/DeadCodeElimination.cpp b/src/passes/DeadCodeElimination.cpp
index caafb755d..0b382f465 100644
--- a/src/passes/DeadCodeElimination.cpp
+++ b/src/passes/DeadCodeElimination.cpp
@@ -48,7 +48,9 @@ struct DeadCodeElimination
// local.get might have prevented validation).
bool requiresNonNullableLocalFixups() override { return false; }
- Pass* create() override { return new DeadCodeElimination; }
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<DeadCodeElimination>();
+ }
// as we remove code, we must keep the types of other nodes valid
TypeUpdater typeUpdater;
diff --git a/src/passes/Directize.cpp b/src/passes/Directize.cpp
index af020aca6..ba99d62e9 100644
--- a/src/passes/Directize.cpp
+++ b/src/passes/Directize.cpp
@@ -69,7 +69,9 @@ using TableInfoMap = std::unordered_map<Name, TableInfo>;
struct FunctionDirectizer : public WalkerPass<PostWalker<FunctionDirectizer>> {
bool isFunctionParallel() override { return true; }
- Pass* create() override { return new FunctionDirectizer(tables); }
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<FunctionDirectizer>(tables);
+ }
FunctionDirectizer(const TableInfoMap& tables) : tables(tables) {}
@@ -199,14 +201,14 @@ private:
};
struct Directize : public Pass {
- void run(PassRunner* runner, Module* module) override {
+ void run(Module* module) override {
if (module->tables.empty()) {
return;
}
// TODO: consider a per-table option here
auto initialContentsImmutable =
- runner->options.getArgumentOrDefault(
+ getPassOptions().getArgumentOrDefault(
"directize-initial-contents-immutable", "") != "";
// Set up the initial info.
@@ -273,7 +275,7 @@ struct Directize : public Pass {
}
// We can optimize!
- FunctionDirectizer(tables).run(runner, module);
+ FunctionDirectizer(tables).run(getPassRunner(), module);
}
};
diff --git a/src/passes/DuplicateFunctionElimination.cpp b/src/passes/DuplicateFunctionElimination.cpp
index 2ebdca4ba..e797cd843 100644
--- a/src/passes/DuplicateFunctionElimination.cpp
+++ b/src/passes/DuplicateFunctionElimination.cpp
@@ -37,11 +37,11 @@ struct DuplicateFunctionElimination : public Pass {
// This pass merges functions but does not alter their contents.
bool requiresNonNullableLocalFixups() override { return false; }
- void run(PassRunner* runner, Module* module) override {
+ void run(Module* module) override {
// Multiple iterations may be necessary: A and B may be identical only after
// we see the functions C1 and C2 that they call are in fact identical.
// Rarely, such "chains" can be very long, so we limit how many we do.
- auto& options = runner->options;
+ auto& options = getPassOptions();
Index limit;
if (options.optimizeLevel >= 3 || options.shrinkLevel >= 1) {
limit = module->functions.size(); // no limit
@@ -56,7 +56,7 @@ struct DuplicateFunctionElimination : public Pass {
limit--;
// Hash all the functions
auto hashes = FunctionHasher::createMap(module);
- FunctionHasher(&hashes).run(runner, module);
+ FunctionHasher(&hashes).run(getPassRunner(), module);
// Find hash-equal groups
std::map<uint32_t, std::vector<Function*>> hashGroups;
ModuleUtils::iterDefinedFunctions(*module, [&](Function* func) {
@@ -96,7 +96,7 @@ struct DuplicateFunctionElimination : public Pass {
// remove the duplicates
module->removeFunctions(
[&](Function* func) { return duplicates.count(func->name) > 0; });
- OptUtils::replaceFunctions(runner, *module, replacements);
+ OptUtils::replaceFunctions(getPassRunner(), *module, replacements);
} else {
break;
}
diff --git a/src/passes/DuplicateImportElimination.cpp b/src/passes/DuplicateImportElimination.cpp
index 1a0319e3a..33ce2288a 100644
--- a/src/passes/DuplicateImportElimination.cpp
+++ b/src/passes/DuplicateImportElimination.cpp
@@ -31,7 +31,7 @@ struct DuplicateImportElimination : public Pass {
// This pass does not alter function contents.
bool requiresNonNullableLocalFixups() override { return false; }
- void run(PassRunner* runner, Module* module) override {
+ void run(Module* module) override {
ImportInfo imports(*module);
std::map<Name, Name> replacements;
std::map<std::pair<Name, Name>, Name> seen;
@@ -54,7 +54,7 @@ struct DuplicateImportElimination : public Pass {
}
if (!replacements.empty()) {
module->updateMaps();
- OptUtils::replaceFunctions(runner, *module, replacements);
+ OptUtils::replaceFunctions(getPassRunner(), *module, replacements);
for (auto name : toRemove) {
module->removeFunction(name);
}
diff --git a/src/passes/ExtractFunction.cpp b/src/passes/ExtractFunction.cpp
index f75c04cbe..e3f2a5538 100644
--- a/src/passes/ExtractFunction.cpp
+++ b/src/passes/ExtractFunction.cpp
@@ -54,25 +54,24 @@ static void extract(PassRunner* runner, Module* module, Name name) {
// Remove unneeded things.
PassRunner postRunner(runner);
postRunner.add("remove-unused-module-elements");
- postRunner.setIsNested(true);
postRunner.run();
}
struct ExtractFunction : public Pass {
- void run(PassRunner* runner, Module* module) override {
- Name name = runner->options.getArgument(
+ void run(Module* module) override {
+ Name name = getPassOptions().getArgument(
"extract-function",
"ExtractFunction usage: wasm-opt --extract-function=FUNCTION_NAME");
- extract(runner, module, name);
+ extract(getPassRunner(), module, name);
}
};
struct ExtractFunctionIndex : public Pass {
- void run(PassRunner* runner, Module* module) override {
+ void run(Module* module) override {
std::string index =
- runner->options.getArgument("extract-function-index",
- "ExtractFunctionIndex usage: wasm-opt "
- "--extract-function-index=FUNCTION_INDEX");
+ getPassOptions().getArgument("extract-function-index",
+ "ExtractFunctionIndex usage: wasm-opt "
+ "--extract-function-index=FUNCTION_INDEX");
for (char c : index) {
if (!std::isdigit(c)) {
Fatal() << "Expected numeric function index";
@@ -85,7 +84,7 @@ struct ExtractFunctionIndex : public Pass {
}
// Assumes imports are at the beginning
Name name = module->functions[i]->name;
- extract(runner, module, name);
+ extract(getPassRunner(), module, name);
}
};
diff --git a/src/passes/Flatten.cpp b/src/passes/Flatten.cpp
index 771183d2c..e8dec3010 100644
--- a/src/passes/Flatten.cpp
+++ b/src/passes/Flatten.cpp
@@ -76,7 +76,9 @@ struct Flatten
// FIXME DWARF updating does not handle local changes yet.
bool invalidatesDWARF() override { return true; }
- Pass* create() override { return new Flatten; }
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<Flatten>();
+ }
// For each expression, a bunch of expressions that should execute right
// before it
diff --git a/src/passes/FuncCastEmulation.cpp b/src/passes/FuncCastEmulation.cpp
index 5e62ec9fc..80818907f 100644
--- a/src/passes/FuncCastEmulation.cpp
+++ b/src/passes/FuncCastEmulation.cpp
@@ -116,8 +116,8 @@ struct ParallelFuncCastEmulation
: public WalkerPass<PostWalker<ParallelFuncCastEmulation>> {
bool isFunctionParallel() override { return true; }
- Pass* create() override {
- return new ParallelFuncCastEmulation(ABIType, numParams);
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<ParallelFuncCastEmulation>(ABIType, numParams);
}
ParallelFuncCastEmulation(HeapType ABIType, Index numParams)
@@ -151,9 +151,9 @@ private:
};
struct FuncCastEmulation : public Pass {
- void run(PassRunner* runner, Module* module) override {
- Index numParams =
- std::stoul(runner->options.getArgumentOrDefault("max-func-params", "16"));
+ void run(Module* module) override {
+ Index numParams = std::stoul(
+ getPassOptions().getArgumentOrDefault("max-func-params", "16"));
// we just need the one ABI function type for all indirect calls
HeapType ABIType(
Signature(Type(std::vector<Type>(numParams, Type::i64)), Type::i64));
@@ -171,7 +171,7 @@ struct FuncCastEmulation : public Pass {
});
// update call_indirects
- ParallelFuncCastEmulation(ABIType, numParams).run(runner, module);
+ ParallelFuncCastEmulation(ABIType, numParams).run(getPassRunner(), module);
}
private:
diff --git a/src/passes/GUFA.cpp b/src/passes/GUFA.cpp
index 1f620f8db..eedf5f20c 100644
--- a/src/passes/GUFA.cpp
+++ b/src/passes/GUFA.cpp
@@ -63,8 +63,8 @@ struct GUFAOptimizer
GUFAOptimizer(ContentOracle& oracle, bool optimizing)
: oracle(oracle), optimizing(optimizing) {}
- GUFAOptimizer* create() override {
- return new GUFAOptimizer(oracle, optimizing);
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<GUFAOptimizer>(oracle, optimizing);
}
bool optimized = false;
@@ -289,8 +289,7 @@ struct GUFAOptimizer
return;
}
- PassRunner runner(getModule(), getPassOptions());
- runner.setIsNested(true);
+ PassRunner runner(getPassRunner());
// New unreachables we added have created dead code we can remove. If we do
// not do this, then running GUFA repeatedly can actually increase code size
// (by adding multiple unneeded unreachables).
@@ -329,9 +328,9 @@ struct GUFAPass : public Pass {
GUFAPass(bool optimizing) : optimizing(optimizing) {}
- void run(PassRunner* runner, Module* module) override {
+ void run(Module* module) override {
ContentOracle oracle(*module);
- GUFAOptimizer(oracle, optimizing).run(runner, module);
+ GUFAOptimizer(oracle, optimizing).run(getPassRunner(), module);
}
};
diff --git a/src/passes/GlobalEffects.cpp b/src/passes/GlobalEffects.cpp
index 2f816a0bd..6ed2d413a 100644
--- a/src/passes/GlobalEffects.cpp
+++ b/src/passes/GlobalEffects.cpp
@@ -26,11 +26,11 @@
namespace wasm {
struct GenerateGlobalEffects : public Pass {
- void run(PassRunner* runner, Module* module) override {
+ void run(Module* module) override {
// TODO: Full transitive closure of effects. For now, we just look at each
// function by itself.
- auto& funcEffectsMap = runner->options.funcEffectsMap;
+ auto& funcEffectsMap = getPassOptions().funcEffectsMap;
// First, clear any previous effects.
funcEffectsMap.reset();
@@ -50,7 +50,7 @@ struct GenerateGlobalEffects : public Pass {
// Gather the effects.
auto effects =
- std::make_unique<EffectAnalyzer>(runner->options, *module, func);
+ std::make_unique<EffectAnalyzer>(getPassOptions(), *module, func);
// If the body has a call, give up - that means we can't infer a more
// specific set of effects than the pessimistic case of just assuming
@@ -80,9 +80,7 @@ struct GenerateGlobalEffects : public Pass {
};
struct DiscardGlobalEffects : public Pass {
- void run(PassRunner* runner, Module* module) override {
- runner->options.funcEffectsMap.reset();
- }
+ void run(Module* module) override { getPassOptions().funcEffectsMap.reset(); }
};
Pass* createGenerateGlobalEffectsPass() { return new GenerateGlobalEffects(); }
diff --git a/src/passes/GlobalRefining.cpp b/src/passes/GlobalRefining.cpp
index 626fbaeb5..f3bea3d3d 100644
--- a/src/passes/GlobalRefining.cpp
+++ b/src/passes/GlobalRefining.cpp
@@ -34,7 +34,7 @@ struct GlobalRefining : public Pass {
// Only modifies globals and global.get operations.
bool requiresNonNullableLocalFixups() override { return false; }
- void run(PassRunner* runner, Module* module) override {
+ void run(Module* module) override {
if (!module->features.hasGC()) {
return;
}
@@ -114,7 +114,9 @@ struct GlobalRefining : public Pass {
GetUpdater(GlobalRefining& parent, Module& wasm)
: parent(parent), wasm(wasm) {}
- GetUpdater* create() override { return new GetUpdater(parent, wasm); }
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<GetUpdater>(parent, wasm);
+ }
// If we modify anything in a function then we must refinalize so that
// types propagate outwards.
@@ -135,7 +137,7 @@ struct GlobalRefining : public Pass {
}
}
};
- GetUpdater(*this, *module).run(runner, module);
+ GetUpdater(*this, *module).run(getPassRunner(), module);
}
};
diff --git a/src/passes/GlobalStructInference.cpp b/src/passes/GlobalStructInference.cpp
index 1cba976a6..d0810a7fa 100644
--- a/src/passes/GlobalStructInference.cpp
+++ b/src/passes/GlobalStructInference.cpp
@@ -64,7 +64,7 @@ struct GlobalStructInference : public Pass {
// them. If a global is not present here, it cannot be optimized.
std::unordered_map<HeapType, std::vector<Name>> typeGlobals;
- void run(PassRunner* runner, Module* module) override {
+ void run(Module* module) override {
if (!module->features.hasGC()) {
return;
}
@@ -185,7 +185,9 @@ struct GlobalStructInference : public Pass {
: public WalkerPass<PostWalker<FunctionOptimizer>> {
bool isFunctionParallel() override { return true; }
- Pass* create() override { return new FunctionOptimizer(parent); }
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<FunctionOptimizer>(parent);
+ }
FunctionOptimizer(GlobalStructInference& parent) : parent(parent) {}
@@ -312,7 +314,7 @@ struct GlobalStructInference : public Pass {
GlobalStructInference& parent;
};
- FunctionOptimizer(*this).run(runner, module);
+ FunctionOptimizer(*this).run(getPassRunner(), module);
}
};
diff --git a/src/passes/GlobalTypeOptimization.cpp b/src/passes/GlobalTypeOptimization.cpp
index dad54d116..694523200 100644
--- a/src/passes/GlobalTypeOptimization.cpp
+++ b/src/passes/GlobalTypeOptimization.cpp
@@ -62,8 +62,9 @@ struct FieldInfo {
struct FieldInfoScanner
: public StructUtils::StructScanner<FieldInfo, FieldInfoScanner> {
- Pass* create() override {
- return new FieldInfoScanner(functionNewInfos, functionSetGetInfos);
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<FieldInfoScanner>(functionNewInfos,
+ functionSetGetInfos);
}
FieldInfoScanner(
@@ -112,7 +113,7 @@ struct GlobalTypeOptimization : public Pass {
static const Index RemovedField = Index(-1);
std::unordered_map<HeapType, std::vector<Index>> indexesAfterRemovals;
- void run(PassRunner* runner, Module* module) override {
+ void run(Module* module) override {
if (!module->features.hasGC()) {
return;
}
@@ -124,8 +125,8 @@ struct GlobalTypeOptimization : public Pass {
StructUtils::FunctionStructValuesMap<FieldInfo> functionNewInfos(*module),
functionSetGetInfos(*module);
FieldInfoScanner scanner(functionNewInfos, functionSetGetInfos);
- scanner.run(runner, module);
- scanner.runOnModuleCode(runner, module);
+ scanner.run(getPassRunner(), module);
+ scanner.runOnModuleCode(getPassRunner(), module);
// Combine the data from the functions.
functionSetGetInfos.combineInto(combinedSetGetInfos);
@@ -241,7 +242,7 @@ struct GlobalTypeOptimization : public Pass {
// that we can identify, and only after this should we update all the types
// throughout the module.)
if (!indexesAfterRemovals.empty()) {
- removeFieldsInInstructions(runner, *module);
+ removeFieldsInInstructions(*module);
}
// Update the types in the entire module.
@@ -314,7 +315,7 @@ struct GlobalTypeOptimization : public Pass {
// After updating the types to remove certain fields, we must also remove
// them from struct instructions.
- void removeFieldsInInstructions(PassRunner* runner, Module& wasm) {
+ void removeFieldsInInstructions(Module& wasm) {
struct FieldRemover : public WalkerPass<PostWalker<FieldRemover>> {
bool isFunctionParallel() override { return true; }
@@ -322,7 +323,9 @@ struct GlobalTypeOptimization : public Pass {
FieldRemover(GlobalTypeOptimization& parent) : parent(parent) {}
- FieldRemover* create() override { return new FieldRemover(parent); }
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<FieldRemover>(parent);
+ }
void visitStructNew(StructNew* curr) {
if (curr->type == Type::unreachable) {
@@ -433,8 +436,8 @@ struct GlobalTypeOptimization : public Pass {
};
FieldRemover remover(*this);
- remover.run(runner, &wasm);
- remover.runOnModuleCode(runner, &wasm);
+ remover.run(getPassRunner(), &wasm);
+ remover.runOnModuleCode(getPassRunner(), &wasm);
}
};
diff --git a/src/passes/Heap2Local.cpp b/src/passes/Heap2Local.cpp
index 104a5bbcd..91298106d 100644
--- a/src/passes/Heap2Local.cpp
+++ b/src/passes/Heap2Local.cpp
@@ -732,7 +732,9 @@ struct Heap2LocalOptimizer {
struct Heap2Local : public WalkerPass<PostWalker<Heap2Local>> {
bool isFunctionParallel() override { return true; }
- Pass* create() override { return new Heap2Local(); }
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<Heap2Local>();
+ }
void doWalkFunction(Function* func) {
// Multiple rounds of optimization may work in theory, as once we turn one
diff --git a/src/passes/I64ToI32Lowering.cpp b/src/passes/I64ToI32Lowering.cpp
index 002e4568d..313070e9a 100644
--- a/src/passes/I64ToI32Lowering.cpp
+++ b/src/passes/I64ToI32Lowering.cpp
@@ -99,7 +99,9 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
// TODO: allow module-level transformations in parallel passes
bool isFunctionParallel() override { return false; }
- Pass* create() override { return new I64ToI32Lowering; }
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<I64ToI32Lowering>();
+ }
void doWalkModule(Module* module) {
if (!builder) {
diff --git a/src/passes/Inlining.cpp b/src/passes/Inlining.cpp
index 21c06e528..c03b404b0 100644
--- a/src/passes/Inlining.cpp
+++ b/src/passes/Inlining.cpp
@@ -140,8 +140,8 @@ struct FunctionInfoScanner
FunctionInfoScanner(NameInfoMap* infos) : infos(infos) {}
- FunctionInfoScanner* create() override {
- return new FunctionInfoScanner(infos);
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<FunctionInfoScanner>(infos);
}
void visitLoop(Loop* curr) {
@@ -209,7 +209,9 @@ struct Planner : public WalkerPass<PostWalker<Planner>> {
Planner(InliningState* state) : state(state) {}
- Planner* create() override { return new Planner(state); }
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<Planner>(state);
+ }
void visitCall(Call* curr) {
// plan to inline if we know this is valid to inline, and if the call is
@@ -832,11 +834,9 @@ struct Inlining : public Pass {
std::unique_ptr<FunctionSplitter> functionSplitter;
- PassRunner* runner = nullptr;
Module* module = nullptr;
- void run(PassRunner* runner_, Module* module_) override {
- runner = runner_;
+ void run(Module* module_) override {
module = module_;
// No point to do more iterations than the number of functions, as it means
@@ -919,9 +919,8 @@ struct Inlining : public Pass {
infos[func->name];
}
{
- PassRunner runner(module);
FunctionInfoScanner scanner(&infos);
- scanner.run(&runner, module);
+ scanner.run(getPassRunner(), module);
scanner.walkModuleCode(module);
}
for (auto& ex : module->exports) {
@@ -935,9 +934,9 @@ struct Inlining : public Pass {
// When optimizing heavily for size, we may potentially split functions in
// order to inline parts of them.
- if (runner->options.optimizeLevel >= 3 && !runner->options.shrinkLevel) {
+ if (getPassOptions().optimizeLevel >= 3 && !getPassOptions().shrinkLevel) {
functionSplitter =
- std::make_unique<FunctionSplitter>(module, runner->options);
+ std::make_unique<FunctionSplitter>(module, getPassOptions());
}
}
@@ -962,7 +961,7 @@ struct Inlining : public Pass {
funcNames.push_back(func->name);
}
// find and plan inlinings
- Planner(&state).run(runner, module);
+ Planner(&state).run(getPassRunner(), module);
// perform inlinings TODO: parallelize
std::unordered_map<Name, Index> inlinedUses; // how many uses we inlined
// which functions were inlined into
@@ -1015,7 +1014,7 @@ struct Inlining : public Pass {
wasm::UniqueNameMapper::uniquify(func->body);
}
if (optimize && inlinedInto.size() > 0) {
- OptUtils::optimizeAfterInlining(inlinedInto, module, runner);
+ OptUtils::optimizeAfterInlining(inlinedInto, module, getPassRunner());
}
// remove functions that we no longer need after inlining
module->removeFunctions([&](Function* func) {
@@ -1028,7 +1027,7 @@ struct Inlining : public Pass {
bool worthInlining(Name name) {
// Check if the function itself is worth inlining as it is.
- if (infos[name].worthInlining(runner->options)) {
+ if (infos[name].worthInlining(getPassOptions())) {
return true;
}
@@ -1051,7 +1050,7 @@ struct Inlining : public Pass {
// are guaranteed to inline after this.
Function* getActuallyInlinedFunction(Function* func) {
// If we want to inline this function itself, do so.
- if (infos[func->name].worthInlining(runner->options)) {
+ if (infos[func->name].worthInlining(getPassOptions())) {
return func;
}
@@ -1095,7 +1094,7 @@ static const char* MAIN = "main";
static const char* ORIGINAL_MAIN = "__original_main";
struct InlineMainPass : public Pass {
- void run(PassRunner* runner, Module* module) override {
+ void run(Module* module) override {
auto* main = module->getFunctionOrNull(MAIN);
auto* originalMain = module->getFunctionOrNull(ORIGINAL_MAIN);
if (!main || main->imported() || !originalMain ||
diff --git a/src/passes/Intrinsics.cpp b/src/passes/Intrinsics.cpp
index 1b5a50bbb..faba23816 100644
--- a/src/passes/Intrinsics.cpp
+++ b/src/passes/Intrinsics.cpp
@@ -24,7 +24,9 @@ namespace wasm {
struct IntrinsicLowering : public WalkerPass<PostWalker<IntrinsicLowering>> {
bool isFunctionParallel() override { return true; }
- Pass* create() override { return new IntrinsicLowering; }
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<IntrinsicLowering>();
+ }
void visitCall(Call* curr) {
if (Intrinsics(*getModule()).isCallWithoutEffects(curr)) {
diff --git a/src/passes/JSPI.cpp b/src/passes/JSPI.cpp
index c7c8493d8..9660b962d 100644
--- a/src/passes/JSPI.cpp
+++ b/src/passes/JSPI.cpp
@@ -40,7 +40,7 @@ struct JSPI : public Pass {
Type externref = Type(HeapType::ext, Nullable);
- void run(PassRunner* runner, Module* module) override {
+ void run(Module* module) override {
Builder builder(*module);
// Create a global to store the suspender that is passed into exported
// functions and will then need to be passed out to the imported functions.
diff --git a/src/passes/LegalizeJSInterface.cpp b/src/passes/LegalizeJSInterface.cpp
index dd702ba7d..bbef5109d 100644
--- a/src/passes/LegalizeJSInterface.cpp
+++ b/src/passes/LegalizeJSInterface.cpp
@@ -58,15 +58,15 @@ struct LegalizeJSInterface : public Pass {
LegalizeJSInterface(bool full) : full(full) {}
- void run(PassRunner* runner, Module* module) override {
+ void run(Module* module) override {
setTempRet0 = nullptr;
getTempRet0 = nullptr;
auto exportOriginals =
- !runner->options
+ !getPassOptions()
.getArgumentOrDefault("legalize-js-interface-export-originals", "")
.empty();
exportedHelpers =
- !runner->options
+ !getPassOptions()
.getArgumentOrDefault("legalize-js-interface-exported-helpers", "")
.empty();
// for each illegal export, we must export a legalized stub instead
@@ -129,7 +129,9 @@ struct LegalizeJSInterface : public Pass {
struct Fixer : public WalkerPass<PostWalker<Fixer>> {
bool isFunctionParallel() override { return true; }
- Pass* create() override { return new Fixer(illegalImportsToLegal); }
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<Fixer>(illegalImportsToLegal);
+ }
std::map<Name, Name>* illegalImportsToLegal;
@@ -159,8 +161,8 @@ struct LegalizeJSInterface : public Pass {
};
Fixer fixer(&illegalImportsToLegal);
- fixer.run(runner, module);
- fixer.runOnModuleCode(runner, module);
+ fixer.run(getPassRunner(), module);
+ fixer.runOnModuleCode(getPassRunner(), module);
// Finally we can remove all the now-unused illegal imports
for (const auto& pair : illegalImportsToLegal) {
diff --git a/src/passes/LimitSegments.cpp b/src/passes/LimitSegments.cpp
index 0af54c582..2ea95b56a 100644
--- a/src/passes/LimitSegments.cpp
+++ b/src/passes/LimitSegments.cpp
@@ -21,7 +21,7 @@
namespace wasm {
struct LimitSegments : public Pass {
- void run(PassRunner* runner, Module* module) override {
+ void run(Module* module) override {
if (!MemoryUtils::ensureLimitedSegments(*module)) {
std::cerr << "Unable to merge segments. "
<< "wasm VMs may not accept this binary" << std::endl;
diff --git a/src/passes/LocalCSE.cpp b/src/passes/LocalCSE.cpp
index e777241a4..97d31b9d3 100644
--- a/src/passes/LocalCSE.cpp
+++ b/src/passes/LocalCSE.cpp
@@ -526,7 +526,9 @@ struct LocalCSE : public WalkerPass<PostWalker<LocalCSE>> {
// FIXME DWARF updating does not handle local changes yet.
bool invalidatesDWARF() override { return true; }
- Pass* create() override { return new LocalCSE(); }
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<LocalCSE>();
+ }
void doWalkFunction(Function* func) {
auto& options = getPassOptions();
diff --git a/src/passes/LocalSubtyping.cpp b/src/passes/LocalSubtyping.cpp
index 31e689075..cf8570986 100644
--- a/src/passes/LocalSubtyping.cpp
+++ b/src/passes/LocalSubtyping.cpp
@@ -41,7 +41,9 @@ struct LocalSubtyping : public WalkerPass<PostWalker<LocalSubtyping>> {
// type to be non-nullable if it would validate.
bool requiresNonNullableLocalFixups() override { return false; }
- Pass* create() override { return new LocalSubtyping(); }
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<LocalSubtyping>();
+ }
void doWalkFunction(Function* func) {
if (!getModule()->features.hasGC()) {
diff --git a/src/passes/LoopInvariantCodeMotion.cpp b/src/passes/LoopInvariantCodeMotion.cpp
index c70c8e5fe..61c85d8a4 100644
--- a/src/passes/LoopInvariantCodeMotion.cpp
+++ b/src/passes/LoopInvariantCodeMotion.cpp
@@ -37,7 +37,9 @@ struct LoopInvariantCodeMotion
: public WalkerPass<ExpressionStackWalker<LoopInvariantCodeMotion>> {
bool isFunctionParallel() override { return true; }
- Pass* create() override { return new LoopInvariantCodeMotion; }
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<LoopInvariantCodeMotion>();
+ }
typedef std::unordered_set<LocalSet*> LoopSets;
diff --git a/src/passes/MemoryPacking.cpp b/src/passes/MemoryPacking.cpp
index 0f2cf6f14..98b9c1df7 100644
--- a/src/passes/MemoryPacking.cpp
+++ b/src/passes/MemoryPacking.cpp
@@ -99,11 +99,10 @@ struct MemoryPacking : public Pass {
// TODO: don't run at all if the module has no memories
bool requiresNonNullableLocalFixups() override { return false; }
- void run(PassRunner* runner, Module* module) override;
+ void run(Module* module) override;
bool canOptimize(std::vector<std::unique_ptr<Memory>>& memories,
- std::vector<std::unique_ptr<DataSegment>>& dataSegments,
- const PassOptions& passOptions);
- void optimizeBulkMemoryOps(PassRunner* runner, Module* module);
+ std::vector<std::unique_ptr<DataSegment>>& dataSegments);
+ void optimizeBulkMemoryOps(Module* module);
void getSegmentReferrers(Module* module, ReferrersMap& referrers);
void dropUnusedSegments(Module* module,
std::vector<std::unique_ptr<DataSegment>>& segments,
@@ -123,14 +122,12 @@ struct MemoryPacking : public Pass {
const Referrers& referrers,
Replacements& replacements,
const Index segmentIndex);
- void replaceBulkMemoryOps(PassRunner* runner,
- Module* module,
- Replacements& replacements);
+ void replaceBulkMemoryOps(Module* module, Replacements& replacements);
};
-void MemoryPacking::run(PassRunner* runner, Module* module) {
+void MemoryPacking::run(Module* module) {
// Does not have multi-memories support
- if (!canOptimize(module->memories, module->dataSegments, runner->options)) {
+ if (!canOptimize(module->memories, module->dataSegments)) {
return;
}
@@ -145,7 +142,7 @@ void MemoryPacking::run(PassRunner* runner, Module* module) {
// segments that can be dropped entirely and allows later replacement
// creation to make more assumptions about what these instructions will look
// like, such as memory.inits not having both zero offset and size.
- optimizeBulkMemoryOps(runner, module);
+ optimizeBulkMemoryOps(module);
getSegmentReferrers(module, referrers);
dropUnusedSegments(module, segments, referrers);
}
@@ -181,14 +178,13 @@ void MemoryPacking::run(PassRunner* runner, Module* module) {
module->updateDataSegmentsMap();
if (module->features.hasBulkMemory()) {
- replaceBulkMemoryOps(runner, module, replacements);
+ replaceBulkMemoryOps(module, replacements);
}
}
bool MemoryPacking::canOptimize(
std::vector<std::unique_ptr<Memory>>& memories,
- std::vector<std::unique_ptr<DataSegment>>& dataSegments,
- const PassOptions& passOptions) {
+ std::vector<std::unique_ptr<DataSegment>>& dataSegments) {
if (memories.empty() || memories.size() > 1) {
return false;
}
@@ -196,7 +192,7 @@ bool MemoryPacking::canOptimize(
// We must optimize under the assumption that memory has been initialized to
// zero. That is the case for a memory declared in the module, but for a
// memory that is imported, we must be told that it is zero-initialized.
- if (memory->imported() && !passOptions.zeroFilledMemory) {
+ if (memory->imported() && !getPassOptions().zeroFilledMemory) {
return false;
}
@@ -378,14 +374,16 @@ void MemoryPacking::calculateRanges(const std::unique_ptr<DataSegment>& segment,
std::swap(ranges, mergedRanges);
}
-void MemoryPacking::optimizeBulkMemoryOps(PassRunner* runner, Module* module) {
+void MemoryPacking::optimizeBulkMemoryOps(Module* module) {
struct Optimizer : WalkerPass<PostWalker<Optimizer>> {
bool isFunctionParallel() override { return true; }
// This operates on linear memory, and does not affect reference locals.
bool requiresNonNullableLocalFixups() override { return false; }
- Pass* create() override { return new Optimizer; }
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<Optimizer>();
+ }
bool needsRefinalizing;
@@ -448,7 +446,7 @@ void MemoryPacking::optimizeBulkMemoryOps(PassRunner* runner, Module* module) {
}
}
} optimizer;
- optimizer.run(runner, module);
+ optimizer.run(getPassRunner(), module);
}
void MemoryPacking::getSegmentReferrers(Module* module,
@@ -779,8 +777,7 @@ void MemoryPacking::createReplacements(Module* module,
}
}
-void MemoryPacking::replaceBulkMemoryOps(PassRunner* runner,
- Module* module,
+void MemoryPacking::replaceBulkMemoryOps(Module* module,
Replacements& replacements) {
struct Replacer : WalkerPass<PostWalker<Replacer>> {
bool isFunctionParallel() override { return true; }
@@ -791,7 +788,9 @@ void MemoryPacking::replaceBulkMemoryOps(PassRunner* runner,
Replacements& replacements;
Replacer(Replacements& replacements) : replacements(replacements){};
- Pass* create() override { return new Replacer(replacements); }
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<Replacer>(replacements);
+ }
void visitMemoryInit(MemoryInit* curr) {
auto replacement = replacements.find(curr);
@@ -805,7 +804,7 @@ void MemoryPacking::replaceBulkMemoryOps(PassRunner* runner,
replaceCurrent(replacement->second(getFunction()));
}
} replacer(replacements);
- replacer.run(runner, module);
+ replacer.run(getPassRunner(), module);
}
Pass* createMemoryPackingPass() { return new MemoryPacking(); }
diff --git a/src/passes/MergeBlocks.cpp b/src/passes/MergeBlocks.cpp
index 225f4f05d..45b9ebd9e 100644
--- a/src/passes/MergeBlocks.cpp
+++ b/src/passes/MergeBlocks.cpp
@@ -403,7 +403,9 @@ struct MergeBlocks
PostWalker<MergeBlocks, UnifiedExpressionVisitor<MergeBlocks>>> {
bool isFunctionParallel() override { return true; }
- Pass* create() override { return new MergeBlocks; }
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<MergeBlocks>();
+ }
BranchUtils::BranchSeekerCache branchInfo;
diff --git a/src/passes/MergeLocals.cpp b/src/passes/MergeLocals.cpp
index e478db739..a7f765cb4 100644
--- a/src/passes/MergeLocals.cpp
+++ b/src/passes/MergeLocals.cpp
@@ -62,7 +62,9 @@ struct MergeLocals
// FIXME DWARF updating does not handle local changes yet.
bool invalidatesDWARF() override { return true; }
- Pass* create() override { return new MergeLocals(); }
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<MergeLocals>();
+ }
void doWalkFunction(Function* func) {
// first, instrument the graph by modifying each copy
diff --git a/src/passes/MergeSimilarFunctions.cpp b/src/passes/MergeSimilarFunctions.cpp
index 38cae8059..e5e50423a 100644
--- a/src/passes/MergeSimilarFunctions.cpp
+++ b/src/passes/MergeSimilarFunctions.cpp
@@ -174,7 +174,7 @@ struct EquivalentClass {
struct MergeSimilarFunctions : public Pass {
bool invalidatesDWARF() override { return true; }
- void run(PassRunner* runner, Module* module) override {
+ void run(Module* module) override {
std::vector<EquivalentClass> classes;
collectEquivalentClasses(classes, module);
std::sort(
diff --git a/src/passes/MinifyImportsAndExports.cpp b/src/passes/MinifyImportsAndExports.cpp
index 3e919c799..2105f025c 100644
--- a/src/passes/MinifyImportsAndExports.cpp
+++ b/src/passes/MinifyImportsAndExports.cpp
@@ -59,7 +59,7 @@ private:
// Generates minified names that are valid in JS.
// Names are computed lazily.
- void run(PassRunner* runner, Module* module) override {
+ void run(Module* module) override {
// Minify the imported names.
Names::MinifiedNameGenerator names;
std::map<Name, Name> oldToNew;
diff --git a/src/passes/NameList.cpp b/src/passes/NameList.cpp
index a0078e263..8556065ba 100644
--- a/src/passes/NameList.cpp
+++ b/src/passes/NameList.cpp
@@ -28,7 +28,7 @@ namespace wasm {
struct NameList : public Pass {
bool modifiesBinaryenIR() override { return false; }
- void run(PassRunner* runner, Module* module) override {
+ void run(Module* module) override {
ModuleUtils::iterDefinedFunctions(*module, [&](Function* func) {
std::cout << " " << func->name << " : "
<< Measurer::measure(func->body) << '\n';
diff --git a/src/passes/NameTypes.cpp b/src/passes/NameTypes.cpp
index 3ad35fa1d..fcf6df5ab 100644
--- a/src/passes/NameTypes.cpp
+++ b/src/passes/NameTypes.cpp
@@ -30,7 +30,7 @@ static const size_t NameLenLimit = 20;
struct NameTypes : public Pass {
bool requiresNonNullableLocalFixups() override { return false; }
- void run(PassRunner* runner, Module* module) override {
+ void run(Module* module) override {
// Find all the types.
std::vector<HeapType> types = ModuleUtils::collectHeapTypes(*module);
diff --git a/src/passes/OnceReduction.cpp b/src/passes/OnceReduction.cpp
index 1eb76c29e..c1500f185 100644
--- a/src/passes/OnceReduction.cpp
+++ b/src/passes/OnceReduction.cpp
@@ -88,7 +88,9 @@ struct Scanner : public WalkerPass<PostWalker<Scanner>> {
Scanner(OptInfo& optInfo) : optInfo(optInfo) {}
- Scanner* create() override { return new Scanner(optInfo); }
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<Scanner>(optInfo);
+ }
// All the globals we read from. Any read of a global prevents us from
// optimizing, unless it is the single read at the top of an "only" function
@@ -219,7 +221,9 @@ struct Optimizer
Optimizer(OptInfo& optInfo) : optInfo(optInfo) {}
- Optimizer* create() override { return new Optimizer(optInfo); }
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<Optimizer>(optInfo);
+ }
void visitGlobalSet(GlobalSet* curr) {
if (currBasicBlock) {
@@ -344,7 +348,7 @@ private:
} // anonymous namespace
struct OnceReduction : public Pass {
- void run(PassRunner* runner, Module* module) override {
+ void run(Module* module) override {
OptInfo optInfo;
// Fill out the initial data.
@@ -374,7 +378,7 @@ struct OnceReduction : public Pass {
}
// Scan the module to find out which globals and functions are "once".
- Scanner(optInfo).run(runner, module);
+ Scanner(optInfo).run(getPassRunner(), module);
// Combine the information. We found which globals appear to be "once", but
// other information may have proven they are not so, in fact. Specifically,
@@ -419,7 +423,7 @@ struct OnceReduction : public Pass {
optInfo.newOnceGlobalsSetInFuncs[func->name];
}
- Optimizer(optInfo).run(runner, module);
+ Optimizer(optInfo).run(getPassRunner(), module);
optInfo.onceGlobalsSetInFuncs =
std::move(optInfo.newOnceGlobalsSetInFuncs);
diff --git a/src/passes/OptimizeAddedConstants.cpp b/src/passes/OptimizeAddedConstants.cpp
index f48989d5b..aadff5112 100644
--- a/src/passes/OptimizeAddedConstants.cpp
+++ b/src/passes/OptimizeAddedConstants.cpp
@@ -264,7 +264,9 @@ struct OptimizeAddedConstants
OptimizeAddedConstants(bool propagate) : propagate(propagate) {}
- Pass* create() override { return new OptimizeAddedConstants(propagate); }
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<OptimizeAddedConstants>(propagate);
+ }
void visitLoad(Load* curr) {
MemoryAccessOptimizer<OptimizeAddedConstants, Load> optimizer(
diff --git a/src/passes/OptimizeForJS.cpp b/src/passes/OptimizeForJS.cpp
index 589374c06..0f68412dd 100644
--- a/src/passes/OptimizeForJS.cpp
+++ b/src/passes/OptimizeForJS.cpp
@@ -28,7 +28,9 @@ namespace wasm {
struct OptimizeForJSPass : public WalkerPass<PostWalker<OptimizeForJSPass>> {
bool isFunctionParallel() override { return true; }
- Pass* create() override { return new OptimizeForJSPass; }
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<OptimizeForJSPass>();
+ }
void visitBinary(Binary* curr) {
using namespace Abstract;
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp
index e9cf3baaa..fc034a24f 100644
--- a/src/passes/OptimizeInstructions.cpp
+++ b/src/passes/OptimizeInstructions.cpp
@@ -201,7 +201,9 @@ struct OptimizeInstructions
: public WalkerPass<PostWalker<OptimizeInstructions>> {
bool isFunctionParallel() override { return true; }
- Pass* create() override { return new OptimizeInstructions; }
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<OptimizeInstructions>();
+ }
bool fastMath;
diff --git a/src/passes/PickLoadSigns.cpp b/src/passes/PickLoadSigns.cpp
index f55013ff3..d30e0a381 100644
--- a/src/passes/PickLoadSigns.cpp
+++ b/src/passes/PickLoadSigns.cpp
@@ -28,7 +28,9 @@ namespace wasm {
struct PickLoadSigns : public WalkerPass<ExpressionStackWalker<PickLoadSigns>> {
bool isFunctionParallel() override { return true; }
- Pass* create() override { return new PickLoadSigns; }
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<PickLoadSigns>();
+ }
struct Usage {
Index signedUsages = 0;
diff --git a/src/passes/Poppify.cpp b/src/passes/Poppify.cpp
index f787fb904..582753c4b 100644
--- a/src/passes/Poppify.cpp
+++ b/src/passes/Poppify.cpp
@@ -447,21 +447,22 @@ void Poppifier::poppify(Expression* expr) {
class PoppifyFunctionsPass : public Pass {
bool isFunctionParallel() override { return true; }
- void
- runOnFunction(PassRunner* runner, Module* module, Function* func) override {
+ void runOnFunction(Module* module, Function* func) override {
if (func->profile != IRProfile::Poppy) {
Poppifier(func, module).write();
func->profile = IRProfile::Poppy;
}
}
- Pass* create() override { return new PoppifyFunctionsPass; }
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<PoppifyFunctionsPass>();
+ }
};
} // anonymous namespace
class PoppifyPass : public Pass {
- void run(PassRunner* runner, Module* module) {
- PassRunner subRunner(runner);
+ void run(Module* module) {
+ PassRunner subRunner(getPassRunner());
subRunner.add(std::make_unique<PoppifyFunctionsPass>());
// TODO: Enable this once it handles Poppy blocks correctly
// subRunner.add(std::make_unique<ReFinalize>());
diff --git a/src/passes/PostEmscripten.cpp b/src/passes/PostEmscripten.cpp
index b4828a852..e17c529bb 100644
--- a/src/passes/PostEmscripten.cpp
+++ b/src/passes/PostEmscripten.cpp
@@ -46,7 +46,9 @@ struct SegmentRemover : WalkerPass<PostWalker<SegmentRemover>> {
bool isFunctionParallel() override { return true; }
- Pass* create() override { return new SegmentRemover(segment); }
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<SegmentRemover>(segment);
+ }
void visitMemoryInit(MemoryInit* curr) {
if (segment == curr->segment) {
@@ -197,14 +199,14 @@ struct EmJsWalker : public PostWalker<EmJsWalker> {
} // namespace
struct PostEmscripten : public Pass {
- void run(PassRunner* runner, Module* module) override {
- removeExports(runner, *module);
- removeEmJsExports(runner, *module);
+ void run(Module* module) override {
+ removeExports(*module);
+ removeEmJsExports(*module);
// Optimize exceptions
- optimizeExceptions(runner, module);
+ optimizeExceptions(module);
}
- void removeExports(PassRunner* runner, Module& module) {
+ void removeExports(Module& module) {
std::vector<Address> segmentOffsets; // segment index => address offset
calcSegmentOffsets(module, segmentOffsets);
@@ -216,7 +218,7 @@ struct PostEmscripten : public Pass {
module.removeExport("__stop_em_js");
}
- void removeEmJsExports(PassRunner* runner, Module& module) {
+ void removeEmJsExports(Module& module) {
EmJsWalker walker;
walker.walkModule(&module);
for (const Export& exp : walker.toRemove) {
@@ -233,7 +235,7 @@ struct PostEmscripten : public Pass {
// An invoke is a call to JS with a function pointer; JS does a try-catch
// and calls the pointer, catching and reporting any error. If we know no
// exception will be thrown, we can simply skip the invoke.
- void optimizeExceptions(PassRunner* runner, Module* module) {
+ void optimizeExceptions(Module* module) {
// First, check if this code even uses invokes.
bool hasInvokes = false;
for (auto& imp : module->functions) {
@@ -277,7 +279,9 @@ struct PostEmscripten : public Pass {
struct OptimizeInvokes : public WalkerPass<PostWalker<OptimizeInvokes>> {
bool isFunctionParallel() override { return true; }
- Pass* create() override { return new OptimizeInvokes(map, flatTable); }
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<OptimizeInvokes>(map, flatTable);
+ }
std::map<Function*, Info>& map;
TableUtils::FlatTable& flatTable;
@@ -317,7 +321,7 @@ struct PostEmscripten : public Pass {
}
}
};
- OptimizeInvokes(analyzer.map, flatTable).run(runner, module);
+ OptimizeInvokes(analyzer.map, flatTable).run(getPassRunner(), module);
}
};
diff --git a/src/passes/Precompute.cpp b/src/passes/Precompute.cpp
index 35f218362..466614d14 100644
--- a/src/passes/Precompute.cpp
+++ b/src/passes/Precompute.cpp
@@ -199,7 +199,9 @@ struct Precompute
PostWalker<Precompute, UnifiedExpressionVisitor<Precompute>>> {
bool isFunctionParallel() override { return true; }
- Pass* create() override { return new Precompute(propagate); }
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<Precompute>(propagate);
+ }
bool propagate = false;
diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp
index 2a031ad01..01b004d97 100644
--- a/src/passes/Print.cpp
+++ b/src/passes/Print.cpp
@@ -3365,9 +3365,9 @@ public:
bool modifiesBinaryenIR() override { return false; }
- void run(PassRunner* runner, Module* module) override {
+ void run(Module* module) override {
PrintSExpression print(o);
- print.setDebugInfo(runner->options.debugInfo);
+ print.setDebugInfo(getPassOptions().debugInfo);
print.visitModule(module);
}
};
@@ -3381,10 +3381,10 @@ public:
MinifiedPrinter() = default;
MinifiedPrinter(std::ostream* o) : Printer(o) {}
- void run(PassRunner* runner, Module* module) override {
+ void run(Module* module) override {
PrintSExpression print(o);
print.setMinify(true);
- print.setDebugInfo(runner->options.debugInfo);
+ print.setDebugInfo(getPassOptions().debugInfo);
print.visitModule(module);
}
};
@@ -3398,10 +3398,10 @@ public:
FullPrinter() = default;
FullPrinter(std::ostream* o) : Printer(o) {}
- void run(PassRunner* runner, Module* module) override {
+ void run(Module* module) override {
PrintSExpression print(o);
print.setFull(true);
- print.setDebugInfo(runner->options.debugInfo);
+ print.setDebugInfo(getPassOptions().debugInfo);
print.currModule = module;
print.visitModule(module);
}
@@ -3416,9 +3416,9 @@ public:
PrintStackIR() = default;
PrintStackIR(std::ostream* o) : Printer(o) {}
- void run(PassRunner* runner, Module* module) override {
+ void run(Module* module) override {
PrintSExpression print(o);
- print.setDebugInfo(runner->options.debugInfo);
+ print.setDebugInfo(getPassOptions().debugInfo);
print.setStackIR(true);
print.currModule = module;
print.visitModule(module);
@@ -3603,7 +3603,12 @@ namespace std {
std::ostream& operator<<(std::ostream& o, wasm::Module& module) {
wasm::PassRunner runner(&module);
- wasm::Printer(&o).run(&runner, &module);
+ wasm::Printer printer(&o);
+ // Do not use runner.run(), since that will cause an infinite recursion in
+ // BINARYEN_PASS_DEBUG=3, which prints modules (using this function) as part
+ // of running passes.
+ printer.setPassRunner(&runner);
+ printer.run(&module);
return o;
}
diff --git a/src/passes/PrintCallGraph.cpp b/src/passes/PrintCallGraph.cpp
index 79938e650..6022c8703 100644
--- a/src/passes/PrintCallGraph.cpp
+++ b/src/passes/PrintCallGraph.cpp
@@ -33,7 +33,7 @@ namespace wasm {
struct PrintCallGraph : public Pass {
bool modifiesBinaryenIR() override { return false; }
- void run(PassRunner* runner, Module* module) override {
+ void run(Module* module) override {
std::ostream& o = std::cout;
o << "digraph call {\n"
" rankdir = LR;\n"
diff --git a/src/passes/PrintFeatures.cpp b/src/passes/PrintFeatures.cpp
index 6b89e18d6..4b7e201e9 100644
--- a/src/passes/PrintFeatures.cpp
+++ b/src/passes/PrintFeatures.cpp
@@ -27,7 +27,7 @@ namespace wasm {
struct PrintFeatures : public Pass {
bool modifiesBinaryenIR() override { return false; }
- void run(PassRunner* runner, Module* module) override {
+ void run(Module* module) override {
module->features.iterFeatures([](FeatureSet::Feature f) {
std::cout << "--enable-" << FeatureSet::toString(f) << std::endl;
});
diff --git a/src/passes/PrintFunctionMap.cpp b/src/passes/PrintFunctionMap.cpp
index 325f4e48d..08f5a359b 100644
--- a/src/passes/PrintFunctionMap.cpp
+++ b/src/passes/PrintFunctionMap.cpp
@@ -34,10 +34,10 @@ namespace wasm {
struct PrintFunctionMap : public Pass {
bool modifiesBinaryenIR() override { return false; }
- void run(PassRunner* runner, Module* module) override {
+ void run(Module* module) override {
// If an argument is provided, write to that file; otherwise write to
// stdout.
- auto outFile = runner->options.getArgumentOrDefault("symbolmap", "");
+ auto outFile = getPassOptions().getArgumentOrDefault("symbolmap", "");
Output output(outFile, Flags::Text);
auto& o = output.getStream();
Index i = 0;
diff --git a/src/passes/ReReloop.cpp b/src/passes/ReReloop.cpp
index 4499bb07b..9fef75367 100644
--- a/src/passes/ReReloop.cpp
+++ b/src/passes/ReReloop.cpp
@@ -36,7 +36,9 @@ namespace wasm {
struct ReReloop final : public Pass {
bool isFunctionParallel() override { return true; }
- Pass* create() override { return new ReReloop; }
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<ReReloop>();
+ }
std::unique_ptr<CFG::Relooper> relooper;
std::unique_ptr<Builder> builder;
@@ -291,9 +293,7 @@ struct ReReloop final : public Pass {
// TODO: optimize with this?
}
- void runOnFunction(PassRunner* runner,
- Module* module,
- Function* function) override {
+ void runOnFunction(Module* module, Function* function) override {
Flat::verifyFlatness(function);
// since control flow is flattened, this is pretty simple
diff --git a/src/passes/RedundantSetElimination.cpp b/src/passes/RedundantSetElimination.cpp
index 0b4cad056..9a60331dd 100644
--- a/src/passes/RedundantSetElimination.cpp
+++ b/src/passes/RedundantSetElimination.cpp
@@ -63,7 +63,9 @@ struct RedundantSetElimination
Info>> {
bool isFunctionParallel() override { return true; }
- Pass* create() override { return new RedundantSetElimination(); }
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<RedundantSetElimination>();
+ }
Index numLocals;
diff --git a/src/passes/RemoveMemory.cpp b/src/passes/RemoveMemory.cpp
index 6f2f9aee7..1520be1e8 100644
--- a/src/passes/RemoveMemory.cpp
+++ b/src/passes/RemoveMemory.cpp
@@ -24,7 +24,7 @@
namespace wasm {
struct RemoveMemory : public Pass {
- void run(PassRunner* runner, Module* module) override {
+ void run(Module* module) override {
module->removeDataSegments([&](DataSegment* curr) { return true; });
}
};
diff --git a/src/passes/RemoveNonJSOps.cpp b/src/passes/RemoveNonJSOps.cpp
index 84df4ec1e..227046b81 100644
--- a/src/passes/RemoveNonJSOps.cpp
+++ b/src/passes/RemoveNonJSOps.cpp
@@ -56,7 +56,9 @@ struct RemoveNonJSOpsPass : public WalkerPass<PostWalker<RemoveNonJSOpsPass>> {
bool isFunctionParallel() override { return false; }
- Pass* create() override { return new RemoveNonJSOpsPass; }
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<RemoveNonJSOpsPass>();
+ }
void doWalkModule(Module* module) {
// Intrinsics may use scratch memory, ensure it.
@@ -339,7 +341,9 @@ struct StubUnsupportedJSOpsPass
: public WalkerPass<PostWalker<StubUnsupportedJSOpsPass>> {
bool isFunctionParallel() override { return true; }
- Pass* create() override { return new StubUnsupportedJSOpsPass; }
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<StubUnsupportedJSOpsPass>();
+ }
void visitUnary(Unary* curr) {
switch (curr->op) {
diff --git a/src/passes/RemoveUnusedBrs.cpp b/src/passes/RemoveUnusedBrs.cpp
index b867dc4c2..e0f82b4a4 100644
--- a/src/passes/RemoveUnusedBrs.cpp
+++ b/src/passes/RemoveUnusedBrs.cpp
@@ -117,7 +117,9 @@ static bool tooCostlyToRunUnconditionally(const PassOptions& passOptions,
struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> {
bool isFunctionParallel() override { return true; }
- Pass* create() override { return new RemoveUnusedBrs; }
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<RemoveUnusedBrs>();
+ }
bool anotherCycle;
diff --git a/src/passes/RemoveUnusedModuleElements.cpp b/src/passes/RemoveUnusedModuleElements.cpp
index 139f6f655..c77bff9af 100644
--- a/src/passes/RemoveUnusedModuleElements.cpp
+++ b/src/passes/RemoveUnusedModuleElements.cpp
@@ -239,7 +239,7 @@ struct RemoveUnusedModuleElements : public Pass {
RemoveUnusedModuleElements(bool rootAllFunctions)
: rootAllFunctions(rootAllFunctions) {}
- void run(PassRunner* runner, Module* module) override {
+ void run(Module* module) override {
std::vector<ModuleElement> roots;
// Module start is a root.
if (module->start.is()) {
diff --git a/src/passes/RemoveUnusedNames.cpp b/src/passes/RemoveUnusedNames.cpp
index 4c74245f0..e7cc4aef6 100644
--- a/src/passes/RemoveUnusedNames.cpp
+++ b/src/passes/RemoveUnusedNames.cpp
@@ -35,7 +35,9 @@ struct RemoveUnusedNames
// without names are ignored, see the README section on non-nullable locals).
bool requiresNonNullableLocalFixups() override { return false; }
- Pass* create() override { return new RemoveUnusedNames; }
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<RemoveUnusedNames>();
+ }
// We maintain a list of branches that we saw in children, then when we reach
// a parent block, we know if it was branched to
diff --git a/src/passes/ReorderFunctions.cpp b/src/passes/ReorderFunctions.cpp
index 6f87e74a6..b6c7a4984 100644
--- a/src/passes/ReorderFunctions.cpp
+++ b/src/passes/ReorderFunctions.cpp
@@ -44,7 +44,9 @@ struct CallCountScanner : public WalkerPass<PostWalker<CallCountScanner>> {
CallCountScanner(NameCountMap* counts) : counts(counts) {}
- CallCountScanner* create() override { return new CallCountScanner(counts); }
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<CallCountScanner>(counts);
+ }
void visitCall(Call* curr) {
// can't add a new element in parallel
@@ -60,7 +62,7 @@ struct ReorderFunctions : public Pass {
// Only reorders functions, does not change their contents.
bool requiresNonNullableLocalFixups() override { return false; }
- void run(PassRunner* runner, Module* module) override {
+ void run(Module* module) override {
NameCountMap counts;
// fill in info, as we operate on it in parallel (each function to its own
// entry)
@@ -68,7 +70,7 @@ struct ReorderFunctions : public Pass {
counts[func->name];
}
// find counts on function calls
- CallCountScanner(&counts).run(runner, module);
+ CallCountScanner(&counts).run(getPassRunner(), module);
// find counts on global usages
if (module->start.is()) {
counts[module->start]++;
diff --git a/src/passes/ReorderLocals.cpp b/src/passes/ReorderLocals.cpp
index ce06afd68..d931cca2a 100644
--- a/src/passes/ReorderLocals.cpp
+++ b/src/passes/ReorderLocals.cpp
@@ -35,7 +35,9 @@ struct ReorderLocals : public WalkerPass<PostWalker<ReorderLocals>> {
// Sorting and removing unused locals cannot affect validation.
bool requiresNonNullableLocalFixups() override { return false; }
- Pass* create() override { return new ReorderLocals; }
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<ReorderLocals>();
+ }
// local index => times it is used
std::vector<Index> counts;
diff --git a/src/passes/RoundTrip.cpp b/src/passes/RoundTrip.cpp
index f2bdffefb..0e289d529 100644
--- a/src/passes/RoundTrip.cpp
+++ b/src/passes/RoundTrip.cpp
@@ -28,7 +28,7 @@
namespace wasm {
struct RoundTrip : public Pass {
- void run(PassRunner* runner, Module* module) override {
+ void run(Module* module) override {
BufferWithRandomAccess buffer;
// Save features, which would not otherwise make it through a round trip if
// the target features section has been stripped. We also need them in order
@@ -39,7 +39,7 @@ struct RoundTrip : public Pass {
ModuleUtils::clearModule(*module);
auto input = buffer.getAsChars();
WasmBinaryBuilder parser(*module, features, input);
- parser.setDWARF(runner->options.debugInfo);
+ parser.setDWARF(getPassOptions().debugInfo);
try {
parser.read();
} catch (ParseException& p) {
diff --git a/src/passes/SSAify.cpp b/src/passes/SSAify.cpp
index 089def301..3d9b8bda6 100644
--- a/src/passes/SSAify.cpp
+++ b/src/passes/SSAify.cpp
@@ -73,7 +73,9 @@ struct SSAify : public Pass {
// FIXME DWARF updating does not handle local changes yet.
bool invalidatesDWARF() override { return true; }
- Pass* create() override { return new SSAify(allowMerges); }
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<SSAify>(allowMerges);
+ }
SSAify(bool allowMerges) : allowMerges(allowMerges) {}
@@ -84,8 +86,7 @@ struct SSAify : public Pass {
// things we add to the function prologue
std::vector<Expression*> functionPrepends;
- void
- runOnFunction(PassRunner* runner, Module* module_, Function* func_) override {
+ void runOnFunction(Module* module_, Function* func_) override {
module = module_;
func = func_;
LocalGraph graph(func);
diff --git a/src/passes/SafeHeap.cpp b/src/passes/SafeHeap.cpp
index eccb521d2..0e9e8aeef 100644
--- a/src/passes/SafeHeap.cpp
+++ b/src/passes/SafeHeap.cpp
@@ -69,8 +69,8 @@ struct AccessInstrumenter : public WalkerPass<PostWalker<AccessInstrumenter>> {
bool isFunctionParallel() override { return true; }
- AccessInstrumenter* create() override {
- return new AccessInstrumenter(ignoreFunctions);
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<AccessInstrumenter>(ignoreFunctions);
}
AccessInstrumenter(std::set<Name> ignoreFunctions)
@@ -131,10 +131,8 @@ static std::set<Name> findCalledFunctions(Module* module, Name startFunc) {
}
struct SafeHeap : public Pass {
- PassOptions options;
- void run(PassRunner* runner, Module* module) override {
- options = runner->options;
+ void run(Module* module) override {
assert(!module->memories.empty());
// add imports
addImports(module);
@@ -147,7 +145,7 @@ struct SafeHeap : public Pass {
// not available until after it has run.
std::set<Name> ignoreFunctions = findCalledFunctions(module, module->start);
ignoreFunctions.insert(getSbrkPtr);
- AccessInstrumenter(ignoreFunctions).run(runner, module);
+ AccessInstrumenter(ignoreFunctions).run(getPassRunner(), module);
// add helper checking funcs and imports
addGlobals(module, module->features);
}
@@ -394,9 +392,10 @@ struct SafeHeap : public Pass {
Type indexType,
bool is64,
Name memory) {
- auto upperOp = is64 ? options.lowMemoryUnused ? LtUInt64 : EqInt64
- : options.lowMemoryUnused ? LtUInt32 : EqInt32;
- auto upperBound = options.lowMemoryUnused ? PassOptions::LowMemoryBound : 0;
+ bool lowMemUnused = getPassOptions().lowMemoryUnused;
+ auto upperOp = is64 ? lowMemUnused ? LtUInt64 : EqInt64
+ : lowMemUnused ? LtUInt32 : EqInt32;
+ auto upperBound = lowMemUnused ? PassOptions::LowMemoryBound : 0;
Expression* brkLocation;
if (sbrk.is()) {
brkLocation =
diff --git a/src/passes/SetGlobals.cpp b/src/passes/SetGlobals.cpp
index 4109eb69b..58a82a50b 100644
--- a/src/passes/SetGlobals.cpp
+++ b/src/passes/SetGlobals.cpp
@@ -28,8 +28,8 @@ struct SetGlobals : public Pass {
// Only modifies globals.
bool requiresNonNullableLocalFixups() override { return false; }
- void run(PassRunner* runner, Module* module) override {
- Name input = runner->options.getArgument(
+ void run(Module* module) override {
+ Name input = getPassRunner()->options.getArgument(
"set-globals",
"SetGlobals usage: wasm-opt --pass-arg=set-globals@x=y,z=w");
diff --git a/src/passes/SignaturePruning.cpp b/src/passes/SignaturePruning.cpp
index ca7bd0548..4e6334057 100644
--- a/src/passes/SignaturePruning.cpp
+++ b/src/passes/SignaturePruning.cpp
@@ -48,7 +48,7 @@ struct SignaturePruning : public Pass {
// type has no improvement that we can find, it will not appear in this map.
std::unordered_map<HeapType, Signature> newSignatures;
- void run(PassRunner* runner, Module* module) override {
+ void run(Module* module) override {
if (!module->features.hasGC()) {
return;
}
@@ -193,8 +193,12 @@ struct SignaturePruning : public Pass {
}
auto oldParams = sig.params;
- auto removedIndexes = ParamUtils::removeParameters(
- funcs, unusedParams, info.calls, info.callRefs, module, runner);
+ auto removedIndexes = ParamUtils::removeParameters(funcs,
+ unusedParams,
+ info.calls,
+ info.callRefs,
+ module,
+ getPassRunner());
if (removedIndexes.empty()) {
continue;
}
diff --git a/src/passes/SignatureRefining.cpp b/src/passes/SignatureRefining.cpp
index d00626fca..488e2c6cc 100644
--- a/src/passes/SignatureRefining.cpp
+++ b/src/passes/SignatureRefining.cpp
@@ -50,7 +50,7 @@ struct SignatureRefining : public Pass {
// will not appear in this map.
std::unordered_map<HeapType, Signature> newSignatures;
- void run(PassRunner* runner, Module* module) override {
+ void run(Module* module) override {
if (!module->features.hasGC()) {
return;
}
@@ -254,7 +254,9 @@ struct SignatureRefining : public Pass {
CodeUpdater(SignatureRefining& parent, Module& wasm)
: parent(parent), wasm(wasm) {}
- CodeUpdater* create() override { return new CodeUpdater(parent, wasm); }
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<CodeUpdater>(parent, wasm);
+ }
void doWalkFunction(Function* func) {
auto iter = parent.newSignatures.find(func->type);
@@ -275,7 +277,7 @@ struct SignatureRefining : public Pass {
}
}
};
- CodeUpdater(*this, *module).run(runner, module);
+ CodeUpdater(*this, *module).run(getPassRunner(), module);
// Rewrite the types.
GlobalTypeRewriter::updateSignatures(newSignatures, *module);
@@ -283,7 +285,7 @@ struct SignatureRefining : public Pass {
if (refinedResults) {
// After return types change we need to propagate.
// TODO: we could do this only in relevant functions perhaps
- ReFinalize().run(runner, module);
+ ReFinalize().run(getPassRunner(), module);
}
}
};
diff --git a/src/passes/SimplifyGlobals.cpp b/src/passes/SimplifyGlobals.cpp
index daaa82447..463261d35 100644
--- a/src/passes/SimplifyGlobals.cpp
+++ b/src/passes/SimplifyGlobals.cpp
@@ -97,7 +97,9 @@ struct GlobalUseScanner : public WalkerPass<PostWalker<GlobalUseScanner>> {
GlobalUseScanner(GlobalInfoMap* infos) : infos(infos) {}
- GlobalUseScanner* create() override { return new GlobalUseScanner(infos); }
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<GlobalUseScanner>(infos);
+ }
void visitGlobalSet(GlobalSet* curr) {
(*infos)[curr->name].written++;
@@ -307,8 +309,8 @@ struct GlobalUseModifier : public WalkerPass<PostWalker<GlobalUseModifier>> {
GlobalUseModifier(NameNameMap* copiedParentMap)
: copiedParentMap(copiedParentMap) {}
- GlobalUseModifier* create() override {
- return new GlobalUseModifier(copiedParentMap);
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<GlobalUseModifier>(copiedParentMap);
}
void visitGlobalGet(GlobalGet* curr) {
@@ -331,8 +333,8 @@ struct ConstantGlobalApplier
ConstantGlobalApplier(NameSet* constantGlobals, bool optimize)
: constantGlobals(constantGlobals), optimize(optimize) {}
- ConstantGlobalApplier* create() override {
- return new ConstantGlobalApplier(constantGlobals, optimize);
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<ConstantGlobalApplier>(constantGlobals, optimize);
}
void visitExpression(Expression* curr) {
@@ -377,8 +379,7 @@ struct ConstantGlobalApplier
void visitFunction(Function* curr) {
if (replaced && optimize) {
- PassRunner runner(getModule(), getPassRunner()->options);
- runner.setIsNested(true);
+ PassRunner runner(getPassRunner());
runner.addDefaultFunctionOptimizationPasses();
runner.runOnFunction(curr);
}
@@ -399,8 +400,8 @@ struct GlobalSetRemover : public WalkerPass<PostWalker<GlobalSetRemover>> {
bool isFunctionParallel() override { return true; }
- GlobalSetRemover* create() override {
- return new GlobalSetRemover(toRemove, optimize);
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<GlobalSetRemover>(toRemove, optimize);
}
void visitGlobalSet(GlobalSet* curr) {
@@ -412,8 +413,7 @@ struct GlobalSetRemover : public WalkerPass<PostWalker<GlobalSetRemover>> {
void visitFunction(Function* curr) {
if (removed && optimize) {
- PassRunner runner(getModule(), getPassRunner()->options);
- runner.setIsNested(true);
+ PassRunner runner(getPassRunner());
runner.addDefaultFunctionOptimizationPasses();
runner.runOnFunction(curr);
}
@@ -428,7 +428,6 @@ private:
} // anonymous namespace
struct SimplifyGlobals : public Pass {
- PassRunner* runner;
Module* module;
GlobalInfoMap map;
@@ -436,8 +435,7 @@ struct SimplifyGlobals : public Pass {
SimplifyGlobals(bool optimize = false) : optimize(optimize) {}
- void run(PassRunner* runner_, Module* module_) override {
- runner = runner_;
+ void run(Module* module_) override {
module = module_;
while (iteration()) {
@@ -475,7 +473,7 @@ struct SimplifyGlobals : public Pass {
map[ex->value].exported = true;
}
}
- GlobalUseScanner(&map).run(runner, module);
+ GlobalUseScanner(&map).run(getPassRunner(), module);
// We now know which are immutable in practice.
for (auto& global : module->globals) {
auto& info = map[global->name];
@@ -564,7 +562,8 @@ struct SimplifyGlobals : public Pass {
// then see that since the global has no writes, it is a constant, which
// will lead to removal of gets, and after removing them, the global itself
// will be removed as well.
- GlobalSetRemover(&globalsNotNeedingSets, optimize).run(runner, module);
+ GlobalSetRemover(&globalsNotNeedingSets, optimize)
+ .run(getPassRunner(), module);
return more;
}
@@ -595,7 +594,7 @@ struct SimplifyGlobals : public Pass {
}
}
// Apply to the gets.
- GlobalUseModifier(&copiedParentMap).run(runner, module);
+ GlobalUseModifier(&copiedParentMap).run(getPassRunner(), module);
}
}
@@ -633,7 +632,8 @@ struct SimplifyGlobals : public Pass {
constantGlobals.insert(global->name);
}
}
- ConstantGlobalApplier(&constantGlobals, optimize).run(runner, module);
+ ConstantGlobalApplier(&constantGlobals, optimize)
+ .run(getPassRunner(), module);
}
};
diff --git a/src/passes/SimplifyLocals.cpp b/src/passes/SimplifyLocals.cpp
index 6250b1321..dfbc7551a 100644
--- a/src/passes/SimplifyLocals.cpp
+++ b/src/passes/SimplifyLocals.cpp
@@ -71,8 +71,9 @@ struct SimplifyLocals
SimplifyLocals<allowTee, allowStructure, allowNesting>>> {
bool isFunctionParallel() override { return true; }
- Pass* create() override {
- return new SimplifyLocals<allowTee, allowStructure, allowNesting>();
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<
+ SimplifyLocals<allowTee, allowStructure, allowNesting>>();
}
// information for a local.set we can sink
diff --git a/src/passes/SpillPointers.cpp b/src/passes/SpillPointers.cpp
index 04193c2d2..991a7b8c1 100644
--- a/src/passes/SpillPointers.cpp
+++ b/src/passes/SpillPointers.cpp
@@ -37,7 +37,9 @@ struct SpillPointers
: public WalkerPass<LivenessWalker<SpillPointers, Visitor<SpillPointers>>> {
bool isFunctionParallel() override { return true; }
- Pass* create() override { return new SpillPointers; }
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<SpillPointers>();
+ }
// a mapping of the pointers to all the spillable things. We need to know
// how to replace them, and as we spill we may modify them. This map
diff --git a/src/passes/StackCheck.cpp b/src/passes/StackCheck.cpp
index 11ab1fe4e..9fba683b8 100644
--- a/src/passes/StackCheck.cpp
+++ b/src/passes/StackCheck.cpp
@@ -70,8 +70,8 @@ struct EnforceStackLimits : public WalkerPass<PostWalker<EnforceStackLimits>> {
// Only affects linear memory operations.
bool requiresNonNullableLocalFixups() override { return false; }
- Pass* create() override {
- return new EnforceStackLimits(
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<EnforceStackLimits>(
stackPointer, stackBase, stackLimit, builder, handler);
}
@@ -126,7 +126,7 @@ private:
};
struct StackCheck : public Pass {
- void run(PassRunner* runner, Module* module) override {
+ void run(Module* module) override {
Global* stackPointer = getStackPointerGlobal(*module);
if (!stackPointer) {
BYN_DEBUG(std::cerr << "no stack pointer found\n");
@@ -139,7 +139,7 @@ struct StackCheck : public Pass {
Name handler;
auto handlerName =
- runner->options.getArgumentOrDefault("stack-check-handler", "");
+ getPassOptions().getArgumentOrDefault("stack-check-handler", "");
if (handlerName != "") {
handler = handlerName;
importStackOverflowHandler(
@@ -163,9 +163,8 @@ struct StackCheck : public Pass {
Builder::Mutable));
// Instrument all the code.
- PassRunner innerRunner(module);
EnforceStackLimits(stackPointer, stackBase, stackLimit, builder, handler)
- .run(&innerRunner, module);
+ .run(getPassRunner(), module);
// Generate the exported function.
auto limitsFunc = builder.makeFunction(
diff --git a/src/passes/StackIR.cpp b/src/passes/StackIR.cpp
index e896af0f5..2614a36a1 100644
--- a/src/passes/StackIR.cpp
+++ b/src/passes/StackIR.cpp
@@ -31,7 +31,9 @@ namespace wasm {
struct GenerateStackIR : public WalkerPass<PostWalker<GenerateStackIR>> {
bool isFunctionParallel() override { return true; }
- Pass* create() override { return new GenerateStackIR; }
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<GenerateStackIR>();
+ }
bool modifiesBinaryenIR() override { return false; }
@@ -336,7 +338,9 @@ private:
struct OptimizeStackIR : public WalkerPass<PostWalker<OptimizeStackIR>> {
bool isFunctionParallel() override { return true; }
- Pass* create() override { return new OptimizeStackIR; }
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<OptimizeStackIR>();
+ }
bool modifiesBinaryenIR() override { return false; }
diff --git a/src/passes/Strip.cpp b/src/passes/Strip.cpp
index 7c9f61061..00cd87ae0 100644
--- a/src/passes/Strip.cpp
+++ b/src/passes/Strip.cpp
@@ -36,7 +36,7 @@ struct Strip : public Pass {
Strip(Decider decider) : decider(decider) {}
- void run(PassRunner* runner, Module* module) override {
+ void run(Module* module) override {
// Remove name and debug sections.
auto& sections = module->userSections;
sections.erase(std::remove_if(sections.begin(), sections.end(), decider),
diff --git a/src/passes/StripTargetFeatures.cpp b/src/passes/StripTargetFeatures.cpp
index 878004a98..cb5b8c814 100644
--- a/src/passes/StripTargetFeatures.cpp
+++ b/src/passes/StripTargetFeatures.cpp
@@ -23,7 +23,7 @@ struct StripTargetFeatures : public Pass {
bool isStripped = false;
StripTargetFeatures(bool isStripped) : isStripped(isStripped) {}
- void run(PassRunner* runner, Module* module) override {
+ void run(Module* module) override {
module->hasFeaturesSection = !isStripped;
}
};
diff --git a/src/passes/TrapMode.cpp b/src/passes/TrapMode.cpp
index ee245af88..8ea6fbfa1 100644
--- a/src/passes/TrapMode.cpp
+++ b/src/passes/TrapMode.cpp
@@ -306,7 +306,9 @@ public:
TrapModePass(TrapMode mode) : mode(mode) { assert(mode != TrapMode::Allow); }
- Pass* create() override { return new TrapModePass(mode); }
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<TrapModePass>(mode);
+ }
void visitUnary(Unary* curr) {
replaceCurrent(makeTrappingUnary(curr, *trappingFunctions));
diff --git a/src/passes/TypeRefining.cpp b/src/passes/TypeRefining.cpp
index 3d3f981db..6ce503cc0 100644
--- a/src/passes/TypeRefining.cpp
+++ b/src/passes/TypeRefining.cpp
@@ -38,8 +38,9 @@ using FieldInfo = LUBFinder;
struct FieldInfoScanner
: public StructUtils::StructScanner<FieldInfo, FieldInfoScanner> {
- Pass* create() override {
- return new FieldInfoScanner(functionNewInfos, functionSetGetInfos);
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<FieldInfoScanner>(functionNewInfos,
+ functionSetGetInfos);
}
FieldInfoScanner(
@@ -98,7 +99,7 @@ struct TypeRefining : public Pass {
StructUtils::StructValuesMap<FieldInfo> finalInfos;
- void run(PassRunner* runner, Module* module) override {
+ void run(Module* module) override {
if (!module->features.hasGC()) {
return;
}
@@ -111,8 +112,8 @@ struct TypeRefining : public Pass {
StructUtils::FunctionStructValuesMap<FieldInfo> functionNewInfos(*module),
functionSetGetInfos(*module);
FieldInfoScanner scanner(functionNewInfos, functionSetGetInfos);
- scanner.run(runner, module);
- scanner.runOnModuleCode(runner, module);
+ scanner.run(getPassRunner(), module);
+ scanner.runOnModuleCode(getPassRunner(), module);
// Combine the data from the functions.
StructUtils::StructValuesMap<FieldInfo> combinedNewInfos;
@@ -222,8 +223,8 @@ struct TypeRefining : public Pass {
}
if (canOptimize) {
- updateInstructions(*module, runner);
- updateTypes(*module, runner);
+ updateInstructions(*module);
+ updateTypes(*module);
}
}
@@ -234,7 +235,7 @@ struct TypeRefining : public Pass {
// at all, and we can end up with a situation where we alter the type to
// something that is invalid for that read. To ensure the code still
// validates, simply remove such reads.
- void updateInstructions(Module& wasm, PassRunner* runner) {
+ void updateInstructions(Module& wasm) {
struct ReadUpdater : public WalkerPass<PostWalker<ReadUpdater>> {
bool isFunctionParallel() override { return true; }
@@ -245,7 +246,9 @@ struct TypeRefining : public Pass {
ReadUpdater(TypeRefining& parent) : parent(parent) {}
- ReadUpdater* create() override { return new ReadUpdater(parent); }
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<ReadUpdater>(parent);
+ }
void visitStructGet(StructGet* curr) {
if (curr->ref->type == Type::unreachable) {
@@ -274,11 +277,11 @@ struct TypeRefining : public Pass {
};
ReadUpdater updater(*this);
- updater.run(runner, &wasm);
- updater.runOnModuleCode(runner, &wasm);
+ updater.run(getPassRunner(), &wasm);
+ updater.runOnModuleCode(getPassRunner(), &wasm);
}
- void updateTypes(Module& wasm, PassRunner* runner) {
+ void updateTypes(Module& wasm) {
class TypeRewriter : public GlobalTypeRewriter {
TypeRefining& parent;
@@ -303,7 +306,7 @@ struct TypeRefining : public Pass {
TypeRewriter(wasm, *this).update();
- ReFinalize().run(runner, &wasm);
+ ReFinalize().run(getPassRunner(), &wasm);
}
};
diff --git a/src/passes/Untee.cpp b/src/passes/Untee.cpp
index 848e88a65..0123ed45f 100644
--- a/src/passes/Untee.cpp
+++ b/src/passes/Untee.cpp
@@ -31,7 +31,7 @@ namespace wasm {
struct Untee : public WalkerPass<PostWalker<Untee>> {
bool isFunctionParallel() override { return true; }
- Pass* create() override { return new Untee; }
+ std::unique_ptr<Pass> create() override { return std::make_unique<Untee>(); }
void visitLocalSet(LocalSet* curr) {
if (curr->isTee()) {
diff --git a/src/passes/Vacuum.cpp b/src/passes/Vacuum.cpp
index a29c74a89..44abed27b 100644
--- a/src/passes/Vacuum.cpp
+++ b/src/passes/Vacuum.cpp
@@ -33,7 +33,7 @@ namespace wasm {
struct Vacuum : public WalkerPass<ExpressionStackWalker<Vacuum>> {
bool isFunctionParallel() override { return true; }
- Pass* create() override { return new Vacuum; }
+ std::unique_ptr<Pass> create() override { return std::make_unique<Vacuum>(); }
TypeUpdater typeUpdater;
diff --git a/src/passes/opt-utils.h b/src/passes/opt-utils.h
index 28ace047a..9bc81c382 100644
--- a/src/passes/opt-utils.h
+++ b/src/passes/opt-utils.h
@@ -64,8 +64,8 @@ struct FunctionRefReplacer
FunctionRefReplacer(MaybeReplace maybeReplace) : maybeReplace(maybeReplace) {}
- FunctionRefReplacer* create() override {
- return new FunctionRefReplacer(maybeReplace);
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<FunctionRefReplacer>(maybeReplace);
}
void visitCall(Call* curr) { maybeReplace(curr->target); }
diff --git a/src/passes/pass.cpp b/src/passes/pass.cpp
index c548b66c5..4036b8f47 100644
--- a/src/passes/pass.cpp
+++ b/src/passes/pass.cpp
@@ -896,7 +896,11 @@ void PassRunner::runPass(Pass* pass) {
checker = std::unique_ptr<AfterEffectModuleChecker>(
new AfterEffectModuleChecker(wasm));
}
- pass->run(this, wasm);
+ // Passes can only be run once and we deliberately do not clear the pass
+ // runner after running the pass, so there must not already be a runner here.
+ assert(!pass->getPassRunner());
+ pass->setPassRunner(this);
+ pass->run(wasm);
handleAfterEffects(pass);
if (getPassDebug()) {
checker->check();
@@ -925,15 +929,17 @@ void PassRunner::runPassOnFunction(Pass* pass, Function* func) {
bodyBefore << *func->body << '\n';
}
- // function-parallel passes get a new instance per function
- auto instance = std::unique_ptr<Pass>(pass->create());
std::unique_ptr<AfterEffectFunctionChecker> checker;
if (passDebug) {
- checker = std::unique_ptr<AfterEffectFunctionChecker>(
- new AfterEffectFunctionChecker(func));
+ checker = std::make_unique<AfterEffectFunctionChecker>(func);
}
- instance->runOnFunction(this, wasm, func);
+
+ // Function-parallel passes get a new instance per function
+ auto instance = pass->create();
+ instance->setPassRunner(this);
+ instance->runOnFunction(wasm, func);
handleAfterEffects(pass, func);
+
if (passDebug) {
checker->check();
}
diff --git a/src/passes/test_passes.cpp b/src/passes/test_passes.cpp
index 4ea5b8696..54c4818e8 100644
--- a/src/passes/test_passes.cpp
+++ b/src/passes/test_passes.cpp
@@ -31,12 +31,13 @@ namespace {
// Pass to test EHUtil::handleBlockNestedPops function
struct CatchPopFixup : public WalkerPass<PostWalker<CatchPopFixup>> {
bool isFunctionParallel() override { return true; }
- Pass* create() override { return new CatchPopFixup; }
+ std::unique_ptr<Pass> create() override {
+ return std::make_unique<CatchPopFixup>();
+ }
void doWalkFunction(Function* func) {
EHUtils::handleBlockNestedPops(func, *getModule());
}
- void run(PassRunner* runner, Module* module) override {}
};
} // anonymous namespace