diff options
author | Alon Zakai <alonzakai@gmail.com> | 2016-04-06 20:51:08 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2016-04-06 20:51:08 -0700 |
commit | 53f4c97487e90baa226614e63867add700ed12e5 (patch) | |
tree | 39fedb3dc417d7aa19c6475ad031815fb6577e54 /src/ast_utils.h | |
parent | e5b5e0111879ef7bd80c7d36f22bd9844faa8d4f (diff) | |
download | binaryen-53f4c97487e90baa226614e63867add700ed12e5.tar.gz binaryen-53f4c97487e90baa226614e63867add700ed12e5.tar.bz2 binaryen-53f4c97487e90baa226614e63867add700ed12e5.zip |
EffectsAnalyzer
Diffstat (limited to 'src/ast_utils.h')
-rw-r--r-- | src/ast_utils.h | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/src/ast_utils.h b/src/ast_utils.h index 44a4bcc21..598081342 100644 --- a/src/ast_utils.h +++ b/src/ast_utils.h @@ -39,6 +39,48 @@ struct BreakSeeker : public WasmWalker<BreakSeeker> { } }; +// Look for side effects, including control flow +// TODO: look at individual locals + +struct EffectAnalyzer : public WasmWalker<EffectAnalyzer> { + bool branches = false; + bool calls = false; + bool readsLocal = false; + bool writesLocal = false; + bool readsMemory = false; + bool writesMemory = false; + + bool accessesLocal() { return readsLocal || writesLocal; } + bool accessesMemory() { return calls || readsMemory || writesMemory; } + bool hasSideEffects() { return calls || writesLocal || writesMemory; } + + // checks if these effects would invalidate another set (e.g., if we write, we invalidate someone that reads, they can't be moved past us) + bool invalidates(EffectAnalyzer& other) { + return branches || ((writesMemory || calls) && other.accessesMemory()) || (writesLocal && other.accessesLocal()); + } + + void visitIf(If *curr) { branches = true; } + void visitBreak(Break *curr) { branches = true; } + void visitSwitch(Switch *curr) { branches = true; } + void visitCall(Call *curr) { calls = true; } + void visitCallImport(CallImport *curr) { calls = true; } + void visitCallIndirect(CallIndirect *curr) { calls = true; } + void visitGetLocal(GetLocal *curr) { readsLocal = true; } + void visitSetLocal(SetLocal *curr) { writesLocal = true; } + void visitLoad(Load *curr) { readsMemory = true; } + void visitStore(Store *curr) { writesMemory = true; } + void visitReturn(Return *curr) { branches = true; } + void visitHost(Host *curr) { calls = true; } + void visitUnreachable(Unreachable *curr) { branches = true; } +}; + +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(); + } +}; + } // namespace wasm #endif // wasm_ast_utils_h |