diff options
author | Alon Zakai <alonzakai@gmail.com> | 2016-05-14 18:54:37 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2016-05-15 16:28:57 -0700 |
commit | a76a828b7b086d80b6673fa8e87887d84f7c5488 (patch) | |
tree | ee7edb22ec0c82a23cd89f20d78dd870cfddf615 /src | |
parent | 9f25d3db7fae275160880721cf67a27c89e6a122 (diff) | |
download | binaryen-a76a828b7b086d80b6673fa8e87887d84f7c5488.tar.gz binaryen-a76a828b7b086d80b6673fa8e87887d84f7c5488.tar.bz2 binaryen-a76a828b7b086d80b6673fa8e87887d84f7c5488.zip |
make an instance per function in function-parallel passes, so passes don't need to clean up internal stuff
Diffstat (limited to 'src')
-rw-r--r-- | src/wasm-traversal.h | 22 |
1 files changed, 12 insertions, 10 deletions
diff --git a/src/wasm-traversal.h b/src/wasm-traversal.h index 59fea2a56..afa20ecb5 100644 --- a/src/wasm-traversal.h +++ b/src/wasm-traversal.h @@ -148,7 +148,7 @@ struct Walker : public VisitorType { // if you do not ad global state that could be raced on, your pass could be // function-parallel. // - // Function-parallel passes create an instance of the Walker class per core. + // Function-parallel passes create an instance of the Walker class per function. // That means that you can't rely on Walker object properties to persist across // your functions, and you can't expect a new object to be created for each // function either (which could be very inefficient). @@ -191,32 +191,34 @@ struct Walker : public VisitorType { self->visitExport(curr.get()); } - auto processFunction = [](SubType* instance, Function* func) { + auto processFunction = [](Module* module, SubType* instance, Function* func) { + std::unique_ptr<SubType> allocated; + if (!instance) { + instance = new SubType; + allocated = std::unique_ptr<SubType>(instance); + assert(module); + instance->setModule(module); + } instance->setFunction(func); instance->walk(func->body); instance->visitFunction(func); - instance->setFunction(nullptr); }; // if this is not a function-parallel traversal, run // sequentially if (!self->isFunctionParallel()) { for (auto& curr : module->functions) { - processFunction(self, curr.get()); + processFunction(nullptr, self, curr.get()); } } else { // execute in parallel on helper threads size_t num = ThreadPool::get()->size(); - std::vector<std::unique_ptr<SubType>> instances; std::vector<std::function<ThreadWorkState ()>> doWorkers; std::atomic<size_t> nextFunction; nextFunction.store(0); size_t numFunctions = module->functions.size(); for (size_t i = 0; i < num; i++) { - auto* instance = new SubType(); - instance->setModule(getModule()); - instances.push_back(std::unique_ptr<SubType>(instance)); - doWorkers.push_back([instance, &nextFunction, numFunctions, &module, processFunction]() { + doWorkers.push_back([&nextFunction, numFunctions, &module, processFunction]() { auto index = nextFunction.fetch_add(1); // get the next task, if there is one if (index >= numFunctions) { @@ -224,7 +226,7 @@ struct Walker : public VisitorType { } Function* curr = module->functions[index].get(); // do the current task - processFunction(instance, curr); + processFunction(module, nullptr, curr); if (index + 1 == numFunctions) { return ThreadWorkState::Finished; // we did the last one } |