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/ast_utils.h | |
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/ast_utils.h')
-rw-r--r-- | src/ast_utils.h | 23 |
1 files changed, 20 insertions, 3 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); } }; |