Skip to content

Conversation

@indietyp
Copy link
Member

Add call graph analysis for MIR

🌟 What is the purpose of this PR?

This PR adds a call graph analysis pass for MIR that tracks function call relationships between definitions. The call graph can be used for call site enumeration, reachability analysis, and optimization decisions.

🔍 What does this change?

  • Adds CallGraph to represent function call relationships between DefIds
  • Implements CallGraphAnalysis pass to populate the graph from MIR bodies
  • Adds CallKind enum to distinguish between direct function calls, filter functions, and other references
  • Adds id field to Body struct to track the definition ID of each body
  • Implements Display for Location and GraphReadLocation to improve debugging
  • Includes comprehensive tests with snapshots to verify call graph construction

Pre-Merge Checklist 🚀

🚢 Has this modified a publishable library?

This PR:

  • does not modify any publishable blocks or libraries, or modifications do not need publishing

📜 Does this require a change to the docs?

The changes in this PR:

  • are internal and do not require a docs change

🕸️ Does this require a change to the Turbo Graph?

The changes in this PR:

  • do not affect the execution graph

🛡 What tests cover this?

  • Comprehensive unit tests for various call patterns:
    • Direct function calls
    • Function arguments containing DefIds
    • Multiple calls from the same body
    • Call chains across multiple bodies
    • Recursive calls
    • Indirect calls via locals

@cursor
Copy link

cursor bot commented Dec 23, 2025

PR Summary

Implements inter-procedural call graph construction for MIR and plumbs definition IDs through bodies to enable cross-body analysis and debugging.

  • Add CallGraph with edge kinds CallKind::{Apply,Filter,Opaque} and Display for human-readable output
  • New CallGraphAnalysis pass to traverse bodies and record edges (including graph-read filter sites)
  • Extend Body with id: DefId; set in builder::finish (placeholder) and assigned during reify via push_with
  • Implement Display for Location and GraphReadLocation (e.g., bb0:1) to annotate call sites
  • Update visitors to ignore Body.id and adjust traversal; re-export analysis in pass::analysis
  • Add focused snapshot tests covering direct/indirect calls, arguments, multiple calls, chains, and recursion

Written by Cursor Bugbot for commit 9d0c0ed. This will update automatically on new commits. Configure here.

Copy link
Member Author

indietyp commented Dec 23, 2025

@augmentcode
Copy link

augmentcode bot commented Dec 23, 2025

🤖 Augment PR Summary

Summary: Adds an inter-procedural call graph analysis pass for HashQL MIR to track cross-definition references and call sites.

Changes:

  • Introduce CallGraph (backed by LinkedGraph) keyed by DefId nodes and CallKind-annotated edges.
  • Add CallGraphAnalysis visitor pass that walks MIR bodies and records Apply, graph-read Filter, and Opaque references.
  • Extend Body with id: DefId and plumb assignment through lowering via push_with.
  • Implement Display for Location and GraphReadLocation to improve debugging / snapshots.
  • Expose call graph analysis from pass::analysis.
  • Add snapshot-based unit tests covering direct calls, call chains, recursion, argument references, and indirect calls via locals.

Technical Notes: Direct call edges are only emitted when the callee is syntactically a DefId (indirect calls via locals are treated as Opaque until later lowering/SROA removes most indirections).

🤖 Was this summary useful? React with 👍 or 👎

Copy link

@augmentcode augmentcode bot left a comment

Choose a reason for hiding this comment

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

Review completed. 1 suggestions posted.

Fix All in Augment

Comment augment review to trigger a new review at any time.

fn run(&mut self, _: &mut MirContext<'env, 'heap>, body: &Body<'heap>) {
let mut visitor = CallGraphVisitor {
kind: CallKind::Opaque,
caller: body.id,
Copy link

Choose a reason for hiding this comment

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

CallGraphAnalysis assumes body.id is a valid in-domain DefId; otherwise add_edge will panic (e.g., bodies produced by BodyBuilder::finish default to DefId::MAX unless overwritten). Consider asserting/documenting this precondition here to make failures easier to diagnose.

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎

@codecov
Copy link

codecov bot commented Dec 23, 2025

Codecov Report

❌ Patch coverage is 91.93548% with 25 lines in your changes missing coverage. Please review.
✅ Project coverage is 59.25%. Comparing base (65c3381) to head (9d0c0ed).

Files with missing lines Patch % Lines
...ocal/hashql/mir/src/pass/analysis/callgraph/mod.rs 73.91% 18 Missing ⚠️
...ibs/@local/hashql/mir/src/body/terminator/graph.rs 0.00% 6 Missing ⚠️
libs/@local/hashql/mir/src/visit/mut.rs 50.00% 1 Missing ⚠️
Additional details and impacted files
@@                                         Coverage Diff                                         @@
##           bm/be-258-hashql-implement-transformationpass-changed-detection    #8214      +/-   ##
===================================================================================================
+ Coverage                                                            59.15%   59.25%   +0.10%     
===================================================================================================
  Files                                                                 1197     1201       +4     
  Lines                                                               113726   114033     +307     
  Branches                                                              5060     5060              
===================================================================================================
+ Hits                                                                 67275    67572     +297     
- Misses                                                               45675    45685      +10     
  Partials                                                               776      776              
Flag Coverage Δ
rust.hashql-compiletest 46.65% <ø> (ø)
rust.hashql-mir 88.51% <91.93%> (+0.27%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@codspeed-hq
Copy link

codspeed-hq bot commented Dec 23, 2025

CodSpeed Performance Report

Merging #8214 will not alter performance

Comparing bm/be-227-hashql-implement-call-graph (9d0c0ed) with bm/be-258-hashql-implement-transformationpass-changed-detection (65c3381)

Summary

✅ 17 untouched

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/libs Relates to first-party libraries/crates/packages (area) area/tests New or updated tests type/eng > backend Owned by the @backend team

Development

Successfully merging this pull request may close these issues.

2 participants