summaryrefslogtreecommitdiff
path: root/src/ir
diff options
context:
space:
mode:
Diffstat (limited to 'src/ir')
-rw-r--r--src/ir/effects.h4
-rw-r--r--src/ir/module-utils.h57
2 files changed, 59 insertions, 2 deletions
diff --git a/src/ir/effects.h b/src/ir/effects.h
index 7c64beafd..b7c420100 100644
--- a/src/ir/effects.h
+++ b/src/ir/effects.h
@@ -27,7 +27,7 @@ namespace wasm {
struct EffectAnalyzer
: public PostWalker<EffectAnalyzer, OverriddenVisitor<EffectAnalyzer>> {
- EffectAnalyzer(PassOptions& passOptions, Expression* ast = nullptr) {
+ EffectAnalyzer(const PassOptions& passOptions, Expression* ast = nullptr) {
ignoreImplicitTraps = passOptions.ignoreImplicitTraps;
debugInfo = passOptions.debugInfo;
if (ast) {
@@ -372,7 +372,7 @@ struct EffectAnalyzer
// Helpers
static bool
- canReorder(PassOptions& passOptions, Expression* a, Expression* b) {
+ canReorder(const PassOptions& passOptions, Expression* a, Expression* b) {
EffectAnalyzer aEffects(passOptions, a);
EffectAnalyzer bEffects(passOptions, b);
return !aEffects.invalidates(bEffects);
diff --git a/src/ir/module-utils.h b/src/ir/module-utils.h
index c13e9f1ca..88298fd43 100644
--- a/src/ir/module-utils.h
+++ b/src/ir/module-utils.h
@@ -19,6 +19,7 @@
#include "ir/find_all.h"
#include "ir/manipulation.h"
+#include "pass.h"
#include "wasm.h"
namespace wasm {
@@ -287,6 +288,62 @@ template<typename T> inline void iterDefinedEvents(Module& wasm, T visitor) {
}
}
+// Performs a parallel map on function in the module, emitting a map object
+// of function => result.
+// TODO: use in inlining and elsewhere
+template<typename T> struct ParallelFunctionMap {
+
+ typedef std::map<Function*, T> Map;
+ Map map;
+
+ typedef std::function<void(Function*, T&)> Func;
+
+ struct Info {
+ Map* map;
+ Func work;
+ };
+
+ ParallelFunctionMap(Module& wasm, Func work) {
+ // Fill in map, as we operate on it in parallel (each function to its own
+ // entry).
+ for (auto& func : wasm.functions) {
+ map[func.get()];
+ }
+
+ // Run on the imports first. TODO: parallelize this too
+ for (auto& func : wasm.functions) {
+ if (func->imported()) {
+ work(func.get(), map[func.get()]);
+ }
+ }
+
+ // Run on the implemented functions.
+ struct Mapper : public WalkerPass<PostWalker<Mapper>> {
+
+ bool isFunctionParallel() override { return true; }
+
+ Mapper(Info* info) : info(info) {}
+
+ Mapper* create() override { return new Mapper(info); }
+
+ void doWalkFunction(Function* curr) {
+ assert((*info->map).count(curr));
+ info->work(curr, (*info->map)[curr]);
+ }
+
+ private:
+ Info* info;
+ };
+
+ Info info = {&map, work};
+
+ PassRunner runner(&wasm);
+ runner.setIsNested(true);
+ runner.add<Mapper>(&info);
+ runner.run();
+ }
+};
+
} // namespace ModuleUtils
} // namespace wasm