diff options
Diffstat (limited to 'src/passes')
-rw-r--r-- | src/passes/LowerIfElse.cpp | 51 | ||||
-rw-r--r-- | src/passes/NameManager.cpp | 68 |
2 files changed, 119 insertions, 0 deletions
diff --git a/src/passes/LowerIfElse.cpp b/src/passes/LowerIfElse.cpp new file mode 100644 index 000000000..ff84c6844 --- /dev/null +++ b/src/passes/LowerIfElse.cpp @@ -0,0 +1,51 @@ +// +// Lowers if (x) y else z into +// +// L: { +// if (x) break (y) L +// z +// } +// +// This is useful for investigating how beneficial if_else is. +// + +#include <memory> + +#include <wasm.h> +#include <pass.h> + +namespace wasm { + +struct LowerIfElse : public Pass { + LowerIfElse() : Pass("lower-if-else") {} + + MixedArena* allocator; + std::unique_ptr<NameManager> namer; + + void prepare(PassRunner* runner, Module *module) override { + allocator = runner->allocator; + namer = std::unique_ptr<NameManager>(new NameManager()); + namer->run(runner, module); + } + + void visitIf(If *curr) override { + if (curr->ifFalse) { + auto block = allocator->alloc<Block>(); + auto name = namer->getUnique("L"); // TODO: getUniqueInFunction + block->name = name; + block->list.push_back(curr); + block->list.push_back(curr->ifFalse); + curr->ifFalse = nullptr; + auto break_ = allocator->alloc<Break>(); + break_->name = name; + break_->value = curr->ifTrue; + curr->ifTrue = break_; + replaceCurrent(block); + } + } +}; + +static RegisterPass<LowerIfElse> registerPass; + +} // namespace wasm + diff --git a/src/passes/NameManager.cpp b/src/passes/NameManager.cpp new file mode 100644 index 000000000..13a6dd9f9 --- /dev/null +++ b/src/passes/NameManager.cpp @@ -0,0 +1,68 @@ +// +// NameManager +// + +#include <wasm.h> +#include <pass.h> + +namespace wasm { + +Name NameManager::getUnique(std::string prefix) { + while (1) { + Name curr = cashew::IString((prefix + std::to_string(counter++)).c_str(), false); + if (names.find(curr) == names.end()) { + names.insert(curr); + return curr; + } + } +} + +void NameManager::visitBlock(Block* curr) { + names.insert(curr->name); +} +void NameManager::visitLoop(Loop* curr) { + names.insert(curr->out); + names.insert(curr->in); +} +void NameManager::visitLabel(Label* curr) { + names.insert(curr->name); +} +void NameManager::visitBreak(Break* curr) { + names.insert(curr->name); +} +void NameManager::visitSwitch(Switch* curr) { + names.insert(curr->name); + names.insert(curr->default_); + for (auto& target : curr->targets) { + names.insert(target); + } +} +void NameManager::visitCall(Call* curr) { + names.insert(curr->target); +} +void NameManager::visitCallImport(CallImport* curr) { + names.insert(curr->target); +} +void NameManager::visitFunctionType(FunctionType* curr) { + names.insert(curr->name); +} +void NameManager::visitFunction(Function* curr) { + names.insert(curr->name); + for (auto& param : curr->params) { + names.insert(param.name); + } + for (auto& local : curr->locals) { + names.insert(local.name); + } +} +void NameManager::visitImport(Import* curr) { + names.insert(curr->name); +} +void NameManager::visitExport(Export* curr) { + names.insert(curr->name); +} + +static RegisterPass<NameManager> registerPass; + +} // namespace wasm + |