⚡ perf(mq-lang): add AST optimizer with multi-pass optimization pipeline #1818
Merged
Conversation
Add Expr::SelectorChain(SmallVec<[Selector; 4]>) to the AST to represent sequences of consecutive selectors that have been merged by the optimizer. Update code.rs, eval.rs, macro_expand.rs, and lib.rs accordingly, and hook the optimizer into Engine::compile and Engine::eval.
Introduce optimizer.rs with the following passes applied before evaluation: - Phase 1: constant folding (arithmetic, string, comparison, logical), dead branch elimination, And/Or literal short-circuit, Paren unwrap - Phase 2: SelectorChain fusion — merge consecutive Selector nodes into a single SelectorChain to reduce eval_program loop iterations - Phase 3-1: InterpolatedString constant folding, let-binding literal propagation with re-fold after substitution - Phase 3-2: small function inlining (single-node body, no free vars, no recursion) with post-inline constant folding - Phase 3-3: tail-call optimization — rewrite self-tail-recursive functions as var + loop + break/continue to eliminate stack growth
…Level Redesign the optimizer to eliminate unnecessary allocations and add configurable optimization levels via Engine::set_optimization_level(). Key changes: - Add OptimizationLevel enum (None/Basic/Full) exposed on Engine - Merge propagate_let_literals + optimize_node into single propagate_and_fold pass - Skip inlining/TCO passes entirely when no Def nodes are present - Add ptr_eq checks to avoid node allocations when sub-expressions are unchanged - Add early return to merge_selector_chains when no consecutive selectors exist - Add fast path to propagate_and_fold that returns original program when unchanged - Replace HashMap with FxHashMap for inlinable function tracking - Replace HashMap with stack-allocated SmallVec (LiteralEnv) for let propagation env - Enable substitution into InterpolatedString Expr segments for compile-time folding - Promote Expr(Literal(String)) segments to Text in InterpolatedString optimizer
- Replace FxHashMap with EnvContext (Small=SmallVec / Large=FxHashMap) in Env so child scopes with few bindings avoid heap allocation entirely - Add lazy_map_program for zero-copy AST passes when no node changes - Add optimize_nested to reuse parent user_defs in sub-program bodies - Add dead-def elimination (top-level only) after function inlining - Add builtin constants for math (ceil/round/abs/trunc), type conversion (to_string/to_number), and string ops (trim/upcase/starts_with/replace, etc.) - Expand env tests with proptest property-based test suite
Collapse nested if-let blocks into a single if-let with && to satisfy the clippy::collapsible_if lint required by --all-features --all-targets.
…ments - Add doc comments to Optimizer::optimize, EnvError::to_runtime_error, EnvError::to_runtime_error_with_token, Env::len, Env::define, and Env::resolve - Trim redundant implementation-detail paragraphs from private method comments in optimizer (optimize_nested, propagate_and_fold, LiteralEnv type alias) - Remove obvious inline comments in try_fold_call and collect_called_fns_node
…Vec size Replace magic number 6 in SmallVec type parameter with a named constant derived from PROMOTE_THRESHOLD - 1, making the invariant explicit and preventing future divergence between the two values.
Add `--optimize-level` CLI flag (none/basic/full) so users can select the optimization pass at runtime. Change the default OptimizationLevel from Full to None so behavior is stable unless explicitly opted in.
…r> in debugger feature iter_entries is only used under the debugger feature (non-hot path), so boxing is acceptable and removes the boilerplate Either enum and its Iterator impl.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.