Skip to content

Conversation

@rafaelha
Copy link
Contributor

The inline pass (as part of a Walk rewrite) has O(n^2) time complexity which is a performance issue.

An extra factor of n is coming from inline.py where each block is split in two, and the inline region is inserted in the middle. Splitting blocks in two comes with the extra O(n) factor:

after_block = ir.Block()
stmt = call_like.next_stmt
while stmt is not None:
    stmt.detach()
    after_block.stmts.append(stmt)
    stmt = call_like.next_stmt

This PR introduces a partial workaround. Simple regions with just a single block are inlined by inserting all of their statements directly. Since statements form a linked list, this is O(1).

For my test case, I observe that this fix reduces runtime and brings the time complexity of the inline pass back to O(n).

image

However, we should refactor the inline pass to scale linearly even in the general case.

@rafaelha rafaelha requested a review from Roger-luo October 28, 2025 19:03
@rafaelha rafaelha self-assigned this Oct 28, 2025
@github-actions
Copy link
Contributor

github-actions bot commented Oct 28, 2025

☂️ Python Coverage

current status: ✅

Overall Coverage

Lines Covered Coverage Threshold Status
11488 10226 89% 0% 🟢

New Files

No new covered files...

Modified Files

File Coverage Status
src/kirin/rewrite/inline.py 95% 🟢
TOTAL 95% 🟢

updated for commit: bf2c025 by action🐍

@codecov
Copy link

codecov bot commented Oct 28, 2025

Codecov Report

❌ Patch coverage is 91.30435% with 4 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/kirin/rewrite/inline.py 91.30% 4 Missing ⚠️

📢 Thoughts on this report? Let us know!

@github-actions
Copy link
Contributor

github-actions bot commented Oct 28, 2025

PR Preview Action v1.6.2
Preview removed because the pull request was closed.
2025-10-29 22:00 UTC

@cduck
Copy link
Contributor

cduck commented Oct 28, 2025

Looks like you need to check for None or cast to satisfy pyright (src/kirin/rewrite/inline.py:198-199).

rafaelha and others added 2 commits October 28, 2025 16:37
Co-authored-by: Casey Duckering <cduck@users.noreply.github.com>
@Roger-luo Roger-luo merged commit a664b05 into main Oct 29, 2025
13 checks passed
@Roger-luo Roger-luo deleted the rafaelha/simple-inlining-with-linear-time-complexity branch October 29, 2025 22:00
Roger-luo pushed a commit that referenced this pull request Oct 29, 2025
The inline pass (as part of a `Walk` rewrite) has O(n^2) time complexity
which is a performance issue.

An extra factor of `n` is coming from `inline.py` where each block is
split in two, and the inline region is inserted in the middle. Splitting
blocks in two comes with the extra O(n) factor:
```python
after_block = ir.Block()
stmt = call_like.next_stmt
while stmt is not None:
    stmt.detach()
    after_block.stmts.append(stmt)
    stmt = call_like.next_stmt
```

This PR introduces a partial workaround. Simple regions with just a
single block are inlined by inserting all of their statements directly.
Since statements form a linked list, this is O(1).

For my test case, I observe that this fix reduces runtime and brings the
time complexity of the inline pass back to O(n).

<img width="489" height="358" alt="image"
src="https://github.com/user-attachments/assets/3b11560f-670f-45d3-84b0-0959693f47b4"
/>

However, we should refactor the inline pass to scale linearly even in
the general case.

---------

Co-authored-by: Casey Duckering <cduck@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants