diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/passes/SimplifyGlobals.cpp | 39 | ||||
-rw-r--r-- | src/passes/pass.cpp | 1 |
2 files changed, 40 insertions, 0 deletions
diff --git a/src/passes/SimplifyGlobals.cpp b/src/passes/SimplifyGlobals.cpp index 5fa1686fc..71aafa491 100644 --- a/src/passes/SimplifyGlobals.cpp +++ b/src/passes/SimplifyGlobals.cpp @@ -51,6 +51,7 @@ struct GlobalInfo { bool imported = false; bool exported = false; std::atomic<bool> written; + std::atomic<bool> read; }; using GlobalInfoMap = std::map<Name, GlobalInfo>; @@ -64,6 +65,8 @@ struct GlobalUseScanner : public WalkerPass<PostWalker<GlobalUseScanner>> { void visitGlobalSet(GlobalSet* curr) { (*infos)[curr->name].written = true; } + void visitGlobalGet(GlobalGet* curr) { (*infos)[curr->name].read = true; } + private: GlobalInfoMap* infos; }; @@ -163,6 +166,23 @@ private: std::map<Name, Literals> currConstantGlobals; }; +struct GlobalSetRemover : public WalkerPass<PostWalker<GlobalSetRemover>> { + GlobalSetRemover(NameSet* toRemove) : toRemove(toRemove) {} + + bool isFunctionParallel() override { return true; } + + GlobalSetRemover* create() override { return new GlobalSetRemover(toRemove); } + + void visitGlobalSet(GlobalSet* curr) { + if (toRemove->count(curr->name) != 0) { + ExpressionManipulator::nop(curr); + } + } + +private: + NameSet* toRemove; +}; + } // anonymous namespace struct SimplifyGlobals : public Pass { @@ -180,6 +200,8 @@ struct SimplifyGlobals : public Pass { analyze(); + removeWritesToUnreadGlobals(); + preferEarlierImports(); propagateConstantsToGlobals(); @@ -211,6 +233,23 @@ struct SimplifyGlobals : public Pass { } } + void removeWritesToUnreadGlobals() { + // Globals that are not exports and not read from can be eliminated + // (even if they are written to). + NameSet unreadGlobals; + for (auto& global : module->globals) { + auto& info = map[global->name]; + if (!info.imported && !info.exported && !info.read) { + unreadGlobals.insert(global->name); + // We can now mark this global as immutable, and un-written, since we + // are about to remove all the `.set` operations on it. + global->mutable_ = false; + info.written = false; + } + } + GlobalSetRemover(&unreadGlobals).run(runner, module); + } + void preferEarlierImports() { // Optimize uses of immutable globals, prefer the earlier import when // there is a copy. diff --git a/src/passes/pass.cpp b/src/passes/pass.cpp index 733b61467..4da870ae9 100644 --- a/src/passes/pass.cpp +++ b/src/passes/pass.cpp @@ -483,6 +483,7 @@ void PassRunner::addDefaultGlobalOptimizationPostPasses() { } else { add("simplify-globals"); } + add("vacuum"); // simplify-globals can generate extra nops add("remove-unused-module-elements"); // may allow more inlining/dae/etc., need --converge for that add("directize"); |