Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VM: optimization step into the gnovm pipeline #2796

Open
10 tasks
petar-dambovaliev opened this issue Sep 13, 2024 · 1 comment
Open
10 tasks

VM: optimization step into the gnovm pipeline #2796

petar-dambovaliev opened this issue Sep 13, 2024 · 1 comment
Assignees
Labels
📦 🤖 gnovm Issues or PRs gnovm related

Comments

@petar-dambovaliev
Copy link
Contributor

petar-dambovaliev commented Sep 13, 2024

I've compiled a set of optimizations that are appropriate for the gnovm design and architecture.
Some of these need to be done in a particular order.
For example, Dead Code Elimination needs to be done after constant and constant folding and constant value propagation.
Also, some of these, like Common Subexpression Elimination, Memoization and Result Caching and Control Flow Optimizations need to be done in a following pass over the AST because they depend on previous optimizations to be fully done.

  • Constant folding: #2800
    Involves evaluating constant expressions at compile time (or during an optimization pass) rather than at runtime. This means if an expression involves only constants, it can be simplified immediately.
    It aims to reduce runtime overhead by computing constant expressions once during the compilation phase or interpretation phase, rather than at each execution.

  • Propagate Constant Values: #2798
    Replace all uses of the constants with the actual constant value in subsequent expressions.
    Update the AST by replacing variable nodes with literal nodes where applicable.

  • Optimize Loop-Invariant Constants:
    Identify variables with constant values that appear inside loops but are assigned outside the loop.
    Move constant expressions out of the loop to avoid repeated evaluation.

  • Perform Dead Code Elimination
    After propagating constants, identify if certain branches of control flow can be eliminated (e.g., if if (false) is detected).
    Remove or ignore unreachable code paths during execution.

  • Memoize and Cache Results
    Cache results of constant expressions that might be expensive to compute and reuse them when the same expression appears.

  • Control Flow Optimizations
    Branch Pruning: Simplifying conditional branches by evaluating the condition at compile time, eliminating branches that are not needed.

  • Peephole Optimizations
    Description: Perform small, localized optimizations on the AST to simplify or eliminate unnecessary operations.
    Example: Simplify expressions like x * 1 to just x, or eliminate code like x = x which does nothing.

  • Scope Optimization (Variable Lookup Caching)
    Description: Speed up variable lookups by caching variable references during execution.
    Example: Variable lookups in nested scopes can be slow. Cache variables in a flattened scope lookup table to avoid repeated scope traversal.

  • Memoization (Result Caching)
    Description: Cache the results of expensive computations or functions with deterministic outputs to avoid recalculating them.
    Example: If a function f(x) is called repeatedly with the same argument, cache the result after the first call and reuse it.

  • Common Subexpression Elimination
    Description: If the same expression is evaluated multiple times, store its result and reuse it rather than recomputing.
    Example: For x = a + b; y = a + b;, compute a + b once and reuse the result.

@jaekwon
Copy link
Contributor

jaekwon commented Oct 21, 2024

A lot of these we should consider after launch slowly, or even for Gno2.

Some of these things we might not want to do, e.g. dead code elimination; makes sense for Go, but Gno's preprocessor also needs to be fast (we can't cache all nodes of all smart contracts in memory, AND parsing the code may be faster than persisting nodes). Arguably we could store information separately alongside the code, but is the complexity really worth it?

In general would prefer to have a complete, frozen, simple Gno1 implementation to be used as a reference for future optimizations and experiments; a minimal codebase would be better suited for forks of Gno.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
📦 🤖 gnovm Issues or PRs gnovm related
Development

No branches or pull requests

4 participants