Skip to content

Cache the block order and skip unchanged nested regions in ConstantPropagation - #2476

Queued
ThrudPrimrose wants to merge 1 commit into
mainfrom
perf/constant-propagation-schedule
Queued

Cache the block order and skip unchanged nested regions in ConstantPropagation#2476
ThrudPrimrose wants to merge 1 commit into
mainfrom
perf/constant-propagation-schedule

Conversation

@ThrudPrimrose

Copy link
Copy Markdown
Collaborator

Constant collection is a fixpoint over each control flow region, and it recursed into nested regions
from inside the fixpoint loop. So every sweep of every region re-ran blockorder_topological_sort,
which computes immediate dominators and branch merges over the region, and a region nested d levels
deep was re-analysed on every sweep at every enclosing level.

Neither is needed. The CFG does not change while constants are being collected, so the block order is
the same on every sweep and can be cached; and a nested region is a function of its incoming
constants, so an unchanged input reaches the same fixpoint and does not need re-collecting. The
transfer and meet rules are untouched — this only changes the schedule.

Measured on the CloudSC kernel, parsed once with to_sdfg(simplify=False) and deepcopied fresh for
every timed run, arms interleaved rep by rep. Median (min–max), 5 reps:

unsimplified, 6342 blocks / 5890 states
  apply_pass    old  4.93s (4.77-5.11)    new  1.66s (1.61-1.72)    2.97x

after ScalarToSymbolPromotion + ControlFlowRaising, 6612 blocks
  apply_pass    old 24.16s (23.21-24.74)  new  8.72s (8.16-8.86)    2.77x

SimplifyPass, 4 reps
                old 84.8s (82.7-92.3)     new 76.1s (74.8-78.9)     1.11x

The box was not idle, so treat the absolute times as loaded; within-arm spread is under 5% and every
rep interleaves the arms, so the ratios hold.

Old and new produce identical output: the same propagated-symbol set, and equal SDFGs across symbols,
data descriptors, compile-time constants, blocks, interstate conditions and assignments, dataflow
nodes, tasklet code, memlets, loop headers and conditional branches.

Split out of #2470 so the scheduling change can be reviewed and merged on its own; the CloudSC corpus,
its integration tests and the timing budget stay there and rebase onto this.

…opagation

Constant collection is a fixpoint over each control flow region, and it recursed into nested regions
from inside the fixpoint loop. So every sweep of every region re-ran blockorder_topological_sort,
which computes immediate dominators and branch merges, and a region nested d levels deep was
re-analysed on every sweep at every enclosing level.

Neither is needed. The CFG does not change while constants are being collected, so the block order
is the same on every sweep. What a nested region computes is a function of its 'in' constants alone,
so re-collecting it with unchanged inputs recomputes the same fixpoint.

Cache the block order per region, and record the 'in' constants each nested region was last
collected with so it is re-collected only when those change. The transfer and meet rules are
untouched.

@acalotoiu acalotoiu left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Awesome!

@acalotoiu
acalotoiu added this pull request to the merge queue Aug 4, 2026
Any commits made after this event will not be merged.
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.

2 participants