diff options
author | Alon Zakai <alonzakai@gmail.com> | 2016-04-26 17:39:14 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2016-04-26 17:39:14 -0700 |
commit | dd778824cfc60c4478bbe7690769f444dad92803 (patch) | |
tree | ac664a729e5918c8ea19030ed45c0efe7bbf0ef9 /src | |
parent | 1b01c37546262069391e5a41e8a4a6daf2471a36 (diff) | |
download | binaryen-dd778824cfc60c4478bbe7690769f444dad92803.tar.gz binaryen-dd778824cfc60c4478bbe7690769f444dad92803.tar.bz2 binaryen-dd778824cfc60c4478bbe7690769f444dad92803.zip |
ast_utils improvements (#399)
* make EffectAnalyzer a little more fun to use
* create a convert() method that can turn a node into a smaller node, reusing its memory, and use that in nop()
* use convert in wasm-linker
Diffstat (limited to 'src')
-rw-r--r-- | src/ast_utils.h | 23 | ||||
-rw-r--r-- | src/passes/RemoveUnusedBrs.cpp | 9 | ||||
-rw-r--r-- | src/wasm-linker.cpp | 6 |
3 files changed, 25 insertions, 13 deletions
diff --git a/src/ast_utils.h b/src/ast_utils.h index 55499d808..66dbf039a 100644 --- a/src/ast_utils.h +++ b/src/ast_utils.h @@ -49,6 +49,11 @@ struct BreakSeeker : public PostWalker<BreakSeeker, Visitor<BreakSeeker>> { // TODO: optimize struct EffectAnalyzer : public PostWalker<EffectAnalyzer, Visitor<EffectAnalyzer>> { + EffectAnalyzer() {} + EffectAnalyzer(Expression *ast) { + walk(ast); + } + bool branches = false; bool calls = false; std::set<Index> localsRead; @@ -115,9 +120,21 @@ struct EffectAnalyzer : public PostWalker<EffectAnalyzer, Visitor<EffectAnalyzer }; struct ExpressionManipulator { - // Nop is the smallest node, so we can always nop-ify another node in our arena - static void nop(Expression* target) { - *static_cast<Nop*>(target) = Nop(); + // Re-use a node's memory. This helps avoid allocation when optimizing. + template<typename InputType, typename OutputType> + static OutputType* convert(InputType *input) { + static_assert(sizeof(OutputType) <= sizeof(InputType), + "Can only convert to a smaller size Expression node"); + input->~InputType(); // arena-allocaed, so no destructor, but avoid UB. + OutputType* output = (OutputType*)(input); + new (output) OutputType; + return output; + } + + // Convenience method for nop, which is a common conversion + template<typename InputType> + static void nop(InputType* target) { + convert<InputType, Nop>(target); } }; diff --git a/src/passes/RemoveUnusedBrs.cpp b/src/passes/RemoveUnusedBrs.cpp index f4efef173..5c21908a8 100644 --- a/src/passes/RemoveUnusedBrs.cpp +++ b/src/passes/RemoveUnusedBrs.cpp @@ -181,14 +181,11 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs, Visitor<R if (curr->ifFalse) { // if with else, consider turning it into a select if there is no control flow // TODO: estimate cost - EffectAnalyzer condition; - condition.walk(curr->condition); + EffectAnalyzer condition(curr->condition); if (!condition.hasSideEffects()) { - EffectAnalyzer ifTrue; - ifTrue.walk(curr->ifTrue); + EffectAnalyzer ifTrue(curr->ifTrue); if (!ifTrue.hasSideEffects()) { - EffectAnalyzer ifFalse; - ifFalse.walk(curr->ifFalse); + EffectAnalyzer ifFalse(curr->ifFalse); if (!ifFalse.hasSideEffects()) { auto* select = getModule()->allocator.alloc<Select>(); select->condition = curr->condition; diff --git a/src/wasm-linker.cpp b/src/wasm-linker.cpp index 4fb7ea4ae..7524f439a 100644 --- a/src/wasm-linker.cpp +++ b/src/wasm-linker.cpp @@ -16,6 +16,7 @@ #include "wasm-linker.h" #include "asm_v_wasm.h" +#include "ast_utils.h" #include "support/utilities.h" #include "wasm-builder.h" #include "wasm-printing.h" @@ -64,12 +65,9 @@ void Linker::layout() { // Change each call. The target is the same since it's still the name. // Delete and re-allocate the Expression as CallImport to avoid undefined // behavior. - static_assert(sizeof(Call) >= sizeof(CallImport), - "Cannot reallocate a CallImport in a Call arena slot"); for (auto* call : f.second) { Call callCopy = std::move(*call); - call->~Call(); - CallImport* newCall = new (call) CallImport; + CallImport* newCall = ExpressionManipulator::convert<Call, CallImport>(call); newCall->type = callCopy.type; newCall->operands = std::move(callCopy.operands); newCall->target = target; |