[ImportVerilog] Add capture analysis pre-pass for functions#10094
[ImportVerilog] Add capture analysis pre-pass for functions#10094fabianschuiki merged 1 commit intomainfrom
Conversation
There was a problem hiding this comment.
Not blocking at all but it’s a bit unfortunate that we have to run this level of analysis at the Slang AST. While the current complexity is manageable, if it continues to grow, I wonder if it's a good idea to introduce an intermediate operation to capture variables (e.g., a function-like operation without IsolatedFromAbove, maybe moore.closure) so we can progressively lower it.
|
@uenoku I went back and forth on this a bit. Intuitively, I thought lowering everything and then finding captured variables as SSA value uses that cross the function boundary sounded pretty good. But the problem with that is that we need to keep a map from AST nodes to SSA values around, instead of just keeping scoped hash maps and popping scopes as we leave them. That whole thing started to feel very ugly and messy compared to analyzing the captures at the frontend language level using the AST, and then just emitting the right IR for that directly 🤔 |
4882b1a to
34ecdfc
Compare
|
Thanks for the comments @uenoku -- I've addressed them 👍 |
34ecdfc to
17871eb
Compare
17871eb to
9bebba2
Compare
Add a pre-pass over the slang AST that determines which non-local, non-global variables each function captures, either directly or transitively through calls. This walks the entire AST, collecting variable references and call graph edges, then propagates captures through the inverse call graph using a worklist until stable. This analysis is a prerequisite for switching ImportVerilog to a two-phase declare-then-define approach for functions. Currently, function bodies are converted eagerly during package/module member iteration, which can fail when a function transitively references a variable that hasn't been declared yet (e.g., UVM's `m_uvm_core_state`). With the capture sets known upfront, function declarations can include the correct capture parameters from the start, and body conversion can be deferred. Also add `MapVector`, `SmallMapVector`, and `SmallSetVector` re-exports. The analysis is not yet directly used in ImportVerilog. This will be done in a follow-up commit. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
9bebba2 to
88297f5
Compare
|
|
||
| /// Test fixture that skips all tests when running under Valgrind, since slang | ||
| /// triggers Valgrind's uninitialized value detection. | ||
| class CaptureAnalysisTest : public testing::Test { |
Add a pre-pass over the slang AST that determines which non-local, non-global variables each function captures, either directly or transitively through calls. This walks the entire AST, collecting variable references and call graph edges, then propagates captures through the inverse call graph using a worklist until stable. This analysis is a prerequisite for switching ImportVerilog to a two-phase declare-then-define approach for functions. Currently, function bodies are converted eagerly during package/module member iteration, which can fail when a function transitively references a variable that hasn't been declared yet (e.g., UVM's `m_uvm_core_state`). With the capture sets known upfront, function declarations can include the correct capture parameters from the start, and body conversion can be deferred. Also add `MapVector`, `SmallMapVector`, and `SmallSetVector` re-exports. The analysis is not yet directly used in ImportVerilog. This will be done in a follow-up commit. Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add a pre-pass over the slang AST that determines which non-local, non-global variables each function captures, either directly or transitively through calls. This walks the entire AST, collecting variable references and call graph edges, then propagates captures through the inverse call graph using a worklist until stable.
This analysis is a prerequisite for switching ImportVerilog to a two-phase declare-then-define approach for functions. Currently, function bodies are converted eagerly during package/module member iteration, which can fail when a function transitively references a variable that hasn't been declared yet (e.g., UVM's
m_uvm_core_state). With the capture sets known upfront, function declarations can include the correct capture parameters from the start, and body conversion can be deferred.Also add
MapVector,SmallMapVector, andSmallSetVectorre-exports.The analysis is not yet directly used in ImportVerilog. This will be done in a follow-up commit.