- 
                Notifications
    
You must be signed in to change notification settings  - Fork 68
 
Use std::list for IR scopes #5475
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
          
Description
 Changes walkthrough 📝
 PR Reviewer Guide 🔍Here are some key observations to aid the review process: 
  | 
    
| 
           !test  | 
    
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Greptile Overview
Greptile Summary
This PR refactors the Scope class to use std::list<Expr*> instead of std::vector<Expr*> for storing expressions. This change improves insertion/deletion performance for scope operations while maintaining correctness throughout the codebase.
Key Changes:
- Changed 
Scope::exprs_fromstd::vector<Expr*>tostd::list<Expr*>(using type aliasExprList) - Removed direct indexing methods (
at(),operator[]) fromScopeclass - Updated all code using indexed access to use iterator-based operations (
std::prev(),std::next(),.front(),.back()) - Added overloads in visitor classes (
IrVisitor,ConstIrVisitor) to handlestd::list<Expr*> - Templated several utility functions to work with generic expression containers
 - In places requiring indexed access, created local vector copies to maintain semantics
 
Benefits:
- O(1) insertion/deletion at any position (previously O(n) with vector)
 - Better performance for scope manipulation operations common in compiler passes
 - No change to external API semantics
 
Confidence Score: 5/5
- This PR is safe to merge - the refactoring is thorough, systematic, and well-tested
 - The changes are a clean internal refactor with no algorithmic changes. All call sites have been properly updated to use iterator-based operations or create local copies where needed. The tests have been updated to match the new API, and the change improves performance without altering semantics.
 - No files require special attention - all changes follow consistent patterns
 
Important Files Changed
File Analysis
| Filename | Score | Overview | 
|---|---|---|
| csrc/ir/internal_nodes.h | 5/5 | Changed Scope::exprs_ from std::vector<Expr*> to std::list<Expr*>, removed direct indexing methods at() and operator[] | 
| csrc/ir/nodes.cpp | 5/5 | Updated Scope methods to use list iterators with std::advance() and std::next() instead of pointer arithmetic | 
| csrc/kernel_ir_dispatch.cpp | 5/5 | Added handle() overloads for std::list<Expr*> in both IrVisitor and ConstIrVisitor, removed unnecessary vector copies | 
| csrc/device_lower/pass/circular_buffer.cpp | 4/5 | Replaced vector indexing with list iterators, added conversion to const_iterator for reverse iterator operations | 
| csrc/device_lower/pass/insert_syncs.cpp | 5/5 | Replaced vector indexing with std::prev() for accessing elements from the end of the list | 
| csrc/device_lower/pass/scalar_hoist.cpp | 5/5 | Added local vector copy to maintain indexing semantics when accessing scope expressions | 
Sequence Diagram
sequenceDiagram
    participant Client as Client Code
    participant Scope as Scope Class
    participant ExprList as std::list<Expr*>
    participant Visitor as IrVisitor
    
    Note over Scope,ExprList: Core Data Structure Change
    Client->>Scope: insert_after(ref, expr)
    Scope->>ExprList: std::find(ref)
    ExprList-->>Scope: iterator
    Scope->>ExprList: insert(std::next(it), expr)
    ExprList-->>Client: O(1) insertion
    
    Note over Client,Visitor: Visitor Pattern Updates
    Client->>Visitor: handle(exprs)
    alt exprs is std::vector
        Visitor->>Visitor: handle(vector overload)
    else exprs is std::list
        Visitor->>Visitor: handle(list overload)
    end
    Visitor->>Visitor: dispatch each expr
    Visitor-->>Client: processed exprs
    
    Note over Client,ExprList: Indexed Access Pattern
    Client->>Client: Need indexed access?
    alt Direct iteration OK
        Client->>ExprList: iterate with iterators
    else Need random access
        Client->>Client: Create local vector copy
        Client->>Client: Use vector indexing
    end
    19 files reviewed, no comments
| 
           @jacobhinkle and @naoyam before I polish this PR further, is it a terrible idea? Initially, I wanted to make hir::ForLoop's scope a linked list so I can fast insert allocations/deallocations to the middle of a list. However, hir::ForLoop shares the same Scope data structure as kir::ForLoop so I made this change. Alternatively, I could change only hir::ForLoop to store the loop body as a linked list.  | 
    
          
 Looks like  Other than that, I don't have any particular concern.  | 
    
Summary
Scopeto store statements instd::list<Expr*>so iterator stability matches mutation patternsScope::ExprListalias, iterator-based access,flattenScopedExprsoverload, etc.)toVector,.at,operator[]), fixing the build after the container swapiteratorAthelper sinceerase(size_t)is the only remaining index-based operationTesting
cmake --build python/build --target install -- -j 8bin/test_nvfuserfrom running; command attempted)