Skip to content

Optimization epic #98

@jeaye

Description

@jeaye

General

  • Constant propagation (substituting constants in where possible)
  • Constant folding (compile-time eval of pure expressions with literals)
    • Requires tracking pure fns
  • Share closure contexts by having common value ordering across mutually recursive functions
  • Guaranteed named recursion TCO
  • AST-level function inlining (requires interop to be a big win)
    • Clojure uses this to inline RT.get, Numbers.multiply, etc
    • Don't duplicate body in inline meta; just use :inline true
      • Then we need to deal with merging fn bodies; use an implicit let to create the params by name
    • Use a recursive count on the fn body to do cost analysis

Function attribute tracking

Vars

  • If a var has :jank/static? true meta, deref + store it in the module's global ctor and never deref it again (superseded by direct linking)
    • Also, in each function, only load it once

Dead code elimination

  • Dead branches
  • Pure statements

Boxing

Startup

  • Group all fns into a single module to load
  • Box globals in static memory, not with the GC
  • Add CLI option to elide meta (see Clojure's elide-meta)
  • Two phase jank compilation which bakes in core libs during the second phase (i.e. instant startup)

Form rewriting

  • Auto-transient
  • Auto-transducer
  • Zero-cost map destructuring (see here)
  • General loop unrolling
  • Specific loop unrolling (i.e. get-in)
  • Faster str usage (a la stringer)
  • Replace first and second on known countable types with nth
  • Change recursion into loop/recur
  • Auto record creation, for map literals

IR-specific

  • Don't require boxing strings for reading globals #301
  • Don't put meta into globals
  • Optimize the passes we run and offer different levels
  • Put this into closure context for named recursion
    • Can also work by forcing normal functions into closures if they're named recursive

Interop

  • Avoid repeated trait conversions for the same value

AOT-only

  • Direct linking (dynamic call)
  • Direct linking (direct call)
  • Unused var removal (includes defns)
  • Flag to elide var meta
  • Remove unused args from fns
  • Unity build (i.e. one object file for all namespaces)
  • Automatic inlining
    • Given that we have inlining based on meta, defined above, if we're compiling with direct linking we can automatically inline any fn which passes cost analysis

Runtime

  • Use immer to merge maps

References

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions