Expand description
Let-Inlining pass for TLExpr trees.
This module provides a let-inlining optimization pass that substitutes
Let-bound variables into their usage sites, reducing the number of
explicit bindings and enabling downstream passes to work with smaller,
simpler trees.
§Inlining Strategy
Three independent criteria control whether a binding is inlined:
-
Single-use inlining (
inline_single_use): If the bound variable appears free exactly once in the body, inlining is always safe — it does not duplicate work. -
Constant inlining (
inline_constants): If the bound value is aConstant(f64), it is cheap to duplicate so we always inline regardless of use count. -
Variable-alias inlining (
inline_vars): If the bound value is a zero-argumentPred(which serves as a variable reference in TLExpr), we inline it unconditionally because the binding is just a rename.
A max_inline_depth guard prevents inlining of deeply nested sub-trees
to keep code-size growth bounded.
§Correctness
Substitution respects capture: when descending into a binder that re-uses the same variable name, substitution stops at that binder boundary.
§Example
use tensorlogic_compiler::inline::{LetInliner, InlineConfig};
use tensorlogic_ir::TLExpr;
let inliner = LetInliner::with_default();
// Let x = 5.0 in Add(x, x) → Add(5.0, 5.0)
let expr = TLExpr::let_binding(
"x",
TLExpr::Constant(5.0),
TLExpr::add(
TLExpr::pred("x", vec![]),
TLExpr::pred("x", vec![]),
),
);
let (result, stats) = inliner.run(expr);
assert_eq!(stats.constant_inlines, 1);Re-exports§
pub use config::InlineConfig;pub use config::InlineStats;pub use traversal::LetInliner;