Skip to content

Optimize LiftTrivialIf and re-run it only on block-count change#2460

Open
ThrudPrimrose wants to merge 4 commits into
mainfrom
optimize-lift-trivial-if
Open

Optimize LiftTrivialIf and re-run it only on block-count change#2460
ThrudPrimrose wants to merge 4 commits into
mainfrom
optimize-lift-trivial-if

Conversation

@ThrudPrimrose

Copy link
Copy Markdown
Collaborator

Ports the optimized LiftTrivialIf (range-aware boundary-guard folding, cartesian-product/unsatisfiable branch pruning, deterministic relabeling, whole-SDFG bookkeeping walks gated on an actual removal so it is no longer quadratic in block count) and narrows should_reapply to Modifies.States so the pass re-runs only when a conditional block is added or removed, not on every interstate-edge change.

Ports the optimized LiftTrivialIf: range-aware folding of loop boundary guards
(iteration-range tautology/contradiction), cartesian-product/unsatisfiable branch
pruning for if/elif chains, deterministic block relabeling, and gating the
whole-SDFG bookkeeping walks (set_nested_sdfg_parent_references + reset_cfg_list)
on an actual removal so the pass is no longer quadratic in block count.

should_reapply now fires only on Modifies.States (a ConditionalBlock added or
removed, or a loop peel that shifts an enclosing range) instead of the whole CFG:
interstate-edge content changes never create or destroy a conditional, so reacting
to them only re-scanned the SDFG for no new work.
@ThrudPrimrose
ThrudPrimrose marked this pull request as draft July 23, 2026 14:48
The parent-reference / cfg-list repair after a branch splice no longer walks the
whole SDFG once per control-flow block. add_node already fixes every moved block's
parent_graph/sdfg, so only the deep-copied NestedSDFG nodes' parent pointers are
repaired, scoped to the spliced subtree, and the CFG-list index is refreshed once
at the end of the pass (only when something changed). The up-front whole-SDFG
relabel is replaced by relabeling just the spliced top-level blocks.

The per-condition triviality check (pystr_to_symbolic + evaluate, the pass's real
hot spot) is memoized in a module-level lru_cache(maxsize=16384, typed=True) keyed
on the condition string. Because it is module-level, not per-instance, it also hits
across the FixedPointPipeline's repeated pass re-invocations. On the CloudSC
frontend this cuts a warm LiftTrivialIf run from ~640ms to ~36ms; results are
unchanged (removal counts identical, all validated).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant