Skip to content

BE-614: HashQL: Generate synthetic closure bodies for intrinsics used as first-class values#8895

Open
indietyp wants to merge 3 commits into
bm/be-615-hashql-introduce-synthetic-closures-and-trivial-closurefrom
bm/be-614-hashql-generate-synthetic-mir-bodies-for-intrinsics-in-value
Open

BE-614: HashQL: Generate synthetic closure bodies for intrinsics used as first-class values#8895
indietyp wants to merge 3 commits into
bm/be-615-hashql-introduce-synthetic-closures-and-trivial-closurefrom
bm/be-614-hashql-generate-synthetic-mir-bodies-for-intrinsics-in-value

Conversation

@indietyp

Copy link
Copy Markdown
Member

🌟 What is the purpose of this PR?

Allows intrinsics to be used in value position (passed as arguments, bound to variables) by generating synthetic MIR wrapper bodies during reification. Previously, intrinsics like <= could only appear at call sites where specialization rewrites them. Now they can flow through higher-order functions:

let apply = fn (a, b, f) = (f a b) in
(apply 2 3 <=)

🔍 What does this change?

Synthetic body generation:

  • Synthetics struct in CrossCompileState manages creation and caching of wrapper bodies
  • SyntheticBuilder generates MIR bodies with fat closure ABI (unit env as first parameter)
  • T! macro for matching qualified paths against ConstantSymbol arrays: &T![::core::cmp::gt] in slice patterns, sym::path::core::cmp::gt::CONST for the name
  • Dispatch table covers all first-classable intrinsics (comparison, boolean, arithmetic, bitwise) with local binary!/unary! macros deriving path and name from the same segments

Thin-call specialization:

  • rvalue_call_thin_specialize recognizes Call(Thin, Qualified(intrinsic), []) (the administrative thunk-force from the thunking phase) and produces the closure aggregate directly, skipping thunk body generation
  • Type unwrapping handles the thunking phase's () -> ClosureType wrapper to extract the actual signature

Intrinsic classification:

  • First-classable: comparison (gt, lt, gte, lte, eq, ne), boolean (and, or, not), arithmetic (add, sub), bitwise (and, or, not)
  • Unconstructible MIR ops (BinOp variants with ! payload): mul, div, rem, mod, pow, xor, shl, shr
  • No MIR ops: sqrt, cbrt, root
  • Not first-classable (syntactic forms): graph::head::entities, graph::body::filter, graph::tail::collect produce a specific user-facing diagnostic

Diagnostics:

  • intrinsic_not_first_class: user-facing error for graph intrinsics in value position
  • synthetic_binary_arity_mismatch / synthetic_unary_arity_mismatch: ICE for monomorphized type invariant violations

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

⚠️ Known issues

  • Bare intrinsic at module root ("<=" as the entire program) is not supported. The thunking phase does not wrap the root body when it is a variable, so it never reaches the synthetic machinery. Tracked with a run: skip test.

🐾 Next steps

  • Untyped property access (the original motivation for this work)
  • Module system support for root-level qualified paths (BE-67)

🛡 What tests cover this?

Compiletests (8 new):

  • reify/synthetic-intrinsic-value: basic synthetic body generation and thin-call specialization
  • reify/synthetic-intrinsic-reused: same intrinsic used twice shares one body (caching)
  • reify/synthetic-intrinsic-multiple: different intrinsics get separate bodies
  • reify/synthetic-graph-not-first-class: graph intrinsic in value position produces error
  • reify/synthetic-intrinsic-bare: bare intrinsic at root (run: skip)
  • interpret/synthetic-intrinsic-value: end-to-end correctness (evaluates to true)
  • post_inline/synthetic-intrinsic-hof: full optimization cascade with constants (collapses to return true)
  • post_inline/synthetic-intrinsic-hof-dynamic: HOF with dynamic inputs collapses to bare x <= y

❓ How to test this?

cargo run --package hashql-compiletest -- run --filter "test(synthetic)"

📹 Demo

The post_inline/synthetic-intrinsic-hof-dynamic test shows the full cascade. A higher-order function receiving <= as a value with dynamic inputs:

Initial:  construct closure for <=, pass to apply, call through fat pointer
Final:    %0 = input LOAD x
          %1 = input LOAD y
          %2 = %0 <= %1
          return %2

All indirection eliminated. Indistinguishable from writing ["<=", x, y] directly.

Copilot AI review requested due to automatic review settings June 22, 2026 16:43
@vercel

vercel Bot commented Jun 22, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
hash Error Error Jun 30, 2026 12:48pm
2 Skipped Deployments
Project Deployment Actions Updated (UTC)
hashdotdesign-tokens Ignored Ignored Preview Jun 30, 2026 12:48pm
petrinaut Skipped Skipped Jun 30, 2026 12:48pm

@vercel vercel Bot temporarily deployed to Preview – petrinaut June 22, 2026 16:43 Inactive
@indietyp indietyp changed the title BE-614: HashQL MIR: Generate synthetic closure bodies for intrinsics used as first-class values BE-614: HashQL: Generate synthetic closure bodies for intrinsics used as first-class values Jun 22, 2026
@cursor

cursor Bot commented Jun 22, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Touches core MIR reification and closure/call lowering; behavior is well-covered by compiletests but wrong intrinsic dispatch or ABI could affect all HashQL compilation paths.

Overview
Enables intrinsics in value position (e.g. passing <= into a higher-order function) by generating cached synthetic MIR closure bodies during HIR→MIR reification, instead of treating qualified paths as unsupported.

A new Synthetics layer in reify matches known ::core::… paths, builds fat-closure ABI bodies (Source::Synthetic) for cmp/bool/math/bits ops, and optionally wraps them in thunks. operand on qualified variables resolves through synthetics to FnPtr thunks; rvalue_call_thin_specialize beta-reduces administrative Call(Thin, Qualified, []) into closure aggregates. Graph intrinsics in value position get intrinsic_not_first_class; unknown paths still fall back to the existing external-modules diagnostic without duplicates when a synthetic error was already emitted.

Supporting tweaks: From<ConstantSymbol> for Symbol, sym::lhs/sym::rhs, scratch.reset() after reify in graph compile, and compiletests for reify/interpret/post-inline behavior.

Reviewed by Cursor Bugbot for commit 85c859a. Bugbot is set up for automated code reviews on this repo. Configure here.

Copy link
Copy Markdown
Member Author

Warning

This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
Learn more

This stack of pull requests is managed by Graphite. Learn more about stacking.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 48906c1. Configure here.

Comment thread libs/@local/hashql/mir/src/reify/synthetic.rs
@codecov

codecov Bot commented Jun 22, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0% with 3 lines in your changes missing coverage. Please review.
⚠️ Please upload report for BASE (bm/be-615-hashql-introduce-synthetic-closures-and-trivial-closure@f03d9a1). Learn more about missing BASE report.

Files with missing lines Patch % Lines
libs/@local/hashql/core/src/symbol/mod.rs 0.00% 3 Missing ⚠️
Additional details and impacted files
@@                                         Coverage Diff                                          @@
##             bm/be-615-hashql-introduce-synthetic-closures-and-trivial-closure    #8895   +/-   ##
====================================================================================================
  Coverage                                                                     ?   81.98%           
====================================================================================================
  Files                                                                        ?      168           
  Lines                                                                        ?    25146           
  Branches                                                                     ?      717           
====================================================================================================
  Hits                                                                         ?    20616           
  Misses                                                                       ?     4323           
  Partials                                                                     ?      207           
Flag Coverage Δ
rust.hashql-core 79.27% <0.00%> (?)
rust.hashql-syntax-jexpr 94.04% <ø> (?)

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

☔ View full report in Codecov by Harness.
📢 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

codspeed-hq Bot commented Jun 22, 2026

Copy link
Copy Markdown

Merging this PR will degrade performance by 27.89%

❌ 1 regressed benchmark
✅ 55 untouched benchmarks
⏩ 24 skipped benchmarks1

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Benchmark BASE HEAD Efficiency
pattern_match_constant 150.8 ns 209.2 ns -27.89%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing bm/be-614-hashql-generate-synthetic-mir-bodies-for-intrinsics-in-value (85c859a) with bm/be-615-hashql-introduce-synthetic-closures-and-trivial-closure (f03d9a1)

Open in CodSpeed

Footnotes

  1. 24 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@indietyp indietyp force-pushed the bm/be-614-hashql-generate-synthetic-mir-bodies-for-intrinsics-in-value branch from 48906c1 to c5a86df Compare June 23, 2026 09:41
