feat(ir): add CtrlFlowTransform pass to eliminate break/continue from loops#494
feat(ir): add CtrlFlowTransform pass to eliminate break/continue from loops#494YunjiQin wants to merge 6 commits intohw-native-sys:mainfrom
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds a new CtrlFlowTransform pass that rewrites BreakStmt/ContinueStmt into structured control flow, plus IR property, verifier, PTO codegen expression visitors, Python bindings, docs, and unit/integration tests to exercise and validate the transformation and downstream codegen. Changes
Sequence DiagramsequenceDiagram
participant User
participant PassManager
participant UnrollLoops
participant CtrlFlowTransform
participant Verifier
participant ConvertToSSA
participant PTOCodeGen
User->>PassManager: compile(program)
PassManager->>UnrollLoops: apply()
UnrollLoops-->>PassManager: IR (may contain break/continue)
PassManager->>CtrlFlowTransform: apply()
Note over CtrlFlowTransform: Phase 1: eliminate continue\nPhase 2: eliminate break (for→while w/ __break flag)
CtrlFlowTransform-->>PassManager: IR (StructuredCtrlFlow)
PassManager->>Verifier: verify(StructuredCtrlFlow)
Verifier-->>PassManager: valid / errors
PassManager->>ConvertToSSA: apply()
ConvertToSSA-->>PassManager: IR (SSA)
PassManager->>PTOCodeGen: emit(IR)
Note over PTOCodeGen: uses new VisitExpr_ handlers and bool emission changes
PTOCodeGen-->>User: generated artifact
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~30 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. 📝 Coding Plan
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment Tip You can disable poems in the walkthrough.Disable the |
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request significantly enhances the compiler's intermediate representation (IR) by introducing a new pass that transforms unstructured control flow statements ( Highlights
Changelog
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request introduces a significant feature: the CtrlFlowTransform pass, which eliminates break and continue statements from loops by converting them into structured control flow. This is a crucial step for enabling more of Python's control flow constructs in the compiler. The implementation is comprehensive, spanning the C++ pass itself, a corresponding verifier, Python bindings, documentation, and a solid suite of unit and system tests. My review identified two high-severity issues: a potential data type bug in the C++ implementation where INT32 is hardcoded for loop variable increments, and the omission of this new pass from the CCE optimization strategy. Addressing these will ensure the feature is both correct and complete.
cf02721 to
95638b8
Compare
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.claude/rules/pass-doc-ordering.md:
- Around line 24-31: The pass-order table is missing InferTileMemorySpace and
ResolveTransposeLayout and incorrectly marks ExpandMixedKernel as not in any
strategy; update the table so that the sequence and numbering match the actual
Default pipeline (as asserted in tests/ut/ir/transforms/test_pass_manager.py) by
inserting entries for InferTileMemorySpace and ResolveTransposeLayout in the
correct positions and changing the ExpandMixedKernel entry to indicate it is
part of the Default strategy, ensuring the pass names (InferTileMemorySpace,
ResolveTransposeLayout, ExpandMixedKernel) and subsequent pass numbers are
adjusted accordingly.
In `@docs/en/dev/passes/00-pass_manager.md`:
- Around line 62-64: The docs erroneously list a non-existent IR property
FlattenedSingleStmt as invalidated by the ConvertToSSA and FlattenCallExpr
passes; update the table rows for ConvertToSSA and FlattenCallExpr to remove
FlattenedSingleStmt and instead list only NormalizedStmtStructure (matching
kConvertToSSAProperties and kFlattenCallExprProperties in pass_properties.h and
the IRProperty enum defined in ir_property.h). Ensure the table entries for
those passes match the actual invalidation sets used by kConvertToSSAProperties
and kFlattenCallExprProperties.
In `@include/pypto/ir/verifier/verifier.h`:
- Around line 183-184: Update the comment for the StructuredCtrlFlow
PropertyVerifier to accurately describe its scope: state that it verifies that
no BreakStmt or ContinueStmt remains in function bodies of InCore-type functions
only, and that it intentionally skips Host and Orchestration function types;
reference the verifier class/name StructuredCtrlFlow and the checked constructs
BreakStmt and ContinueStmt so readers understand the narrowed contract.
In `@src/codegen/pto/pto_codegen.cpp`:
- Around line 1156-1172: The BitShiftRightPtr, MinPtr, and MaxPtr visitor
implementations always emit signed MLIR ops; update PTOCodegen::VisitExpr_(const
ir::BitShiftRightPtr&), PTOCodegen::VisitExpr_(const ir::MinPtr&), and
PTOCodegen::VisitExpr_(const ir::MaxPtr&) to inspect the operand scalar dtype
(use ir::GetScalarDtype(op->a) or equivalent and DataType::IsUnsignedInt()) and
choose the unsigned op names ("arith.shrui", "arith.minui", "arith.maxui") when
the dtype is unsigned, otherwise keep the signed variants ("arith.shrsi",
"arith.minsi", "arith.maxsi"); use GetTypeString()/existing helpers to build the
call into VisitBinaryArithExpr accordingly. Also note similar unsigned-vs-signed
fixes will be needed for FloatDiv/RemInt in a follow-up.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 4f39ac44-8818-4e4b-baa5-7fab3154c30c
📒 Files selected for processing (52)
.claude/rules/pass-doc-ordering.mdCMakeLists.txtdocs/en/dev/language/00-python_syntax.mddocs/en/dev/passes/00-pass_manager.mddocs/en/dev/passes/01-unroll_loops.mddocs/en/dev/passes/02-ctrl_flow_transform.mddocs/en/dev/passes/03-convert_to_ssa.mddocs/en/dev/passes/04-flatten_call_expr.mddocs/en/dev/passes/05-split_chunked_loops.mddocs/en/dev/passes/06-interchange_chunk_loops.mddocs/en/dev/passes/07-outline_incore_scopes.mddocs/en/dev/passes/08-outline_cluster_scopes.mddocs/en/dev/passes/10-flatten_tile_nd_to_2d.mddocs/en/dev/passes/11-expand_mixed_kernel.mddocs/en/dev/passes/12-init_memref.mddocs/en/dev/passes/13-basic_memory_reuse.mddocs/en/dev/passes/14-insert_sync.mddocs/en/dev/passes/15-allocate_memory_addr.mddocs/en/dev/passes/16-utility_passes.mddocs/zh-cn/dev/language/00-python_syntax.mddocs/zh-cn/dev/passes/00-pass_manager.mddocs/zh-cn/dev/passes/01-unroll_loops.mddocs/zh-cn/dev/passes/02-ctrl_flow_transform.mddocs/zh-cn/dev/passes/03-convert_to_ssa.mddocs/zh-cn/dev/passes/04-flatten_call_expr.mddocs/zh-cn/dev/passes/05-split_chunked_loops.mddocs/zh-cn/dev/passes/06-interchange_chunk_loops.mddocs/zh-cn/dev/passes/07-outline_incore_scopes.mddocs/zh-cn/dev/passes/08-outline_cluster_scopes.mddocs/zh-cn/dev/passes/10-flatten_tile_nd_to_2d.mddocs/zh-cn/dev/passes/11-expand_mixed_kernel.mddocs/zh-cn/dev/passes/12-init_memref.mddocs/zh-cn/dev/passes/13-basic_memory_reuse.mddocs/zh-cn/dev/passes/14-insert_sync.mddocs/zh-cn/dev/passes/15-allocate_memory_addr.mddocs/zh-cn/dev/passes/16-utility_passes.mdinclude/pypto/codegen/pto/pto_codegen.hinclude/pypto/ir/transforms/ir_property.hinclude/pypto/ir/transforms/pass_properties.hinclude/pypto/ir/transforms/passes.hinclude/pypto/ir/verifier/verifier.hpython/bindings/modules/passes.cpppython/pypto/ir/pass_manager.pypython/pypto/pypto_core/passes.pyisrc/codegen/pto/pto_codegen.cppsrc/ir/transforms/ctrl_flow_transform_pass.cppsrc/ir/transforms/ir_property.cppsrc/ir/verifier/property_verifier_registry.cppsrc/ir/verifier/verify_structured_ctrl_flow_pass.cpptests/st/runtime/test_ctrl_flow.pytests/ut/ir/transforms/test_ctrl_flow_transform.pytests/ut/ir/transforms/test_pass_manager.py
- Update pass-doc-ordering table to match actual Default pipeline (add InferTileMemorySpace, ResolveTransposeLayout; fix ExpandMixedKernel) - Remove non-existent FlattenedSingleStmt from pass property docs - Fix FlattenCallExpr required/produced properties to match code - Narrow StructuredCtrlFlow verifier comment to reflect InCore-only scope - Use unsigned MLIR ops (shrui/divui/minui/maxui) for unsigned int types in PTO codegen
95638b8 to
1f9611a
Compare
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
python/pypto/ir/pass_manager.py (1)
72-91:⚠️ Potential issue | 🔴 CriticalCCE strategy should include
CtrlFlowTransformto handlebreak/continuestatements.The CCE strategy omits
CtrlFlowTransform, but still runsUnrollLoopsfirst. WhileUnrollLoopsonly expands unroll-loops and does not generatebreak/continue, user code can still contain regular loops (pl.range) withbreak/continuestatements. WithoutCtrlFlowTransform, these statements would pass through to CCE codegen unchanged. However,CCECodegenhas no visitor methods forBreakStmtorContinueStmt, causing codegen to fail. The Default strategy avoids this by includingCtrlFlowTransformafterUnrollLoopsto eliminate allbreak/continuebefore downstream passes.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@python/pypto/ir/pass_manager.py` around lines 72 - 91, The CCE optimization list in OptimizationStrategy.CCE is missing the CtrlFlowTransform step which removes break/continue before codegen; add an entry for ("CtrlFlowTransform", lambda: passes.ctrl_flow_transform()) immediately after the existing ("UnrollLoops", lambda: passes.unroll_loops()) entry so that CtrlFlowTransform runs before downstream passes (ensuring CCECodegen won't see BreakStmt/ContinueStmt).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In `@python/pypto/ir/pass_manager.py`:
- Around line 72-91: The CCE optimization list in OptimizationStrategy.CCE is
missing the CtrlFlowTransform step which removes break/continue before codegen;
add an entry for ("CtrlFlowTransform", lambda: passes.ctrl_flow_transform())
immediately after the existing ("UnrollLoops", lambda: passes.unroll_loops())
entry so that CtrlFlowTransform runs before downstream passes (ensuring
CCECodegen won't see BreakStmt/ContinueStmt).
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 90d68965-1ff8-4b39-a0f3-2a71f5c4f252
📒 Files selected for processing (52)
.claude/rules/pass-doc-ordering.mdCMakeLists.txtdocs/en/dev/language/00-python_syntax.mddocs/en/dev/passes/00-pass_manager.mddocs/en/dev/passes/01-unroll_loops.mddocs/en/dev/passes/02-ctrl_flow_transform.mddocs/en/dev/passes/03-convert_to_ssa.mddocs/en/dev/passes/04-flatten_call_expr.mddocs/en/dev/passes/05-split_chunked_loops.mddocs/en/dev/passes/06-interchange_chunk_loops.mddocs/en/dev/passes/07-outline_incore_scopes.mddocs/en/dev/passes/08-outline_cluster_scopes.mddocs/en/dev/passes/10-flatten_tile_nd_to_2d.mddocs/en/dev/passes/11-expand_mixed_kernel.mddocs/en/dev/passes/12-init_memref.mddocs/en/dev/passes/13-basic_memory_reuse.mddocs/en/dev/passes/14-insert_sync.mddocs/en/dev/passes/15-allocate_memory_addr.mddocs/en/dev/passes/16-utility_passes.mddocs/zh-cn/dev/language/00-python_syntax.mddocs/zh-cn/dev/passes/00-pass_manager.mddocs/zh-cn/dev/passes/01-unroll_loops.mddocs/zh-cn/dev/passes/02-ctrl_flow_transform.mddocs/zh-cn/dev/passes/03-convert_to_ssa.mddocs/zh-cn/dev/passes/04-flatten_call_expr.mddocs/zh-cn/dev/passes/05-split_chunked_loops.mddocs/zh-cn/dev/passes/06-interchange_chunk_loops.mddocs/zh-cn/dev/passes/07-outline_incore_scopes.mddocs/zh-cn/dev/passes/08-outline_cluster_scopes.mddocs/zh-cn/dev/passes/10-flatten_tile_nd_to_2d.mddocs/zh-cn/dev/passes/11-expand_mixed_kernel.mddocs/zh-cn/dev/passes/12-init_memref.mddocs/zh-cn/dev/passes/13-basic_memory_reuse.mddocs/zh-cn/dev/passes/14-insert_sync.mddocs/zh-cn/dev/passes/15-allocate_memory_addr.mddocs/zh-cn/dev/passes/16-utility_passes.mdinclude/pypto/codegen/pto/pto_codegen.hinclude/pypto/ir/transforms/ir_property.hinclude/pypto/ir/transforms/pass_properties.hinclude/pypto/ir/transforms/passes.hinclude/pypto/ir/verifier/verifier.hpython/bindings/modules/passes.cpppython/pypto/ir/pass_manager.pypython/pypto/pypto_core/passes.pyisrc/codegen/pto/pto_codegen.cppsrc/ir/transforms/ctrl_flow_transform_pass.cppsrc/ir/transforms/ir_property.cppsrc/ir/verifier/property_verifier_registry.cppsrc/ir/verifier/verify_structured_ctrl_flow_pass.cpptests/st/runtime/test_ctrl_flow.pytests/ut/ir/transforms/test_ctrl_flow_transform.pytests/ut/ir/transforms/test_pass_manager.py
✅ Files skipped from review due to trivial changes (1)
- docs/zh-cn/dev/passes/02-ctrl_flow_transform.md
🚧 Files skipped from review as they are similar to previous changes (10)
- CMakeLists.txt
- docs/en/dev/passes/01-unroll_loops.md
- docs/zh-cn/dev/language/00-python_syntax.md
- src/ir/verifier/property_verifier_registry.cpp
- include/pypto/codegen/pto/pto_codegen.h
- tests/ut/ir/transforms/test_pass_manager.py
- python/pypto/pypto_core/passes.pyi
- include/pypto/ir/transforms/ir_property.h
- src/ir/transforms/ir_property.cpp
- docs/en/dev/language/00-python_syntax.md
- Update pass-doc-ordering table to match actual Default pipeline (add InferTileMemorySpace, ResolveTransposeLayout; fix ExpandMixedKernel) - Remove non-existent FlattenedSingleStmt from pass property docs - Fix FlattenCallExpr required/produced properties to match code - Narrow StructuredCtrlFlow verifier comment to reflect InCore-only scope - Use unsigned MLIR ops (shrui/divui/minui/maxui) for unsigned int types in PTO codegen
1f9611a to
352318b
Compare
… loops Transform break and continue statements into flag-based control flow using iter_args, enabling SSA conversion for programs with early exits. The pass rewrites loops to use boolean flags and conditional yields, preserving semantics while producing structured control flow. Includes StructuredCtrlFlow IRProperty, property verifier, full cross-layer bindings (C++/Python/stubs), per-pass documentation (EN/ZH-CN), and renumbered pass docs to match pipeline execution order.
…ions Skip break/continue elimination for Host/Orchestration functions since they support native control flow. Also fix ConstBool codegen to emit MLIR-compatible integer literals and clean up duplicate includes.
Add expression visitors for 15 operators missing from PTO codegen: - Logical: And, Or, Xor - Bitwise: BitAnd, BitOr, BitXor, BitShiftLeft, BitShiftRight - Other binary: FloatDiv, Min, Max - Unary: Not, Neg, Abs, BitNot Maps to corresponding MLIR arith/math dialect operations with int/float dispatch where applicable.
- Update pass-doc-ordering table to match actual Default pipeline (add InferTileMemorySpace, ResolveTransposeLayout; fix ExpandMixedKernel) - Remove non-existent FlattenedSingleStmt from pass property docs - Fix FlattenCallExpr required/produced properties to match code - Narrow StructuredCtrlFlow verifier comment to reflect InCore-only scope - Use unsigned MLIR ops (shrui/divui/minui/maxui) for unsigned int types in PTO codegen
Add <cstddef>, <optional>, and kind_traits.h to satisfy misc-include-cleaner checks.
Rewrite CtrlFlowTransform pass to handle break and continue in SSA-form IR using phi-node-based yield value resolution. Supports nested ifs, multiple escapes per loop, combined break+continue, and while loops. Add 48 comprehensive tests covering all edge cases.
352318b to
b2a4416
Compare
Summary
CtrlFlowTransformpass that rewritesbreakandcontinuestatements into flag-based control flow usingiter_args, enabling SSA conversion for programs with early exitsStructuredCtrlFlowIRProperty and its property verifier to track and validate structured control flow invariantspass-doc-ordering.md)Key Changes
src/ir/transforms/ctrl_flow_transform_pass.cpp— transforms break/continue into boolean flags with conditional yieldssrc/ir/verifier/verify_structured_ctrl_flow_pass.cpp— validates no break/continue remains post-transformTesting
tests/ut/ir/transforms/test_ctrl_flow_transform.pycovering break, continue, nested loops, and combined casestests/st/runtime/test_ctrl_flow.pytests/ut/ir/transforms/test_pass_manager.pyRelated Issues
Fixes #448