@indietyp indietyp force-pushed the bm/be-615-hashql-introduce-synthetic-closures-and-trivial-closure branch from 8efe84c to a0c8ad1 Compare June 23, 2026 09:41
@vercel vercel Bot temporarily deployed to Preview – petrinaut June 23, 2026 09:41 Inactive
@indietyp indietyp force-pushed the bm/be-614-hashql-generate-synthetic-mir-bodies-for-intrinsics-in-value branch from c5a86df to feac27a Compare June 23, 2026 09:52
@indietyp indietyp force-pushed the bm/be-615-hashql-introduce-synthetic-closures-and-trivial-closure branch from a0c8ad1 to 0ddf199 Compare June 23, 2026 09:52
@vercel vercel Bot temporarily deployed to Preview – petrinaut June 23, 2026 09:52 Inactive
Copilot AI review requested due to automatic review settings June 23, 2026 10:02
@indietyp indietyp force-pushed the bm/be-615-hashql-introduce-synthetic-closures-and-trivial-closure branch from 0ddf199 to d051ddb Compare June 23, 2026 10:02
@indietyp indietyp force-pushed the bm/be-614-hashql-generate-synthetic-mir-bodies-for-intrinsics-in-value branch from feac27a to 5f1207d Compare June 23, 2026 10:02
@vercel vercel Bot temporarily deployed to Preview – petrinaut June 23, 2026 10:03 Inactive

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 25 out of 25 changed files in this pull request and generated 3 comments.

Comment thread libs/@local/hashql/mir/src/reify/synthetic.rs
Comment thread libs/@local/hashql/mir/src/reify/synthetic.rs
Comment thread libs/@local/hashql/mir/src/reify/atom.rs
@github-actions

Copy link
Copy Markdown
Contributor

Benchmark results

@rust/hash-graph-benches – Integrations

policy_resolution_large

Function Value Mean Flame graphs
resolve_policies_for_actor user: empty, selectivity: high, policies: 2002 $$26.7 \mathrm{ms} \pm 174 \mathrm{μs}\left({\color{gray}1.88 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: low, policies: 1 $$3.41 \mathrm{ms} \pm 17.7 \mathrm{μs}\left({\color{gray}-3.213 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: medium, policies: 1001 $$12.7 \mathrm{ms} \pm 100 \mathrm{μs}\left({\color{gray}0.770 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: high, policies: 3314 $$44.2 \mathrm{ms} \pm 383 \mathrm{μs}\left({\color{gray}1.66 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: low, policies: 1 $$15.0 \mathrm{ms} \pm 114 \mathrm{μs}\left({\color{gray}-1.675 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: medium, policies: 1526 $$24.3 \mathrm{ms} \pm 171 \mathrm{μs}\left({\color{gray}-0.931 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: high, policies: 2078 $$27.9 \mathrm{ms} \pm 142 \mathrm{μs}\left({\color{gray}3.96 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: low, policies: 1 $$3.97 \mathrm{ms} \pm 60.1 \mathrm{μs}\left({\color{gray}2.47 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: medium, policies: 1033 $$14.0 \mathrm{ms} \pm 87.7 \mathrm{μs}\left({\color{red}5.06 \mathrm{\%}}\right) $$ Flame Graph

policy_resolution_medium

Function Value Mean Flame graphs
resolve_policies_for_actor user: empty, selectivity: high, policies: 102 $$3.73 \mathrm{ms} \pm 23.5 \mathrm{μs}\left({\color{gray}0.336 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: low, policies: 1 $$3.03 \mathrm{ms} \pm 16.0 \mathrm{μs}\left({\color{lightgreen}-12.233 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: medium, policies: 51 $$3.35 \mathrm{ms} \pm 14.9 \mathrm{μs}\left({\color{gray}-3.334 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: high, policies: 269 $$5.21 \mathrm{ms} \pm 50.3 \mathrm{μs}\left({\color{gray}0.634 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: low, policies: 1 $$3.59 \mathrm{ms} \pm 17.3 \mathrm{μs}\left({\color{gray}-1.337 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: medium, policies: 107 $$4.16 \mathrm{ms} \pm 31.4 \mathrm{μs}\left({\color{gray}0.974 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: high, policies: 133 $$4.37 \mathrm{ms} \pm 28.0 \mathrm{μs}\left({\color{gray}-0.558 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: low, policies: 1 $$3.50 \mathrm{ms} \pm 17.3 \mathrm{μs}\left({\color{gray}1.33 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: medium, policies: 63 $$4.09 \mathrm{ms} \pm 31.2 \mathrm{μs}\left({\color{gray}1.34 \mathrm{\%}}\right) $$ Flame Graph

policy_resolution_none

Function Value Mean Flame graphs
resolve_policies_for_actor user: empty, selectivity: high, policies: 2 $$2.72 \mathrm{ms} \pm 13.4 \mathrm{μs}\left({\color{gray}3.05 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: low, policies: 1 $$2.54 \mathrm{ms} \pm 15.3 \mathrm{μs}\left({\color{gray}1.50 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: medium, policies: 1 $$2.69 \mathrm{ms} \pm 16.4 \mathrm{μs}\left({\color{gray}4.16 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: high, policies: 8 $$2.97 \mathrm{ms} \pm 14.6 \mathrm{μs}\left({\color{gray}2.06 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: low, policies: 1 $$2.78 \mathrm{ms} \pm 16.3 \mathrm{μs}\left({\color{gray}4.49 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: medium, policies: 3 $$2.96 \mathrm{ms} \pm 18.1 \mathrm{μs}\left({\color{gray}3.56 \mathrm{\%}}\right) $$ Flame Graph

policy_resolution_small

Function Value Mean Flame graphs
resolve_policies_for_actor user: empty, selectivity: high, policies: 52 $$3.03 \mathrm{ms} \pm 19.1 \mathrm{μs}\left({\color{gray}1.26 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: low, policies: 1 $$2.77 \mathrm{ms} \pm 18.6 \mathrm{μs}\left({\color{gray}0.026 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: empty, selectivity: medium, policies: 25 $$2.96 \mathrm{ms} \pm 13.2 \mathrm{μs}\left({\color{gray}-0.949 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: high, policies: 94 $$3.39 \mathrm{ms} \pm 20.4 \mathrm{μs}\left({\color{gray}-1.993 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: low, policies: 1 $$2.94 \mathrm{ms} \pm 12.4 \mathrm{μs}\left({\color{gray}-0.704 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: seeded, selectivity: medium, policies: 26 $$3.26 \mathrm{ms} \pm 14.2 \mathrm{μs}\left({\color{gray}-0.252 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: high, policies: 66 $$3.33 \mathrm{ms} \pm 18.0 \mathrm{μs}\left({\color{gray}0.506 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: low, policies: 1 $$2.99 \mathrm{ms} \pm 16.9 \mathrm{μs}\left({\color{gray}1.48 \mathrm{\%}}\right) $$ Flame Graph
resolve_policies_for_actor user: system, selectivity: medium, policies: 29 $$3.35 \mathrm{ms} \pm 26.9 \mathrm{μs}\left({\color{gray}0.723 \mathrm{\%}}\right) $$ Flame Graph

read_scaling_complete

Function Value Mean Flame graphs
entity_by_id;one_depth 1 entities $$42.8 \mathrm{ms} \pm 204 \mathrm{μs}\left({\color{gray}3.20 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;one_depth 10 entities $$33.4 \mathrm{ms} \pm 203 \mathrm{μs}\left({\color{lightgreen}-15.538 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;one_depth 25 entities $$36.3 \mathrm{ms} \pm 170 \mathrm{μs}\left({\color{lightgreen}-13.426 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;one_depth 5 entities $$32.1 \mathrm{ms} \pm 180 \mathrm{μs}\left({\color{lightgreen}-13.664 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;one_depth 50 entities $$42.7 \mathrm{ms} \pm 226 \mathrm{μs}\left({\color{lightgreen}-22.029 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 1 entities $$50.0 \mathrm{ms} \pm 312 \mathrm{μs}\left({\color{lightgreen}-18.260 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 10 entities $$41.2 \mathrm{ms} \pm 261 \mathrm{μs}\left({\color{lightgreen}-22.645 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 25 entities $$93.4 \mathrm{ms} \pm 408 \mathrm{μs}\left({\color{lightgreen}-12.795 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 5 entities $$35.0 \mathrm{ms} \pm 233 \mathrm{μs}\left({\color{lightgreen}-37.989 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;two_depth 50 entities $$276 \mathrm{ms} \pm 933 \mathrm{μs}\left({\color{lightgreen}-8.745 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 1 entities $$10.5 \mathrm{ms} \pm 56.8 \mathrm{μs}\left({\color{lightgreen}-23.522 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 10 entities $$10.6 \mathrm{ms} \pm 65.7 \mathrm{μs}\left({\color{lightgreen}-20.076 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 25 entities $$10.7 \mathrm{ms} \pm 66.0 \mathrm{μs}\left({\color{lightgreen}-21.553 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 5 entities $$10.4 \mathrm{ms} \pm 80.4 \mathrm{μs}\left({\color{lightgreen}-23.806 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id;zero_depth 50 entities $$10.7 \mathrm{ms} \pm 61.5 \mathrm{μs}\left({\color{lightgreen}-25.985 \mathrm{\%}}\right) $$ Flame Graph

read_scaling_linkless

Function Value Mean Flame graphs
entity_by_id 1 entities $$10.5 \mathrm{ms} \pm 73.6 \mathrm{μs}\left({\color{lightgreen}-24.301 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id 10 entities $$10.7 \mathrm{ms} \pm 50.2 \mathrm{μs}\left({\color{lightgreen}-21.928 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id 100 entities $$10.9 \mathrm{ms} \pm 66.7 \mathrm{μs}\left({\color{lightgreen}-22.613 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id 1000 entities $$11.1 \mathrm{ms} \pm 69.5 \mathrm{μs}\left({\color{lightgreen}-20.782 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id 10000 entities $$10.9 \mathrm{ms} \pm 70.0 \mathrm{μs}\left({\color{lightgreen}-25.492 \mathrm{\%}}\right) $$ Flame Graph

representative_read_entity

Function Value Mean Flame graphs
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/block/v/1 $$11.0 \mathrm{ms} \pm 101 \mathrm{μs}\left({\color{lightgreen}-23.437 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/book/v/1 $$11.1 \mathrm{ms} \pm 69.7 \mathrm{μs}\left({\color{lightgreen}-22.183 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/building/v/1 $$11.0 \mathrm{ms} \pm 57.4 \mathrm{μs}\left({\color{lightgreen}-14.912 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/organization/v/1 $$11.3 \mathrm{ms} \pm 75.1 \mathrm{μs}\left({\color{lightgreen}-20.391 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/page/v/2 $$10.9 \mathrm{ms} \pm 63.8 \mathrm{μs}\left({\color{lightgreen}-17.833 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/person/v/1 $$11.0 \mathrm{ms} \pm 56.2 \mathrm{μs}\left({\color{lightgreen}-22.408 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/playlist/v/1 $$11.3 \mathrm{ms} \pm 58.7 \mathrm{μs}\left({\color{lightgreen}-18.877 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/song/v/1 $$11.0 \mathrm{ms} \pm 71.3 \mathrm{μs}\left({\color{lightgreen}-22.823 \mathrm{\%}}\right) $$ Flame Graph
entity_by_id entity type ID: https://blockprotocol.org/@alice/types/entity-type/uk-address/v/1 $$11.2 \mathrm{ms} \pm 75.0 \mathrm{μs}\left({\color{lightgreen}-16.767 \mathrm{\%}}\right) $$ Flame Graph

representative_read_entity_type

Function Value Mean Flame graphs
get_entity_type_by_id Account ID: bf5a9ef5-dc3b-43cf-a291-6210c0321eba $$8.63 \mathrm{ms} \pm 50.6 \mathrm{μs}\left({\color{lightgreen}-16.663 \mathrm{\%}}\right) $$ Flame Graph

representative_read_multiple_entities

Function Value Mean Flame graphs
entity_by_property traversal_paths=0 0 $$60.5 \mathrm{ms} \pm 393 \mathrm{μs}\left({\color{lightgreen}-10.956 \mathrm{\%}}\right) $$
entity_by_property traversal_paths=255 1,resolve_depths=inherit:1;values:255;properties:255;links:127;link_dests:126;type:true $$109 \mathrm{ms} \pm 532 \mathrm{μs}\left({\color{lightgreen}-15.839 \mathrm{\%}}\right) $$
entity_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:0;properties:0;links:0;link_dests:0;type:false $$68.6 \mathrm{ms} \pm 926 \mathrm{μs}\left({\color{lightgreen}-8.120 \mathrm{\%}}\right) $$
entity_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:0;properties:0;links:1;link_dests:0;type:true $$77.9 \mathrm{ms} \pm 608 \mathrm{μs}\left({\color{lightgreen}-8.637 \mathrm{\%}}\right) $$
entity_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:0;properties:2;links:1;link_dests:0;type:true $$82.5 \mathrm{ms} \pm 563 \mathrm{μs}\left({\color{lightgreen}-13.460 \mathrm{\%}}\right) $$
entity_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:2;properties:2;links:1;link_dests:0;type:true $$88.9 \mathrm{ms} \pm 547 \mathrm{μs}\left({\color{lightgreen}-13.593 \mathrm{\%}}\right) $$
link_by_source_by_property traversal_paths=0 0 $$45.0 \mathrm{ms} \pm 282 \mathrm{μs}\left({\color{lightgreen}-11.268 \mathrm{\%}}\right) $$
link_by_source_by_property traversal_paths=255 1,resolve_depths=inherit:1;values:255;properties:255;links:127;link_dests:126;type:true $$74.3 \mathrm{ms} \pm 389 \mathrm{μs}\left({\color{lightgreen}-11.610 \mathrm{\%}}\right) $$
link_by_source_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:0;properties:0;links:0;link_dests:0;type:false $$52.0 \mathrm{ms} \pm 425 \mathrm{μs}\left({\color{lightgreen}-9.563 \mathrm{\%}}\right) $$
link_by_source_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:0;properties:0;links:1;link_dests:0;type:true $$62.5 \mathrm{ms} \pm 338 \mathrm{μs}\left({\color{lightgreen}-10.507 \mathrm{\%}}\right) $$
link_by_source_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:0;properties:2;links:1;link_dests:0;type:true $$63.8 \mathrm{ms} \pm 302 \mathrm{μs}\left({\color{lightgreen}-11.557 \mathrm{\%}}\right) $$
link_by_source_by_property traversal_paths=2 1,resolve_depths=inherit:0;values:2;properties:2;links:1;link_dests:0;type:true $$64.1 \mathrm{ms} \pm 275 \mathrm{μs}\left({\color{lightgreen}-10.835 \mathrm{\%}}\right) $$

scenarios

Function Value Mean Flame graphs
full_test query-limited $$125 \mathrm{ms} \pm 595 \mathrm{μs}\left({\color{gray}-4.932 \mathrm{\%}}\right) $$ Flame Graph
full_test query-unlimited $$136 \mathrm{ms} \pm 449 \mathrm{μs}\left({\color{gray}-3.805 \mathrm{\%}}\right) $$ Flame Graph
linked_queries query-limited $$23.6 \mathrm{ms} \pm 120 \mathrm{μs}\left({\color{red}29.6 \mathrm{\%}}\right) $$ Flame Graph
linked_queries query-unlimited $$529 \mathrm{ms} \pm 894 \mathrm{μs}\left({\color{gray}-2.114 \mathrm{\%}}\right) $$ Flame Graph

@indietyp indietyp force-pushed the bm/be-614-hashql-generate-synthetic-mir-bodies-for-intrinsics-in-value branch from 5f1207d to d2c1bc0 Compare June 30, 2026 09:56
@indietyp indietyp force-pushed the bm/be-615-hashql-introduce-synthetic-closures-and-trivial-closure branch from d051ddb to 996e625 Compare June 30, 2026 09:56
@vercel vercel Bot temporarily deployed to Preview – petrinaut June 30, 2026 09:56 Inactive
@indietyp indietyp force-pushed the bm/be-614-hashql-generate-synthetic-mir-bodies-for-intrinsics-in-value branch from d2c1bc0 to b96a707 Compare June 30, 2026 12:44
@indietyp indietyp force-pushed the bm/be-615-hashql-introduce-synthetic-closures-and-trivial-closure branch from 996e625 to 0a0050d Compare June 30, 2026 12:44
@vercel vercel Bot temporarily deployed to Preview – petrinaut June 30, 2026 12:44 Inactive
Copilot AI review requested due to automatic review settings June 30, 2026 12:45
@indietyp indietyp force-pushed the bm/be-615-hashql-introduce-synthetic-closures-and-trivial-closure branch from 0a0050d to f03d9a1 Compare June 30, 2026 12:45
@indietyp indietyp force-pushed the bm/be-614-hashql-generate-synthetic-mir-bodies-for-intrinsics-in-value branch from b96a707 to 85c859a Compare June 30, 2026 12:45
@vercel vercel Bot temporarily deployed to Preview – petrinaut June 30, 2026 12:45 Inactive

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 25 out of 25 changed files in this pull request and generated 2 comments.

Comment on lines +231 to +239
// MIR ops exist but are unconstructible (BinOp variants carry `!`)
&T![::core::math::mul]
| &T![::core::math::div]
| &T![::core::math::rem]
| &T![::core::math::r#mod]
| &T![::core::math::pow]
| &T![::core::bits::xor]
| &T![::core::bits::shl]
| &T![::core::bits::shr] => None,
Comment on lines +241 to +242
// math functions without direct MIR ops
&T![::core::math::sqrt] | &T![::core::math::cbrt] | &T![::core::math::root] => None,
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