From 3a34a3fecd9b6ebceaac7521f624d7d647551482 Mon Sep 17 00:00:00 2001 From: Bilal Mahmoud Date: Sun, 22 Mar 2026 18:24:40 +0100 Subject: [PATCH 1/6] feat: checkpoint --- .../hashql/core/src/id/bit_vec/finite.rs | 100 ++++++++++++++++++ .../hashql/mir/src/pass/execution/cost/mod.rs | 59 ++++++++++- .../hashql/mir/src/pass/execution/mod.rs | 6 +- .../src/pass/execution/placement/arc/mod.rs | 12 +-- .../src/pass/execution/placement/arc/tests.rs | 24 ++--- .../execution/placement/solve/condensation.rs | 6 +- .../execution/placement/solve/csp/tests.rs | 48 ++++----- .../placement/solve/estimate/tests.rs | 10 +- .../src/pass/execution/placement/solve/mod.rs | 4 +- .../pass/execution/placement/solve/tests.rs | 34 +++--- .../mir/src/pass/execution/splitting/mod.rs | 86 +++++++++++---- .../mir/src/pass/execution/splitting/tests.rs | 10 +- .../execution/statement_placement/common.rs | 42 +++++++- .../statement_placement/embedding/mod.rs | 57 ++++++++-- .../statement_placement/interpret/mod.rs | 25 ++++- .../pass/execution/statement_placement/mod.rs | 6 +- .../statement_placement/postgres/mod.rs | 45 +++++++- .../execution/terminator_placement/mod.rs | 24 +++-- .../execution/terminator_placement/tests.rs | 8 +- 19 files changed, 472 insertions(+), 134 deletions(-) diff --git a/libs/@local/hashql/core/src/id/bit_vec/finite.rs b/libs/@local/hashql/core/src/id/bit_vec/finite.rs index 9ccfddd22ad..1a9c66daac6 100644 --- a/libs/@local/hashql/core/src/id/bit_vec/finite.rs +++ b/libs/@local/hashql/core/src/id/bit_vec/finite.rs @@ -339,6 +339,28 @@ impl FiniteBitSet { Some(I::from_u32(self.store.trailing_zeros())) } + /// Returns `true` if `self` is a superset of `other` (contains all bits set in `other`). + #[inline] + #[must_use] + pub const fn is_superset(&self, other: &Self) -> bool + where + T: [const] FiniteBitSetIntegral, + { + // `other` is a subset of `self` iff `other & self == other` + other.store & self.store == other.store + } + + /// Returns `true` if `self` is a subset of `other` (all bits set in `self` are also set in + /// `other`). + #[inline] + #[must_use] + pub const fn is_subset(&self, other: &Self) -> bool + where + T: [const] FiniteBitSetIntegral, + { + other.is_superset(self) + } + /// Returns an iterator over the indices of set bits. #[inline] pub fn iter(&self) -> FiniteBitIter { @@ -863,6 +885,84 @@ mod tests { assert_eq!(set, original); } + #[test] + fn is_superset_of_subset() { + let mut a: FiniteBitSet = FiniteBitSet::new_empty(8); + a.insert_range(TestId::from_usize(0)..=TestId::from_usize(5), 8); + + let mut b: FiniteBitSet = FiniteBitSet::new_empty(8); + b.insert(TestId::from_usize(1)); + b.insert(TestId::from_usize(3)); + + assert!(a.is_superset(&b)); + assert!(!b.is_superset(&a)); + } + + #[test] + fn is_subset_of_superset() { + let mut a: FiniteBitSet = FiniteBitSet::new_empty(8); + a.insert(TestId::from_usize(2)); + a.insert(TestId::from_usize(4)); + + let mut b: FiniteBitSet = FiniteBitSet::new_empty(8); + b.insert_range(TestId::from_usize(0)..=TestId::from_usize(7), 8); + + assert!(a.is_subset(&b)); + assert!(!b.is_subset(&a)); + } + + #[test] + fn empty_is_subset_of_everything() { + let empty: FiniteBitSet = FiniteBitSet::new_empty(8); + + let mut full: FiniteBitSet = FiniteBitSet::new_empty(8); + full.insert_range(TestId::from_usize(0)..=TestId::from_usize(7), 8); + + assert!(empty.is_subset(&full)); + assert!(empty.is_subset(&empty)); + assert!(full.is_superset(&empty)); + } + + #[test] + fn equal_sets_are_both_subset_and_superset() { + let mut a: FiniteBitSet = FiniteBitSet::new_empty(8); + a.insert(TestId::from_usize(1)); + a.insert(TestId::from_usize(5)); + + let b = a; + + assert!(a.is_subset(&b)); + assert!(a.is_superset(&b)); + } + + #[test] + fn disjoint_sets_are_not_subsets() { + let mut a: FiniteBitSet = FiniteBitSet::new_empty(8); + a.insert(TestId::from_usize(0)); + a.insert(TestId::from_usize(1)); + + let mut b: FiniteBitSet = FiniteBitSet::new_empty(8); + b.insert(TestId::from_usize(6)); + b.insert(TestId::from_usize(7)); + + assert!(!a.is_subset(&b)); + assert!(!a.is_superset(&b)); + assert!(!b.is_subset(&a)); + assert!(!b.is_superset(&a)); + } + + #[test] + fn overlapping_sets_are_not_subsets() { + let mut a: FiniteBitSet = FiniteBitSet::new_empty(8); + a.insert_range(TestId::from_usize(0)..=TestId::from_usize(3), 8); + + let mut b: FiniteBitSet = FiniteBitSet::new_empty(8); + b.insert_range(TestId::from_usize(2)..=TestId::from_usize(5), 8); + + assert!(!a.is_subset(&b)); + assert!(!a.is_superset(&b)); + } + #[test] fn negate_full_width() { let mut set: FiniteBitSet = FiniteBitSet::new_empty(8); diff --git a/libs/@local/hashql/mir/src/pass/execution/cost/mod.rs b/libs/@local/hashql/mir/src/pass/execution/cost/mod.rs index 7c971af0fa7..6e548b414f7 100644 --- a/libs/@local/hashql/mir/src/pass/execution/cost/mod.rs +++ b/libs/@local/hashql/mir/src/pass/execution/cost/mod.rs @@ -1,12 +1,15 @@ //! Cost tracking for execution planning. //! -//! Two levels of cost representation: +//! Three levels of cost representation: //! //! - **Per-statement**: [`StatementCostVec`] records the [`Cost`] of each statement on a given //! target. Produced by the statement placement pass and consumed by [`BasicBlockCostAnalysis`]. //! -//! - **Per-block**: [`BasicBlockCostVec`] aggregates statement costs and adds a path transfer -//! premium for non-origin backends. This is what the placement solver operates on. +//! - **Per-terminator**: [`TerminatorCostVec`] records the [`Cost`] of each block's terminator on a +//! given target. Produced alongside statement costs during placement analysis. +//! +//! - **Per-block**: [`BasicBlockCostVec`] aggregates statement and terminator costs and adds a path +//! transfer premium for non-origin backends. This is what the placement solver operates on. use alloc::alloc::Global; use core::{ @@ -20,7 +23,11 @@ use std::f32; pub(crate) use self::analysis::{BasicBlockCostAnalysis, BasicBlockCostVec}; use super::block_partitioned_vec::BlockPartitionedVec; use crate::{ - body::{basic_block::BasicBlockId, basic_blocks::BasicBlocks, location::Location}, + body::{ + basic_block::{BasicBlockId, BasicBlockVec}, + basic_blocks::BasicBlocks, + location::Location, + }, macros::{forward_ref_binop, forward_ref_op_assign}, pass::analysis::size_estimation::InformationUnit, }; @@ -326,6 +333,50 @@ impl Sum for ApproxCost { } } +/// Per-block cost of executing the terminator on a given target. +/// +/// Each block has exactly one terminator. A `None` cost indicates the target cannot execute that +/// terminator (the terminator's operands are not supported on the target). One instance exists per +/// target inside `TargetArray`. +#[derive(Debug)] +pub(crate) struct TerminatorCostVec(BasicBlockVec, A>); + +impl TerminatorCostVec { + /// Creates a cost vector with one slot per block, all initialized to `None` (unsupported). + pub(crate) fn new_in(blocks: &BasicBlocks, alloc: A) -> Self { + Self(BasicBlockVec::with_capacity_in(blocks.len(), alloc)) + } +} + +impl TerminatorCostVec { + /// Returns `true` if no terminators have assigned costs. + #[cfg(test)] + pub(crate) fn all_unassigned(&self) -> bool { + self.0.iter().all(Option::is_none) + } + + /// Returns the cost for the terminator in `block`, or `None` if the target cannot execute it. + pub(crate) fn of(&self, block: BasicBlockId) -> Option { + self.0.lookup(block).copied() + } + + pub(crate) fn of_mut(&mut self, block: BasicBlockId) -> Option<&mut Cost> { + self.0.lookup_mut(block) + } + + pub(crate) fn insert(&mut self, block: BasicBlockId, cost: Cost) { + self.0.insert(block, cost); + } + + /// Returns the approximate cost for the terminator in `block`, or zero if unassigned. + pub(crate) fn approx(&self, block: BasicBlockId) -> ApproxCost { + self.0 + .lookup(block) + .copied() + .map_or(ApproxCost::ZERO, ApproxCost::from) + } +} + /// Dense cost map for all statements in a body. /// /// Stores the execution cost for every statement, indexed by [`Location`]. A `None` cost diff --git a/libs/@local/hashql/mir/src/pass/execution/mod.rs b/libs/@local/hashql/mir/src/pass/execution/mod.rs index ff0a03efa7a..0a4cb16412d 100644 --- a/libs/@local/hashql/mir/src/pass/execution/mod.rs +++ b/libs/@local/hashql/mir/src/pass/execution/mod.rs @@ -78,17 +78,21 @@ impl<'heap, S: BumpAllocator> ExecutionAnalysis<'_, 'heap, S> { }; let mut statement_costs: TargetArray<_> = TargetArray::from_fn(|_| None); + let mut terminator_costs: TargetArray<_> = TargetArray::from_fn(|_| None); for target in TargetId::all() { let mut statement = TargetPlacementStatement::new_in(target, &self.scratch); - let statement_cost = + let (statement_cost, terminator_cost) = statement.statement_placement_in(context, body, vertex, &self.scratch); statement_costs[target] = Some(statement_cost); + terminator_costs[target] = Some(terminator_cost); } let mut statement_costs = statement_costs.map(|cost| cost.unwrap_or_else(|| unreachable!())); + let mut terminator_costs = + terminator_costs.map(|cost| cost.unwrap_or_else(|| unreachable!())); let mut assignments = BasicBlockSplitting::new_in(&self.scratch).split_in( context, diff --git a/libs/@local/hashql/mir/src/pass/execution/placement/arc/mod.rs b/libs/@local/hashql/mir/src/pass/execution/placement/arc/mod.rs index 240552db65d..08879dfa65e 100644 --- a/libs/@local/hashql/mir/src/pass/execution/placement/arc/mod.rs +++ b/libs/@local/hashql/mir/src/pass/execution/placement/arc/mod.rs @@ -69,7 +69,7 @@ use crate::{ Body, basic_block::{BasicBlockId, BasicBlockSlice}, }, - pass::execution::{target::TargetBitSet, terminator_placement::TerminatorCostVec}, + pass::execution::{target::TargetBitSet, terminator_placement::TerminatorTransitionCostVec}, }; /// Deduplicated worklist of directed arcs `(x, y)`. @@ -111,13 +111,13 @@ impl PairWorkQueue { /// AC-3 arc consistency enforcer over per-block target domains. /// -/// Operates on mutable [`TargetBitSet`] domains and [`TerminatorCostVec`] transition matrices. -/// After [`run_in`](Self::run_in), every surviving target in a block's domain has at least one -/// compatible transition partner across each incident CFG edge, and the matrices are pruned to -/// match the narrowed domains. +/// Operates on mutable [`TargetBitSet`] domains and [`TerminatorTransitionCostVec`] transition +/// matrices. After [`run_in`](Self::run_in), every surviving target in a block's domain has at +/// least one compatible transition partner across each incident CFG edge, and the matrices are +/// pruned to match the narrowed domains. pub(crate) struct ArcConsistency<'ctx, A: Allocator> { pub blocks: &'ctx mut BasicBlockSlice, - pub terminators: &'ctx mut TerminatorCostVec, + pub terminators: &'ctx mut TerminatorTransitionCostVec, } impl ArcConsistency<'_, A> { diff --git a/libs/@local/hashql/mir/src/pass/execution/placement/arc/tests.rs b/libs/@local/hashql/mir/src/pass/execution/placement/arc/tests.rs index 1a9765b3ee0..e540acf2c80 100644 --- a/libs/@local/hashql/mir/src/pass/execution/placement/arc/tests.rs +++ b/libs/@local/hashql/mir/src/pass/execution/placement/arc/tests.rs @@ -15,7 +15,7 @@ use crate::{ intern::Interner, pass::execution::{ target::{TargetBitSet, TargetId}, - terminator_placement::{TerminatorCostVec, TransMatrix}, + terminator_placement::{TerminatorTransitionCostVec, TransMatrix}, }, }; @@ -42,7 +42,7 @@ fn bb(index: u32) -> BasicBlockId { fn run_ac3<'heap>( body: &Body<'heap>, domains: &mut [TargetBitSet], - terminators: &mut TerminatorCostVec<&'heap Heap>, + terminators: &mut TerminatorTransitionCostVec<&'heap Heap>, ) { let mut arc = ArcConsistency { blocks: BasicBlockSlice::from_raw_mut(domains), @@ -81,7 +81,7 @@ fn already_consistent_no_pruning() { }); let mut domains = [all_targets(), all_targets()]; - let mut terminators = TerminatorCostVec::new(&body.basic_blocks, &heap); + let mut terminators = TerminatorTransitionCostVec::new(&body.basic_blocks, &heap); terminators.of_mut(bb(0))[0] = full_matrix(); let before = domains; @@ -113,7 +113,7 @@ fn source_side_pruning() { let mut matrix = TransMatrix::new(); matrix.insert(TargetId::Interpreter, TargetId::Interpreter, cost!(0)); - let mut terminators = TerminatorCostVec::new(&body.basic_blocks, &heap); + let mut terminators = TerminatorTransitionCostVec::new(&body.basic_blocks, &heap); terminators.of_mut(bb(0))[0] = matrix; run_ac3(&body, &mut domains, &mut terminators); @@ -149,7 +149,7 @@ fn target_side_pruning() { matrix.insert(TargetId::Interpreter, TargetId::Interpreter, cost!(0)); matrix.insert(TargetId::Postgres, TargetId::Postgres, cost!(0)); - let mut terminators = TerminatorCostVec::new(&body.basic_blocks, &heap); + let mut terminators = TerminatorTransitionCostVec::new(&body.basic_blocks, &heap); terminators.of_mut(bb(0))[0] = matrix; run_ac3(&body, &mut domains, &mut terminators); @@ -190,7 +190,7 @@ fn mutual_pruning_both_sides() { let mut matrix = TransMatrix::new(); matrix.insert(TargetId::Interpreter, TargetId::Interpreter, cost!(0)); - let mut terminators = TerminatorCostVec::new(&body.basic_blocks, &heap); + let mut terminators = TerminatorTransitionCostVec::new(&body.basic_blocks, &heap); terminators.of_mut(bb(0))[0] = matrix; run_ac3(&body, &mut domains, &mut terminators); @@ -230,7 +230,7 @@ fn diamond_cfg_pruning() { let mut m_interp = TransMatrix::new(); m_interp.insert(TargetId::Interpreter, TargetId::Interpreter, cost!(0)); - let mut terminators = TerminatorCostVec::new(&body.basic_blocks, &heap); + let mut terminators = TerminatorTransitionCostVec::new(&body.basic_blocks, &heap); let matrices = terminators.of_mut(bb(0)); matrices[0] = m_interp; matrices[1] = m_interp; @@ -264,7 +264,7 @@ fn self_loop_pruning() { matrix.insert(TargetId::Interpreter, TargetId::Interpreter, cost!(0)); matrix.insert(TargetId::Postgres, TargetId::Postgres, cost!(0)); - let mut terminators = TerminatorCostVec::new(&body.basic_blocks, &heap); + let mut terminators = TerminatorTransitionCostVec::new(&body.basic_blocks, &heap); terminators.of_mut(bb(0))[0] = matrix; run_ac3(&body, &mut domains, &mut terminators); @@ -303,7 +303,7 @@ fn bidirectional_edges_require_joint_support() { let mut reverse = TransMatrix::new(); reverse.insert(TargetId::Postgres, TargetId::Postgres, cost!(0)); - let mut terminators = TerminatorCostVec::new(&body.basic_blocks, &heap); + let mut terminators = TerminatorTransitionCostVec::new(&body.basic_blocks, &heap); terminators.of_mut(bb(0))[0] = forward; terminators.of_mut(bb(1))[0] = reverse; @@ -338,7 +338,7 @@ fn matrix_pruned_after_ac3() { matrix.insert(TargetId::Postgres, TargetId::Interpreter, cost!(10)); matrix.insert(TargetId::Embedding, TargetId::Interpreter, cost!(20)); - let mut terminators = TerminatorCostVec::new(&body.basic_blocks, &heap); + let mut terminators = TerminatorTransitionCostVec::new(&body.basic_blocks, &heap); terminators.of_mut(bb(0))[0] = matrix; run_ac3(&body, &mut domains, &mut terminators); @@ -368,7 +368,7 @@ fn single_block_no_edges() { }); let mut domains = [all_targets()]; - let mut terminators = TerminatorCostVec::new(&body.basic_blocks, &heap); + let mut terminators = TerminatorTransitionCostVec::new(&body.basic_blocks, &heap); run_ac3(&body, &mut domains, &mut terminators); @@ -403,7 +403,7 @@ fn switchint_multiple_edges_to_same_block() { let mut m1 = TransMatrix::new(); m1.insert(TargetId::Interpreter, TargetId::Interpreter, cost!(0)); - let mut terminators = TerminatorCostVec::new(&body.basic_blocks, &heap); + let mut terminators = TerminatorTransitionCostVec::new(&body.basic_blocks, &heap); let matrices = terminators.of_mut(bb(0)); matrices[0] = m0; matrices[1] = m1; diff --git a/libs/@local/hashql/mir/src/pass/execution/placement/solve/condensation.rs b/libs/@local/hashql/mir/src/pass/execution/placement/solve/condensation.rs index f1e12b5c3c0..a0e32f762cb 100644 --- a/libs/@local/hashql/mir/src/pass/execution/placement/solve/condensation.rs +++ b/libs/@local/hashql/mir/src/pass/execution/placement/solve/condensation.rs @@ -32,7 +32,7 @@ use super::{ }; use crate::{ body::{Body, basic_block::BasicBlockId}, - pass::execution::terminator_placement::{TerminatorCostVec, TransMatrix}, + pass::execution::terminator_placement::{TerminatorTransitionCostVec, TransMatrix}, }; /// A placement region containing a single basic block. @@ -105,7 +105,7 @@ impl<'alloc, S: BumpAllocator> Condensation<'alloc, S> { /// Builds the condensation from a [`Body`]'s CFG and terminator transition costs. pub(crate) fn new( body: &Body<'_>, - terminators: &TerminatorCostVec, + terminators: &TerminatorTransitionCostVec, alloc: &'alloc S, ) -> Self { let scc = Tarjan::new_in(&body.basic_blocks, alloc).run(); @@ -153,7 +153,7 @@ impl<'alloc, S: BumpAllocator> Condensation<'alloc, S> { } /// Populates the condensation graph with regions and boundary edges. - fn fill(&mut self, body: &Body<'_>, terminators: &TerminatorCostVec) { + fn fill(&mut self, body: &Body<'_>, terminators: &TerminatorTransitionCostVec) { for scc in self.scc.iter_nodes() { let members = self.scc_members.of(scc); diff --git a/libs/@local/hashql/mir/src/pass/execution/placement/solve/csp/tests.rs b/libs/@local/hashql/mir/src/pass/execution/placement/solve/csp/tests.rs index 57b38f9ae90..e993a2a9474 100644 --- a/libs/@local/hashql/mir/src/pass/execution/placement/solve/csp/tests.rs +++ b/libs/@local/hashql/mir/src/pass/execution/placement/solve/csp/tests.rs @@ -21,7 +21,7 @@ use crate::{ }, }, target::{TargetArray, TargetId}, - terminator_placement::{TerminatorCostVec, TransMatrix}, + terminator_placement::{TerminatorTransitionCostVec, TransMatrix}, }, }; @@ -70,7 +70,7 @@ fn narrow_restricts_successor_domain() { let domains = [all_targets(), all_targets(), all_targets(), all_targets()]; let statements: TargetArray> = IdArray::from_fn(|_: TargetId| StatementCostVec::new_in(&body.basic_blocks, &heap)); - let mut terminators = TerminatorCostVec::new(&body.basic_blocks, &heap); + let mut terminators = TerminatorTransitionCostVec::new(&body.basic_blocks, &heap); terminators! { terminators; bb(0): [I->I = 0, I->P = 0]; bb(1): [complete(1)]; @@ -120,7 +120,7 @@ fn narrow_restricts_predecessor_domain() { let domains = [all_targets(), all_targets(), all_targets(), all_targets()]; let statements: TargetArray> = IdArray::from_fn(|_: TargetId| StatementCostVec::new_in(&body.basic_blocks, &heap)); - let mut terminators = TerminatorCostVec::new(&body.basic_blocks, &heap); + let mut terminators = TerminatorTransitionCostVec::new(&body.basic_blocks, &heap); terminators! { terminators; bb(0): [complete(1)]; bb(1): [complete(1)]; @@ -171,7 +171,7 @@ fn narrow_to_empty_domain() { let domains = [target_set(&[I]), target_set(&[P]), all_targets()]; let statements: TargetArray> = IdArray::from_fn(|_: TargetId| StatementCostVec::new_in(&body.basic_blocks, &heap)); - let mut terminators = TerminatorCostVec::new(&body.basic_blocks, &heap); + let mut terminators = TerminatorTransitionCostVec::new(&body.basic_blocks, &heap); terminators! { terminators; bb(0): [ complete(1); @@ -220,7 +220,7 @@ fn narrow_multiple_edges_intersect() { let domains = [all_targets(), all_targets(), all_targets(), all_targets()]; let statements: TargetArray> = IdArray::from_fn(|_: TargetId| StatementCostVec::new_in(&body.basic_blocks, &heap)); - let mut terminators = TerminatorCostVec::new(&body.basic_blocks, &heap); + let mut terminators = TerminatorTransitionCostVec::new(&body.basic_blocks, &heap); terminators! { terminators; bb(0): [ I->I = 0, I->P = 0; @@ -282,7 +282,7 @@ fn replay_narrowing_resets_then_repropagates() { let domains = [all_targets(), all_targets(), all_targets(), all_targets()]; let statements: TargetArray> = IdArray::from_fn(|_: TargetId| StatementCostVec::new_in(&body.basic_blocks, &heap)); - let mut terminators = TerminatorCostVec::new(&body.basic_blocks, &heap); + let mut terminators = TerminatorTransitionCostVec::new(&body.basic_blocks, &heap); terminators! { terminators; bb(0): [I->I = 0, I->P = 0, P->E = 0]; bb(1): [complete(1)]; @@ -360,7 +360,7 @@ fn lower_bound_min_block_cost_per_block() { bb(2): I = 5, P = 15 } - let mut terminators = TerminatorCostVec::new(&body.basic_blocks, &heap); + let mut terminators = TerminatorTransitionCostVec::new(&body.basic_blocks, &heap); terminators! { terminators; bb(0): [diagonal(0)]; bb(1): [diagonal(0)]; @@ -415,7 +415,7 @@ fn lower_bound_min_transition_cost_per_edge() { let statements: TargetArray> = IdArray::from_fn(|_: TargetId| StatementCostVec::new_in(&body.basic_blocks, &heap)); - let mut terminators = TerminatorCostVec::new(&body.basic_blocks, &heap); + let mut terminators = TerminatorTransitionCostVec::new(&body.basic_blocks, &heap); terminators! { terminators; bb(0): [diagonal(0)]; bb(1): [I->P = 10, P->I = 3]; @@ -467,7 +467,7 @@ fn lower_bound_skips_self_loop_edges() { let statements: TargetArray> = IdArray::from_fn(|_: TargetId| StatementCostVec::new_in(&body.basic_blocks, &heap)); - let mut terminators = TerminatorCostVec::new(&body.basic_blocks, &heap); + let mut terminators = TerminatorTransitionCostVec::new(&body.basic_blocks, &heap); terminators! { terminators; bb(0): [ diagonal(0); @@ -522,7 +522,7 @@ fn lower_bound_fixed_successor_uses_concrete_target() { let statements: TargetArray> = IdArray::from_fn(|_: TargetId| StatementCostVec::new_in(&body.basic_blocks, &heap)); - let mut terminators = TerminatorCostVec::new(&body.basic_blocks, &heap); + let mut terminators = TerminatorTransitionCostVec::new(&body.basic_blocks, &heap); terminators! { terminators; bb(0): [diagonal(0)]; bb(1): [I->P = 10, I->I = 0]; @@ -579,7 +579,7 @@ fn lower_bound_all_fixed_returns_zero() { bb(1): I = 5 } - let mut terminators = TerminatorCostVec::new(&body.basic_blocks, &heap); + let mut terminators = TerminatorTransitionCostVec::new(&body.basic_blocks, &heap); terminators! { terminators; bb(0): [ I->I = 3; @@ -633,7 +633,7 @@ fn mrv_selects_smallest_domain() { ]; let statements: TargetArray> = IdArray::from_fn(|_: TargetId| StatementCostVec::new_in(&body.basic_blocks, &heap)); - let mut terminators = TerminatorCostVec::new(&body.basic_blocks, &heap); + let mut terminators = TerminatorTransitionCostVec::new(&body.basic_blocks, &heap); terminators! { terminators; bb(0): [complete(1)]; bb(1): [complete(1)]; @@ -682,7 +682,7 @@ fn mrv_tiebreak_by_constraint_degree() { let domains = [ip, ip, ip, all_targets()]; let statements: TargetArray> = IdArray::from_fn(|_: TargetId| StatementCostVec::new_in(&body.basic_blocks, &heap)); - let mut terminators = TerminatorCostVec::new(&body.basic_blocks, &heap); + let mut terminators = TerminatorTransitionCostVec::new(&body.basic_blocks, &heap); terminators! { terminators; bb(0): [ complete(1); @@ -736,7 +736,7 @@ fn mrv_skips_fixed_blocks() { ]; let statements: TargetArray> = IdArray::from_fn(|_: TargetId| StatementCostVec::new_in(&body.basic_blocks, &heap)); - let mut terminators = TerminatorCostVec::new(&body.basic_blocks, &heap); + let mut terminators = TerminatorTransitionCostVec::new(&body.basic_blocks, &heap); terminators! { terminators; bb(0): [complete(1)]; bb(1): [complete(1)]; @@ -794,7 +794,7 @@ fn greedy_solves_two_block_loop() { bb(1): I = 8, P = 3 } - let mut terminators = TerminatorCostVec::new(&body.basic_blocks, &heap); + let mut terminators = TerminatorTransitionCostVec::new(&body.basic_blocks, &heap); terminators! { terminators; bb(0): [diagonal(0), I->P = 5, P->I = 5]; bb(1): [ @@ -847,7 +847,7 @@ fn greedy_rollback_finds_alternative() { let statements: TargetArray> = IdArray::from_fn(|_: TargetId| StatementCostVec::new_in(&body.basic_blocks, &heap)); - let mut terminators = TerminatorCostVec::new(&body.basic_blocks, &heap); + let mut terminators = TerminatorTransitionCostVec::new(&body.basic_blocks, &heap); terminators! { terminators; bb(0): [complete(1)]; bb(1): [I->P = 0]; @@ -905,7 +905,7 @@ fn greedy_fails_when_infeasible() { let statements: TargetArray> = IdArray::from_fn(|_: TargetId| StatementCostVec::new_in(&body.basic_blocks, &heap)); - let mut terminators = TerminatorCostVec::new(&body.basic_blocks, &heap); + let mut terminators = TerminatorTransitionCostVec::new(&body.basic_blocks, &heap); terminators! { terminators; bb(0): [ I->I = 0; @@ -960,7 +960,7 @@ fn bnb_finds_optimal() { bb(2): I = 1, P = 50 } - let mut terminators = TerminatorCostVec::new(&body.basic_blocks, &heap); + let mut terminators = TerminatorTransitionCostVec::new(&body.basic_blocks, &heap); terminators! { terminators; bb(0): [ diagonal(0), I->P = 20, P->I = 20; @@ -1017,7 +1017,7 @@ fn bnb_retains_ranked_solutions() { bb(1): I = 5, P = 10, E = 15 } - let mut terminators = TerminatorCostVec::new(&body.basic_blocks, &heap); + let mut terminators = TerminatorTransitionCostVec::new(&body.basic_blocks, &heap); terminators! { terminators; bb(0): [ diagonal(0); @@ -1091,7 +1091,7 @@ fn bnb_pruning_preserves_optimal() { bb(3): I = 1, P = 1 } - let mut terminators = TerminatorCostVec::new(&body.basic_blocks, &heap); + let mut terminators = TerminatorTransitionCostVec::new(&body.basic_blocks, &heap); terminators! { terminators; bb(0): [diagonal(0), I->P = 100, P->I = 100]; bb(1): [diagonal(0), I->P = 100, P->I = 100]; @@ -1149,7 +1149,7 @@ fn retry_returns_ranked_solutions_in_order() { bb(1): I = 1, P = 2 } - let mut terminators = TerminatorCostVec::new(&body.basic_blocks, &heap); + let mut terminators = TerminatorTransitionCostVec::new(&body.basic_blocks, &heap); terminators! { terminators; bb(0): [ diagonal(0), I->P = 5, P->I = 5; @@ -1219,7 +1219,7 @@ fn retry_exhausts_then_perturbs() { bb(1): I = 1, P = 2 } - let mut terminators = TerminatorCostVec::new(&body.basic_blocks, &heap); + let mut terminators = TerminatorTransitionCostVec::new(&body.basic_blocks, &heap); terminators! { terminators; bb(0): [ diagonal(0); @@ -1283,7 +1283,7 @@ fn greedy_rollback_on_empty_heap() { bb(0): I = 0, P = 5 } - let mut terminators = TerminatorCostVec::new(&body.basic_blocks, &heap); + let mut terminators = TerminatorTransitionCostVec::new(&body.basic_blocks, &heap); // arm0 (bb0→bb2): complete (exit edge, always feasible) // arm1 (bb0→bb1): swap-only transitions (I→P, P→I) // bb1→bb0: from I go to P or I @@ -1356,7 +1356,7 @@ fn retry_perturbation_after_ranked_exhaustion() { } // All transitions allowed → all combinations feasible - let mut terminators = TerminatorCostVec::new(&body.basic_blocks, &heap); + let mut terminators = TerminatorTransitionCostVec::new(&body.basic_blocks, &heap); terminators! { terminators; bb(0): [ complete(0); diff --git a/libs/@local/hashql/mir/src/pass/execution/placement/solve/estimate/tests.rs b/libs/@local/hashql/mir/src/pass/execution/placement/solve/estimate/tests.rs index f773a30a004..4713a4945ba 100644 --- a/libs/@local/hashql/mir/src/pass/execution/placement/solve/estimate/tests.rs +++ b/libs/@local/hashql/mir/src/pass/execution/placement/solve/estimate/tests.rs @@ -16,7 +16,7 @@ use crate::{ pass::execution::{ cost::StatementCostVec, target::{TargetArray, TargetId}, - terminator_placement::{TerminatorCostVec, TransMatrix}, + terminator_placement::{TerminatorTransitionCostVec, TransMatrix}, }, }; @@ -155,7 +155,7 @@ fn self_loop_edges_excluded_from_cost() { stmt_costs! { statements; bb(0): I = 5, P = 5 } - let mut terminators = TerminatorCostVec::new(&body.basic_blocks, &heap); + let mut terminators = TerminatorTransitionCostVec::new(&body.basic_blocks, &heap); terminators! { terminators; bb(0): [ I->I = 0, P->I = 0; @@ -221,7 +221,7 @@ fn boundary_multiplier_applied_to_cross_region_edges() { let statements: TargetArray> = IdArray::from_fn(|_: TargetId| StatementCostVec::new_in(&body.basic_blocks, &heap)); - let mut terminators = TerminatorCostVec::new(&body.basic_blocks, &heap); + let mut terminators = TerminatorTransitionCostVec::new(&body.basic_blocks, &heap); terminators! { terminators; bb(0): [diagonal(0), I->P = 20, P->I = 0]; bb(1): [diagonal(0), I->P = 0, P->I = 20] @@ -294,7 +294,7 @@ fn infeasible_transition_returns_none() { let statements: TargetArray> = IdArray::from_fn(|_: TargetId| StatementCostVec::new_in(&body.basic_blocks, &heap)); - let mut terminators = TerminatorCostVec::new(&body.basic_blocks, &heap); + let mut terminators = TerminatorTransitionCostVec::new(&body.basic_blocks, &heap); terminators! { terminators; bb(0): [I->I = 0] } @@ -359,7 +359,7 @@ fn unassigned_neighbor_uses_heuristic_minimum() { bb(1): I = 3, P = 7 } - let mut terminators = TerminatorCostVec::new(&body.basic_blocks, &heap); + let mut terminators = TerminatorTransitionCostVec::new(&body.basic_blocks, &heap); terminators! { terminators; bb(0): [diagonal(0), I->P = 10, P->I = 5] } diff --git a/libs/@local/hashql/mir/src/pass/execution/placement/solve/mod.rs b/libs/@local/hashql/mir/src/pass/execution/placement/solve/mod.rs index e0b685fd39e..690b2033352 100644 --- a/libs/@local/hashql/mir/src/pass/execution/placement/solve/mod.rs +++ b/libs/@local/hashql/mir/src/pass/execution/placement/solve/mod.rs @@ -29,7 +29,7 @@ use crate::{ context::MirContext, pass::execution::{ ApproxCost, cost::BasicBlockCostVec, target::TargetId, - terminator_placement::TerminatorCostVec, + terminator_placement::TerminatorTransitionCostVec, }, }; @@ -82,7 +82,7 @@ fn back_edge_span(body: &Body<'_>, members: &[BasicBlockId]) -> SpanId { #[derive(Debug, Copy, Clone)] pub(crate) struct PlacementSolverContext<'ctx, A: Allocator> { pub blocks: &'ctx BasicBlockCostVec, - pub terminators: &'ctx TerminatorCostVec, + pub terminators: &'ctx TerminatorTransitionCostVec, } impl<'ctx, A: Allocator> PlacementSolverContext<'ctx, A> { diff --git a/libs/@local/hashql/mir/src/pass/execution/placement/solve/tests.rs b/libs/@local/hashql/mir/src/pass/execution/placement/solve/tests.rs index a4520cd2f82..dccddddf66e 100644 --- a/libs/@local/hashql/mir/src/pass/execution/placement/solve/tests.rs +++ b/libs/@local/hashql/mir/src/pass/execution/placement/solve/tests.rs @@ -32,7 +32,7 @@ use crate::{ cost::{BasicBlockCostAnalysis, BasicBlockCostVec, StatementCostVec}, placement::error::PlacementDiagnosticCategory, target::{TargetArray, TargetBitSet, TargetId}, - terminator_placement::{TerminatorCostVec, TransMatrix}, + terminator_placement::{TerminatorTransitionCostVec, TransMatrix}, traversal::TransferCostConfig, }, }, @@ -160,7 +160,7 @@ pub(crate) fn run_solver<'heap>( interner: &Interner<'heap>, domains: &[TargetBitSet], statements: &TargetArray>, - terminators: &TerminatorCostVec<&'heap Heap>, + terminators: &TerminatorTransitionCostVec<&'heap Heap>, ) -> BasicBlockVec { let mut context = MirContext::new(env, interner); let block_costs = make_block_costs(body, domains, statements, env.heap); @@ -246,7 +246,7 @@ fn forward_pass_assigns_all_blocks() { let statements: TargetArray> = IdArray::from_fn(|_: TargetId| StatementCostVec::new_in(&body.basic_blocks, &heap)); - let mut terminators = TerminatorCostVec::new(&body.basic_blocks, &heap); + let mut terminators = TerminatorTransitionCostVec::new(&body.basic_blocks, &heap); terminators! { terminators; bb(0): [ complete(1); @@ -322,7 +322,7 @@ fn backward_pass_improves_suboptimal_forward() { // bb0: arm0=bb2(else), arm1=bb1(then). All transitions at cost 0. // bb1→bb3: P→P=0 (cheap), P→I=50 (expensive), I→I=0. // bb2→bb3: same-target only (diagonal). - let mut terminators = TerminatorCostVec::new(&body.basic_blocks, &heap); + let mut terminators = TerminatorTransitionCostVec::new(&body.basic_blocks, &heap); terminators! { terminators; bb(0): [ complete(0); @@ -399,7 +399,7 @@ fn rewind_triggers_on_join_with_conflicting_predecessors() { // bb0: arm0=bb2(else), arm1=bb1(then). All transitions allowed. // bb1→bb3: same-target only. bb2→bb3: swap only. - let mut terminators = TerminatorCostVec::new(&body.basic_blocks, &heap); + let mut terminators = TerminatorTransitionCostVec::new(&body.basic_blocks, &heap); terminators! { terminators; bb(0): [ complete(0); @@ -484,7 +484,7 @@ fn rewind_skips_exhausted_region() { bb(1): I = 0, P = 10 } - let mut terminators = TerminatorCostVec::new(&body.basic_blocks, &heap); + let mut terminators = TerminatorTransitionCostVec::new(&body.basic_blocks, &heap); terminators! { terminators; bb(0): [complete(0)]; bb(1): [ @@ -530,7 +530,7 @@ fn single_block_trivial_region() { bb(0): I = 10, P = 5 } - let terminators = TerminatorCostVec::new(&body.basic_blocks, &heap); + let terminators = TerminatorTransitionCostVec::new(&body.basic_blocks, &heap); let result = run_solver(&body, &env, &interner, &domains, &statements, &terminators); @@ -583,7 +583,7 @@ fn cyclic_region_in_forward_backward() { bb(2): I = 3, P = 1 } - let mut terminators = TerminatorCostVec::new(&body.basic_blocks, &heap); + let mut terminators = TerminatorTransitionCostVec::new(&body.basic_blocks, &heap); terminators! { terminators; bb(0): [I->I = 0, I->P = 5]; bb(1): [diagonal(0), I->P = 5, P->I = 5]; @@ -668,7 +668,7 @@ fn rewind_retries_cyclic_region() { bb(2): I = 0, P = 1 } - let mut terminators = TerminatorCostVec::new(&body.basic_blocks, &heap); + let mut terminators = TerminatorTransitionCostVec::new(&body.basic_blocks, &heap); // bb2→bb3 (arm0, else): diagonal — forces bb3 to match SCC target. // SCC solver sees this as feasible for both I and P (each has a matching // target in bb3's domain {I,P}). @@ -766,7 +766,7 @@ fn rewind_skips_exhausted_cyclic_region() { bb(0): I = 0, P = 5 } - let mut terminators = TerminatorCostVec::new(&body.basic_blocks, &heap); + let mut terminators = TerminatorTransitionCostVec::new(&body.basic_blocks, &heap); // bb0→bb3 (arm0, else): swap only — I→P, P→I. // bb0→bb1 (arm1, then): complete — permissive SCC entry. // SCC internal bb1→bb2: diagonal. bb2→bb1 (arm1, then): diagonal. @@ -833,7 +833,7 @@ fn rewind_exhausts_all_regions() { let statements: TargetArray> = IdArray::from_fn(|_: TargetId| StatementCostVec::new_in(&body.basic_blocks, &heap)); - let mut terminators = TerminatorCostVec::new(&body.basic_blocks, &heap); + let mut terminators = TerminatorTransitionCostVec::new(&body.basic_blocks, &heap); terminators! { terminators; bb(0): [diagonal(0); diagonal(0)]; bb(1): [diagonal(0)]; @@ -904,7 +904,7 @@ fn forward_pass_rewinds_on_cyclic_failure() { bb(0): I = 0, P = 5 } - let mut terminators = TerminatorCostVec::new(&body.basic_blocks, &heap); + let mut terminators = TerminatorTransitionCostVec::new(&body.basic_blocks, &heap); // bb0→bb1 diagonal forces bb1==bb0. SCC internals only allow P. terminators! { terminators; bb(0): [diagonal(0)]; @@ -979,7 +979,7 @@ fn backward_pass_keeps_assignment_when_csp_fails() { bb(2): I = 0, P = 10 } - let mut terminators = TerminatorCostVec::new(&body.basic_blocks, &heap); + let mut terminators = TerminatorTransitionCostVec::new(&body.basic_blocks, &heap); // SCC internal diagonal. Exit bb2→bb3(arm0) only to I. terminators! { terminators; bb(0): [complete(0)]; @@ -1086,7 +1086,7 @@ fn backward_pass_adopts_better_cyclic_solution() { bb(2): I = 10, P = 0 } - let mut terminators = TerminatorCostVec::new(&body.basic_blocks, &heap); + let mut terminators = TerminatorTransitionCostVec::new(&body.basic_blocks, &heap); terminators! { terminators; bb(0): [complete(0)]; bb(1): [diagonal(0)]; @@ -1147,7 +1147,7 @@ fn trivial_failure_emits_diagnostic() { let statements: TargetArray> = IdArray::from_fn(|_: TargetId| StatementCostVec::new_in(&body.basic_blocks, &heap)); - let mut terminators = TerminatorCostVec::new(&body.basic_blocks, &heap); + let mut terminators = TerminatorTransitionCostVec::new(&body.basic_blocks, &heap); terminators! { terminators; bb(0): [diagonal(0); diagonal(0)]; bb(1): [diagonal(0)]; @@ -1214,7 +1214,7 @@ fn cyclic_failure_emits_diagnostic() { // bb1→bb0 (arm0, goto): only I→P — forces bb1=I, bb0=P. // Contradiction: bb1 must be both P and I. AC-3 wipes the domain. // bb0→bb2 (arm0, else): permissive, irrelevant to the SCC. - let mut terminators = TerminatorCostVec::new(&body.basic_blocks, &heap); + let mut terminators = TerminatorTransitionCostVec::new(&body.basic_blocks, &heap); terminators! { terminators; bb(0): [ complete(0); @@ -1279,7 +1279,7 @@ fn path_premiums_influence_placement() { // Equal base costs so the path premium is the deciding factor. stmt_costs! { statements; bb(0): I = 1, P = 1, E = 1 } - let terminators = TerminatorCostVec::new(&body.basic_blocks, &heap); + let terminators = TerminatorTransitionCostVec::new(&body.basic_blocks, &heap); let config = TransferCostConfig::new(InformationRange::value(InformationUnit::new(100))); let block_costs = make_block_costs_with_config(&body, &domains, &statements, &config, &heap); diff --git a/libs/@local/hashql/mir/src/pass/execution/splitting/mod.rs b/libs/@local/hashql/mir/src/pass/execution/splitting/mod.rs index 7dacfa90feb..514a291681d 100644 --- a/libs/@local/hashql/mir/src/pass/execution/splitting/mod.rs +++ b/libs/@local/hashql/mir/src/pass/execution/splitting/mod.rs @@ -18,7 +18,7 @@ use hashql_core::{ use super::{ Cost, - cost::StatementCostVec, + cost::{StatementCostVec, TerminatorCostVec}, target::{TargetArray, TargetBitSet, TargetId}, }; use crate::{ @@ -39,7 +39,7 @@ mod tests; /// /// A target is supported when its [`Cost`] entry is present for that statement. #[expect(clippy::cast_possible_truncation)] -fn supported(costs: &TargetArray<&[Option]>, index: usize) -> TargetBitSet { +fn supported_statement(costs: &TargetArray<&[Option]>, index: usize) -> TargetBitSet { let mut output = FiniteBitSet::new_empty(TargetId::VARIANT_COUNT as u32); for (cost_index, cost) in costs.iter_enumerated() { @@ -49,6 +49,19 @@ fn supported(costs: &TargetArray<&[Option]>, index: usize) -> TargetBitSet output } +fn supported_terminator( + costs: &TargetArray>, + block: BasicBlockId, +) -> TargetBitSet { + let mut output = FiniteBitSet::new_empty(TargetId::VARIANT_COUNT as u32); + + for (cost_index, cost) in costs.iter_enumerated() { + output.set(cost_index, cost.of(block).is_some()); + } + + output +} + /// Counts contiguous target regions per [`BasicBlock`]. /// /// Returns a non-zero count for each block. Blocks with fewer than two statements @@ -57,12 +70,13 @@ fn supported(costs: &TargetArray<&[Option]>, index: usize) -> TargetBitSet fn count_regions( body: &Body<'_>, statement_costs: &TargetArray>, + terminator_costs: &TargetArray>, alloc: B, -) -> BasicBlockVec, B> { +) -> BasicBlockVec<(NonZero, bool), B> { // Start with one region per block and only grow when target support changes. let mut regions = BasicBlockVec::from_elem_in( // SAFETY: 1 is not 0 - unsafe { NonZero::new_unchecked(1) }, + (unsafe { NonZero::new_unchecked(1) }, false), body.basic_blocks.len(), alloc, ); @@ -70,8 +84,8 @@ fn count_regions( for (id, block) in body.basic_blocks.iter_enumerated() { let costs = statement_costs.each_ref().map(|costs| costs.of(id)); - if block.statements.len() < 2 { - // Zero or one statement cannot introduce a target boundary. + if block.statements.is_empty() { + // Zero statements cannot introduce a target boundary. continue; } @@ -79,7 +93,7 @@ fn count_regions( let mut current: TargetBitSet = FiniteBitSet::new_empty(TargetId::VARIANT_COUNT as u32); for stmt_index in 0..block.statements.len() { - let next = supported(&costs, stmt_index); + let next = supported_statement(&costs, stmt_index); // Always count the first statement as a region start. This keeps the count non-zero // even if cost data is missing or malformed. @@ -89,9 +103,23 @@ fn count_regions( } } + let mut has_separate_terminator_region = false; + + // Check if the terminator narrows the target set of the last statement region. + // If the terminator supports a strict subset of backends, it needs its own region + // so that the preceding statements can still be assigned to the wider set. + let terminator_supported = supported_terminator(&terminator_costs, id); + if !terminator_supported.is_superset(¤t) { + total += 1; + has_separate_terminator_region = true; + } + // SAFETY: The loop always counts the first statement for blocks with 2+ statements, so // total cannot be zero here. - regions[id] = unsafe { NonZero::new_unchecked(total) }; + regions[id] = ( + unsafe { NonZero::new_unchecked(total) }, + has_separate_terminator_region, + ); } regions @@ -128,8 +156,9 @@ impl<'heap> VisitorMut<'heap> for RemapBasicBlockId<'_> { fn offset_basic_blocks<'heap, A: Allocator, S: Allocator + Clone>( context: &MirContext<'_, 'heap>, body: &mut Body<'heap>, - regions: &BasicBlockSlice>, + regions: &BasicBlockSlice<(NonZero, bool)>, statement_costs: &mut TargetArray>, + terminator_costs: &mut TargetArray>, scratch: S, alloc: A, ) -> BasicBlockVec { @@ -143,7 +172,7 @@ fn offset_basic_blocks<'heap, A: Allocator, S: Allocator + Clone>( let mut indices = BasicBlockVec::from_elem_in(BasicBlockId::MIN, body.basic_blocks.len(), scratch); - for (id, regions) in regions.iter_enumerated() { + for (id, (regions, _)) in regions.iter_enumerated() { indices[id] = length; length.increment_by(regions.get()); } @@ -176,7 +205,9 @@ fn offset_basic_blocks<'heap, A: Allocator, S: Allocator + Clone>( let mut index = BasicBlockId::START; for &[start_id, end_id] in indices.windows() { let region = &mut body.basic_blocks.as_mut()[start_id..end_id]; - debug_assert_eq!(region.len(), regions[index].get()); + let (region_len, has_separate_terminator_region) = regions[index]; + + debug_assert_eq!(region.len(), region_len.get()); let costs = statement_costs.each_ref().map(|cost| cost.of(index)); @@ -188,7 +219,7 @@ fn offset_basic_blocks<'heap, A: Allocator, S: Allocator + Clone>( targets[start_id] .insert_range(TargetId::MIN..=TargetId::MAX, TargetId::VARIANT_COUNT); } else { - targets[start_id] = supported(&costs, 0); + targets[start_id] = supported_statement(&costs, 0); } index.increment_by(1); @@ -226,14 +257,32 @@ fn offset_basic_blocks<'heap, A: Allocator, S: Allocator + Clone>( }; let mut rest = rest; + let mut runs = 0; + + // If the terminator narrows the target set, peel off the last block for it. + // That block is already empty (placeholder) and already holds the original terminator + // (from the `mem::swap` above). We just need to record its target affinity and exclude + // it from the statement-peeling loop. + if has_separate_terminator_region { + let [statements @ .., _] = rest else { + unreachable!() + }; + + rest = statements; + + // Write the target before incrementing `runs`, matching the convention in the + // statement-peeling loop below. `terminator_costs` is indexed by original (pre-split) + // block IDs, so we use `index` rather than a post-split ID. + targets[end_id.minus(runs + 1)] = supported_terminator(terminator_costs, index); + runs += 1; + } + // Peel off runs and move them into recipient blocks counted from the end. - let mut current = supported(&costs, start.statements.len() - 1); + let mut current = supported_statement(&costs, start.statements.len() - 1); let mut ptr = start.statements.len() - 1; - let mut runs = 0; - while let [remaining @ .., recipient] = rest { - while supported(&costs, ptr) == current { + while supported_statement(&costs, ptr) == current { ptr -= 1; } @@ -247,13 +296,13 @@ fn offset_basic_blocks<'heap, A: Allocator, S: Allocator + Clone>( "Each run contains at least one statement" ); - current = supported(&costs, ptr); + current = supported_statement(&costs, ptr); recipient.statements = statements; rest = remaining; runs += 1; } - debug_assert_eq!(runs, regions[index].get() - 1); + debug_assert_eq!(runs, region_len.get() - 1); // The first block holds the remaining run. targets[start_id] = current; @@ -261,6 +310,7 @@ fn offset_basic_blocks<'heap, A: Allocator, S: Allocator + Clone>( index.increment_by(1); } + // TODO: must remap for cost in statement_costs.iter_mut() { cost.remap(&body.basic_blocks); } diff --git a/libs/@local/hashql/mir/src/pass/execution/splitting/tests.rs b/libs/@local/hashql/mir/src/pass/execution/splitting/tests.rs index ec24c5fcfc9..67121e8fb85 100644 --- a/libs/@local/hashql/mir/src/pass/execution/splitting/tests.rs +++ b/libs/@local/hashql/mir/src/pass/execution/splitting/tests.rs @@ -17,7 +17,7 @@ use hashql_core::{ use hashql_diagnostics::DiagnosticIssues; use insta::{Settings, assert_snapshot}; -use super::{BasicBlockSplitting, count_regions, offset_basic_blocks, supported}; +use super::{BasicBlockSplitting, count_regions, offset_basic_blocks, supported_statement}; use crate::{ body::{ Body, @@ -135,7 +135,7 @@ fn supported_all_targets() { let costs: TargetArray<&[Option]> = TargetArray::from_raw([&[Some(cost!(1))], &[Some(cost!(2))], &[Some(cost!(3))]]); - let result = supported(&costs, 0); + let result = supported_statement(&costs, 0); let expected = Targets { interpreter: true, postgres: true, @@ -150,7 +150,7 @@ fn supported_all_targets() { fn supported_no_targets() { let costs: TargetArray<&[Option]> = TargetArray::from_raw([&[None], &[None], &[None]]); - let result = supported(&costs, 0); + let result = supported_statement(&costs, 0); assert!(result.is_empty()); } @@ -159,7 +159,7 @@ fn supported_no_targets() { fn supported_single_target() { let costs: TargetArray<&[_]> = TargetArray::from_raw([&[Some(cost!(1))], &[None], &[None]]); - let result = supported(&costs, 0); + let result = supported_statement(&costs, 0); assert!(result.contains(TargetId::Interpreter)); assert!(!result.contains(TargetId::Postgres)); @@ -171,7 +171,7 @@ fn supported_mixed_targets() { let costs: TargetArray<&[_]> = TargetArray::from_raw([&[Some(cost!(1))], &[Some(cost!(2))], &[None]]); - let result = supported(&costs, 0); + let result = supported_statement(&costs, 0); let expected = Targets { interpreter: true, postgres: true, diff --git a/libs/@local/hashql/mir/src/pass/execution/statement_placement/common.rs b/libs/@local/hashql/mir/src/pass/execution/statement_placement/common.rs index aaf098cf66b..2ea7cdda04b 100644 --- a/libs/@local/hashql/mir/src/pass/execution/statement_placement/common.rs +++ b/libs/@local/hashql/mir/src/pass/execution/statement_placement/common.rs @@ -19,7 +19,7 @@ use crate::{ place::Projection, rvalue::RValue, statement::{Assign, Statement, StatementKind}, - terminator::TerminatorKind, + terminator::{Terminator, TerminatorKind}, }, context::MirContext, pass::{ @@ -29,7 +29,7 @@ use crate::{ }, execution::{ Cost, - cost::StatementCostVec, + cost::{StatementCostVec, TerminatorCostVec}, traversal::{Access, EntityPath}, }, }, @@ -73,6 +73,14 @@ pub(crate) trait Supported<'heap> { operand: &Operand<'heap>, ) -> bool; + fn is_supported_terminator( + &self, + context: &MirContext<'_, 'heap>, + body: &Body<'heap>, + domain: &DenseBitSet, + terminator: &Terminator<'heap>, + ) -> bool; + /// Checks whether a type can be unambiguously deserialized after crossing a backend boundary. /// /// Returns `true` by default. Targets that serialize values to a lossy format (e.g., jsonb) @@ -97,6 +105,16 @@ where T::is_supported_rvalue(self, context, body, domain, rvalue) } + fn is_supported_terminator( + &self, + context: &MirContext<'_, 'heap>, + body: &Body<'heap>, + domain: &DenseBitSet, + terminator: &Terminator<'heap>, + ) -> bool { + T::is_supported_terminator(self, context, body, domain, terminator) + } + fn is_supported_operand( &self, context: &MirContext<'_, 'heap>, @@ -276,6 +294,7 @@ pub(crate) struct CostVisitor<'ctx, 'env, 'heap, S, A: Allocator> { pub cost: Cost, pub statement_costs: StatementCostVec, + pub terminator_costs: TerminatorCostVec, pub supported: S, } @@ -313,6 +332,25 @@ where Ok(()) } + + fn visit_terminator( + &mut self, + location: Location, + terminator: &Terminator<'heap>, + ) -> Self::Result { + let is_supported = self.supported.is_supported_terminator( + self.context, + self.body, + self.dispatchable, + terminator, + ); + + if is_supported { + self.terminator_costs.insert(location.block, self.cost); + } + + Ok(()) + } } /// Determines which backend can access an entity field projection. diff --git a/libs/@local/hashql/mir/src/pass/execution/statement_placement/embedding/mod.rs b/libs/@local/hashql/mir/src/pass/execution/statement_placement/embedding/mod.rs index 90a4da7c7bf..cc0e6ed0543 100644 --- a/libs/@local/hashql/mir/src/pass/execution/statement_placement/embedding/mod.rs +++ b/libs/@local/hashql/mir/src/pass/execution/statement_placement/embedding/mod.rs @@ -7,11 +7,20 @@ use super::{ common::{CostVisitor, OnceValue, Supported, SupportedAnalysis}, }; use crate::{ - body::{Body, Source, local::Local, operand::Operand, place::Place, rvalue::RValue}, + body::{ + Body, Source, + local::Local, + operand::Operand, + place::Place, + rvalue::RValue, + terminator::{Goto, Return, SwitchInt, Terminator, TerminatorKind}, + }, context::MirContext, pass::execution::{ - Cost, VertexType, cost::StatementCostVec, - statement_placement::common::entity_projection_access, traversal::Access, + Cost, VertexType, + cost::{StatementCostVec, TerminatorCostVec}, + statement_placement::common::entity_projection_access, + traversal::Access, }, visit::Visitor as _, }; @@ -65,6 +74,38 @@ impl<'heap> Supported<'heap> for EmbeddingSupported { } } + fn is_supported_terminator( + &self, + context: &MirContext<'_, 'heap>, + body: &Body<'heap>, + domain: &DenseBitSet, + terminator: &Terminator<'heap>, + ) -> bool { + match &terminator.kind { + TerminatorKind::Goto(Goto { target }) => target + .args + .iter() + .all(|arg| self.is_supported_operand(context, body, domain, arg)), + TerminatorKind::SwitchInt(SwitchInt { + discriminant, + targets, + }) => { + self.is_supported_operand(context, body, domain, discriminant) + && targets.targets().iter().all(|target| { + target + .args + .iter() + .all(|arg| self.is_supported_operand(context, body, domain, arg)) + }) + } + TerminatorKind::Return(Return { value }) => { + self.is_supported_operand(context, body, domain, value) + } + TerminatorKind::GraphRead(_) => false, + TerminatorKind::Unreachable => true, + } + } + fn is_supported_operand( &self, _: &MirContext<'_, 'heap>, @@ -106,13 +147,14 @@ impl<'heap, A: Allocator + Clone, S: Allocator> StatementPlacement<'heap, A> body: &Body<'heap>, vertex: VertexType, alloc: A, - ) -> StatementCostVec { - let statement_costs = StatementCostVec::new_in(&body.basic_blocks, alloc); + ) -> (StatementCostVec, TerminatorCostVec) { + let statement_costs = StatementCostVec::new_in(&body.basic_blocks, alloc.clone()); + let terminator_costs = TerminatorCostVec::new_in(&body.basic_blocks, alloc); match body.source { Source::GraphReadFilter(_) => {} Source::Ctor(_) | Source::Closure(..) | Source::Thunk(..) | Source::Intrinsic(_) => { - return statement_costs; + return (statement_costs, terminator_costs); } } @@ -148,11 +190,12 @@ impl<'heap, A: Allocator + Clone, S: Allocator> StatementPlacement<'heap, A> cost: self.statement_cost, statement_costs, + terminator_costs, supported: &EmbeddingSupported { vertex }, }; visitor.visit_body(body); - visitor.statement_costs + (visitor.statement_costs, visitor.terminator_costs) } } diff --git a/libs/@local/hashql/mir/src/pass/execution/statement_placement/interpret/mod.rs b/libs/@local/hashql/mir/src/pass/execution/statement_placement/interpret/mod.rs index 419cccded41..eebbb5dbefb 100644 --- a/libs/@local/hashql/mir/src/pass/execution/statement_placement/interpret/mod.rs +++ b/libs/@local/hashql/mir/src/pass/execution/statement_placement/interpret/mod.rs @@ -6,11 +6,12 @@ use crate::{ Body, Source, location::Location, statement::{Statement, StatementKind}, + terminator::Terminator, }, context::MirContext, pass::execution::{ VertexType, - cost::{Cost, StatementCostVec}, + cost::{Cost, StatementCostVec, TerminatorCostVec}, }, visit::Visitor, }; @@ -22,6 +23,7 @@ struct CostVisitor { cost: Cost, statement_costs: StatementCostVec, + terminator_costs: TerminatorCostVec, } impl<'heap, A: Allocator> Visitor<'heap> for CostVisitor { @@ -43,6 +45,17 @@ impl<'heap, A: Allocator> Visitor<'heap> for CostVisitor { Ok(()) } + + fn visit_terminator(&mut self, location: Location, _: &Terminator<'heap>) -> Self::Result { + // Because interpreter is our base case, every terminator is supported, via the default base + // cost. + // Because this is done *before* basic block splitting, we assign the same cost to as well, + // splitting, then assigns a cumulative cost of `0` for generated GOTOs to not distort the + // cost distribution. + self.terminator_costs.insert(location.block, self.cost); + + Ok(()) + } } /// Statement placement for the [`Interpreter`](super::super::TargetId::Interpreter) execution @@ -68,22 +81,24 @@ impl<'heap, A: Allocator + Clone> StatementPlacement<'heap, A> for InterpreterSt body: &Body<'heap>, _: VertexType, alloc: A, - ) -> StatementCostVec { - let statement_costs = StatementCostVec::new_in(&body.basic_blocks, alloc); + ) -> (StatementCostVec, TerminatorCostVec) { + let statement_costs = StatementCostVec::new_in(&body.basic_blocks, alloc.clone()); + let terminator_costs = TerminatorCostVec::new_in(&body.basic_blocks, alloc); match body.source { Source::GraphReadFilter(_) => {} Source::Ctor(_) | Source::Closure(..) | Source::Thunk(..) | Source::Intrinsic(_) => { - return statement_costs; + return (statement_costs, terminator_costs); } } let mut visitor = CostVisitor { cost: self.statement_cost, statement_costs, + terminator_costs, }; visitor.visit_body(body); - visitor.statement_costs + (visitor.statement_costs, visitor.terminator_costs) } } diff --git a/libs/@local/hashql/mir/src/pass/execution/statement_placement/mod.rs b/libs/@local/hashql/mir/src/pass/execution/statement_placement/mod.rs index 3b9ca7852be..49a64593990 100644 --- a/libs/@local/hashql/mir/src/pass/execution/statement_placement/mod.rs +++ b/libs/@local/hashql/mir/src/pass/execution/statement_placement/mod.rs @@ -23,7 +23,7 @@ pub(crate) use self::{ embedding::EmbeddingStatementPlacement, interpret::InterpreterStatementPlacement, postgres::PostgresStatementPlacement, }; -use super::{VertexType, target::TargetId}; +use super::{VertexType, cost::TerminatorCostVec, target::TargetId}; use crate::{body::Body, context::MirContext, pass::execution::cost::StatementCostVec}; /// Computes statement placement costs for a specific execution target. @@ -50,7 +50,7 @@ pub(crate) trait StatementPlacement<'heap, A: Allocator> { body: &Body<'heap>, vertex: VertexType, alloc: A, - ) -> StatementCostVec; + ) -> (StatementCostVec, TerminatorCostVec); } pub(crate) enum TargetPlacementStatement<'heap, S: Allocator> { @@ -80,7 +80,7 @@ impl<'heap, A: Allocator + Clone, S: Allocator> StatementPlacement<'heap, A> body: &Body<'heap>, vertex: VertexType, alloc: A, - ) -> StatementCostVec { + ) -> (StatementCostVec, TerminatorCostVec) { match self { TargetPlacementStatement::Interpreter(placement) => { placement.statement_placement_in(context, body, vertex, alloc) diff --git a/libs/@local/hashql/mir/src/pass/execution/statement_placement/postgres/mod.rs b/libs/@local/hashql/mir/src/pass/execution/statement_placement/postgres/mod.rs index 10be791ff9c..637d6cb3aa9 100644 --- a/libs/@local/hashql/mir/src/pass/execution/statement_placement/postgres/mod.rs +++ b/libs/@local/hashql/mir/src/pass/execution/statement_placement/postgres/mod.rs @@ -25,11 +25,12 @@ use crate::{ operand::Operand, place::{FieldIndex, Place, ProjectionKind}, rvalue::{Aggregate, AggregateKind, BinOp, Binary, RValue, Unary}, + terminator::{Goto, Return, SwitchInt, Terminator, TerminatorKind}, }, context::MirContext, pass::execution::{ VertexType, - cost::{Cost, StatementCostVec}, + cost::{Cost, StatementCostVec, TerminatorCostVec}, statement_placement::common::entity_projection_access, traversal::Access, }, @@ -446,6 +447,38 @@ impl<'heap, A: Allocator> Supported<'heap> for PostgresSupported<'_, 'heap, A> { } } + fn is_supported_terminator( + &self, + context: &MirContext<'_, 'heap>, + body: &Body<'heap>, + domain: &DenseBitSet, + terminator: &Terminator<'heap>, + ) -> bool { + match &terminator.kind { + TerminatorKind::Goto(Goto { target }) => target + .args + .iter() + .all(|arg| self.is_supported_operand(context, body, domain, arg)), + TerminatorKind::SwitchInt(SwitchInt { + discriminant, + targets, + }) => { + self.is_supported_operand(context, body, domain, discriminant) + && targets.targets().iter().all(|target| { + target + .args + .iter() + .all(|arg| self.is_supported_operand(context, body, domain, arg)) + }) + } + TerminatorKind::Return(Return { value }) => { + self.is_supported_operand(context, body, domain, value) + } + TerminatorKind::GraphRead(_) => false, + TerminatorKind::Unreachable => true, + } + } + fn is_supported_operand( &self, context: &MirContext<'_, 'heap>, @@ -698,13 +731,14 @@ impl<'heap, A: Allocator + Clone, S: Allocator> StatementPlacement<'heap, A> body: &Body<'heap>, vertex: VertexType, alloc: A, - ) -> StatementCostVec { - let statement_costs = StatementCostVec::new_in(&body.basic_blocks, alloc); + ) -> (StatementCostVec, TerminatorCostVec) { + let statement_costs = StatementCostVec::new_in(&body.basic_blocks, alloc.clone()); + let terminator_costs = TerminatorCostVec::new_in(&body.basic_blocks, alloc); match body.source { Source::GraphReadFilter(_) => {} Source::Ctor(_) | Source::Closure(..) | Source::Thunk(..) | Source::Intrinsic(_) => { - return statement_costs; + return (statement_costs, terminator_costs); } } @@ -740,11 +774,12 @@ impl<'heap, A: Allocator + Clone, S: Allocator> StatementPlacement<'heap, A> cost: self.statement_cost, statement_costs, + terminator_costs, supported: &supported, }; visitor.visit_body(body); - visitor.statement_costs + (visitor.statement_costs, visitor.terminator_costs) } } diff --git a/libs/@local/hashql/mir/src/pass/execution/terminator_placement/mod.rs b/libs/@local/hashql/mir/src/pass/execution/terminator_placement/mod.rs index b0d41247077..a260ca21170 100644 --- a/libs/@local/hashql/mir/src/pass/execution/terminator_placement/mod.rs +++ b/libs/@local/hashql/mir/src/pass/execution/terminator_placement/mod.rs @@ -10,7 +10,7 @@ //! # Main Types //! //! - [`TransMatrix`]: Per-edge transition costs indexed by (source, destination) target pairs -//! - [`TerminatorCostVec`]: Collection of transition matrices for all edges in a body +//! - [`TerminatorTransitionCostVec`]: Collection of transition matrices for all edges in a body //! - [`TerminatorPlacement`]: Analysis driver that computes placement for a body //! //! # Transition Rules @@ -251,9 +251,11 @@ forward_ref_op_assign!(impl AddAssign::add_assign for TransMatrix); /// [`Return`]: TerminatorKind::Return /// [`Unreachable`]: TerminatorKind::Unreachable #[derive(Debug)] -pub(crate) struct TerminatorCostVec(BlockPartitionedVec); +pub(crate) struct TerminatorTransitionCostVec( + BlockPartitionedVec, +); -impl TerminatorCostVec { +impl TerminatorTransitionCostVec { /// Creates a cost vector sized for `blocks`, with all transitions initially disallowed. pub(crate) fn new(blocks: &BasicBlocks, alloc: A) -> Self { Self(BlockPartitionedVec::new_in( @@ -273,7 +275,7 @@ impl TerminatorCostVec { } } -impl TerminatorCostVec { +impl TerminatorTransitionCostVec { pub(crate) const fn len(&self) -> usize { self.0.len() } @@ -444,8 +446,8 @@ impl PopulateEdgeMatrix { /// Computes terminator placement for a [`Body`]. /// /// Analyzes control flow edges to determine valid backend transitions and their costs. The -/// resulting [`TerminatorCostVec`] is used by the execution planner alongside statement placement -/// to select optimal execution targets. +/// resulting [`TerminatorTransitionCostVec`] is used by the execution planner alongside statement +/// placement to select optimal execution targets. /// /// # Usage /// @@ -505,7 +507,7 @@ impl TerminatorPlacement { vertex: VertexType, footprint: &BodyFootprint<&'heap Heap>, targets: &BasicBlockSlice, - ) -> TerminatorCostVec { + ) -> TerminatorTransitionCostVec { self.terminator_placement_in(body, vertex, footprint, targets, Global) } @@ -516,8 +518,8 @@ impl TerminatorPlacement { /// execute on (from statement placement), and `footprint` provides size estimates for /// computing transfer costs. /// - /// The returned [`TerminatorCostVec`] can be indexed by block ID to get the transition - /// matrices for that block's successor edges. + /// The returned [`TerminatorTransitionCostVec`] can be indexed by block ID to get the + /// transition matrices for that block's successor edges. pub(crate) fn terminator_placement_in<'heap, A: Allocator + Clone>( &self, body: &Body<'heap>, @@ -525,12 +527,12 @@ impl TerminatorPlacement { footprint: &BodyFootprint<&'heap Heap>, targets: &BasicBlockSlice, alloc: A, - ) -> TerminatorCostVec { + ) -> TerminatorTransitionCostVec { let live_in = self.compute_liveness(body, vertex); let scc = self.compute_scc(body); let switch_cost = backend_switch_cost(); - let mut output = TerminatorCostVec::new(&body.basic_blocks, alloc); + let mut output = TerminatorTransitionCostVec::new(&body.basic_blocks, alloc); let mut required_locals = DenseBitSet::new_empty(body.local_decls.len()); for (block_id, block) in body.basic_blocks.iter_enumerated() { diff --git a/libs/@local/hashql/mir/src/pass/execution/terminator_placement/tests.rs b/libs/@local/hashql/mir/src/pass/execution/terminator_placement/tests.rs index d76a0c5058c..7fcdbae7058 100644 --- a/libs/@local/hashql/mir/src/pass/execution/terminator_placement/tests.rs +++ b/libs/@local/hashql/mir/src/pass/execution/terminator_placement/tests.rs @@ -18,7 +18,7 @@ use hashql_core::{ use hashql_diagnostics::DiagnosticIssues; use insta::{Settings, assert_snapshot}; -use super::{Cost, TerminatorCostVec, TerminatorPlacement, TransMatrix}; +use super::{Cost, TerminatorPlacement, TerminatorTransitionCostVec, TransMatrix}; use crate::{ body::{ Body, @@ -91,7 +91,7 @@ fn assert_snapshot<'heap>( name: &'static str, context: &MirContext<'_, 'heap>, body: &Body<'heap>, - edges: &TerminatorCostVec, + edges: &TerminatorTransitionCostVec, ) { let formatter = Formatter::new(context.heap); let type_formatter = TypeFormatter::new(&formatter, context.env, TypeFormatterOptions::terse()); @@ -123,7 +123,7 @@ fn assert_snapshot<'heap>( } fn format_edge_summary( - edges: &TerminatorCostVec, + edges: &TerminatorTransitionCostVec, ) -> impl Display + '_ { fmt::from_fn(move |fmt| { for block in 0..edges.block_count() { @@ -176,7 +176,7 @@ fn terminator_cost_vec_successor_counts() { } }); - let costs = TerminatorCostVec::new(&body.basic_blocks, &heap); + let costs = TerminatorTransitionCostVec::new(&body.basic_blocks, &heap); assert_eq!(costs.of(BasicBlockId::new(0)).len(), 1); assert_eq!(costs.of(BasicBlockId::new(1)).len(), 3); From c28649e5a5dff9a181dca595208899c82e6eb3a9 Mon Sep 17 00:00:00 2001 From: Bilal Mahmoud Date: Sun, 22 Mar 2026 18:29:37 +0100 Subject: [PATCH 2/6] feat: checkpoint --- .../hashql/mir/src/pass/execution/cost/mod.rs | 40 +++++++++++++++++- .../hashql/mir/src/pass/execution/mod.rs | 7 ++-- .../mir/src/pass/execution/splitting/mod.rs | 41 +++++++++++-------- .../execution/statement_placement/tests.rs | 3 +- 4 files changed, 70 insertions(+), 21 deletions(-) diff --git a/libs/@local/hashql/mir/src/pass/execution/cost/mod.rs b/libs/@local/hashql/mir/src/pass/execution/cost/mod.rs index 6e548b414f7..c90a432d1ef 100644 --- a/libs/@local/hashql/mir/src/pass/execution/cost/mod.rs +++ b/libs/@local/hashql/mir/src/pass/execution/cost/mod.rs @@ -20,11 +20,13 @@ use core::{ }; use std::f32; +use hashql_core::id::Id as _; + pub(crate) use self::analysis::{BasicBlockCostAnalysis, BasicBlockCostVec}; use super::block_partitioned_vec::BlockPartitionedVec; use crate::{ body::{ - basic_block::{BasicBlockId, BasicBlockVec}, + basic_block::{BasicBlockId, BasicBlockSlice, BasicBlockVec}, basic_blocks::BasicBlocks, location::Location, }, @@ -368,6 +370,42 @@ impl TerminatorCostVec { self.0.insert(block, cost); } + /// Remaps terminator costs after block splitting. + /// + /// For each original block, the original terminator cost is placed on the last block + /// of its region (which holds the original terminator after splitting). All preceding + /// blocks in the region received synthesized `Goto` terminators and get zero cost. + /// + /// Operates in-place by extending the vec, then shuffling entries from back to front + /// to avoid overwriting unprocessed entries. + pub(crate) fn remap(&mut self, regions: &BasicBlockSlice<(core::num::NonZero, bool)>) { + let mut new_length = BasicBlockId::START; + for (_, (region_len, _)) in regions.iter_enumerated() { + new_length.increment_by(region_len.get()); + } + + // Extend to the new size. New slots are initialized to `None`. + self.0.fill_until(new_length.minus(1), || None); + + // Walk regions in reverse so we never overwrite an unprocessed original entry. + let mut write = new_length; + for (original, (region_len, _)) in regions.iter_enumerated().rev() { + let original_cost = self.0[original]; + + // The last block in the region holds the original terminator. + write.decrement_by(1); + self.0[write] = original_cost; + + // Preceding blocks have synthesized Goto terminators: zero cost. + for _ in 1..region_len.get() { + write.decrement_by(1); + self.0[write] = Some(cost!(0)); + } + } + + debug_assert_eq!(write, BasicBlockId::START); + } + /// Returns the approximate cost for the terminator in `block`, or zero if unassigned. pub(crate) fn approx(&self, block: BasicBlockId) -> ApproxCost { self.0 diff --git a/libs/@local/hashql/mir/src/pass/execution/mod.rs b/libs/@local/hashql/mir/src/pass/execution/mod.rs index 0a4cb16412d..e4e29225413 100644 --- a/libs/@local/hashql/mir/src/pass/execution/mod.rs +++ b/libs/@local/hashql/mir/src/pass/execution/mod.rs @@ -98,6 +98,7 @@ impl<'heap, S: BumpAllocator> ExecutionAnalysis<'_, 'heap, S> { context, body, &mut statement_costs, + &mut terminator_costs, &self.scratch, ); @@ -105,7 +106,7 @@ impl<'heap, S: BumpAllocator> ExecutionAnalysis<'_, 'heap, S> { TransferCostConfig::new(InformationRange::full()), &self.scratch, ); - let mut terminator_costs = terminators.terminator_placement_in( + let mut transition_costs = terminators.terminator_placement_in( body, vertex, &self.footprints[body.id], @@ -115,7 +116,7 @@ impl<'heap, S: BumpAllocator> ExecutionAnalysis<'_, 'heap, S> { ArcConsistency { blocks: &mut assignments, - terminators: &mut terminator_costs, + terminators: &mut transition_costs, } .run_in(body, &self.scratch); @@ -132,7 +133,7 @@ impl<'heap, S: BumpAllocator> ExecutionAnalysis<'_, 'heap, S> { let mut solver = PlacementSolverContext { blocks: &block_costs, - terminators: &terminator_costs, + terminators: &transition_costs, } .build_in(body, &self.scratch); diff --git a/libs/@local/hashql/mir/src/pass/execution/splitting/mod.rs b/libs/@local/hashql/mir/src/pass/execution/splitting/mod.rs index 514a291681d..e4b96f7f59d 100644 --- a/libs/@local/hashql/mir/src/pass/execution/splitting/mod.rs +++ b/libs/@local/hashql/mir/src/pass/execution/splitting/mod.rs @@ -49,8 +49,8 @@ fn supported_statement(costs: &TargetArray<&[Option]>, index: usize) -> Ta output } -fn supported_terminator( - costs: &TargetArray>, +fn supported_terminator( + costs: &TargetArray>, block: BasicBlockId, ) -> TargetBitSet { let mut output = FiniteBitSet::new_empty(TargetId::VARIANT_COUNT as u32); @@ -67,10 +67,10 @@ fn supported_terminator( /// Returns a non-zero count for each block. Blocks with fewer than two statements /// always yield one region. #[expect(unsafe_code, clippy::cast_possible_truncation)] -fn count_regions( +fn count_regions( body: &Body<'_>, statement_costs: &TargetArray>, - terminator_costs: &TargetArray>, + terminator_costs: &TargetArray>, alloc: B, ) -> BasicBlockVec<(NonZero, bool), B> { // Start with one region per block and only grow when target support changes. @@ -152,7 +152,7 @@ impl<'heap> VisitorMut<'heap> for RemapBasicBlockId<'_> { /// /// Remaps all [`BasicBlockId`] references, connects split blocks with [`Goto`] chains, /// and updates [`StatementCostVec`] to reflect the new layout. -#[expect(clippy::cast_possible_truncation)] +#[expect(clippy::cast_possible_truncation, clippy::too_many_lines)] fn offset_basic_blocks<'heap, A: Allocator, S: Allocator + Clone>( context: &MirContext<'_, 'heap>, body: &mut Body<'heap>, @@ -214,10 +214,9 @@ fn offset_basic_blocks<'heap, A: Allocator, S: Allocator + Clone>( if region.len() < 2 { debug_assert_eq!(region.len(), 1); - // Unlike other regions, these may be empty. Mark empty blocks as supported everywhere. if costs[TargetId::Interpreter].is_empty() { - targets[start_id] - .insert_range(TargetId::MIN..=TargetId::MAX, TargetId::VARIANT_COUNT); + // No statements: the block's target affinity comes from its terminator. + targets[start_id] = supported_terminator(terminator_costs, index); } else { targets[start_id] = supported_statement(&costs, 0); } @@ -310,11 +309,14 @@ fn offset_basic_blocks<'heap, A: Allocator, S: Allocator + Clone>( index.increment_by(1); } - // TODO: must remap for cost in statement_costs.iter_mut() { cost.remap(&body.basic_blocks); } + for cost in terminator_costs.iter_mut() { + cost.remap(regions); + } + targets } @@ -349,36 +351,43 @@ impl BasicBlockSplitting { context: &MirContext<'_, 'heap>, body: &mut Body<'heap>, statement_costs: &mut TargetArray>, + terminator_costs: &mut TargetArray>, ) -> BasicBlockVec where S: Clone, { - self.split_in(context, body, statement_costs, Global) + self.split_in(context, body, statement_costs, terminator_costs, Global) } - /// Splits [`Body`] blocks and returns per-block [`TargetBitSet`] affinities along with - /// the per-block region counts used during splitting. + /// Splits [`Body`] blocks and returns per-block [`TargetBitSet`] affinities. /// - /// The first element is indexed by the new [`BasicBlockId`]s. The second element maps - /// each original block to the number of blocks it was split into, which callers can use - /// to redistribute parallel data structures. + /// Partitions blocks so each resulting block's statements share the same target support, + /// with an additional split when the terminator narrows the target set. Updates both + /// `statement_costs` and `terminator_costs` to reflect the new block layout. pub(crate) fn split_in<'heap, A: Allocator>( &self, context: &MirContext<'_, 'heap>, body: &mut Body<'heap>, statement_costs: &mut TargetArray>, + terminator_costs: &mut TargetArray>, alloc: A, ) -> BasicBlockVec where S: Clone, { - let regions = count_regions(body, statement_costs, self.scratch.clone()); + let regions = count_regions( + body, + statement_costs, + terminator_costs, + self.scratch.clone(), + ); offset_basic_blocks( context, body, ®ions, statement_costs, + terminator_costs, self.scratch.clone(), alloc, ) diff --git a/libs/@local/hashql/mir/src/pass/execution/statement_placement/tests.rs b/libs/@local/hashql/mir/src/pass/execution/statement_placement/tests.rs index cf254b59d4b..b9332be3481 100644 --- a/libs/@local/hashql/mir/src/pass/execution/statement_placement/tests.rs +++ b/libs/@local/hashql/mir/src/pass/execution/statement_placement/tests.rs @@ -104,7 +104,8 @@ pub(crate) fn run_placement<'heap>( let vertex = VertexType::from_local(context.env, &body.local_decls[Local::VERTEX]) .unwrap_or_else(|| unimplemented!("lookup for declared type")); - let statement_costs = placement.statement_placement_in(context, &body, vertex, context.heap); + let (statement_costs, _terminator_costs) = + placement.statement_placement_in(context, &body, vertex, context.heap); (body, statement_costs) } From 3fb4ef355d0e8684011089ce4e1179eaeeedc2b7 Mon Sep 17 00:00:00 2001 From: Bilal Mahmoud Date: Sun, 22 Mar 2026 18:43:56 +0100 Subject: [PATCH 3/6] feat: checkpoint --- .../hashql/mir/src/pass/execution/cost/mod.rs | 2 + .../mir/src/pass/execution/splitting/mod.rs | 15 +- .../mir/src/pass/execution/splitting/tests.rs | 191 ++++++++++++++---- .../execution/statement_placement/tests.rs | 63 ++++-- libs/@local/hashql/mir/src/pretty/text.rs | 53 ++++- 5 files changed, 256 insertions(+), 68 deletions(-) diff --git a/libs/@local/hashql/mir/src/pass/execution/cost/mod.rs b/libs/@local/hashql/mir/src/pass/execution/cost/mod.rs index c90a432d1ef..db91da4db70 100644 --- a/libs/@local/hashql/mir/src/pass/execution/cost/mod.rs +++ b/libs/@local/hashql/mir/src/pass/execution/cost/mod.rs @@ -362,6 +362,7 @@ impl TerminatorCostVec { self.0.lookup(block).copied() } + #[expect(dead_code, reason = "will be used by downstream cost analysis")] pub(crate) fn of_mut(&mut self, block: BasicBlockId) -> Option<&mut Cost> { self.0.lookup_mut(block) } @@ -407,6 +408,7 @@ impl TerminatorCostVec { } /// Returns the approximate cost for the terminator in `block`, or zero if unassigned. + #[expect(dead_code, reason = "will be used by downstream cost analysis")] pub(crate) fn approx(&self, block: BasicBlockId) -> ApproxCost { self.0 .lookup(block) diff --git a/libs/@local/hashql/mir/src/pass/execution/splitting/mod.rs b/libs/@local/hashql/mir/src/pass/execution/splitting/mod.rs index e4b96f7f59d..e71128f5ad6 100644 --- a/libs/@local/hashql/mir/src/pass/execution/splitting/mod.rs +++ b/libs/@local/hashql/mir/src/pass/execution/splitting/mod.rs @@ -38,9 +38,8 @@ mod tests; /// Returns a [`TargetBitSet`] of execution targets that can cover the statement at `index`. /// /// A target is supported when its [`Cost`] entry is present for that statement. -#[expect(clippy::cast_possible_truncation)] fn supported_statement(costs: &TargetArray<&[Option]>, index: usize) -> TargetBitSet { - let mut output = FiniteBitSet::new_empty(TargetId::VARIANT_COUNT as u32); + let mut output = FiniteBitSet::new_empty(TargetId::VARIANT_COUNT_U32); for (cost_index, cost) in costs.iter_enumerated() { output.set(cost_index, cost[index].is_some()); @@ -53,7 +52,7 @@ fn supported_terminator( costs: &TargetArray>, block: BasicBlockId, ) -> TargetBitSet { - let mut output = FiniteBitSet::new_empty(TargetId::VARIANT_COUNT as u32); + let mut output = FiniteBitSet::new_empty(TargetId::VARIANT_COUNT_U32); for (cost_index, cost) in costs.iter_enumerated() { output.set(cost_index, cost.of(block).is_some()); @@ -66,7 +65,7 @@ fn supported_terminator( /// /// Returns a non-zero count for each block. Blocks with fewer than two statements /// always yield one region. -#[expect(unsafe_code, clippy::cast_possible_truncation)] +#[expect(unsafe_code)] fn count_regions( body: &Body<'_>, statement_costs: &TargetArray>, @@ -90,7 +89,7 @@ fn count_regions( } let mut total = 0; - let mut current: TargetBitSet = FiniteBitSet::new_empty(TargetId::VARIANT_COUNT as u32); + let mut current: TargetBitSet = FiniteBitSet::new_empty(TargetId::VARIANT_COUNT_U32); for stmt_index in 0..block.statements.len() { let next = supported_statement(&costs, stmt_index); @@ -108,7 +107,7 @@ fn count_regions( // Check if the terminator narrows the target set of the last statement region. // If the terminator supports a strict subset of backends, it needs its own region // so that the preceding statements can still be assigned to the wider set. - let terminator_supported = supported_terminator(&terminator_costs, id); + let terminator_supported = supported_terminator(terminator_costs, id); if !terminator_supported.is_superset(¤t) { total += 1; has_separate_terminator_region = true; @@ -152,7 +151,7 @@ impl<'heap> VisitorMut<'heap> for RemapBasicBlockId<'_> { /// /// Remaps all [`BasicBlockId`] references, connects split blocks with [`Goto`] chains, /// and updates [`StatementCostVec`] to reflect the new layout. -#[expect(clippy::cast_possible_truncation, clippy::too_many_lines)] +#[expect(clippy::too_many_lines)] fn offset_basic_blocks<'heap, A: Allocator, S: Allocator + Clone>( context: &MirContext<'_, 'heap>, body: &mut Body<'heap>, @@ -178,7 +177,7 @@ fn offset_basic_blocks<'heap, A: Allocator, S: Allocator + Clone>( } let mut targets = BasicBlockVec::from_elem_in( - FiniteBitSet::new_empty(TargetId::VARIANT_COUNT as u32), + FiniteBitSet::new_empty(TargetId::VARIANT_COUNT_U32), length.as_usize(), alloc, ); diff --git a/libs/@local/hashql/mir/src/pass/execution/splitting/tests.rs b/libs/@local/hashql/mir/src/pass/execution/splitting/tests.rs index 67121e8fb85..3876f854426 100644 --- a/libs/@local/hashql/mir/src/pass/execution/splitting/tests.rs +++ b/libs/@local/hashql/mir/src/pass/execution/splitting/tests.rs @@ -30,7 +30,7 @@ use crate::{ context::MirContext, intern::Interner, pass::execution::{ - cost::{Cost, StatementCostVec}, + cost::{Cost, StatementCostVec, TerminatorCostVec}, target::{TargetArray, TargetBitSet, TargetId}, }, pretty::{TextFormatAnnotations, TextFormatOptions}, @@ -92,6 +92,20 @@ fn make_target_costs<'heap, const N: usize>( costs } +/// Creates terminator costs where every target supports every block's terminator. +fn make_all_supported_terminator_costs<'heap>( + body: &Body<'heap>, + heap: &'heap Heap, +) -> TargetArray> { + TargetArray::from_fn(|_| { + let mut costs = TerminatorCostVec::new_in(&body.basic_blocks, heap); + for (id, _) in body.basic_blocks.iter_enumerated() { + costs.insert(id, cost!(1)); + } + costs + }) +} + fn assert_assignment_locals(body: &Body<'_>, block_id: BasicBlockId, expected: &[&str]) { let block = &body.basic_blocks[block_id]; assert_eq!(block.statements.len(), expected.len()); @@ -201,9 +215,10 @@ fn count_regions_empty_block() { }); let costs = TargetArray::from_fn(|_| StatementCostVec::new_in(&body.basic_blocks, &heap)); - let regions = count_regions(&body, &costs, Global); + let terminator_costs = make_all_supported_terminator_costs(&body, &heap); + let regions = count_regions(&body, &costs, &terminator_costs, Global); - assert_eq!(regions[BasicBlockId::new(0)].get(), 1); + assert_eq!(regions[BasicBlockId::new(0)].0.get(), 1); } #[test] @@ -223,9 +238,10 @@ fn count_regions_single_statement() { let patterns = TargetArray::from_raw([[[true]], [[true]], [[false]]]); let costs = make_target_costs(&body, patterns, &heap); - let regions = count_regions(&body, &costs, Global); + let terminator_costs = make_all_supported_terminator_costs(&body, &heap); + let regions = count_regions(&body, &costs, &terminator_costs, Global); - assert_eq!(regions[BasicBlockId::new(0)].get(), 1); + assert_eq!(regions[BasicBlockId::new(0)].0.get(), 1); } #[test] @@ -251,9 +267,10 @@ fn count_regions_uniform_support() { [[false, false, false]], ]); let costs = make_target_costs(&body, patterns, &heap); - let regions = count_regions(&body, &costs, Global); + let terminator_costs = make_all_supported_terminator_costs(&body, &heap); + let regions = count_regions(&body, &costs, &terminator_costs, Global); - assert_eq!(regions[BasicBlockId::new(0)].get(), 1); + assert_eq!(regions[BasicBlockId::new(0)].0.get(), 1); } #[test] @@ -274,9 +291,10 @@ fn count_regions_two_regions() { let patterns = TargetArray::from_raw([[[true, true]], [[true, false]], [[false, false]]]); let costs = make_target_costs(&body, patterns, &heap); - let regions = count_regions(&body, &costs, Global); + let terminator_costs = make_all_supported_terminator_costs(&body, &heap); + let regions = count_regions(&body, &costs, &terminator_costs, Global); - assert_eq!(regions[BasicBlockId::new(0)].get(), 2); + assert_eq!(regions[BasicBlockId::new(0)].0.get(), 2); } #[test] @@ -302,9 +320,10 @@ fn count_regions_three_regions() { [[false, false, false]], ]); let costs = make_target_costs(&body, patterns, &heap); - let regions = count_regions(&body, &costs, Global); + let terminator_costs = make_all_supported_terminator_costs(&body, &heap); + let regions = count_regions(&body, &costs, &terminator_costs, Global); - assert_eq!(regions[BasicBlockId::new(0)].get(), 3); + assert_eq!(regions[BasicBlockId::new(0)].0.get(), 3); } #[test] @@ -331,9 +350,10 @@ fn count_regions_alternating() { [[false, false, false, false]], ]); let costs = make_target_costs(&body, patterns, &heap); - let regions = count_regions(&body, &costs, Global); + let terminator_costs = make_all_supported_terminator_costs(&body, &heap); + let regions = count_regions(&body, &costs, &terminator_costs, Global); - assert_eq!(regions[BasicBlockId::new(0)].get(), 4); + assert_eq!(regions[BasicBlockId::new(0)].0.get(), 4); } // ============================================================================= @@ -364,9 +384,18 @@ fn offset_single_block_no_split() { let patterns = TargetArray::from_raw([[[true]], [[true]], [[false]]]); let mut costs = make_target_costs(&body, patterns, &heap); - let regions = count_regions(&body, &costs, Global); + let mut terminator_costs = make_all_supported_terminator_costs(&body, &heap); + let regions = count_regions(&body, &costs, &terminator_costs, Global); - let targets = offset_basic_blocks(&context, &mut body, ®ions, &mut costs, Global, Global); + let targets = offset_basic_blocks( + &context, + &mut body, + ®ions, + &mut costs, + &mut terminator_costs, + Global, + Global, + ); assert_eq!(body.basic_blocks.len(), 1); assert_eq!(targets.len(), 1); @@ -408,9 +437,18 @@ fn offset_single_block_splits() { let patterns = TargetArray::from_raw([[[true, true]], [[true, false]], [[false, false]]]); let mut costs = make_target_costs(&body, patterns, &heap); - let regions = count_regions(&body, &costs, Global); + let mut terminator_costs = make_all_supported_terminator_costs(&body, &heap); + let regions = count_regions(&body, &costs, &terminator_costs, Global); - let targets = offset_basic_blocks(&context, &mut body, ®ions, &mut costs, Global, Global); + let targets = offset_basic_blocks( + &context, + &mut body, + ®ions, + &mut costs, + &mut terminator_costs, + Global, + Global, + ); assert_eq!(body.basic_blocks.len(), 2); assert_eq!(targets.len(), 2); @@ -464,9 +502,18 @@ fn offset_multiple_blocks_no_splits() { let patterns = TargetArray::from_raw([[[true], [true]], [[true], [true]], [[false], [false]]]); let mut costs = make_target_costs(&body, patterns, &heap); - let regions = count_regions(&body, &costs, Global); + let mut terminator_costs = make_all_supported_terminator_costs(&body, &heap); + let regions = count_regions(&body, &costs, &terminator_costs, Global); - let targets = offset_basic_blocks(&context, &mut body, ®ions, &mut costs, Global, Global); + let targets = offset_basic_blocks( + &context, + &mut body, + ®ions, + &mut costs, + &mut terminator_costs, + Global, + Global, + ); assert_eq!(body.basic_blocks.len(), 2); assert_eq!(targets.len(), 2); @@ -519,9 +566,18 @@ fn offset_multiple_blocks_mixed() { [&[false, false], &[false]], ]); let mut costs = make_target_costs(&body, patterns, &heap); - let regions = count_regions(&body, &costs, Global); + let mut terminator_costs = make_all_supported_terminator_costs(&body, &heap); + let regions = count_regions(&body, &costs, &terminator_costs, Global); - let targets = offset_basic_blocks(&context, &mut body, ®ions, &mut costs, Global, Global); + let targets = offset_basic_blocks( + &context, + &mut body, + ®ions, + &mut costs, + &mut terminator_costs, + Global, + Global, + ); assert_eq!(body.basic_blocks.len(), 3); assert_eq!(targets.len(), 3); @@ -580,9 +636,18 @@ fn offset_terminator_moves_to_last() { [[false, false]], ]); let mut costs = make_target_costs(&body, patterns, &heap); - let regions = count_regions(&body, &costs, Global); + let mut terminator_costs = make_all_supported_terminator_costs(&body, &heap); + let regions = count_regions(&body, &costs, &terminator_costs, Global); - let _targets = offset_basic_blocks(&context, &mut body, ®ions, &mut costs, Global, Global); + let _targets = offset_basic_blocks( + &context, + &mut body, + ®ions, + &mut costs, + &mut terminator_costs, + Global, + Global, + ); assert_return_terminator(&body, BasicBlockId::new(1)); } @@ -617,9 +682,18 @@ fn offset_goto_chain_created() { [[false, false, false]], ]); let mut costs = make_target_costs(&body, patterns, &heap); - let regions = count_regions(&body, &costs, Global); + let mut terminator_costs = make_all_supported_terminator_costs(&body, &heap); + let regions = count_regions(&body, &costs, &terminator_costs, Global); - let _targets = offset_basic_blocks(&context, &mut body, ®ions, &mut costs, Global, Global); + let _targets = offset_basic_blocks( + &context, + &mut body, + ®ions, + &mut costs, + &mut terminator_costs, + Global, + Global, + ); assert_eq!(body.basic_blocks.len(), 3); assert_goto_terminator(&body, BasicBlockId::new(0)); @@ -657,9 +731,18 @@ fn offset_goto_targets_correct() { [[false, false, false]], ]); let mut costs = make_target_costs(&body, patterns, &heap); - let regions = count_regions(&body, &costs, Global); + let mut terminator_costs = make_all_supported_terminator_costs(&body, &heap); + let regions = count_regions(&body, &costs, &terminator_costs, Global); - let _targets = offset_basic_blocks(&context, &mut body, ®ions, &mut costs, Global, Global); + let _targets = offset_basic_blocks( + &context, + &mut body, + ®ions, + &mut costs, + &mut terminator_costs, + Global, + Global, + ); assert_eq!(body.basic_blocks.len(), 3); assert_goto_target(&body, BasicBlockId::new(0), BasicBlockId::new(1)); @@ -696,9 +779,18 @@ fn offset_statements_split_correctly() { [[false, false]], ]); let mut costs = make_target_costs(&body, patterns, &heap); - let regions = count_regions(&body, &costs, Global); + let mut terminator_costs = make_all_supported_terminator_costs(&body, &heap); + let regions = count_regions(&body, &costs, &terminator_costs, Global); - let _targets = offset_basic_blocks(&context, &mut body, ®ions, &mut costs, Global, Global); + let _targets = offset_basic_blocks( + &context, + &mut body, + ®ions, + &mut costs, + &mut terminator_costs, + Global, + Global, + ); assert_assignment_locals(&body, BasicBlockId::new(0), &["x"]); assert_assignment_locals(&body, BasicBlockId::new(1), &["y"]); @@ -734,9 +826,18 @@ fn offset_statement_order_preserved() { [[false, false, false]], ]); let mut costs = make_target_costs(&body, patterns, &heap); - let regions = count_regions(&body, &costs, Global); + let mut terminator_costs = make_all_supported_terminator_costs(&body, &heap); + let regions = count_regions(&body, &costs, &terminator_costs, Global); - let _targets = offset_basic_blocks(&context, &mut body, ®ions, &mut costs, Global, Global); + let _targets = offset_basic_blocks( + &context, + &mut body, + ®ions, + &mut costs, + &mut terminator_costs, + Global, + Global, + ); assert_assignment_locals(&body, BasicBlockId::new(0), &["a"]); assert_assignment_locals(&body, BasicBlockId::new(1), &["b", "c"]); @@ -771,9 +872,18 @@ fn offset_targets_populated() { [[false, false]], ]); let mut costs = make_target_costs(&body, patterns, &heap); - let regions = count_regions(&body, &costs, Global); + let mut terminator_costs = make_all_supported_terminator_costs(&body, &heap); + let regions = count_regions(&body, &costs, &terminator_costs, Global); - let targets = offset_basic_blocks(&context, &mut body, ®ions, &mut costs, Global, Global); + let targets = offset_basic_blocks( + &context, + &mut body, + ®ions, + &mut costs, + &mut terminator_costs, + Global, + Global, + ); let expected_first = Targets { interpreter: true, @@ -930,7 +1040,8 @@ fn split_no_changes_needed() { let mut costs = make_target_costs(&body, patterns, &heap); let splitting = BasicBlockSplitting::new(); - let targets = splitting.split(&context, &mut body, &mut costs); + let mut terminator_costs = make_all_supported_terminator_costs(&body, &heap); + let targets = splitting.split(&context, &mut body, &mut costs, &mut terminator_costs); assert_split("split_no_changes_needed", &context, &body, &costs, &targets); } @@ -966,7 +1077,8 @@ fn split_basic_two_regions() { let mut costs = make_target_costs(&body, patterns, &heap); let splitting = BasicBlockSplitting::new(); - let targets = splitting.split(&context, &mut body, &mut costs); + let mut terminator_costs = make_all_supported_terminator_costs(&body, &heap); + let targets = splitting.split(&context, &mut body, &mut costs, &mut terminator_costs); assert_split("split_basic_two_regions", &context, &body, &costs, &targets); } @@ -1007,7 +1119,8 @@ fn split_multi_block_complex() { let mut costs = make_target_costs(&body, patterns, &heap); let splitting = BasicBlockSplitting::new(); - let targets = splitting.split(&context, &mut body, &mut costs); + let mut terminator_costs = make_all_supported_terminator_costs(&body, &heap); + let targets = splitting.split(&context, &mut body, &mut costs, &mut terminator_costs); assert_split( "split_multi_block_complex", @@ -1050,7 +1163,8 @@ fn split_cost_remap() { let mut costs = make_target_costs(&body, patterns, &heap); let splitting = BasicBlockSplitting::new(); - let targets = splitting.split(&context, &mut body, &mut costs); + let mut terminator_costs = make_all_supported_terminator_costs(&body, &heap); + let targets = splitting.split(&context, &mut body, &mut costs, &mut terminator_costs); assert_split("split_cost_remap", &context, &body, &costs, &targets); } @@ -1093,7 +1207,8 @@ fn split_block_references_updated() { let mut costs = make_target_costs(&body, patterns, &heap); let splitting = BasicBlockSplitting::new(); - let targets = splitting.split(&context, &mut body, &mut costs); + let mut terminator_costs = make_all_supported_terminator_costs(&body, &heap); + let targets = splitting.split(&context, &mut body, &mut costs, &mut terminator_costs); assert_split( "split_block_references_updated", diff --git a/libs/@local/hashql/mir/src/pass/execution/statement_placement/tests.rs b/libs/@local/hashql/mir/src/pass/execution/statement_placement/tests.rs index b9332be3481..2bcf0abff13 100644 --- a/libs/@local/hashql/mir/src/pass/execution/statement_placement/tests.rs +++ b/libs/@local/hashql/mir/src/pass/execution/statement_placement/tests.rs @@ -15,13 +15,13 @@ use insta::{Settings, assert_snapshot}; use super::StatementPlacement; use crate::{ - body::{Body, local::Local, location::Location, statement::Statement}, + body::{Body, local::Local, location::Location, statement::Statement, terminator::Terminator}, builder::body, context::MirContext, intern::Interner, pass::execution::{ VertexType, - cost::StatementCostVec, + cost::{StatementCostVec, TerminatorCostVec}, statement_placement::{ EmbeddingStatementPlacement, InterpreterStatementPlacement, PostgresStatementPlacement, }, @@ -31,7 +31,8 @@ use crate::{ /// Annotation provider that displays statement costs as trailing comments. struct CostAnnotations<'costs, A: Allocator> { - costs: &'costs StatementCostVec, + statement_costs: &'costs StatementCostVec, + terminator_costs: &'costs TerminatorCostVec, } impl TextFormatAnnotations for CostAnnotations<'_, A> { @@ -39,13 +40,27 @@ impl TextFormatAnnotations for CostAnnotations<'_, A> { = impl Display where Self: 'this; + type TerminatorAnnotation<'this, 'heap> + = impl Display + where + Self: 'this; fn annotate_statement<'heap>( &self, location: Location, - _statement: &Statement<'heap>, + _: &Statement<'heap>, ) -> Option> { - let cost = self.costs.get(location)?; + let cost = self.statement_costs.get(location)?; + + Some(core::fmt::from_fn(move |fmt| write!(fmt, "cost: {cost}"))) + } + + fn annotate_terminator<'heap>( + &self, + location: Location, + _: &Terminator<'heap>, + ) -> Option> { + let cost = self.terminator_costs.of(location.block)?; Some(core::fmt::from_fn(move |fmt| write!(fmt, "cost: {cost}"))) } @@ -58,13 +73,14 @@ pub(crate) fn assert_placement<'heap, A: Allocator>( snapshot_subdir: &str, body: &Body<'heap>, context: &MirContext<'_, 'heap>, - statement_costs: &StatementCostVec, + (statement_costs, terminator_costs): &(StatementCostVec, TerminatorCostVec), ) { let formatter = Formatter::new(context.heap); let type_formatter = TypeFormatter::new(&formatter, context.env, TypeFormatterOptions::terse()); let annotations = CostAnnotations { - costs: statement_costs, + statement_costs, + terminator_costs, }; let mut text_format = TextFormatOptions { @@ -100,14 +116,19 @@ pub(crate) fn run_placement<'heap>( context: &MirContext<'_, 'heap>, placement: &mut impl StatementPlacement<'heap, &'heap Heap>, body: Body<'heap>, -) -> (Body<'heap>, StatementCostVec<&'heap Heap>) { +) -> ( + Body<'heap>, + ( + StatementCostVec<&'heap Heap>, + TerminatorCostVec<&'heap Heap>, + ), +) { let vertex = VertexType::from_local(context.env, &body.local_decls[Local::VERTEX]) .unwrap_or_else(|| unimplemented!("lookup for declared type")); - let (statement_costs, _terminator_costs) = - placement.statement_placement_in(context, &body, vertex, context.heap); + let costs = placement.statement_placement_in(context, &body, vertex, context.heap); - (body, statement_costs) + (body, costs) } // ============================================================================= @@ -149,11 +170,17 @@ fn non_graph_read_filter_returns_empty() { let mut embedding = EmbeddingStatementPlacement::new_in(Global); let vertex = VertexType::Entity; - let postgres_statement = postgres.statement_placement_in(&context, &body, vertex, &heap); - let interpreter_statement = interpreter.statement_placement_in(&context, &body, vertex, &heap); - let embedding_statement = embedding.statement_placement_in(&context, &body, vertex, &heap); - - assert!(postgres_statement.all_unassigned()); - assert!(interpreter_statement.all_unassigned()); - assert!(embedding_statement.all_unassigned()); + let (postgres_statements, postgres_terminators) = + postgres.statement_placement_in(&context, &body, vertex, &heap); + let (interpreter_statements, interpreter_terminators) = + interpreter.statement_placement_in(&context, &body, vertex, &heap); + let (embedding_statements, embedding_terminators) = + embedding.statement_placement_in(&context, &body, vertex, &heap); + + assert!(postgres_statements.all_unassigned()); + assert!(postgres_terminators.all_unassigned()); + assert!(interpreter_statements.all_unassigned()); + assert!(interpreter_terminators.all_unassigned()); + assert!(embedding_statements.all_unassigned()); + assert!(embedding_terminators.all_unassigned()); } diff --git a/libs/@local/hashql/mir/src/pretty/text.rs b/libs/@local/hashql/mir/src/pretty/text.rs index 96544f722c8..3b90a785ef4 100644 --- a/libs/@local/hashql/mir/src/pretty/text.rs +++ b/libs/@local/hashql/mir/src/pretty/text.rs @@ -86,6 +86,12 @@ pub trait TextFormatAnnotations { where Self: 'this; + /// The type of annotation displayed after terminators. + type TerminatorAnnotation<'this, 'heap>: Display + = ! + where + Self: 'this; + /// Returns an optional annotation for the given statement at `location`. #[expect(unused_variables, reason = "trait definition")] fn annotate_statement<'heap>( @@ -96,6 +102,15 @@ pub trait TextFormatAnnotations { None } + #[expect(unused_variables, reason = "trait definition")] + fn annotate_terminator<'heap>( + &self, + location: Location, + terminator: &Terminator<'heap>, + ) -> Option> { + None + } + /// Returns an optional annotation for the given local declaration. #[expect(unused_variables, reason = "trait definition")] fn annotate_local_decl<'heap>( @@ -132,6 +147,10 @@ impl TextFormatAnnotations for &mut T { = T::StatementAnnotation<'this, 'heap> where Self: 'this; + type TerminatorAnnotation<'this, 'heap> + = T::TerminatorAnnotation<'this, 'heap> + where + Self: 'this; fn annotate_statement<'heap>( &self, @@ -141,6 +160,14 @@ impl TextFormatAnnotations for &mut T { (**self).annotate_statement(location, statement) } + fn annotate_terminator<'heap>( + &self, + location: Location, + terminator: &Terminator<'heap>, + ) -> Option> { + (**self).annotate_terminator(location, terminator) + } + fn annotate_local_decl<'heap>( &self, local: Local, @@ -503,8 +530,9 @@ where self.newline()?; } + location.statement_index += 1; self.indent(2)?; - self.format_part(&block.terminator)?; + self.format_part((location, &block.terminator))?; self.newline()?; self.indent(1)?; @@ -780,14 +808,31 @@ where } } -impl<'heap, W, S, T, A> FormatPart<&Terminator<'heap>> for TextFormat +impl<'heap, W, S, T, A> FormatPart<(Location, &Terminator<'heap>)> for TextFormat where W: io::Write, S: SourceLookup<'heap>, + A: TextFormatAnnotations, { - fn format_part(&mut self, Terminator { span: _, kind }: &Terminator<'heap>) -> io::Result<()> { + fn format_part( + &mut self, + (location, terminator @ Terminator { span: _, kind }): (Location, &Terminator<'heap>), + ) -> io::Result<()> { self.format_part(TerminatorHead(kind))?; - self.format_part(TerminatorTail(kind)) + self.format_part(TerminatorTail(kind))?; + + let Some(annotation) = self.annotations.annotate_terminator(location, terminator) else { + return Ok(()); + }; + + // We estimate that we never exceed 80 columns, calculate the remaining width, if we don't + // have enough space, we add 4 spaces breathing room. + let remaining_width = 80_usize.checked_sub(self.line_buffer.len()).unwrap_or(4); + self.line_buffer + .resize(self.line_buffer.len() + remaining_width, b' '); + write!(self.line_buffer, "// {annotation}")?; + + Ok(()) } } From 2acf5edf9b0a66475ed38775904563307617778b Mon Sep 17 00:00:00 2001 From: Bilal Mahmoud Date: Sun, 22 Mar 2026 18:50:39 +0100 Subject: [PATCH 4/6] feat: checkpoint --- .../mir/src/pass/execution/cost/analysis.rs | 22 ++++++++++--------- .../hashql/mir/src/pass/execution/cost/mod.rs | 7 +----- .../mir/src/pass/execution/cost/tests.rs | 9 ++++++-- .../hashql/mir/src/pass/execution/mod.rs | 3 ++- .../pass/execution/placement/solve/tests.rs | 2 +- .../mir/src/pass/execution/splitting/mod.rs | 6 +++-- 6 files changed, 27 insertions(+), 22 deletions(-) diff --git a/libs/@local/hashql/mir/src/pass/execution/cost/analysis.rs b/libs/@local/hashql/mir/src/pass/execution/cost/analysis.rs index 3850c247a85..d7a589654c9 100644 --- a/libs/@local/hashql/mir/src/pass/execution/cost/analysis.rs +++ b/libs/@local/hashql/mir/src/pass/execution/cost/analysis.rs @@ -1,6 +1,6 @@ use core::alloc::Allocator; -use super::{ApproxCost, StatementCostVec}; +use super::{ApproxCost, StatementCostVec, TerminatorCostVec}; use crate::{ body::basic_block::{BasicBlock, BasicBlockId, BasicBlockSlice, BasicBlockVec}, pass::{ @@ -98,7 +98,8 @@ impl BasicBlockCostVec { pub(crate) struct BasicBlockCostAnalysis<'ctx, A: Allocator> { pub vertex: VertexType, pub assignments: &'ctx BasicBlockSlice, - pub costs: &'ctx TargetArray>, + pub statement_costs: &'ctx TargetArray>, + pub terminator_costs: &'ctx TargetArray>, } impl BasicBlockCostAnalysis<'_, A> { @@ -109,7 +110,8 @@ impl BasicBlockCostAnalysis<'_, A> { target: TargetId, traversals: TraversalPathBitSet, ) -> BasicBlockTargetCost { - let base = self.costs[target].sum_approx(id); + let mut base = self.statement_costs[target].sum_approx(id); + base += self.terminator_costs[target].approx(id); let mut range = InformationRange::zero(); @@ -234,7 +236,7 @@ mod tests { let analysis = BasicBlockCostAnalysis { vertex: VertexType::Entity, assignments: targets, - costs: &costs, + statement_costs: &costs, }; let result = analysis.analyze_in(&default_config(), &body.basic_blocks, Global); @@ -275,7 +277,7 @@ mod tests { let analysis = BasicBlockCostAnalysis { vertex: VertexType::Entity, assignments: targets, - costs: &costs, + statement_costs: &costs, }; let config = default_config(); @@ -330,7 +332,7 @@ mod tests { let analysis = BasicBlockCostAnalysis { vertex: VertexType::Entity, assignments: targets, - costs: &costs, + statement_costs: &costs, }; let result = analysis.analyze_in(&default_config(), &body.basic_blocks, Global); @@ -387,7 +389,7 @@ mod tests { let analysis = BasicBlockCostAnalysis { vertex: VertexType::Entity, assignments: targets, - costs: &costs, + statement_costs: &costs, }; // Use a bounded properties size so both premiums are finite and comparable. @@ -446,7 +448,7 @@ mod tests { let analysis = BasicBlockCostAnalysis { vertex: VertexType::Entity, assignments: targets, - costs: &costs, + statement_costs: &costs, }; let result = analysis.analyze_in(&config, &body.basic_blocks, Global); @@ -496,7 +498,7 @@ mod tests { let analysis = BasicBlockCostAnalysis { vertex: VertexType::Entity, assignments: targets, - costs: &costs, + statement_costs: &costs, }; let result = analysis.analyze_in(&default_config(), &body.basic_blocks, Global); @@ -549,7 +551,7 @@ mod tests { let analysis = BasicBlockCostAnalysis { vertex: VertexType::Entity, assignments: targets, - costs: &costs, + statement_costs: &costs, }; let result = analysis.analyze_in(&config, &body.basic_blocks, Global); diff --git a/libs/@local/hashql/mir/src/pass/execution/cost/mod.rs b/libs/@local/hashql/mir/src/pass/execution/cost/mod.rs index db91da4db70..5332c985c58 100644 --- a/libs/@local/hashql/mir/src/pass/execution/cost/mod.rs +++ b/libs/@local/hashql/mir/src/pass/execution/cost/mod.rs @@ -362,11 +362,6 @@ impl TerminatorCostVec { self.0.lookup(block).copied() } - #[expect(dead_code, reason = "will be used by downstream cost analysis")] - pub(crate) fn of_mut(&mut self, block: BasicBlockId) -> Option<&mut Cost> { - self.0.lookup_mut(block) - } - pub(crate) fn insert(&mut self, block: BasicBlockId, cost: Cost) { self.0.insert(block, cost); } @@ -408,8 +403,8 @@ impl TerminatorCostVec { } /// Returns the approximate cost for the terminator in `block`, or zero if unassigned. - #[expect(dead_code, reason = "will be used by downstream cost analysis")] pub(crate) fn approx(&self, block: BasicBlockId) -> ApproxCost { + debug_assert!(self.0.contains(block)); self.0 .lookup(block) .copied() diff --git a/libs/@local/hashql/mir/src/pass/execution/cost/tests.rs b/libs/@local/hashql/mir/src/pass/execution/cost/tests.rs index 6f9588f2f00..c91068ea061 100644 --- a/libs/@local/hashql/mir/src/pass/execution/cost/tests.rs +++ b/libs/@local/hashql/mir/src/pass/execution/cost/tests.rs @@ -1,7 +1,12 @@ use alloc::alloc::Global; +use core::num::NonZero; -use super::{Cost, StatementCostVec}; -use crate::body::{basic_block::BasicBlockId, location::Location}; +use super::{Cost, StatementCostVec, TerminatorCostVec}; +use crate::body::{ + basic_block::{BasicBlockId, BasicBlockSlice}, + basic_blocks::BasicBlocks, + location::Location, +}; /// `Cost::new` succeeds for valid values (0 and 100). #[test] diff --git a/libs/@local/hashql/mir/src/pass/execution/mod.rs b/libs/@local/hashql/mir/src/pass/execution/mod.rs index e4e29225413..c1bd420e07b 100644 --- a/libs/@local/hashql/mir/src/pass/execution/mod.rs +++ b/libs/@local/hashql/mir/src/pass/execution/mod.rs @@ -123,7 +123,8 @@ impl<'heap, S: BumpAllocator> ExecutionAnalysis<'_, 'heap, S> { let block_costs = BasicBlockCostAnalysis { vertex, assignments: &assignments, - costs: &statement_costs, + statement_costs: &statement_costs, + terminator_costs: &terminator_costs, } .analyze_in( &TransferCostConfig::new(InformationRange::full()), diff --git a/libs/@local/hashql/mir/src/pass/execution/placement/solve/tests.rs b/libs/@local/hashql/mir/src/pass/execution/placement/solve/tests.rs index dccddddf66e..06581e86a79 100644 --- a/libs/@local/hashql/mir/src/pass/execution/placement/solve/tests.rs +++ b/libs/@local/hashql/mir/src/pass/execution/placement/solve/tests.rs @@ -145,7 +145,7 @@ pub(crate) fn make_block_costs_with_config<'heap>( BasicBlockCostAnalysis { vertex: VertexType::Entity, assignments, - costs: statements, + statement_costs: statements, } .analyze_in(config, &body.basic_blocks, alloc) } diff --git a/libs/@local/hashql/mir/src/pass/execution/splitting/mod.rs b/libs/@local/hashql/mir/src/pass/execution/splitting/mod.rs index e71128f5ad6..f881ccdaf95 100644 --- a/libs/@local/hashql/mir/src/pass/execution/splitting/mod.rs +++ b/libs/@local/hashql/mir/src/pass/execution/splitting/mod.rs @@ -63,8 +63,10 @@ fn supported_terminator( /// Counts contiguous target regions per [`BasicBlock`]. /// -/// Returns a non-zero count for each block. Blocks with fewer than two statements -/// always yield one region. +/// Returns a `(region_count, has_separate_terminator_region)` pair for each block. +/// An extra region is added when the terminator's target support is not a superset +/// of the last statement region's support (including incomparable sets, not just +/// strict subsets). #[expect(unsafe_code)] fn count_regions( body: &Body<'_>, From 343aceec8a1c8f7815bb3b02cb765fbc4c786a4d Mon Sep 17 00:00:00 2001 From: Bilal Mahmoud Date: Sun, 22 Mar 2026 19:31:28 +0100 Subject: [PATCH 5/6] feat: tests --- .../type-extractor/closure-generics.stdout | 4 +- .../definition/constraints-parsing.stdout | 4 +- .../definition/generics-apply-params.stdout | 6 +- .../definition/generics-with-params.stdout | 4 +- .../locals-generic-params-struct.stdout | 4 +- .../definition/locals-generic-params.stdout | 4 +- .../type-extractor/definition/result.stdout | 14 +- .../generic-type-resolution.stdout | 6 +- .../compiletest/src/harness/test/discover.rs | 4 + .../compiletest/src/harness/test/mod.rs | 1 + .../eval/tests/ui/orchestrator/.spec.toml | 2 + .../ui/postgres/comparison-no-cast.aux.mir | 6 +- .../ui/postgres/comparison-no-cast.stdout | 4 +- .../ui/postgres/constant-true-filter.aux.mir | 10 +- .../ui/postgres/constant-true-filter.stdout | 6 +- .../ui/postgres/dict-construction.aux.mir | 6 +- .../ui/postgres/dict-construction.stdout | 4 +- .../ui/postgres/entity-archived-check.aux.mir | 6 +- .../ui/postgres/entity-archived-check.stdout | 4 +- .../postgres/entity-draft-id-equality.aux.mir | 6 +- .../postgres/entity-draft-id-equality.stdout | 2 +- .../postgres/entity-type-ids-lateral.aux.mir | 6 +- .../postgres/entity-type-ids-lateral.stdout | 8 +- .../ui/postgres/entity-uuid-equality.aux.mir | 6 +- .../ui/postgres/entity-uuid-equality.stdout | 4 +- .../postgres/entity-web-id-equality.aux.mir | 6 +- .../ui/postgres/entity-web-id-equality.stdout | 4 +- .../ui/postgres/env-captured-variable.aux.mir | 6 +- .../ui/postgres/env-captured-variable.stdout | 6 +- .../ui/postgres/if-input-branches.aux.mir | 6 +- .../ui/postgres/if-input-branches.stdout | 4 +- .../postgres/input-parameter-exists.aux.mir | 10 +- .../ui/postgres/input-parameter-exists.stdout | 4 +- .../ui/postgres/input-parameter-load.aux.mir | 6 +- .../ui/postgres/input-parameter-load.stdout | 4 +- .../postgres/let-binding-propagation.aux.mir | 6 +- .../postgres/let-binding-propagation.stdout | 4 +- .../ui/postgres/list-construction.aux.mir | 6 +- .../ui/postgres/list-construction.stdout | 4 +- .../ui/postgres/logical-and-inputs.aux.mir | 10 +- .../ui/postgres/logical-and-inputs.stdout | 4 +- .../minimal-select-no-extra-joins.aux.mir | 6 +- .../minimal-select-no-extra-joins.stdout | 4 +- .../ui/postgres/mixed-sources-filter.aux.mir | 6 +- .../ui/postgres/mixed-sources-filter.stdout | 8 +- .../ui/postgres/multiple-filters.aux.mir | 6 +- .../tests/ui/postgres/multiple-filters.stdout | 6 +- .../postgres/nested-if-input-branches.aux.mir | 6 +- .../postgres/nested-if-input-branches.stdout | 4 +- .../ui/postgres/opaque-passthrough.aux.mir | 6 +- .../ui/postgres/opaque-passthrough.stdout | 4 +- .../ui/postgres/struct-construction.aux.mir | 6 +- .../ui/postgres/struct-construction.stdout | 4 +- .../ui/postgres/tuple-construction.aux.mir | 6 +- .../ui/postgres/tuple-construction.stdout | 4 +- .../checking/closure-call-constrained.stdout | 10 +- .../closure-call-unconstrained-direct.stdout | 2 +- .../closure-call-unconstrained.stdout | 20 +- .../lower/checking/closure-constrained.stdout | 10 +- .../checking/collect-filter-graph.stdout | 324 +++++++--- .../ui/lower/checking/filter-graph.stdout | 260 ++++++-- .../ui/lower/checking/minimal-graph.stdout | 146 ++++- .../ui/lower/inference/bind-arguments.stdout | 8 +- .../hir/tests/ui/lower/inference/call.stdout | 4 +- .../closure-call-unconstrained-direct.stdout | 12 +- .../closure-call-unconstrained.stdout | 28 +- .../inference/closure-constrained.stdout | 16 +- .../ui/lower/inference/closure-integer.stdout | 16 +- .../hir/tests/ui/lower/inference/ctor.stdout | 2 +- .../hir/tests/ui/lower/inference/if.stdout | 2 +- .../ui/lower/inference/infer-argument.stdout | 4 +- .../lower/inference/qualified-variable.stdout | 4 +- .../collect-custom-collect.stderr | 32 +- .../collect-filter-graph.stdout | 16 +- .../ui/lower/specialization/complex.stdout | 4 +- .../lower/specialization/filter-graph.stdout | 16 +- .../hashql/hir/tests/ui/reify/closure.stdout | 2 +- .../mir/src/pass/execution/cost/analysis.rs | 71 +++ .../hashql/mir/src/pass/execution/cost/mod.rs | 10 + .../mir/src/pass/execution/cost/tests.rs | 71 ++- .../pass/execution/placement/solve/tests.rs | 8 +- .../mir/src/pass/execution/splitting/tests.rs | 505 +++++++++++++++ .../closure-chain.stdout | 4 +- .../forwarding-closure.stdout | 4 +- .../cascade-switch-then-goto.stdout | 2 +- .../closure-with-const-branch.stdout | 2 +- .../pass/cfg_simplify/const-if-false.stdout | 2 +- .../ui/pass/cfg_simplify/const-if-true.stdout | 2 +- .../pass/cfg_simplify/const-nested-if.stdout | 4 +- .../dead-block-elimination.aux.svg | 566 ++++++++--------- .../dead-block-elimination.stdout | 2 +- .../ui/pass/cfg_simplify/let-in-branch.stdout | 4 +- .../mixed-const-runtime-if.stdout | 2 +- .../data-dependency/binary-operation.stdout | 8 +- .../closure-construction.stdout | 2 +- .../comparison-operators.stdout | 8 +- .../deeply-nested-tuple.stdout | 2 +- .../data-dependency/function-apply.stdout | 2 +- .../function-multiple-args.stdout | 2 +- .../data-dependency/list-construction.stdout | 2 +- .../mixed-projection-chain.stdout | 2 +- .../pass/data-dependency/multiple-uses.stdout | 8 +- .../nested-tuple-projection.stdout | 2 +- .../struct-construction.stdout | 2 +- .../data-dependency/struct-projection.stdout | 2 +- .../data-dependency/tuple-construction.stdout | 2 +- .../data-dependency/tuple-projection.stdout | 2 +- .../tests/ui/pass/dse/live-in-branch.stdout | 4 +- .../pass/dse/nested-tuple-projection.stdout | 2 +- .../mir/tests/ui/pass/dse/showcase.aux.svg | 566 ++++++++--------- .../mir/tests/ui/pass/dse/showcase.stdout | 4 +- .../ui/pass/dse/simple-dead-local.stdout | 2 +- .../ui/pass/dse/used-local-preserved.stdout | 2 +- .../only_vectors_projection_supported.snap | 2 +- .../storage_statements_zero_cost.snap | 2 +- .../interpret/all_statements_supported.snap | 2 +- .../interpret/eq_opaque_entity_uuid.snap | 3 +- .../non_traversal_unaffected_by_costs.snap | 2 +- .../storage_statements_zero_cost.snap | 2 +- .../traversal_multiple_paths_cost.snap | 2 +- .../interpret/traversal_single_path_cost.snap | 2 +- .../traversal_swallowing_reduces_cost.snap | 2 +- .../postgres/aggregate_closure_rejected.snap | 2 +- .../postgres/aggregate_tuple_supported.snap | 2 +- .../postgres/binary_unary_ops_supported.snap | 2 +- .../postgres/diamond_must_analysis.snap | 2 +- .../postgres/entity_projection_column.snap | 2 +- .../postgres/entity_projection_jsonb.snap | 2 +- ...closure_field_rejected_other_accepted.snap | 2 +- .../env_dict_non_string_key_rejected.snap | 2 +- .../env_dict_opaque_string_key_accepted.snap | 2 +- .../env_dict_string_key_accepted.snap | 2 +- .../env_with_closure_type_rejected.snap | 2 +- .../env_without_closure_accepted.snap | 2 +- .../eq_place_vs_constant_accepted.snap | 2 +- .../postgres/eq_same_type_accepted.snap | 2 +- .../postgres/fnptr_constant_rejected.snap | 2 +- .../postgres/input_supported.snap | 2 +- .../serialization_unsafe_edge_propagates.snap | 2 +- ...erialization_unsafe_statement_no_cost.snap | 2 +- .../storage_statements_zero_cost.snap | 2 +- .../chained-projection.stdout | 2 +- .../closure-env-capture.aux.svg | 566 ++++++++--------- .../closure-env-capture.stdout | 2 +- .../pass/forward_substitution/nested.stdout | 2 +- .../param-const-agree.stdout | 2 +- .../param-const-diverge.stdout | 2 +- .../tuple-projection.stdout | 2 +- .../ui/pass/inline/heuristic-inline.stdout | 8 +- .../annihilator-and-false.stdout | 10 +- .../inst_simplify/annihilator-or-true.stdout | 10 +- .../inst_simplify/chained-const-fold.stdout | 10 +- .../pass/inst_simplify/const-fold-eq.stdout | 6 +- .../pass/inst_simplify/const-fold-gt.stdout | 6 +- .../pass/inst_simplify/const-fold-gte.stdout | 6 +- .../pass/inst_simplify/const-fold-lt.stdout | 6 +- .../pass/inst_simplify/const-fold-lte.stdout | 6 +- .../pass/inst_simplify/const-fold-ne.stdout | 6 +- .../const-propagation-locals.stdout | 6 +- .../inst_simplify/identical-operand-eq.stdout | 6 +- .../inst_simplify/identical-operand-gt.stdout | 6 +- .../identical-operand-gte.stdout | 6 +- .../inst_simplify/identical-operand-lt.stdout | 6 +- .../identical-operand-lte.stdout | 6 +- .../inst_simplify/identical-operand-ne.stdout | 6 +- .../inst_simplify/identity-and-true.stdout | 10 +- .../inst_simplify/identity-or-false.stdout | 10 +- .../ui/pass/inst_simplify/showcase.aux.svg | 574 +++++++++--------- .../ui/pass/inst_simplify/showcase.stdout | 18 +- .../cascading-simplification.stdout | 6 +- .../post_inline/closure-env-cleanup.stdout | 2 +- .../constant-propagation-after-inline.stdout | 2 +- .../post_inline/dead-code-from-inline.stdout | 6 +- .../nested-branch-elimination.stdout | 2 +- .../pre_inline/basic-constant-folding.stdout | 2 +- .../pre_inline/chain-simplification.stdout | 12 +- .../closure-with-dead-branch.stdout | 4 +- .../dead-code-after-propagation.stdout | 2 +- .../inst-simplify-with-propagation.stdout | 4 +- .../pass/pre_inline/nested-if-constant.stdout | 6 +- .../pass/pre_inline/nested-let-cleanup.stdout | 2 +- .../pre_inline/thunk-with-dead-code.stdout | 6 +- .../ui/reify/closure-captured-var.stdout | 2 +- .../tests/ui/reify/dict-computed-key.stdout | 2 +- .../mir/tests/ui/reify/nested-if.aux.svg | 566 ++++++++--------- .../mir/tests/ui/reify/nested-if.stdout | 2 +- .../mir/tests/ui/reify/nested-let.stdout | 2 +- .../hashql/mir/tests/ui/reify/reassign.stdout | 2 +- 188 files changed, 3130 insertions(+), 1985 deletions(-) create mode 100644 libs/@local/hashql/eval/tests/ui/orchestrator/.spec.toml diff --git a/libs/@local/hashql/ast/tests/ui/lowering/type-extractor/closure-generics.stdout b/libs/@local/hashql/ast/tests/ui/lowering/type-extractor/closure-generics.stdout index 905726f02a9..86484e63441 100644 --- a/libs/@local/hashql/ast/tests/ui/lowering/type-extractor/closure-generics.stdout +++ b/libs/@local/hashql/ast/tests/ui/lowering/type-extractor/closure-generics.stdout @@ -42,5 +42,5 @@ Expr#0@41 ------------------------ ------------------------ -┌─ 4 -└→ (T:0?26) -> _0 \ No newline at end of file +┌─ 4 +└→ (T:0?30) -> _0 \ No newline at end of file diff --git a/libs/@local/hashql/ast/tests/ui/lowering/type-extractor/definition/constraints-parsing.stdout b/libs/@local/hashql/ast/tests/ui/lowering/type-extractor/definition/constraints-parsing.stdout index 43a9a4732a5..a8ff455c7b0 100644 --- a/libs/@local/hashql/ast/tests/ui/lowering/type-extractor/definition/constraints-parsing.stdout +++ b/libs/@local/hashql/ast/tests/ui/lowering/type-extractor/definition/constraints-parsing.stdout @@ -3,5 +3,5 @@ Expr#4294967040@28 ------------------------ -┌─ Sortable:0 -└→ (items: List) \ No newline at end of file +┌─ Sortable:0 +└→ (items: List) \ No newline at end of file diff --git a/libs/@local/hashql/ast/tests/ui/lowering/type-extractor/definition/generics-apply-params.stdout b/libs/@local/hashql/ast/tests/ui/lowering/type-extractor/definition/generics-apply-params.stdout index 3350715d8ac..adf2d86486d 100644 --- a/libs/@local/hashql/ast/tests/ui/lowering/type-extractor/definition/generics-apply-params.stdout +++ b/libs/@local/hashql/ast/tests/ui/lowering/type-extractor/definition/generics-apply-params.stdout @@ -4,7 +4,7 @@ Expr#4294967040@42 ------------------------ ┌─ StringWrapper:0<> -└→ ([?27 = String] (foo: T:0?27),) +└→ ([?31 = String] (foo: T:0?31),) -┌─ Wrapper:0 -└→ (foo: T:0?26) \ No newline at end of file +┌─ Wrapper:0 +└→ (foo: T:0?30) \ No newline at end of file diff --git a/libs/@local/hashql/ast/tests/ui/lowering/type-extractor/definition/generics-with-params.stdout b/libs/@local/hashql/ast/tests/ui/lowering/type-extractor/definition/generics-with-params.stdout index ad14bfc4195..d3ea7d0c9b8 100644 --- a/libs/@local/hashql/ast/tests/ui/lowering/type-extractor/definition/generics-with-params.stdout +++ b/libs/@local/hashql/ast/tests/ui/lowering/type-extractor/definition/generics-with-params.stdout @@ -3,5 +3,5 @@ Expr#4294967040@23 ------------------------ -┌─ Wrapper:0 -└→ List \ No newline at end of file +┌─ Wrapper:0 +└→ List \ No newline at end of file diff --git a/libs/@local/hashql/ast/tests/ui/lowering/type-extractor/definition/locals-generic-params-struct.stdout b/libs/@local/hashql/ast/tests/ui/lowering/type-extractor/definition/locals-generic-params-struct.stdout index 51aaae50cf1..8509793a8cf 100644 --- a/libs/@local/hashql/ast/tests/ui/lowering/type-extractor/definition/locals-generic-params-struct.stdout +++ b/libs/@local/hashql/ast/tests/ui/lowering/type-extractor/definition/locals-generic-params-struct.stdout @@ -3,5 +3,5 @@ Expr#4294967040@23 ------------------------ -┌─ Box:0 -└→ (foo: T:0?26) \ No newline at end of file +┌─ Box:0 +└→ (foo: T:0?30) \ No newline at end of file diff --git a/libs/@local/hashql/ast/tests/ui/lowering/type-extractor/definition/locals-generic-params.stdout b/libs/@local/hashql/ast/tests/ui/lowering/type-extractor/definition/locals-generic-params.stdout index 1f8d056d45d..68075e0bf2b 100644 --- a/libs/@local/hashql/ast/tests/ui/lowering/type-extractor/definition/locals-generic-params.stdout +++ b/libs/@local/hashql/ast/tests/ui/lowering/type-extractor/definition/locals-generic-params.stdout @@ -3,5 +3,5 @@ Expr#4294967040@18 ------------------------ -┌─ Box:0 -└→ T:0?26 \ No newline at end of file +┌─ Box:0 +└→ T:0?30 \ No newline at end of file diff --git a/libs/@local/hashql/ast/tests/ui/lowering/type-extractor/definition/result.stdout b/libs/@local/hashql/ast/tests/ui/lowering/type-extractor/definition/result.stdout index 8c4f185d8f7..06d4279ccd2 100644 --- a/libs/@local/hashql/ast/tests/ui/lowering/type-extractor/definition/result.stdout +++ b/libs/@local/hashql/ast/tests/ui/lowering/type-extractor/definition/result.stdout @@ -3,12 +3,12 @@ Expr#4294967040@76 ------------------------ -┌─ Err:0 -└→ ::main::Err:0(E:0?34) +┌─ Err:0 +└→ ::main::Err:0(E:0?38) -┌─ Ok:0 -└→ ::main::Ok:0(T:0?33) +┌─ Ok:0 +└→ ::main::Ok:0(T:0?37) -┌─ Result:0 -└→ [?31 = T:1?29] ::main::Ok:0(T:0?31) - | [?32 = E:1?30] ::main::Err:0(E:0?32) \ No newline at end of file +┌─ Result:0 +└→ [?35 = T:1?33] ::main::Ok:0(T:0?35) + | [?36 = E:1?34] ::main::Err:0(E:0?36) \ No newline at end of file diff --git a/libs/@local/hashql/ast/tests/ui/lowering/type-extractor/generic-type-resolution.stdout b/libs/@local/hashql/ast/tests/ui/lowering/type-extractor/generic-type-resolution.stdout index 424350b8ccf..b999839fedf 100644 --- a/libs/@local/hashql/ast/tests/ui/lowering/type-extractor/generic-type-resolution.stdout +++ b/libs/@local/hashql/ast/tests/ui/lowering/type-extractor/generic-type-resolution.stdout @@ -27,9 +27,9 @@ Expr#0@48 ------------------------ -┌─ Box:0 -└→ (value: T:0?26) +┌─ Box:0 +└→ (value: T:0?30) ------------------------ -4 = [?27 = Number] (value: T:0?27) +4 = [?31 = Number] (value: T:0?31) ------------------------ \ No newline at end of file diff --git a/libs/@local/hashql/compiletest/src/harness/test/discover.rs b/libs/@local/hashql/compiletest/src/harness/test/discover.rs index 6b3148bcb32..cb53e2bfa2a 100644 --- a/libs/@local/hashql/compiletest/src/harness/test/discover.rs +++ b/libs/@local/hashql/compiletest/src/harness/test/discover.rs @@ -175,6 +175,10 @@ fn find_test_cases(entry_point: &EntryPoint) -> Vec { ) }; + if spec.skip == Some(true) { + continue; + } + cases.push(TestCase { spec: spec.clone(), path: candidate, diff --git a/libs/@local/hashql/compiletest/src/harness/test/mod.rs b/libs/@local/hashql/compiletest/src/harness/test/mod.rs index 160159e3961..1d9264d1416 100644 --- a/libs/@local/hashql/compiletest/src/harness/test/mod.rs +++ b/libs/@local/hashql/compiletest/src/harness/test/mod.rs @@ -7,6 +7,7 @@ use guppy::graph::{PackageGraph, PackageMetadata}; #[derive(Debug, Clone, PartialEq, Eq, serde::Deserialize)] pub(crate) struct Spec { pub suite: String, + pub skip: Option, } #[derive(Debug, Clone, PartialEq, Eq)] diff --git a/libs/@local/hashql/eval/tests/ui/orchestrator/.spec.toml b/libs/@local/hashql/eval/tests/ui/orchestrator/.spec.toml new file mode 100644 index 00000000000..ef02627aed9 --- /dev/null +++ b/libs/@local/hashql/eval/tests/ui/orchestrator/.spec.toml @@ -0,0 +1,2 @@ +skip = true +suite = "eval/orchestrator" diff --git a/libs/@local/hashql/eval/tests/ui/postgres/comparison-no-cast.aux.mir b/libs/@local/hashql/eval/tests/ui/postgres/comparison-no-cast.aux.mir index 98d2753e013..8ab01df57eb 100644 --- a/libs/@local/hashql/eval/tests/ui/postgres/comparison-no-cast.aux.mir +++ b/libs/@local/hashql/eval/tests/ui/postgres/comparison-no-cast.aux.mir @@ -1,5 +1,5 @@ -thunk {thunk#1}() -> ::graph::TimeAxis { - let %0: ::graph::TimeAxis +thunk {thunk#1}() -> ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes { + let %0: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes bb0(): { %0 = input LOAD time_axis @@ -59,7 +59,7 @@ fn {graph::read::filter@7}(%0: (), %1: ::graph::types::knowledge::entity::Entity thunk {thunk#5}() -> List<::graph::types::knowledge::entity::Entity> { let %0: List<::graph::types::knowledge::entity::Entity> let %1: () - let %2: ::graph::TimeAxis + let %2: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes bb0(): { %2 = input LOAD time_axis diff --git a/libs/@local/hashql/eval/tests/ui/postgres/comparison-no-cast.stdout b/libs/@local/hashql/eval/tests/ui/postgres/comparison-no-cast.stdout index 4670536a811..ff997416812 100644 --- a/libs/@local/hashql/eval/tests/ui/postgres/comparison-no-cast.stdout +++ b/libs/@local/hashql/eval/tests/ui/postgres/comparison-no-cast.stdout @@ -2,9 +2,9 @@ SELECT ("continuation_4_0"."row")."block" AS "continuation_4_0_block", ("continuation_4_0"."row")."locals" AS "continuation_4_0_locals", ("continuation_4_0"."row")."values" AS "continuation_4_0_values" FROM "entity_temporal_metadata" AS "entity_temporal_metadata_0_0_0" -CROSS JOIN LATERAL (SELECT (ROW((($3 > $4)::boolean), NULL, NULL, NULL)::continuation) AS "row" +CROSS JOIN LATERAL (SELECT (ROW(COALESCE(((($3::jsonb) > ($4::jsonb))::boolean), FALSE), NULL, NULL, NULL)::continuation) AS "row" OFFSET 0) AS "continuation_4_0" -WHERE "entity_temporal_metadata_0_0_0"."transaction_time" && $1 AND "entity_temporal_metadata_0_0_0"."decision_time" && $2 AND ("continuation_4_0"."row")."filter" IS NOT FALSE +WHERE "entity_temporal_metadata_0_0_0"."transaction_time" && ($1::tstzrange) AND "entity_temporal_metadata_0_0_0"."decision_time" && ($2::tstzrange) AND ("continuation_4_0"."row")."filter" IS NOT FALSE ════ Parameters ════════════════════════════════════════════════════════════════ diff --git a/libs/@local/hashql/eval/tests/ui/postgres/constant-true-filter.aux.mir b/libs/@local/hashql/eval/tests/ui/postgres/constant-true-filter.aux.mir index 76a15d5fcc5..86de485090d 100644 --- a/libs/@local/hashql/eval/tests/ui/postgres/constant-true-filter.aux.mir +++ b/libs/@local/hashql/eval/tests/ui/postgres/constant-true-filter.aux.mir @@ -1,5 +1,5 @@ -thunk {thunk#1}() -> ::graph::TimeAxis { - let %0: ::graph::TimeAxis +thunk {thunk#1}() -> ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes { + let %0: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes bb0(): { %0 = input LOAD time_axis @@ -9,15 +9,15 @@ thunk {thunk#1}() -> ::graph::TimeAxis { } fn {graph::read::filter@7}(%0: (), %1: ::graph::types::knowledge::entity::Entity) -> Boolean { - bb0(): { // interpreter - return 1 + bb0(): { // postgres + return true } } thunk {thunk#2}() -> List<::graph::types::knowledge::entity::Entity> { let %0: List<::graph::types::knowledge::entity::Entity> let %1: () - let %2: ::graph::TimeAxis + let %2: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes bb0(): { %2 = input LOAD time_axis diff --git a/libs/@local/hashql/eval/tests/ui/postgres/constant-true-filter.stdout b/libs/@local/hashql/eval/tests/ui/postgres/constant-true-filter.stdout index 5f9c348d0e4..0df73c4dc88 100644 --- a/libs/@local/hashql/eval/tests/ui/postgres/constant-true-filter.stdout +++ b/libs/@local/hashql/eval/tests/ui/postgres/constant-true-filter.stdout @@ -1,8 +1,10 @@ ════ SQL ═══════════════════════════════════════════════════════════════════════ -SELECT 1 AS "placeholder" +SELECT ("continuation_1_0"."row")."block" AS "continuation_1_0_block", ("continuation_1_0"."row")."locals" AS "continuation_1_0_locals", ("continuation_1_0"."row")."values" AS "continuation_1_0_values" FROM "entity_temporal_metadata" AS "entity_temporal_metadata_0_0_0" -WHERE "entity_temporal_metadata_0_0_0"."transaction_time" && $1 AND "entity_temporal_metadata_0_0_0"."decision_time" && $2 +CROSS JOIN LATERAL (SELECT (ROW(COALESCE(((1)::boolean), FALSE), NULL, NULL, NULL)::continuation) AS "row" +OFFSET 0) AS "continuation_1_0" +WHERE "entity_temporal_metadata_0_0_0"."transaction_time" && ($1::tstzrange) AND "entity_temporal_metadata_0_0_0"."decision_time" && ($2::tstzrange) AND ("continuation_1_0"."row")."filter" IS NOT FALSE ════ Parameters ════════════════════════════════════════════════════════════════ diff --git a/libs/@local/hashql/eval/tests/ui/postgres/dict-construction.aux.mir b/libs/@local/hashql/eval/tests/ui/postgres/dict-construction.aux.mir index 7c78cd33883..121e5b297c3 100644 --- a/libs/@local/hashql/eval/tests/ui/postgres/dict-construction.aux.mir +++ b/libs/@local/hashql/eval/tests/ui/postgres/dict-construction.aux.mir @@ -1,5 +1,5 @@ -thunk {thunk#1}() -> ::graph::TimeAxis { - let %0: ::graph::TimeAxis +thunk {thunk#1}() -> ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes { + let %0: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes bb0(): { %0 = input LOAD time_axis @@ -63,7 +63,7 @@ fn {graph::read::filter@7}(%0: (), %1: ::graph::types::knowledge::entity::Entity thunk {thunk#7}() -> List<::graph::types::knowledge::entity::Entity> { let %0: List<::graph::types::knowledge::entity::Entity> let %1: () - let %2: ::graph::TimeAxis + let %2: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes bb0(): { %2 = input LOAD time_axis diff --git a/libs/@local/hashql/eval/tests/ui/postgres/dict-construction.stdout b/libs/@local/hashql/eval/tests/ui/postgres/dict-construction.stdout index 7a347f26c72..f649dadb5f0 100644 --- a/libs/@local/hashql/eval/tests/ui/postgres/dict-construction.stdout +++ b/libs/@local/hashql/eval/tests/ui/postgres/dict-construction.stdout @@ -2,9 +2,9 @@ SELECT ("continuation_4_0"."row")."block" AS "continuation_4_0_block", ("continuation_4_0"."row")."locals" AS "continuation_4_0_locals", ("continuation_4_0"."row")."values" AS "continuation_4_0_values" FROM "entity_temporal_metadata" AS "entity_temporal_metadata_0_0_0" -CROSS JOIN LATERAL (SELECT (ROW(((jsonb_build_object("entity_temporal_metadata_0_0_0"."entity_uuid", "entity_temporal_metadata_0_0_0"."web_id") = jsonb_build_object($3, $4))::boolean), NULL, NULL, NULL)::continuation) AS "row" +CROSS JOIN LATERAL (SELECT (ROW(COALESCE(((to_jsonb(jsonb_build_object("entity_temporal_metadata_0_0_0"."entity_uuid", "entity_temporal_metadata_0_0_0"."web_id")) = to_jsonb(jsonb_build_object(($3::jsonb), ($4::jsonb))))::boolean), FALSE), NULL, NULL, NULL)::continuation) AS "row" OFFSET 0) AS "continuation_4_0" -WHERE "entity_temporal_metadata_0_0_0"."transaction_time" && $1 AND "entity_temporal_metadata_0_0_0"."decision_time" && $2 AND ("continuation_4_0"."row")."filter" IS NOT FALSE +WHERE "entity_temporal_metadata_0_0_0"."transaction_time" && ($1::tstzrange) AND "entity_temporal_metadata_0_0_0"."decision_time" && ($2::tstzrange) AND ("continuation_4_0"."row")."filter" IS NOT FALSE ════ Parameters ════════════════════════════════════════════════════════════════ diff --git a/libs/@local/hashql/eval/tests/ui/postgres/entity-archived-check.aux.mir b/libs/@local/hashql/eval/tests/ui/postgres/entity-archived-check.aux.mir index e5c9cdc1591..1f0930a9178 100644 --- a/libs/@local/hashql/eval/tests/ui/postgres/entity-archived-check.aux.mir +++ b/libs/@local/hashql/eval/tests/ui/postgres/entity-archived-check.aux.mir @@ -1,5 +1,5 @@ -thunk {thunk#1}() -> ::graph::TimeAxis { - let %0: ::graph::TimeAxis +thunk {thunk#1}() -> ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes { + let %0: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes bb0(): { %0 = input LOAD time_axis @@ -21,7 +21,7 @@ fn {graph::read::filter@7}(%0: (), %1: ::graph::types::knowledge::entity::Entity thunk {thunk#3}() -> List<::graph::types::knowledge::entity::Entity> { let %0: List<::graph::types::knowledge::entity::Entity> let %1: () - let %2: ::graph::TimeAxis + let %2: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes bb0(): { %2 = input LOAD time_axis diff --git a/libs/@local/hashql/eval/tests/ui/postgres/entity-archived-check.stdout b/libs/@local/hashql/eval/tests/ui/postgres/entity-archived-check.stdout index 355aa0016a8..3ca5b2553d6 100644 --- a/libs/@local/hashql/eval/tests/ui/postgres/entity-archived-check.stdout +++ b/libs/@local/hashql/eval/tests/ui/postgres/entity-archived-check.stdout @@ -4,9 +4,9 @@ SELECT ("continuation_1_0"."row")."block" AS "continuation_1_0_block", ("continu FROM "entity_temporal_metadata" AS "entity_temporal_metadata_0_0_0" INNER JOIN "entity_editions" AS "entity_editions_0_0_1" ON "entity_editions_0_0_1"."entity_edition_id" = "entity_temporal_metadata_0_0_0"."entity_edition_id" -CROSS JOIN LATERAL (SELECT (ROW(((NOT("entity_editions_0_0_1"."archived"))::boolean), NULL, NULL, NULL)::continuation) AS "row" +CROSS JOIN LATERAL (SELECT (ROW(COALESCE(((NOT("entity_editions_0_0_1"."archived"))::boolean), FALSE), NULL, NULL, NULL)::continuation) AS "row" OFFSET 0) AS "continuation_1_0" -WHERE "entity_temporal_metadata_0_0_0"."transaction_time" && $1 AND "entity_temporal_metadata_0_0_0"."decision_time" && $2 AND ("continuation_1_0"."row")."filter" IS NOT FALSE +WHERE "entity_temporal_metadata_0_0_0"."transaction_time" && ($1::tstzrange) AND "entity_temporal_metadata_0_0_0"."decision_time" && ($2::tstzrange) AND ("continuation_1_0"."row")."filter" IS NOT FALSE ════ Parameters ════════════════════════════════════════════════════════════════ diff --git a/libs/@local/hashql/eval/tests/ui/postgres/entity-draft-id-equality.aux.mir b/libs/@local/hashql/eval/tests/ui/postgres/entity-draft-id-equality.aux.mir index 12741a18694..7bfa8544e3a 100644 --- a/libs/@local/hashql/eval/tests/ui/postgres/entity-draft-id-equality.aux.mir +++ b/libs/@local/hashql/eval/tests/ui/postgres/entity-draft-id-equality.aux.mir @@ -1,5 +1,5 @@ -thunk {thunk#1}() -> ::graph::TimeAxis { - let %0: ::graph::TimeAxis +thunk {thunk#1}() -> ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes { + let %0: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes bb0(): { %0 = input LOAD time_axis @@ -33,7 +33,7 @@ fn {graph::read::filter@7}(%0: (), %1: ::graph::types::knowledge::entity::Entity thunk {thunk#4}() -> List<::graph::types::knowledge::entity::Entity> { let %0: List<::graph::types::knowledge::entity::Entity> let %1: () - let %2: ::graph::TimeAxis + let %2: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes bb0(): { %2 = input LOAD time_axis diff --git a/libs/@local/hashql/eval/tests/ui/postgres/entity-draft-id-equality.stdout b/libs/@local/hashql/eval/tests/ui/postgres/entity-draft-id-equality.stdout index 0632230eca6..8fcadb313b4 100644 --- a/libs/@local/hashql/eval/tests/ui/postgres/entity-draft-id-equality.stdout +++ b/libs/@local/hashql/eval/tests/ui/postgres/entity-draft-id-equality.stdout @@ -2,7 +2,7 @@ SELECT "entity_temporal_metadata_0_0_0"."draft_id" AS "draft_id" FROM "entity_temporal_metadata" AS "entity_temporal_metadata_0_0_0" -WHERE "entity_temporal_metadata_0_0_0"."transaction_time" && $1 AND "entity_temporal_metadata_0_0_0"."decision_time" && $2 +WHERE "entity_temporal_metadata_0_0_0"."transaction_time" && ($1::tstzrange) AND "entity_temporal_metadata_0_0_0"."decision_time" && ($2::tstzrange) ════ Parameters ════════════════════════════════════════════════════════════════ diff --git a/libs/@local/hashql/eval/tests/ui/postgres/entity-type-ids-lateral.aux.mir b/libs/@local/hashql/eval/tests/ui/postgres/entity-type-ids-lateral.aux.mir index 2c63fe041d6..de6c0076542 100644 --- a/libs/@local/hashql/eval/tests/ui/postgres/entity-type-ids-lateral.aux.mir +++ b/libs/@local/hashql/eval/tests/ui/postgres/entity-type-ids-lateral.aux.mir @@ -1,5 +1,5 @@ -thunk {thunk#1}() -> ::graph::TimeAxis { - let %0: ::graph::TimeAxis +thunk {thunk#1}() -> ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes { + let %0: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes bb0(): { %0 = input LOAD time_axis @@ -33,7 +33,7 @@ fn {graph::read::filter@7}(%0: (), %1: ::graph::types::knowledge::entity::Entity thunk {thunk#4}() -> List<::graph::types::knowledge::entity::Entity> { let %0: List<::graph::types::knowledge::entity::Entity> let %1: () - let %2: ::graph::TimeAxis + let %2: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes bb0(): { %2 = input LOAD time_axis diff --git a/libs/@local/hashql/eval/tests/ui/postgres/entity-type-ids-lateral.stdout b/libs/@local/hashql/eval/tests/ui/postgres/entity-type-ids-lateral.stdout index 5d666552cf4..8e2ab88b4d8 100644 --- a/libs/@local/hashql/eval/tests/ui/postgres/entity-type-ids-lateral.stdout +++ b/libs/@local/hashql/eval/tests/ui/postgres/entity-type-ids-lateral.stdout @@ -2,14 +2,14 @@ SELECT ("continuation_2_0"."row")."block" AS "continuation_2_0_block", ("continuation_2_0"."row")."locals" AS "continuation_2_0_locals", ("continuation_2_0"."row")."values" AS "continuation_2_0_values" FROM "entity_temporal_metadata" AS "entity_temporal_metadata_0_0_0" -LEFT OUTER JOIN LATERAL (SELECT jsonb_agg(jsonb_build_object($4, "b", $5, "v")) AS "entity_type_ids" +LEFT OUTER JOIN LATERAL (SELECT jsonb_agg(jsonb_build_object(($4::text), "b", ($5::text), "v")) AS "entity_type_ids" FROM "entity_is_of_type_ids" AS "eit" -CROSS JOIN UNNEST("eit"."base_urls", "eit"."versions") AS "u"("b", "v") +CROSS JOIN UNNEST("eit"."base_urls", ("eit"."versions"::text[])) AS "u"("b", "v") WHERE "eit"."entity_edition_id" = "entity_temporal_metadata_0_0_0"."entity_edition_id") AS "entity_is_of_type_ids_0_0_1" ON TRUE -CROSS JOIN LATERAL (SELECT (ROW((("entity_is_of_type_ids_0_0_1"."entity_type_ids" = $3)::boolean), NULL, NULL, NULL)::continuation) AS "row" +CROSS JOIN LATERAL (SELECT (ROW(COALESCE(((to_jsonb("entity_is_of_type_ids_0_0_1"."entity_type_ids") = to_jsonb(($3::jsonb)))::boolean), FALSE), NULL, NULL, NULL)::continuation) AS "row" OFFSET 0) AS "continuation_2_0" -WHERE "entity_temporal_metadata_0_0_0"."transaction_time" && $1 AND "entity_temporal_metadata_0_0_0"."decision_time" && $2 AND ("continuation_2_0"."row")."filter" IS NOT FALSE +WHERE "entity_temporal_metadata_0_0_0"."transaction_time" && ($1::tstzrange) AND "entity_temporal_metadata_0_0_0"."decision_time" && ($2::tstzrange) AND ("continuation_2_0"."row")."filter" IS NOT FALSE ════ Parameters ════════════════════════════════════════════════════════════════ diff --git a/libs/@local/hashql/eval/tests/ui/postgres/entity-uuid-equality.aux.mir b/libs/@local/hashql/eval/tests/ui/postgres/entity-uuid-equality.aux.mir index 8c05e0ee2bc..6cad1540f5a 100644 --- a/libs/@local/hashql/eval/tests/ui/postgres/entity-uuid-equality.aux.mir +++ b/libs/@local/hashql/eval/tests/ui/postgres/entity-uuid-equality.aux.mir @@ -1,5 +1,5 @@ -thunk {thunk#1}() -> ::graph::TimeAxis { - let %0: ::graph::TimeAxis +thunk {thunk#1}() -> ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes { + let %0: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes bb0(): { %0 = input LOAD time_axis @@ -87,7 +87,7 @@ fn {graph::read::filter@7}(%0: (), %1: ::graph::types::knowledge::entity::Entity thunk {thunk#7}() -> List<::graph::types::knowledge::entity::Entity> { let %0: List<::graph::types::knowledge::entity::Entity> let %1: () - let %2: ::graph::TimeAxis + let %2: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes bb0(): { %2 = input LOAD time_axis diff --git a/libs/@local/hashql/eval/tests/ui/postgres/entity-uuid-equality.stdout b/libs/@local/hashql/eval/tests/ui/postgres/entity-uuid-equality.stdout index 751694e918e..30bad1b3f91 100644 --- a/libs/@local/hashql/eval/tests/ui/postgres/entity-uuid-equality.stdout +++ b/libs/@local/hashql/eval/tests/ui/postgres/entity-uuid-equality.stdout @@ -2,9 +2,9 @@ SELECT ("continuation_7_0"."row")."block" AS "continuation_7_0_block", ("continuation_7_0"."row")."locals" AS "continuation_7_0_locals", ("continuation_7_0"."row")."values" AS "continuation_7_0_values" FROM "entity_temporal_metadata" AS "entity_temporal_metadata_0_0_0" -CROSS JOIN LATERAL (SELECT (ROW((("entity_temporal_metadata_0_0_0"."entity_uuid" = $3)::boolean), NULL, NULL, NULL)::continuation) AS "row" +CROSS JOIN LATERAL (SELECT (ROW(COALESCE(((to_jsonb("entity_temporal_metadata_0_0_0"."entity_uuid") = to_jsonb(($3::text)))::boolean), FALSE), NULL, NULL, NULL)::continuation) AS "row" OFFSET 0) AS "continuation_7_0" -WHERE "entity_temporal_metadata_0_0_0"."transaction_time" && $1 AND "entity_temporal_metadata_0_0_0"."decision_time" && $2 AND ("continuation_7_0"."row")."filter" IS NOT FALSE +WHERE "entity_temporal_metadata_0_0_0"."transaction_time" && ($1::tstzrange) AND "entity_temporal_metadata_0_0_0"."decision_time" && ($2::tstzrange) AND ("continuation_7_0"."row")."filter" IS NOT FALSE ════ Parameters ════════════════════════════════════════════════════════════════ diff --git a/libs/@local/hashql/eval/tests/ui/postgres/entity-web-id-equality.aux.mir b/libs/@local/hashql/eval/tests/ui/postgres/entity-web-id-equality.aux.mir index 6ebcab406ec..34bd3f3f127 100644 --- a/libs/@local/hashql/eval/tests/ui/postgres/entity-web-id-equality.aux.mir +++ b/libs/@local/hashql/eval/tests/ui/postgres/entity-web-id-equality.aux.mir @@ -1,5 +1,5 @@ -thunk {thunk#1}() -> ::graph::TimeAxis { - let %0: ::graph::TimeAxis +thunk {thunk#1}() -> ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes { + let %0: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes bb0(): { %0 = input LOAD time_axis @@ -33,7 +33,7 @@ fn {graph::read::filter@7}(%0: (), %1: ::graph::types::knowledge::entity::Entity thunk {thunk#4}() -> List<::graph::types::knowledge::entity::Entity> { let %0: List<::graph::types::knowledge::entity::Entity> let %1: () - let %2: ::graph::TimeAxis + let %2: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes bb0(): { %2 = input LOAD time_axis diff --git a/libs/@local/hashql/eval/tests/ui/postgres/entity-web-id-equality.stdout b/libs/@local/hashql/eval/tests/ui/postgres/entity-web-id-equality.stdout index 9fca9c14ac6..fe5d03119a3 100644 --- a/libs/@local/hashql/eval/tests/ui/postgres/entity-web-id-equality.stdout +++ b/libs/@local/hashql/eval/tests/ui/postgres/entity-web-id-equality.stdout @@ -2,9 +2,9 @@ SELECT ("continuation_2_0"."row")."block" AS "continuation_2_0_block", ("continuation_2_0"."row")."locals" AS "continuation_2_0_locals", ("continuation_2_0"."row")."values" AS "continuation_2_0_values" FROM "entity_temporal_metadata" AS "entity_temporal_metadata_0_0_0" -CROSS JOIN LATERAL (SELECT (ROW((("entity_temporal_metadata_0_0_0"."web_id" = $3)::boolean), NULL, NULL, NULL)::continuation) AS "row" +CROSS JOIN LATERAL (SELECT (ROW(COALESCE(((to_jsonb("entity_temporal_metadata_0_0_0"."web_id") = to_jsonb(($3::jsonb)))::boolean), FALSE), NULL, NULL, NULL)::continuation) AS "row" OFFSET 0) AS "continuation_2_0" -WHERE "entity_temporal_metadata_0_0_0"."transaction_time" && $1 AND "entity_temporal_metadata_0_0_0"."decision_time" && $2 AND ("continuation_2_0"."row")."filter" IS NOT FALSE +WHERE "entity_temporal_metadata_0_0_0"."transaction_time" && ($1::tstzrange) AND "entity_temporal_metadata_0_0_0"."decision_time" && ($2::tstzrange) AND ("continuation_2_0"."row")."filter" IS NOT FALSE ════ Parameters ════════════════════════════════════════════════════════════════ diff --git a/libs/@local/hashql/eval/tests/ui/postgres/env-captured-variable.aux.mir b/libs/@local/hashql/eval/tests/ui/postgres/env-captured-variable.aux.mir index 5af838ddd8a..c51df4ddc66 100644 --- a/libs/@local/hashql/eval/tests/ui/postgres/env-captured-variable.aux.mir +++ b/libs/@local/hashql/eval/tests/ui/postgres/env-captured-variable.aux.mir @@ -9,14 +9,14 @@ fn {graph::read::filter@11}(%0: (::graph::types::knowledge::entity::EntityUuid,) } fn {graph::read::filter@27}(%0: (), %1: ::graph::types::knowledge::entity::Entity) -> Boolean { - bb0(): { // interpreter - return 1 + bb0(): { // postgres + return true } } thunk {thunk#8}() -> List<::graph::types::knowledge::entity::Entity> { let %0: ::graph::types::knowledge::entity::EntityUuid - let %1: ::graph::TimeAxis + let %1: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes let %2: List<::graph::types::knowledge::entity::Entity> let %3: (::graph::types::knowledge::entity::EntityUuid,) diff --git a/libs/@local/hashql/eval/tests/ui/postgres/env-captured-variable.stdout b/libs/@local/hashql/eval/tests/ui/postgres/env-captured-variable.stdout index bb92d00015d..aced634948f 100644 --- a/libs/@local/hashql/eval/tests/ui/postgres/env-captured-variable.stdout +++ b/libs/@local/hashql/eval/tests/ui/postgres/env-captured-variable.stdout @@ -2,12 +2,12 @@ SELECT ("continuation_0_0"."row")."block" AS "continuation_0_0_block", ("continuation_0_0"."row")."locals" AS "continuation_0_0_locals", ("continuation_0_0"."row")."values" AS "continuation_0_0_values" FROM "entity_temporal_metadata" AS "entity_temporal_metadata_0_0_0" -CROSS JOIN LATERAL (SELECT (ROW((("entity_temporal_metadata_0_0_0"."entity_uuid" = $3)::boolean), NULL, NULL, NULL)::continuation) AS "row" +CROSS JOIN LATERAL (SELECT (ROW(COALESCE(((to_jsonb("entity_temporal_metadata_0_0_0"."entity_uuid") = to_jsonb(($3::jsonb)))::boolean), FALSE), NULL, NULL, NULL)::continuation) AS "row" OFFSET 0) AS "continuation_0_0" -WHERE "entity_temporal_metadata_0_0_0"."transaction_time" && $1 AND "entity_temporal_metadata_0_0_0"."decision_time" && $2 AND ("continuation_0_0"."row")."filter" IS NOT FALSE +WHERE "entity_temporal_metadata_0_0_0"."transaction_time" && ($1::tstzrange) AND "entity_temporal_metadata_0_0_0"."decision_time" && ($2::tstzrange) AND ("continuation_0_0"."row")."filter" IS NOT FALSE ════ Parameters ════════════════════════════════════════════════════════════════ $1: TemporalAxis(Transaction) $2: TemporalAxis(Decision) -$3: Env(0, #0) +$3: Env(%3, #0) diff --git a/libs/@local/hashql/eval/tests/ui/postgres/if-input-branches.aux.mir b/libs/@local/hashql/eval/tests/ui/postgres/if-input-branches.aux.mir index d1e8ae0ff3e..a37e4c830d1 100644 --- a/libs/@local/hashql/eval/tests/ui/postgres/if-input-branches.aux.mir +++ b/libs/@local/hashql/eval/tests/ui/postgres/if-input-branches.aux.mir @@ -1,5 +1,5 @@ -thunk {thunk#1}() -> ::graph::TimeAxis { - let %0: ::graph::TimeAxis +thunk {thunk#1}() -> ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes { + let %0: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes bb0(): { %0 = input LOAD time_axis @@ -49,7 +49,7 @@ fn {graph::read::filter@7}(%0: (), %1: ::graph::types::knowledge::entity::Entity thunk {thunk#8}() -> List<::graph::types::knowledge::entity::Entity> { let %0: List<::graph::types::knowledge::entity::Entity> let %1: () - let %2: ::graph::TimeAxis + let %2: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes bb0(): { %2 = input LOAD time_axis diff --git a/libs/@local/hashql/eval/tests/ui/postgres/if-input-branches.stdout b/libs/@local/hashql/eval/tests/ui/postgres/if-input-branches.stdout index 6c87d1f0131..87a155ae195 100644 --- a/libs/@local/hashql/eval/tests/ui/postgres/if-input-branches.stdout +++ b/libs/@local/hashql/eval/tests/ui/postgres/if-input-branches.stdout @@ -2,9 +2,9 @@ SELECT ("continuation_2_0"."row")."block" AS "continuation_2_0_block", ("continuation_2_0"."row")."locals" AS "continuation_2_0_locals", ("continuation_2_0"."row")."values" AS "continuation_2_0_values" FROM "entity_temporal_metadata" AS "entity_temporal_metadata_0_0_0" -CROSS JOIN LATERAL (SELECT CASE WHEN (($3)::int) = 0 THEN (ROW((("entity_temporal_metadata_0_0_0"."entity_uuid" = $4)::boolean), NULL, NULL, NULL)::continuation) WHEN (($3)::int) = 1 THEN (ROW((("entity_temporal_metadata_0_0_0"."entity_uuid" = $5)::boolean), NULL, NULL, NULL)::continuation) END AS "row" +CROSS JOIN LATERAL (SELECT CASE WHEN ((($3::jsonb))::int) IS NULL THEN (ROW(COALESCE(((FALSE)::boolean), FALSE), NULL, NULL, NULL)::continuation) WHEN ((($3::jsonb))::int) = 0 THEN (ROW(COALESCE(((to_jsonb("entity_temporal_metadata_0_0_0"."entity_uuid") = to_jsonb(($4::jsonb)))::boolean), FALSE), NULL, NULL, NULL)::continuation) WHEN ((($3::jsonb))::int) = 1 THEN (ROW(COALESCE(((to_jsonb("entity_temporal_metadata_0_0_0"."entity_uuid") = to_jsonb(($5::jsonb)))::boolean), FALSE), NULL, NULL, NULL)::continuation) END AS "row" OFFSET 0) AS "continuation_2_0" -WHERE "entity_temporal_metadata_0_0_0"."transaction_time" && $1 AND "entity_temporal_metadata_0_0_0"."decision_time" && $2 AND ("continuation_2_0"."row")."filter" IS NOT FALSE +WHERE "entity_temporal_metadata_0_0_0"."transaction_time" && ($1::tstzrange) AND "entity_temporal_metadata_0_0_0"."decision_time" && ($2::tstzrange) AND ("continuation_2_0"."row")."filter" IS NOT FALSE ════ Parameters ════════════════════════════════════════════════════════════════ diff --git a/libs/@local/hashql/eval/tests/ui/postgres/input-parameter-exists.aux.mir b/libs/@local/hashql/eval/tests/ui/postgres/input-parameter-exists.aux.mir index 702591e451a..3bc0c683046 100644 --- a/libs/@local/hashql/eval/tests/ui/postgres/input-parameter-exists.aux.mir +++ b/libs/@local/hashql/eval/tests/ui/postgres/input-parameter-exists.aux.mir @@ -1,5 +1,5 @@ -thunk {thunk#1}() -> ::graph::TimeAxis { - let %0: ::graph::TimeAxis +thunk {thunk#1}() -> ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes { + let %0: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes bb0(): { %0 = input LOAD time_axis @@ -35,7 +35,7 @@ thunk {thunk#4}() -> Boolean { } bb2(): { - return 1 + return true } } @@ -56,14 +56,14 @@ fn {graph::read::filter@7}(%0: (), %1: ::graph::types::knowledge::entity::Entity } bb2(): { // postgres - return 1 + return true } } thunk {thunk#5}() -> List<::graph::types::knowledge::entity::Entity> { let %0: List<::graph::types::knowledge::entity::Entity> let %1: () - let %2: ::graph::TimeAxis + let %2: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes bb0(): { %2 = input LOAD time_axis diff --git a/libs/@local/hashql/eval/tests/ui/postgres/input-parameter-exists.stdout b/libs/@local/hashql/eval/tests/ui/postgres/input-parameter-exists.stdout index 148c2f48505..c486a8c507f 100644 --- a/libs/@local/hashql/eval/tests/ui/postgres/input-parameter-exists.stdout +++ b/libs/@local/hashql/eval/tests/ui/postgres/input-parameter-exists.stdout @@ -2,9 +2,9 @@ SELECT ("continuation_3_0"."row")."block" AS "continuation_3_0_block", ("continuation_3_0"."row")."locals" AS "continuation_3_0_locals", ("continuation_3_0"."row")."values" AS "continuation_3_0_values" FROM "entity_temporal_metadata" AS "entity_temporal_metadata_0_0_0" -CROSS JOIN LATERAL (SELECT CASE WHEN (($3 IS NOT NULL)::int) = 0 THEN (ROW(((1)::boolean), NULL, NULL, NULL)::continuation) WHEN (($3 IS NOT NULL)::int) = 1 THEN (ROW((($3)::boolean), NULL, NULL, NULL)::continuation) END AS "row" +CROSS JOIN LATERAL (SELECT CASE WHEN ((($3::jsonb) IS NOT NULL)::int) IS NULL THEN (ROW(COALESCE(((FALSE)::boolean), FALSE), NULL, NULL, NULL)::continuation) WHEN ((($3::jsonb) IS NOT NULL)::int) = 0 THEN (ROW(COALESCE(((1)::boolean), FALSE), NULL, NULL, NULL)::continuation) WHEN ((($3::jsonb) IS NOT NULL)::int) = 1 THEN (ROW(COALESCE(((($3::jsonb))::boolean), FALSE), NULL, NULL, NULL)::continuation) END AS "row" OFFSET 0) AS "continuation_3_0" -WHERE "entity_temporal_metadata_0_0_0"."transaction_time" && $1 AND "entity_temporal_metadata_0_0_0"."decision_time" && $2 AND ("continuation_3_0"."row")."filter" IS NOT FALSE +WHERE "entity_temporal_metadata_0_0_0"."transaction_time" && ($1::tstzrange) AND "entity_temporal_metadata_0_0_0"."decision_time" && ($2::tstzrange) AND ("continuation_3_0"."row")."filter" IS NOT FALSE ════ Parameters ════════════════════════════════════════════════════════════════ diff --git a/libs/@local/hashql/eval/tests/ui/postgres/input-parameter-load.aux.mir b/libs/@local/hashql/eval/tests/ui/postgres/input-parameter-load.aux.mir index 5bd46f8214a..44c93a8aa9f 100644 --- a/libs/@local/hashql/eval/tests/ui/postgres/input-parameter-load.aux.mir +++ b/libs/@local/hashql/eval/tests/ui/postgres/input-parameter-load.aux.mir @@ -1,5 +1,5 @@ -thunk {thunk#1}() -> ::graph::TimeAxis { - let %0: ::graph::TimeAxis +thunk {thunk#1}() -> ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes { + let %0: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes bb0(): { %0 = input LOAD time_axis @@ -33,7 +33,7 @@ fn {graph::read::filter@7}(%0: (), %1: ::graph::types::knowledge::entity::Entity thunk {thunk#4}() -> List<::graph::types::knowledge::entity::Entity> { let %0: List<::graph::types::knowledge::entity::Entity> let %1: () - let %2: ::graph::TimeAxis + let %2: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes bb0(): { %2 = input LOAD time_axis diff --git a/libs/@local/hashql/eval/tests/ui/postgres/input-parameter-load.stdout b/libs/@local/hashql/eval/tests/ui/postgres/input-parameter-load.stdout index bd0a1866e48..c4ada3afc65 100644 --- a/libs/@local/hashql/eval/tests/ui/postgres/input-parameter-load.stdout +++ b/libs/@local/hashql/eval/tests/ui/postgres/input-parameter-load.stdout @@ -2,9 +2,9 @@ SELECT ("continuation_2_0"."row")."block" AS "continuation_2_0_block", ("continuation_2_0"."row")."locals" AS "continuation_2_0_locals", ("continuation_2_0"."row")."values" AS "continuation_2_0_values" FROM "entity_temporal_metadata" AS "entity_temporal_metadata_0_0_0" -CROSS JOIN LATERAL (SELECT (ROW((("entity_temporal_metadata_0_0_0"."entity_uuid" = $3)::boolean), NULL, NULL, NULL)::continuation) AS "row" +CROSS JOIN LATERAL (SELECT (ROW(COALESCE(((to_jsonb("entity_temporal_metadata_0_0_0"."entity_uuid") = to_jsonb(($3::jsonb)))::boolean), FALSE), NULL, NULL, NULL)::continuation) AS "row" OFFSET 0) AS "continuation_2_0" -WHERE "entity_temporal_metadata_0_0_0"."transaction_time" && $1 AND "entity_temporal_metadata_0_0_0"."decision_time" && $2 AND ("continuation_2_0"."row")."filter" IS NOT FALSE +WHERE "entity_temporal_metadata_0_0_0"."transaction_time" && ($1::tstzrange) AND "entity_temporal_metadata_0_0_0"."decision_time" && ($2::tstzrange) AND ("continuation_2_0"."row")."filter" IS NOT FALSE ════ Parameters ════════════════════════════════════════════════════════════════ diff --git a/libs/@local/hashql/eval/tests/ui/postgres/let-binding-propagation.aux.mir b/libs/@local/hashql/eval/tests/ui/postgres/let-binding-propagation.aux.mir index 99c0ab174d5..090f32ef138 100644 --- a/libs/@local/hashql/eval/tests/ui/postgres/let-binding-propagation.aux.mir +++ b/libs/@local/hashql/eval/tests/ui/postgres/let-binding-propagation.aux.mir @@ -1,5 +1,5 @@ -thunk {thunk#2}() -> ::graph::TimeAxis { - let %0: ::graph::TimeAxis +thunk {thunk#2}() -> ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes { + let %0: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes bb0(): { %0 = input LOAD time_axis @@ -33,7 +33,7 @@ fn {graph::read::filter@7}(%0: (), %1: ::graph::types::knowledge::entity::Entity thunk {thunk#4}() -> List<::graph::types::knowledge::entity::Entity> { let %0: List<::graph::types::knowledge::entity::Entity> let %1: () - let %2: ::graph::TimeAxis + let %2: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes bb0(): { %2 = input LOAD time_axis diff --git a/libs/@local/hashql/eval/tests/ui/postgres/let-binding-propagation.stdout b/libs/@local/hashql/eval/tests/ui/postgres/let-binding-propagation.stdout index bd0a1866e48..c4ada3afc65 100644 --- a/libs/@local/hashql/eval/tests/ui/postgres/let-binding-propagation.stdout +++ b/libs/@local/hashql/eval/tests/ui/postgres/let-binding-propagation.stdout @@ -2,9 +2,9 @@ SELECT ("continuation_2_0"."row")."block" AS "continuation_2_0_block", ("continuation_2_0"."row")."locals" AS "continuation_2_0_locals", ("continuation_2_0"."row")."values" AS "continuation_2_0_values" FROM "entity_temporal_metadata" AS "entity_temporal_metadata_0_0_0" -CROSS JOIN LATERAL (SELECT (ROW((("entity_temporal_metadata_0_0_0"."entity_uuid" = $3)::boolean), NULL, NULL, NULL)::continuation) AS "row" +CROSS JOIN LATERAL (SELECT (ROW(COALESCE(((to_jsonb("entity_temporal_metadata_0_0_0"."entity_uuid") = to_jsonb(($3::jsonb)))::boolean), FALSE), NULL, NULL, NULL)::continuation) AS "row" OFFSET 0) AS "continuation_2_0" -WHERE "entity_temporal_metadata_0_0_0"."transaction_time" && $1 AND "entity_temporal_metadata_0_0_0"."decision_time" && $2 AND ("continuation_2_0"."row")."filter" IS NOT FALSE +WHERE "entity_temporal_metadata_0_0_0"."transaction_time" && ($1::tstzrange) AND "entity_temporal_metadata_0_0_0"."decision_time" && ($2::tstzrange) AND ("continuation_2_0"."row")."filter" IS NOT FALSE ════ Parameters ════════════════════════════════════════════════════════════════ diff --git a/libs/@local/hashql/eval/tests/ui/postgres/list-construction.aux.mir b/libs/@local/hashql/eval/tests/ui/postgres/list-construction.aux.mir index 304c2591a3b..129a0800977 100644 --- a/libs/@local/hashql/eval/tests/ui/postgres/list-construction.aux.mir +++ b/libs/@local/hashql/eval/tests/ui/postgres/list-construction.aux.mir @@ -1,5 +1,5 @@ -thunk {thunk#1}() -> ::graph::TimeAxis { - let %0: ::graph::TimeAxis +thunk {thunk#1}() -> ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes { + let %0: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes bb0(): { %0 = input LOAD time_axis @@ -49,7 +49,7 @@ fn {graph::read::filter@7}(%0: (), %1: ::graph::types::knowledge::entity::Entity thunk {thunk#7}() -> List<::graph::types::knowledge::entity::Entity> { let %0: List<::graph::types::knowledge::entity::Entity> let %1: () - let %2: ::graph::TimeAxis + let %2: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes bb0(): { %2 = input LOAD time_axis diff --git a/libs/@local/hashql/eval/tests/ui/postgres/list-construction.stdout b/libs/@local/hashql/eval/tests/ui/postgres/list-construction.stdout index 6c3997b7dc0..1d748250778 100644 --- a/libs/@local/hashql/eval/tests/ui/postgres/list-construction.stdout +++ b/libs/@local/hashql/eval/tests/ui/postgres/list-construction.stdout @@ -2,9 +2,9 @@ SELECT ("continuation_3_0"."row")."block" AS "continuation_3_0_block", ("continuation_3_0"."row")."locals" AS "continuation_3_0_locals", ("continuation_3_0"."row")."values" AS "continuation_3_0_values" FROM "entity_temporal_metadata" AS "entity_temporal_metadata_0_0_0" -CROSS JOIN LATERAL (SELECT (ROW(((jsonb_build_array("entity_temporal_metadata_0_0_0"."entity_uuid", $3) = jsonb_build_array($4, "entity_temporal_metadata_0_0_0"."entity_uuid"))::boolean), NULL, NULL, NULL)::continuation) AS "row" +CROSS JOIN LATERAL (SELECT (ROW(COALESCE(((to_jsonb(jsonb_build_array("entity_temporal_metadata_0_0_0"."entity_uuid", ($3::jsonb))) = to_jsonb(jsonb_build_array(($4::jsonb), "entity_temporal_metadata_0_0_0"."entity_uuid")))::boolean), FALSE), NULL, NULL, NULL)::continuation) AS "row" OFFSET 0) AS "continuation_3_0" -WHERE "entity_temporal_metadata_0_0_0"."transaction_time" && $1 AND "entity_temporal_metadata_0_0_0"."decision_time" && $2 AND ("continuation_3_0"."row")."filter" IS NOT FALSE +WHERE "entity_temporal_metadata_0_0_0"."transaction_time" && ($1::tstzrange) AND "entity_temporal_metadata_0_0_0"."decision_time" && ($2::tstzrange) AND ("continuation_3_0"."row")."filter" IS NOT FALSE ════ Parameters ════════════════════════════════════════════════════════════════ diff --git a/libs/@local/hashql/eval/tests/ui/postgres/logical-and-inputs.aux.mir b/libs/@local/hashql/eval/tests/ui/postgres/logical-and-inputs.aux.mir index ef01d32c99d..eff60fbb2ea 100644 --- a/libs/@local/hashql/eval/tests/ui/postgres/logical-and-inputs.aux.mir +++ b/libs/@local/hashql/eval/tests/ui/postgres/logical-and-inputs.aux.mir @@ -1,5 +1,5 @@ -thunk {thunk#1}() -> ::graph::TimeAxis { - let %0: ::graph::TimeAxis +thunk {thunk#1}() -> ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes { + let %0: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes bb0(): { %0 = input LOAD time_axis @@ -35,7 +35,7 @@ thunk {thunk#4}() -> Boolean { } bb2(): { - return 0 + return false } } @@ -56,14 +56,14 @@ fn {graph::read::filter@7}(%0: (), %1: ::graph::types::knowledge::entity::Entity } bb2(): { // postgres - return 0 + return false } } thunk {thunk#5}() -> List<::graph::types::knowledge::entity::Entity> { let %0: List<::graph::types::knowledge::entity::Entity> let %1: () - let %2: ::graph::TimeAxis + let %2: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes bb0(): { %2 = input LOAD time_axis diff --git a/libs/@local/hashql/eval/tests/ui/postgres/logical-and-inputs.stdout b/libs/@local/hashql/eval/tests/ui/postgres/logical-and-inputs.stdout index 44e9406d201..294cd646a29 100644 --- a/libs/@local/hashql/eval/tests/ui/postgres/logical-and-inputs.stdout +++ b/libs/@local/hashql/eval/tests/ui/postgres/logical-and-inputs.stdout @@ -2,9 +2,9 @@ SELECT ("continuation_3_0"."row")."block" AS "continuation_3_0_block", ("continuation_3_0"."row")."locals" AS "continuation_3_0_locals", ("continuation_3_0"."row")."values" AS "continuation_3_0_values" FROM "entity_temporal_metadata" AS "entity_temporal_metadata_0_0_0" -CROSS JOIN LATERAL (SELECT CASE WHEN (($3)::int) = 0 THEN (ROW(((0)::boolean), NULL, NULL, NULL)::continuation) WHEN (($3)::int) = 1 THEN (ROW((($4)::boolean), NULL, NULL, NULL)::continuation) END AS "row" +CROSS JOIN LATERAL (SELECT CASE WHEN ((($3::jsonb))::int) IS NULL THEN (ROW(COALESCE(((FALSE)::boolean), FALSE), NULL, NULL, NULL)::continuation) WHEN ((($3::jsonb))::int) = 0 THEN (ROW(COALESCE(((0)::boolean), FALSE), NULL, NULL, NULL)::continuation) WHEN ((($3::jsonb))::int) = 1 THEN (ROW(COALESCE(((($4::jsonb))::boolean), FALSE), NULL, NULL, NULL)::continuation) END AS "row" OFFSET 0) AS "continuation_3_0" -WHERE "entity_temporal_metadata_0_0_0"."transaction_time" && $1 AND "entity_temporal_metadata_0_0_0"."decision_time" && $2 AND ("continuation_3_0"."row")."filter" IS NOT FALSE +WHERE "entity_temporal_metadata_0_0_0"."transaction_time" && ($1::tstzrange) AND "entity_temporal_metadata_0_0_0"."decision_time" && ($2::tstzrange) AND ("continuation_3_0"."row")."filter" IS NOT FALSE ════ Parameters ════════════════════════════════════════════════════════════════ diff --git a/libs/@local/hashql/eval/tests/ui/postgres/minimal-select-no-extra-joins.aux.mir b/libs/@local/hashql/eval/tests/ui/postgres/minimal-select-no-extra-joins.aux.mir index 1b70eb198c4..e8e26e5f88f 100644 --- a/libs/@local/hashql/eval/tests/ui/postgres/minimal-select-no-extra-joins.aux.mir +++ b/libs/@local/hashql/eval/tests/ui/postgres/minimal-select-no-extra-joins.aux.mir @@ -1,5 +1,5 @@ -thunk {thunk#1}() -> ::graph::TimeAxis { - let %0: ::graph::TimeAxis +thunk {thunk#1}() -> ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes { + let %0: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes bb0(): { %0 = input LOAD time_axis @@ -33,7 +33,7 @@ fn {graph::read::filter@7}(%0: (), %1: ::graph::types::knowledge::entity::Entity thunk {thunk#4}() -> List<::graph::types::knowledge::entity::Entity> { let %0: List<::graph::types::knowledge::entity::Entity> let %1: () - let %2: ::graph::TimeAxis + let %2: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes bb0(): { %2 = input LOAD time_axis diff --git a/libs/@local/hashql/eval/tests/ui/postgres/minimal-select-no-extra-joins.stdout b/libs/@local/hashql/eval/tests/ui/postgres/minimal-select-no-extra-joins.stdout index 976e9859736..e5c6bb7f053 100644 --- a/libs/@local/hashql/eval/tests/ui/postgres/minimal-select-no-extra-joins.stdout +++ b/libs/@local/hashql/eval/tests/ui/postgres/minimal-select-no-extra-joins.stdout @@ -2,9 +2,9 @@ SELECT ("continuation_2_0"."row")."block" AS "continuation_2_0_block", ("continuation_2_0"."row")."locals" AS "continuation_2_0_locals", ("continuation_2_0"."row")."values" AS "continuation_2_0_values" FROM "entity_temporal_metadata" AS "entity_temporal_metadata_0_0_0" -CROSS JOIN LATERAL (SELECT (ROW((("entity_temporal_metadata_0_0_0"."web_id" = $3)::boolean), NULL, NULL, NULL)::continuation) AS "row" +CROSS JOIN LATERAL (SELECT (ROW(COALESCE(((to_jsonb("entity_temporal_metadata_0_0_0"."web_id") = to_jsonb(($3::jsonb)))::boolean), FALSE), NULL, NULL, NULL)::continuation) AS "row" OFFSET 0) AS "continuation_2_0" -WHERE "entity_temporal_metadata_0_0_0"."transaction_time" && $1 AND "entity_temporal_metadata_0_0_0"."decision_time" && $2 AND ("continuation_2_0"."row")."filter" IS NOT FALSE +WHERE "entity_temporal_metadata_0_0_0"."transaction_time" && ($1::tstzrange) AND "entity_temporal_metadata_0_0_0"."decision_time" && ($2::tstzrange) AND ("continuation_2_0"."row")."filter" IS NOT FALSE ════ Parameters ════════════════════════════════════════════════════════════════ diff --git a/libs/@local/hashql/eval/tests/ui/postgres/mixed-sources-filter.aux.mir b/libs/@local/hashql/eval/tests/ui/postgres/mixed-sources-filter.aux.mir index 7e038965ce3..aa1758bc481 100644 --- a/libs/@local/hashql/eval/tests/ui/postgres/mixed-sources-filter.aux.mir +++ b/libs/@local/hashql/eval/tests/ui/postgres/mixed-sources-filter.aux.mir @@ -19,14 +19,14 @@ fn {graph::read::filter@20}(%0: (::graph::types::knowledge::entity::EntityUuid,) } fn {graph::read::filter@36}(%0: (), %1: ::graph::types::knowledge::entity::Entity) -> Boolean { - bb0(): { // interpreter - return 1 + bb0(): { // postgres + return true } } thunk {thunk#10}() -> List<::graph::types::knowledge::entity::Entity> { let %0: ::graph::types::knowledge::entity::EntityUuid - let %1: ::graph::TimeAxis + let %1: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes let %2: List<::graph::types::knowledge::entity::Entity> let %3: () let %4: (::graph::types::knowledge::entity::EntityUuid,) diff --git a/libs/@local/hashql/eval/tests/ui/postgres/mixed-sources-filter.stdout b/libs/@local/hashql/eval/tests/ui/postgres/mixed-sources-filter.stdout index 75feded7550..8a609b8857f 100644 --- a/libs/@local/hashql/eval/tests/ui/postgres/mixed-sources-filter.stdout +++ b/libs/@local/hashql/eval/tests/ui/postgres/mixed-sources-filter.stdout @@ -4,14 +4,14 @@ SELECT ("continuation_0_0"."row")."block" AS "continuation_0_0_block", ("continu FROM "entity_temporal_metadata" AS "entity_temporal_metadata_0_0_0" INNER JOIN "entity_editions" AS "entity_editions_0_0_1" ON "entity_editions_0_0_1"."entity_edition_id" = "entity_temporal_metadata_0_0_0"."entity_edition_id" -CROSS JOIN LATERAL (SELECT (ROW(((NOT("entity_editions_0_0_1"."archived"))::boolean), NULL, NULL, NULL)::continuation) AS "row" +CROSS JOIN LATERAL (SELECT (ROW(COALESCE(((NOT("entity_editions_0_0_1"."archived"))::boolean), FALSE), NULL, NULL, NULL)::continuation) AS "row" OFFSET 0) AS "continuation_0_0" -CROSS JOIN LATERAL (SELECT (ROW((("entity_temporal_metadata_0_0_0"."entity_uuid" = $3)::boolean), NULL, NULL, NULL)::continuation) AS "row" +CROSS JOIN LATERAL (SELECT (ROW(COALESCE(((to_jsonb("entity_temporal_metadata_0_0_0"."entity_uuid") = to_jsonb(($3::jsonb)))::boolean), FALSE), NULL, NULL, NULL)::continuation) AS "row" OFFSET 0) AS "continuation_1_0" -WHERE "entity_temporal_metadata_0_0_0"."transaction_time" && $1 AND "entity_temporal_metadata_0_0_0"."decision_time" && $2 AND ("continuation_0_0"."row")."filter" IS NOT FALSE AND ("continuation_1_0"."row")."filter" IS NOT FALSE +WHERE "entity_temporal_metadata_0_0_0"."transaction_time" && ($1::tstzrange) AND "entity_temporal_metadata_0_0_0"."decision_time" && ($2::tstzrange) AND ("continuation_0_0"."row")."filter" IS NOT FALSE AND ("continuation_1_0"."row")."filter" IS NOT FALSE ════ Parameters ════════════════════════════════════════════════════════════════ $1: TemporalAxis(Transaction) $2: TemporalAxis(Decision) -$3: Env(1, #0) +$3: Env(%4, #0) diff --git a/libs/@local/hashql/eval/tests/ui/postgres/multiple-filters.aux.mir b/libs/@local/hashql/eval/tests/ui/postgres/multiple-filters.aux.mir index b35b02a348c..1c709a3ea81 100644 --- a/libs/@local/hashql/eval/tests/ui/postgres/multiple-filters.aux.mir +++ b/libs/@local/hashql/eval/tests/ui/postgres/multiple-filters.aux.mir @@ -1,5 +1,5 @@ -thunk {thunk#2}() -> ::graph::TimeAxis { - let %0: ::graph::TimeAxis +thunk {thunk#2}() -> ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes { + let %0: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes bb0(): { %0 = input LOAD time_axis @@ -56,7 +56,7 @@ thunk {thunk#7}() -> List<::graph::types::knowledge::entity::Entity> { let %0: List<::graph::types::knowledge::entity::Entity> let %1: () let %2: () - let %3: ::graph::TimeAxis + let %3: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes bb0(): { %3 = input LOAD time_axis diff --git a/libs/@local/hashql/eval/tests/ui/postgres/multiple-filters.stdout b/libs/@local/hashql/eval/tests/ui/postgres/multiple-filters.stdout index 528d2e7d33b..10036eef5ac 100644 --- a/libs/@local/hashql/eval/tests/ui/postgres/multiple-filters.stdout +++ b/libs/@local/hashql/eval/tests/ui/postgres/multiple-filters.stdout @@ -2,11 +2,11 @@ SELECT ("continuation_3_0"."row")."block" AS "continuation_3_0_block", ("continuation_3_0"."row")."locals" AS "continuation_3_0_locals", ("continuation_3_0"."row")."values" AS "continuation_3_0_values", ("continuation_4_0"."row")."block" AS "continuation_4_0_block", ("continuation_4_0"."row")."locals" AS "continuation_4_0_locals", ("continuation_4_0"."row")."values" AS "continuation_4_0_values" FROM "entity_temporal_metadata" AS "entity_temporal_metadata_0_0_0" -CROSS JOIN LATERAL (SELECT (ROW((("entity_temporal_metadata_0_0_0"."entity_uuid" = $3)::boolean), NULL, NULL, NULL)::continuation) AS "row" +CROSS JOIN LATERAL (SELECT (ROW(COALESCE(((to_jsonb("entity_temporal_metadata_0_0_0"."entity_uuid") = to_jsonb(($3::jsonb)))::boolean), FALSE), NULL, NULL, NULL)::continuation) AS "row" OFFSET 0) AS "continuation_3_0" -CROSS JOIN LATERAL (SELECT (ROW((("entity_temporal_metadata_0_0_0"."web_id" = $4)::boolean), NULL, NULL, NULL)::continuation) AS "row" +CROSS JOIN LATERAL (SELECT (ROW(COALESCE(((to_jsonb("entity_temporal_metadata_0_0_0"."web_id") = to_jsonb(($4::jsonb)))::boolean), FALSE), NULL, NULL, NULL)::continuation) AS "row" OFFSET 0) AS "continuation_4_0" -WHERE "entity_temporal_metadata_0_0_0"."transaction_time" && $1 AND "entity_temporal_metadata_0_0_0"."decision_time" && $2 AND ("continuation_3_0"."row")."filter" IS NOT FALSE AND ("continuation_4_0"."row")."filter" IS NOT FALSE +WHERE "entity_temporal_metadata_0_0_0"."transaction_time" && ($1::tstzrange) AND "entity_temporal_metadata_0_0_0"."decision_time" && ($2::tstzrange) AND ("continuation_3_0"."row")."filter" IS NOT FALSE AND ("continuation_4_0"."row")."filter" IS NOT FALSE ════ Parameters ════════════════════════════════════════════════════════════════ diff --git a/libs/@local/hashql/eval/tests/ui/postgres/nested-if-input-branches.aux.mir b/libs/@local/hashql/eval/tests/ui/postgres/nested-if-input-branches.aux.mir index e5f2fb7b56a..22203d05ab6 100644 --- a/libs/@local/hashql/eval/tests/ui/postgres/nested-if-input-branches.aux.mir +++ b/libs/@local/hashql/eval/tests/ui/postgres/nested-if-input-branches.aux.mir @@ -1,5 +1,5 @@ -thunk {thunk#1}() -> ::graph::TimeAxis { - let %0: ::graph::TimeAxis +thunk {thunk#1}() -> ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes { + let %0: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes bb0(): { %0 = input LOAD time_axis @@ -65,7 +65,7 @@ fn {graph::read::filter@7}(%0: (), %1: ::graph::types::knowledge::entity::Entity thunk {thunk#12}() -> List<::graph::types::knowledge::entity::Entity> { let %0: List<::graph::types::knowledge::entity::Entity> let %1: () - let %2: ::graph::TimeAxis + let %2: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes bb0(): { %2 = input LOAD time_axis diff --git a/libs/@local/hashql/eval/tests/ui/postgres/nested-if-input-branches.stdout b/libs/@local/hashql/eval/tests/ui/postgres/nested-if-input-branches.stdout index a3e812791fe..acbe1e351eb 100644 --- a/libs/@local/hashql/eval/tests/ui/postgres/nested-if-input-branches.stdout +++ b/libs/@local/hashql/eval/tests/ui/postgres/nested-if-input-branches.stdout @@ -2,9 +2,9 @@ SELECT ("continuation_2_0"."row")."block" AS "continuation_2_0_block", ("continuation_2_0"."row")."locals" AS "continuation_2_0_locals", ("continuation_2_0"."row")."values" AS "continuation_2_0_values" FROM "entity_temporal_metadata" AS "entity_temporal_metadata_0_0_0" -CROSS JOIN LATERAL (SELECT CASE WHEN (($3)::int) = 0 THEN (ROW((("entity_temporal_metadata_0_0_0"."entity_uuid" = $4)::boolean), NULL, NULL, NULL)::continuation) WHEN (($3)::int) = 1 THEN CASE WHEN (($5)::int) = 0 THEN (ROW((("entity_temporal_metadata_0_0_0"."entity_uuid" = $6)::boolean), NULL, NULL, NULL)::continuation) WHEN (($5)::int) = 1 THEN (ROW((("entity_temporal_metadata_0_0_0"."entity_uuid" = $7)::boolean), NULL, NULL, NULL)::continuation) END END AS "row" +CROSS JOIN LATERAL (SELECT CASE WHEN ((($3::jsonb))::int) IS NULL THEN (ROW(COALESCE(((FALSE)::boolean), FALSE), NULL, NULL, NULL)::continuation) WHEN ((($3::jsonb))::int) = 0 THEN (ROW(COALESCE(((to_jsonb("entity_temporal_metadata_0_0_0"."entity_uuid") = to_jsonb(($4::jsonb)))::boolean), FALSE), NULL, NULL, NULL)::continuation) WHEN ((($3::jsonb))::int) = 1 THEN CASE WHEN ((($5::jsonb))::int) IS NULL THEN (ROW(COALESCE(((FALSE)::boolean), FALSE), NULL, NULL, NULL)::continuation) WHEN ((($5::jsonb))::int) = 0 THEN (ROW(COALESCE(((to_jsonb("entity_temporal_metadata_0_0_0"."entity_uuid") = to_jsonb(($6::jsonb)))::boolean), FALSE), NULL, NULL, NULL)::continuation) WHEN ((($5::jsonb))::int) = 1 THEN (ROW(COALESCE(((to_jsonb("entity_temporal_metadata_0_0_0"."entity_uuid") = to_jsonb(($7::jsonb)))::boolean), FALSE), NULL, NULL, NULL)::continuation) END END AS "row" OFFSET 0) AS "continuation_2_0" -WHERE "entity_temporal_metadata_0_0_0"."transaction_time" && $1 AND "entity_temporal_metadata_0_0_0"."decision_time" && $2 AND ("continuation_2_0"."row")."filter" IS NOT FALSE +WHERE "entity_temporal_metadata_0_0_0"."transaction_time" && ($1::tstzrange) AND "entity_temporal_metadata_0_0_0"."decision_time" && ($2::tstzrange) AND ("continuation_2_0"."row")."filter" IS NOT FALSE ════ Parameters ════════════════════════════════════════════════════════════════ diff --git a/libs/@local/hashql/eval/tests/ui/postgres/opaque-passthrough.aux.mir b/libs/@local/hashql/eval/tests/ui/postgres/opaque-passthrough.aux.mir index fda48bf5412..660d39aa265 100644 --- a/libs/@local/hashql/eval/tests/ui/postgres/opaque-passthrough.aux.mir +++ b/libs/@local/hashql/eval/tests/ui/postgres/opaque-passthrough.aux.mir @@ -1,5 +1,5 @@ -thunk {thunk#1}() -> ::graph::TimeAxis { - let %0: ::graph::TimeAxis +thunk {thunk#1}() -> ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes { + let %0: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes bb0(): { %0 = input LOAD time_axis @@ -103,7 +103,7 @@ fn {graph::read::filter@7}(%0: (), %1: ::graph::types::knowledge::entity::Entity thunk {thunk#8}() -> List<::graph::types::knowledge::entity::Entity> { let %0: List<::graph::types::knowledge::entity::Entity> let %1: () - let %2: ::graph::TimeAxis + let %2: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes bb0(): { %2 = input LOAD time_axis diff --git a/libs/@local/hashql/eval/tests/ui/postgres/opaque-passthrough.stdout b/libs/@local/hashql/eval/tests/ui/postgres/opaque-passthrough.stdout index b16f6bacefd..d53b113737a 100644 --- a/libs/@local/hashql/eval/tests/ui/postgres/opaque-passthrough.stdout +++ b/libs/@local/hashql/eval/tests/ui/postgres/opaque-passthrough.stdout @@ -2,9 +2,9 @@ SELECT ("continuation_8_0"."row")."block" AS "continuation_8_0_block", ("continuation_8_0"."row")."locals" AS "continuation_8_0_locals", ("continuation_8_0"."row")."values" AS "continuation_8_0_values" FROM "entity_temporal_metadata" AS "entity_temporal_metadata_0_0_0" -CROSS JOIN LATERAL (SELECT (ROW((("entity_temporal_metadata_0_0_0"."entity_uuid" = $3)::boolean), NULL, NULL, NULL)::continuation) AS "row" +CROSS JOIN LATERAL (SELECT (ROW(COALESCE(((to_jsonb("entity_temporal_metadata_0_0_0"."entity_uuid") = to_jsonb(($3::jsonb)))::boolean), FALSE), NULL, NULL, NULL)::continuation) AS "row" OFFSET 0) AS "continuation_8_0" -WHERE "entity_temporal_metadata_0_0_0"."transaction_time" && $1 AND "entity_temporal_metadata_0_0_0"."decision_time" && $2 AND ("continuation_8_0"."row")."filter" IS NOT FALSE +WHERE "entity_temporal_metadata_0_0_0"."transaction_time" && ($1::tstzrange) AND "entity_temporal_metadata_0_0_0"."decision_time" && ($2::tstzrange) AND ("continuation_8_0"."row")."filter" IS NOT FALSE ════ Parameters ════════════════════════════════════════════════════════════════ diff --git a/libs/@local/hashql/eval/tests/ui/postgres/struct-construction.aux.mir b/libs/@local/hashql/eval/tests/ui/postgres/struct-construction.aux.mir index f63dd51fca6..f4287ad3fc2 100644 --- a/libs/@local/hashql/eval/tests/ui/postgres/struct-construction.aux.mir +++ b/libs/@local/hashql/eval/tests/ui/postgres/struct-construction.aux.mir @@ -1,5 +1,5 @@ -thunk {thunk#1}() -> ::graph::TimeAxis { - let %0: ::graph::TimeAxis +thunk {thunk#1}() -> ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes { + let %0: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes bb0(): { %0 = input LOAD time_axis @@ -63,7 +63,7 @@ fn {graph::read::filter@7}(%0: (), %1: ::graph::types::knowledge::entity::Entity thunk {thunk#7}() -> List<::graph::types::knowledge::entity::Entity> { let %0: List<::graph::types::knowledge::entity::Entity> let %1: () - let %2: ::graph::TimeAxis + let %2: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes bb0(): { %2 = input LOAD time_axis diff --git a/libs/@local/hashql/eval/tests/ui/postgres/struct-construction.stdout b/libs/@local/hashql/eval/tests/ui/postgres/struct-construction.stdout index f630b4d404e..82cb6f0d73f 100644 --- a/libs/@local/hashql/eval/tests/ui/postgres/struct-construction.stdout +++ b/libs/@local/hashql/eval/tests/ui/postgres/struct-construction.stdout @@ -2,9 +2,9 @@ SELECT ("continuation_4_0"."row")."block" AS "continuation_4_0_block", ("continuation_4_0"."row")."locals" AS "continuation_4_0_locals", ("continuation_4_0"."row")."values" AS "continuation_4_0_values" FROM "entity_temporal_metadata" AS "entity_temporal_metadata_0_0_0" -CROSS JOIN LATERAL (SELECT (ROW(((jsonb_build_object($3, "entity_temporal_metadata_0_0_0"."entity_uuid", $4, "entity_temporal_metadata_0_0_0"."web_id") = jsonb_build_object($3, $5, $4, $6))::boolean), NULL, NULL, NULL)::continuation) AS "row" +CROSS JOIN LATERAL (SELECT (ROW(COALESCE(((to_jsonb(jsonb_build_object(($3::text), "entity_temporal_metadata_0_0_0"."entity_uuid", ($4::text), "entity_temporal_metadata_0_0_0"."web_id")) = to_jsonb(jsonb_build_object(($3::text), ($5::jsonb), ($4::text), ($6::jsonb))))::boolean), FALSE), NULL, NULL, NULL)::continuation) AS "row" OFFSET 0) AS "continuation_4_0" -WHERE "entity_temporal_metadata_0_0_0"."transaction_time" && $1 AND "entity_temporal_metadata_0_0_0"."decision_time" && $2 AND ("continuation_4_0"."row")."filter" IS NOT FALSE +WHERE "entity_temporal_metadata_0_0_0"."transaction_time" && ($1::tstzrange) AND "entity_temporal_metadata_0_0_0"."decision_time" && ($2::tstzrange) AND ("continuation_4_0"."row")."filter" IS NOT FALSE ════ Parameters ════════════════════════════════════════════════════════════════ diff --git a/libs/@local/hashql/eval/tests/ui/postgres/tuple-construction.aux.mir b/libs/@local/hashql/eval/tests/ui/postgres/tuple-construction.aux.mir index 8a165d7b2fe..aa383add640 100644 --- a/libs/@local/hashql/eval/tests/ui/postgres/tuple-construction.aux.mir +++ b/libs/@local/hashql/eval/tests/ui/postgres/tuple-construction.aux.mir @@ -1,5 +1,5 @@ -thunk {thunk#1}() -> ::graph::TimeAxis { - let %0: ::graph::TimeAxis +thunk {thunk#1}() -> ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes { + let %0: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes bb0(): { %0 = input LOAD time_axis @@ -63,7 +63,7 @@ fn {graph::read::filter@7}(%0: (), %1: ::graph::types::knowledge::entity::Entity thunk {thunk#7}() -> List<::graph::types::knowledge::entity::Entity> { let %0: List<::graph::types::knowledge::entity::Entity> let %1: () - let %2: ::graph::TimeAxis + let %2: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes bb0(): { %2 = input LOAD time_axis diff --git a/libs/@local/hashql/eval/tests/ui/postgres/tuple-construction.stdout b/libs/@local/hashql/eval/tests/ui/postgres/tuple-construction.stdout index 9846897911e..545cec8b6a8 100644 --- a/libs/@local/hashql/eval/tests/ui/postgres/tuple-construction.stdout +++ b/libs/@local/hashql/eval/tests/ui/postgres/tuple-construction.stdout @@ -2,9 +2,9 @@ SELECT ("continuation_4_0"."row")."block" AS "continuation_4_0_block", ("continuation_4_0"."row")."locals" AS "continuation_4_0_locals", ("continuation_4_0"."row")."values" AS "continuation_4_0_values" FROM "entity_temporal_metadata" AS "entity_temporal_metadata_0_0_0" -CROSS JOIN LATERAL (SELECT (ROW(((jsonb_build_array("entity_temporal_metadata_0_0_0"."entity_uuid", "entity_temporal_metadata_0_0_0"."web_id") = jsonb_build_array($3, $4))::boolean), NULL, NULL, NULL)::continuation) AS "row" +CROSS JOIN LATERAL (SELECT (ROW(COALESCE(((to_jsonb(jsonb_build_array("entity_temporal_metadata_0_0_0"."entity_uuid", "entity_temporal_metadata_0_0_0"."web_id")) = to_jsonb(jsonb_build_array(($3::jsonb), ($4::jsonb))))::boolean), FALSE), NULL, NULL, NULL)::continuation) AS "row" OFFSET 0) AS "continuation_4_0" -WHERE "entity_temporal_metadata_0_0_0"."transaction_time" && $1 AND "entity_temporal_metadata_0_0_0"."decision_time" && $2 AND ("continuation_4_0"."row")."filter" IS NOT FALSE +WHERE "entity_temporal_metadata_0_0_0"."transaction_time" && ($1::tstzrange) AND "entity_temporal_metadata_0_0_0"."decision_time" && ($2::tstzrange) AND ("continuation_4_0"."row")."filter" IS NOT FALSE ════ Parameters ════════════════════════════════════════════════════════════════ diff --git a/libs/@local/hashql/hir/tests/ui/lower/checking/closure-call-constrained.stdout b/libs/@local/hashql/hir/tests/ui/lower/checking/closure-call-constrained.stdout index 9624a0176b7..928ea5f18cd 100644 --- a/libs/@local/hashql/hir/tests/ui/lower/checking/closure-call-constrained.stdout +++ b/libs/@local/hashql/hir/tests/ui/lower/checking/closure-call-constrained.stdout @@ -1,27 +1,27 @@ ════ Initial HIR ═══════════════════════════════════════════════════════════════ -let foo:0 = (a:0: ?26, b:0: ?26): ?26 -> +let foo:0 = (a:0: ?30, b:0: ?30): ?30 -> ::core::math::add(a:0, b:0) in foo:0(2, 3) ════ HIR after type checking ═══════════════════════════════════════════════════ -let foo:0 = (a:0: ?29, b:0: ?29): ?29 -> +let foo:0 = (a:0: ?33, b:0: ?33): ?33 -> ::core::math::add(a:0, b:0) in foo:0(2, 3) ════ Types ═════════════════════════════════════════════════════════════════════ -┌─ let foo:0 = (a:0: ?29, b:0: ?29): ?29 -> +┌─ let foo:0 = (a:0: ?33, b:0: ?33): ?33 -> │ ::core::math::add(a:0, b:0) │ in │ foo:0(2, 3) └→ Integer -┌─ (a:0: ?29, b:0: ?29): ?29 -> ::core::math::add(a:0, b:0) -└→ (T:0?29, T:0?29) -> T:0?29 +┌─ (a:0: ?33, b:0: ?33): ?33 -> ::core::math::add(a:0, b:0) +└→ (T:0?33, T:0?33) -> T:0?33 ┌─ ::core::math::add(a:0, b:0) └→ Integer diff --git a/libs/@local/hashql/hir/tests/ui/lower/checking/closure-call-unconstrained-direct.stdout b/libs/@local/hashql/hir/tests/ui/lower/checking/closure-call-unconstrained-direct.stdout index f4862f6e1b9..a8c368374df 100644 --- a/libs/@local/hashql/hir/tests/ui/lower/checking/closure-call-unconstrained-direct.stdout +++ b/libs/@local/hashql/hir/tests/ui/lower/checking/closure-call-unconstrained-direct.stdout @@ -1,6 +1,6 @@ ════ Initial HIR ═══════════════════════════════════════════════════════════════ -(a:0: ?26): ?26 -> a:0("1") +(a:0: ?30): ?30 -> a:0("1") ════ HIR after type checking ═══════════════════════════════════════════════════ diff --git a/libs/@local/hashql/hir/tests/ui/lower/checking/closure-call-unconstrained.stdout b/libs/@local/hashql/hir/tests/ui/lower/checking/closure-call-unconstrained.stdout index 2d7a03e4cb7..59f74202da5 100644 --- a/libs/@local/hashql/hir/tests/ui/lower/checking/closure-call-unconstrained.stdout +++ b/libs/@local/hashql/hir/tests/ui/lower/checking/closure-call-unconstrained.stdout @@ -1,33 +1,33 @@ ════ Initial HIR ═══════════════════════════════════════════════════════════════ -let foo:0 = (a:0: ?26): ?26 -> a:0, - bar:0 = (a:1: ?28): ?28 -> foo:0(a:1) +let foo:0 = (a:0: ?30): ?30 -> a:0, + bar:0 = (a:1: ?32): ?32 -> foo:0(a:1) in bar:0(2) ════ HIR after type checking ═══════════════════════════════════════════════════ -let foo:0 = (a:0: ?29): ?29 -> a:0, - bar:0 = (a:1: ?31): ?31 -> foo:0(a:1) +let foo:0 = (a:0: ?33): ?33 -> a:0, + bar:0 = (a:1: ?35): ?35 -> foo:0(a:1) in bar:0(2) ════ Types ═════════════════════════════════════════════════════════════════════ -┌─ let foo:0 = (a:0: ?29): ?29 -> a:0, -│ bar:0 = (a:1: ?31): ?31 -> foo:0(a:1) +┌─ let foo:0 = (a:0: ?33): ?33 -> a:0, +│ bar:0 = (a:1: ?35): ?35 -> foo:0(a:1) │ in │ bar:0(2) └→ Integer -┌─ (a:0: ?29): ?29 -> a:0 -└→ (T:0?29) -> T:0?29 +┌─ (a:0: ?33): ?33 -> a:0 +└→ (T:0?33) -> T:0?33 ┌─ a:0 └→ ? -┌─ (a:1: ?31): ?31 -> foo:0(a:1) -└→ (T:1?31) -> T:1?31 +┌─ (a:1: ?35): ?35 -> foo:0(a:1) +└→ (T:1?35) -> T:1?35 ┌─ foo:0(a:1) └→ ? diff --git a/libs/@local/hashql/hir/tests/ui/lower/checking/closure-constrained.stdout b/libs/@local/hashql/hir/tests/ui/lower/checking/closure-constrained.stdout index 6df3304ac34..fa863abad97 100644 --- a/libs/@local/hashql/hir/tests/ui/lower/checking/closure-constrained.stdout +++ b/libs/@local/hashql/hir/tests/ui/lower/checking/closure-constrained.stdout @@ -1,27 +1,27 @@ ════ Initial HIR ═══════════════════════════════════════════════════════════════ -let add:0 = (a:0: ?26, b:0: ?26): ?26 -> +let add:0 = (a:0: ?30, b:0: ?30): ?30 -> ::core::math::add(a:0, b:0) in add:0(1, 2) ════ HIR after type checking ═══════════════════════════════════════════════════ -let add:0 = (a:0: ?29, b:0: ?29): ?29 -> +let add:0 = (a:0: ?33, b:0: ?33): ?33 -> ::core::math::add(a:0, b:0) in add:0(1, 2) ════ Types ═════════════════════════════════════════════════════════════════════ -┌─ let add:0 = (a:0: ?29, b:0: ?29): ?29 -> +┌─ let add:0 = (a:0: ?33, b:0: ?33): ?33 -> │ ::core::math::add(a:0, b:0) │ in │ add:0(1, 2) └→ Integer -┌─ (a:0: ?29, b:0: ?29): ?29 -> ::core::math::add(a:0, b:0) -└→ (T:0?29, T:0?29) -> T:0?29 +┌─ (a:0: ?33, b:0: ?33): ?33 -> ::core::math::add(a:0, b:0) +└→ (T:0?33, T:0?33) -> T:0?33 ┌─ ::core::math::add(a:0, b:0) └→ Number diff --git a/libs/@local/hashql/hir/tests/ui/lower/checking/collect-filter-graph.stdout b/libs/@local/hashql/hir/tests/ui/lower/checking/collect-filter-graph.stdout index 15a323ed088..f232a69153e 100644 --- a/libs/@local/hashql/hir/tests/ui/lower/checking/collect-filter-graph.stdout +++ b/libs/@local/hashql/hir/tests/ui/lower/checking/collect-filter-graph.stdout @@ -57,7 +57,7 @@ edition: ?, inferred: ? ), - record_id: ::graph::types::knowledge::entity::EntityRecordId( + record_id: ::graph::types::knowledge::entity::RecordId( edition_id: ::graph::types::knowledge::entity::EntityEditionId(::core::uuid::Uuid(String)), entity_id: ::graph::types::knowledge::entity::EntityId( draft_id: ::core::option::None(Null) @@ -66,9 +66,17 @@ web_id: ::graph::types::principal::actor_group::web::WebId(::graph::types::principal::actor_group::ActorGroupEntityUuid(::core::uuid::Uuid(String))) ) ), - temporal_versioning: ::graph::types::knowledge::entity::EntityTemporalMetadata( - decision_time: ?, - transaction_time: ? + temporal_versioning: ::graph::types::knowledge::entity::TemporalMetadata( + decision_time: ::graph::temporal::DecisionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )), + transaction_time: ::graph::temporal::TransactionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )) ) ), properties: ? @@ -127,7 +135,7 @@ │ edition: ?, │ inferred: ? │ ), -│ record_id: ::graph::types::knowledge::entity::EntityRecordId( +│ record_id: ::graph::types::knowledge::entity::RecordId( │ edition_id: ::graph::types::knowledge::entity::EntityEditionId(::core::uuid::Uuid(String)), │ entity_id: ::graph::types::knowledge::entity::EntityId( │ draft_id: ::core::option::None(Null) @@ -136,9 +144,17 @@ │ web_id: ::graph::types::principal::actor_group::web::WebId(::graph::types::principal::actor_group::ActorGroupEntityUuid(::core::uuid::Uuid(String))) │ ) │ ), -│ temporal_versioning: ::graph::types::knowledge::entity::EntityTemporalMetadata( -│ decision_time: ?, -│ transaction_time: ? +│ temporal_versioning: ::graph::types::knowledge::entity::TemporalMetadata( +│ decision_time: ::graph::temporal::DecisionTime(::graph::temporal::Interval( +│ end: ::graph::temporal::UnboundedTemporalBound(Null) +│ | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), +│ start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) +│ )), +│ transaction_time: ::graph::temporal::TransactionTime(::graph::temporal::Interval( +│ end: ::graph::temporal::UnboundedTemporalBound(Null) +│ | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), +│ start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) +│ )) │ ) │ ), │ properties: ? @@ -188,7 +204,7 @@ edition: ?, inferred: ? ), - record_id: ::graph::types::knowledge::entity::EntityRecordId( + record_id: ::graph::types::knowledge::entity::RecordId( edition_id: ::graph::types::knowledge::entity::EntityEditionId(::core::uuid::Uuid(String)), entity_id: ::graph::types::knowledge::entity::EntityId( draft_id: ::core::option::None(Null) @@ -197,9 +213,17 @@ web_id: ::graph::types::principal::actor_group::web::WebId(::graph::types::principal::actor_group::ActorGroupEntityUuid(::core::uuid::Uuid(String))) ) ), - temporal_versioning: ::graph::types::knowledge::entity::EntityTemporalMetadata( - decision_time: ?, - transaction_time: ? + temporal_versioning: ::graph::types::knowledge::entity::TemporalMetadata( + decision_time: ::graph::temporal::DecisionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )), + transaction_time: ::graph::temporal::TransactionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )) ) ), properties: ? @@ -246,7 +270,7 @@ edition: ?, inferred: ? ), - record_id: ::graph::types::knowledge::entity::EntityRecordId( + record_id: ::graph::types::knowledge::entity::RecordId( edition_id: ::graph::types::knowledge::entity::EntityEditionId(::core::uuid::Uuid(String)), entity_id: ::graph::types::knowledge::entity::EntityId( draft_id: ::core::option::None(Null) @@ -255,9 +279,17 @@ web_id: ::graph::types::principal::actor_group::web::WebId(::graph::types::principal::actor_group::ActorGroupEntityUuid(::core::uuid::Uuid(String))) ) ), - temporal_versioning: ::graph::types::knowledge::entity::EntityTemporalMetadata( - decision_time: ?, - transaction_time: ? + temporal_versioning: ::graph::types::knowledge::entity::TemporalMetadata( + decision_time: ::graph::temporal::DecisionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )), + transaction_time: ::graph::temporal::TransactionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )) ) ), properties: ? @@ -302,7 +334,7 @@ edition: ?, inferred: ? ), - record_id: ::graph::types::knowledge::entity::EntityRecordId( + record_id: ::graph::types::knowledge::entity::RecordId( edition_id: ::graph::types::knowledge::entity::EntityEditionId(::core::uuid::Uuid(String)), entity_id: ::graph::types::knowledge::entity::EntityId( draft_id: ::core::option::None(Null) @@ -311,9 +343,17 @@ web_id: ::graph::types::principal::actor_group::web::WebId(::graph::types::principal::actor_group::ActorGroupEntityUuid(::core::uuid::Uuid(String))) ) ), - temporal_versioning: ::graph::types::knowledge::entity::EntityTemporalMetadata( - decision_time: ?, - transaction_time: ? + temporal_versioning: ::graph::types::knowledge::entity::TemporalMetadata( + decision_time: ::graph::temporal::DecisionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )), + transaction_time: ::graph::temporal::TransactionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )) ) ), properties: ? @@ -360,7 +400,7 @@ │ edition: ?, │ inferred: ? │ ), -│ record_id: ::graph::types::knowledge::entity::EntityRecordId( +│ record_id: ::graph::types::knowledge::entity::RecordId( │ edition_id: ::graph::types::knowledge::entity::EntityEditionId(::core::uuid::Uuid(String)), │ entity_id: ::graph::types::knowledge::entity::EntityId( │ draft_id: ::core::option::None(Null) @@ -369,9 +409,17 @@ │ web_id: ::graph::types::principal::actor_group::web::WebId(::graph::types::principal::actor_group::ActorGroupEntityUuid(::core::uuid::Uuid(String))) │ ) │ ), -│ temporal_versioning: ::graph::types::knowledge::entity::EntityTemporalMetadata( -│ decision_time: ?, -│ transaction_time: ? +│ temporal_versioning: ::graph::types::knowledge::entity::TemporalMetadata( +│ decision_time: ::graph::temporal::DecisionTime(::graph::temporal::Interval( +│ end: ::graph::temporal::UnboundedTemporalBound(Null) +│ | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), +│ start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) +│ )), +│ transaction_time: ::graph::temporal::TransactionTime(::graph::temporal::Interval( +│ end: ::graph::temporal::UnboundedTemporalBound(Null) +│ | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), +│ start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) +│ )) │ ) │ ), │ properties: ? @@ -423,7 +471,7 @@ edition: ?, inferred: ? ), - record_id: ::graph::types::knowledge::entity::EntityRecordId( + record_id: ::graph::types::knowledge::entity::RecordId( edition_id: ::graph::types::knowledge::entity::EntityEditionId(::core::uuid::Uuid(String)), entity_id: ::graph::types::knowledge::entity::EntityId( draft_id: ::core::option::None(Null) @@ -432,9 +480,17 @@ web_id: ::graph::types::principal::actor_group::web::WebId(::graph::types::principal::actor_group::ActorGroupEntityUuid(::core::uuid::Uuid(String))) ) ), - temporal_versioning: ::graph::types::knowledge::entity::EntityTemporalMetadata( - decision_time: ?, - transaction_time: ? + temporal_versioning: ::graph::types::knowledge::entity::TemporalMetadata( + decision_time: ::graph::temporal::DecisionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )), + transaction_time: ::graph::temporal::TransactionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )) ) ), properties: ? @@ -482,7 +538,7 @@ edition: ?, inferred: ? ), - record_id: ::graph::types::knowledge::entity::EntityRecordId( + record_id: ::graph::types::knowledge::entity::RecordId( edition_id: ::graph::types::knowledge::entity::EntityEditionId(::core::uuid::Uuid(String)), entity_id: ::graph::types::knowledge::entity::EntityId( draft_id: ::core::option::None(Null) @@ -491,9 +547,17 @@ web_id: ::graph::types::principal::actor_group::web::WebId(::graph::types::principal::actor_group::ActorGroupEntityUuid(::core::uuid::Uuid(String))) ) ), - temporal_versioning: ::graph::types::knowledge::entity::EntityTemporalMetadata( - decision_time: ?, - transaction_time: ? + temporal_versioning: ::graph::types::knowledge::entity::TemporalMetadata( + decision_time: ::graph::temporal::DecisionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )), + transaction_time: ::graph::temporal::TransactionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )) ) ), properties: ? @@ -538,7 +602,7 @@ edition: ?, inferred: ? ), - record_id: ::graph::types::knowledge::entity::EntityRecordId( + record_id: ::graph::types::knowledge::entity::RecordId( edition_id: ::graph::types::knowledge::entity::EntityEditionId(::core::uuid::Uuid(String)), entity_id: ::graph::types::knowledge::entity::EntityId( draft_id: ::core::option::None(Null) @@ -547,9 +611,17 @@ web_id: ::graph::types::principal::actor_group::web::WebId(::graph::types::principal::actor_group::ActorGroupEntityUuid(::core::uuid::Uuid(String))) ) ), - temporal_versioning: ::graph::types::knowledge::entity::EntityTemporalMetadata( - decision_time: ?, - transaction_time: ? + temporal_versioning: ::graph::types::knowledge::entity::TemporalMetadata( + decision_time: ::graph::temporal::DecisionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )), + transaction_time: ::graph::temporal::TransactionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )) ) ), properties: ? @@ -595,7 +667,7 @@ edition: ?, inferred: ? ), - record_id: ::graph::types::knowledge::entity::EntityRecordId( + record_id: ::graph::types::knowledge::entity::RecordId( edition_id: ::graph::types::knowledge::entity::EntityEditionId(::core::uuid::Uuid(String)), entity_id: ::graph::types::knowledge::entity::EntityId( draft_id: ::core::option::None(Null) @@ -604,9 +676,17 @@ web_id: ::graph::types::principal::actor_group::web::WebId(::graph::types::principal::actor_group::ActorGroupEntityUuid(::core::uuid::Uuid(String))) ) ), - temporal_versioning: ::graph::types::knowledge::entity::EntityTemporalMetadata( - decision_time: ?, - transaction_time: ? + temporal_versioning: ::graph::types::knowledge::entity::TemporalMetadata( + decision_time: ::graph::temporal::DecisionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )), + transaction_time: ::graph::temporal::TransactionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )) ) ), properties: ? @@ -653,7 +733,7 @@ edition: ?, inferred: ? ), - record_id: ::graph::types::knowledge::entity::EntityRecordId( + record_id: ::graph::types::knowledge::entity::RecordId( edition_id: ::graph::types::knowledge::entity::EntityEditionId(::core::uuid::Uuid(String)), entity_id: ::graph::types::knowledge::entity::EntityId( draft_id: ::core::option::None(Null) @@ -662,9 +742,17 @@ web_id: ::graph::types::principal::actor_group::web::WebId(::graph::types::principal::actor_group::ActorGroupEntityUuid(::core::uuid::Uuid(String))) ) ), - temporal_versioning: ::graph::types::knowledge::entity::EntityTemporalMetadata( - decision_time: ?, - transaction_time: ? + temporal_versioning: ::graph::types::knowledge::entity::TemporalMetadata( + decision_time: ::graph::temporal::DecisionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )), + transaction_time: ::graph::temporal::TransactionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )) ) ), properties: ? @@ -672,7 +760,28 @@ ) ┌─ ::graph::head::entities -└→ (::graph::TimeAxis(:)) -> +└→ ( + ::graph::temporal::PinnedTransactionTimeTemporalAxes( + pinned: ::graph::temporal::TransactionTime(::graph::temporal::Timestamp(Integer)), + variable: ::graph::temporal::DecisionTime(::graph::temporal::Interval( + end: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )) + ) + | ::graph::temporal::PinnedDecisionTimeTemporalAxes( + pinned: ::graph::temporal::DecisionTime(::graph::temporal::Timestamp(Integer)), + variable: ::graph::temporal::TransactionTime(::graph::temporal::Interval( + end: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )) + ) + ) -> ::graph::Graph( 'marker: ::graph::types::knowledge::entity::Entity( encodings: ::graph::types::knowledge::entity::EntityEncodings( @@ -712,7 +821,7 @@ edition: ?, inferred: ? ), - record_id: ::graph::types::knowledge::entity::EntityRecordId( + record_id: ::graph::types::knowledge::entity::RecordId( edition_id: ::graph::types::knowledge::entity::EntityEditionId(::core::uuid::Uuid(String)), entity_id: ::graph::types::knowledge::entity::EntityId( draft_id: ::core::option::None(Null) @@ -721,9 +830,17 @@ web_id: ::graph::types::principal::actor_group::web::WebId(::graph::types::principal::actor_group::ActorGroupEntityUuid(::core::uuid::Uuid(String))) ) ), - temporal_versioning: ::graph::types::knowledge::entity::EntityTemporalMetadata( - decision_time: ?, - transaction_time: ? + temporal_versioning: ::graph::types::knowledge::entity::TemporalMetadata( + decision_time: ::graph::temporal::DecisionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )), + transaction_time: ::graph::temporal::TransactionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )) ) ), properties: ? @@ -731,10 +848,49 @@ ) ┌─ ::graph::tmp::decision_time_now() -└→ ::graph::TimeAxis(:) +└→ ::graph::temporal::PinnedTransactionTimeTemporalAxes( + pinned: ::graph::temporal::TransactionTime(::graph::temporal::Timestamp(Integer)), + variable: ::graph::temporal::DecisionTime(::graph::temporal::Interval( + end: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )) + ) + | ::graph::temporal::PinnedDecisionTimeTemporalAxes( + pinned: ::graph::temporal::DecisionTime(::graph::temporal::Timestamp(Integer)), + variable: ::graph::temporal::TransactionTime(::graph::temporal::Interval( + end: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )) + ) ┌─ ::graph::tmp::decision_time_now -└→ () -> ::graph::TimeAxis(:) +└→ () -> + (::graph::temporal::PinnedTransactionTimeTemporalAxes( + pinned: ::graph::temporal::TransactionTime(::graph::temporal::Timestamp(Integer)), + variable: ::graph::temporal::DecisionTime(::graph::temporal::Interval( + end: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )) + ) + | ::graph::temporal::PinnedDecisionTimeTemporalAxes( + pinned: ::graph::temporal::DecisionTime(::graph::temporal::Timestamp(Integer)), + variable: ::graph::temporal::TransactionTime(::graph::temporal::Interval( + end: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )) + )) ┌─ ( │ vertex:0: ::graph::types::knowledge::entity::Entity( @@ -775,7 +931,7 @@ │ edition: ?, │ inferred: ? │ ), -│ record_id: ::graph::types::knowledge::entity::EntityRecordId( +│ record_id: ::graph::types::knowledge::entity::RecordId( │ edition_id: ::graph::types::knowledge::entity::EntityEditionId(::core::uuid::Uuid(String)), │ entity_id: ::graph::types::knowledge::entity::EntityId( │ draft_id: ::core::option::None(Null) @@ -784,9 +940,17 @@ │ web_id: ::graph::types::principal::actor_group::web::WebId(::graph::types::principal::actor_group::ActorGroupEntityUuid(::core::uuid::Uuid(String))) │ ) │ ), -│ temporal_versioning: ::graph::types::knowledge::entity::EntityTemporalMetadata( -│ decision_time: ?, -│ transaction_time: ? +│ temporal_versioning: ::graph::types::knowledge::entity::TemporalMetadata( +│ decision_time: ::graph::temporal::DecisionTime(::graph::temporal::Interval( +│ end: ::graph::temporal::UnboundedTemporalBound(Null) +│ | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), +│ start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) +│ )), +│ transaction_time: ::graph::temporal::TransactionTime(::graph::temporal::Interval( +│ end: ::graph::temporal::UnboundedTemporalBound(Null) +│ | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), +│ start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) +│ )) │ ) │ ), │ properties: ? @@ -837,7 +1001,7 @@ edition: ?, inferred: ? ), - record_id: ::graph::types::knowledge::entity::EntityRecordId( + record_id: ::graph::types::knowledge::entity::RecordId( edition_id: ::graph::types::knowledge::entity::EntityEditionId(::core::uuid::Uuid(String)), entity_id: ::graph::types::knowledge::entity::EntityId( draft_id: ::core::option::None(Null) @@ -846,9 +1010,17 @@ web_id: ::graph::types::principal::actor_group::web::WebId(::graph::types::principal::actor_group::ActorGroupEntityUuid(::core::uuid::Uuid(String))) ) ), - temporal_versioning: ::graph::types::knowledge::entity::EntityTemporalMetadata( - decision_time: ?, - transaction_time: ? + temporal_versioning: ::graph::types::knowledge::entity::TemporalMetadata( + decision_time: ::graph::temporal::DecisionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )), + transaction_time: ::graph::temporal::TransactionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )) ) ), properties: ? @@ -881,7 +1053,7 @@ ) ┌─ vertex:0.metadata.record_id -└→ ::graph::types::knowledge::entity::EntityRecordId( +└→ ::graph::types::knowledge::entity::RecordId( edition_id: ::graph::types::knowledge::entity::EntityEditionId(::core::uuid::Uuid(String)), entity_id: ::graph::types::knowledge::entity::EntityId( draft_id: ::core::option::None(Null) @@ -905,7 +1077,7 @@ edition: ?, inferred: ? ), - record_id: ::graph::types::knowledge::entity::EntityRecordId( + record_id: ::graph::types::knowledge::entity::RecordId( edition_id: ::graph::types::knowledge::entity::EntityEditionId(::core::uuid::Uuid(String)), entity_id: ::graph::types::knowledge::entity::EntityId( draft_id: ::core::option::None(Null) @@ -914,9 +1086,17 @@ web_id: ::graph::types::principal::actor_group::web::WebId(::graph::types::principal::actor_group::ActorGroupEntityUuid(::core::uuid::Uuid(String))) ) ), - temporal_versioning: ::graph::types::knowledge::entity::EntityTemporalMetadata( - decision_time: ?, - transaction_time: ? + temporal_versioning: ::graph::types::knowledge::entity::TemporalMetadata( + decision_time: ::graph::temporal::DecisionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )), + transaction_time: ::graph::temporal::TransactionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )) ) ) @@ -957,7 +1137,7 @@ edition: ?, inferred: ? ), - record_id: ::graph::types::knowledge::entity::EntityRecordId( + record_id: ::graph::types::knowledge::entity::RecordId( edition_id: ::graph::types::knowledge::entity::EntityEditionId(::core::uuid::Uuid(String)), entity_id: ::graph::types::knowledge::entity::EntityId( draft_id: ::core::option::None(Null) @@ -966,9 +1146,17 @@ web_id: ::graph::types::principal::actor_group::web::WebId(::graph::types::principal::actor_group::ActorGroupEntityUuid(::core::uuid::Uuid(String))) ) ), - temporal_versioning: ::graph::types::knowledge::entity::EntityTemporalMetadata( - decision_time: ?, - transaction_time: ? + temporal_versioning: ::graph::types::knowledge::entity::TemporalMetadata( + decision_time: ::graph::temporal::DecisionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )), + transaction_time: ::graph::temporal::TransactionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )) ) ), properties: ? diff --git a/libs/@local/hashql/hir/tests/ui/lower/checking/filter-graph.stdout b/libs/@local/hashql/hir/tests/ui/lower/checking/filter-graph.stdout index 0d816e96cc8..1fb9dcaa75b 100644 --- a/libs/@local/hashql/hir/tests/ui/lower/checking/filter-graph.stdout +++ b/libs/@local/hashql/hir/tests/ui/lower/checking/filter-graph.stdout @@ -54,7 +54,7 @@ edition: ?, inferred: ? ), - record_id: ::graph::types::knowledge::entity::EntityRecordId( + record_id: ::graph::types::knowledge::entity::RecordId( edition_id: ::graph::types::knowledge::entity::EntityEditionId(::core::uuid::Uuid(String)), entity_id: ::graph::types::knowledge::entity::EntityId( draft_id: ::core::option::None(Null) @@ -63,9 +63,17 @@ web_id: ::graph::types::principal::actor_group::web::WebId(::graph::types::principal::actor_group::ActorGroupEntityUuid(::core::uuid::Uuid(String))) ) ), - temporal_versioning: ::graph::types::knowledge::entity::EntityTemporalMetadata( - decision_time: ?, - transaction_time: ? + temporal_versioning: ::graph::types::knowledge::entity::TemporalMetadata( + decision_time: ::graph::temporal::DecisionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )), + transaction_time: ::graph::temporal::TransactionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )) ) ), properties: ? @@ -122,7 +130,7 @@ │ edition: ?, │ inferred: ? │ ), -│ record_id: ::graph::types::knowledge::entity::EntityRecordId( +│ record_id: ::graph::types::knowledge::entity::RecordId( │ edition_id: ::graph::types::knowledge::entity::EntityEditionId(::core::uuid::Uuid(String)), │ entity_id: ::graph::types::knowledge::entity::EntityId( │ draft_id: ::core::option::None(Null) @@ -131,9 +139,17 @@ │ web_id: ::graph::types::principal::actor_group::web::WebId(::graph::types::principal::actor_group::ActorGroupEntityUuid(::core::uuid::Uuid(String))) │ ) │ ), -│ temporal_versioning: ::graph::types::knowledge::entity::EntityTemporalMetadata( -│ decision_time: ?, -│ transaction_time: ? +│ temporal_versioning: ::graph::types::knowledge::entity::TemporalMetadata( +│ decision_time: ::graph::temporal::DecisionTime(::graph::temporal::Interval( +│ end: ::graph::temporal::UnboundedTemporalBound(Null) +│ | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), +│ start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) +│ )), +│ transaction_time: ::graph::temporal::TransactionTime(::graph::temporal::Interval( +│ end: ::graph::temporal::UnboundedTemporalBound(Null) +│ | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), +│ start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) +│ )) │ ) │ ), │ properties: ? @@ -185,7 +201,7 @@ edition: ?, inferred: ? ), - record_id: ::graph::types::knowledge::entity::EntityRecordId( + record_id: ::graph::types::knowledge::entity::RecordId( edition_id: ::graph::types::knowledge::entity::EntityEditionId(::core::uuid::Uuid(String)), entity_id: ::graph::types::knowledge::entity::EntityId( draft_id: ::core::option::None(Null) @@ -194,9 +210,17 @@ web_id: ::graph::types::principal::actor_group::web::WebId(::graph::types::principal::actor_group::ActorGroupEntityUuid(::core::uuid::Uuid(String))) ) ), - temporal_versioning: ::graph::types::knowledge::entity::EntityTemporalMetadata( - decision_time: ?, - transaction_time: ? + temporal_versioning: ::graph::types::knowledge::entity::TemporalMetadata( + decision_time: ::graph::temporal::DecisionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )), + transaction_time: ::graph::temporal::TransactionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )) ) ), properties: ? @@ -244,7 +268,7 @@ edition: ?, inferred: ? ), - record_id: ::graph::types::knowledge::entity::EntityRecordId( + record_id: ::graph::types::knowledge::entity::RecordId( edition_id: ::graph::types::knowledge::entity::EntityEditionId(::core::uuid::Uuid(String)), entity_id: ::graph::types::knowledge::entity::EntityId( draft_id: ::core::option::None(Null) @@ -253,9 +277,17 @@ web_id: ::graph::types::principal::actor_group::web::WebId(::graph::types::principal::actor_group::ActorGroupEntityUuid(::core::uuid::Uuid(String))) ) ), - temporal_versioning: ::graph::types::knowledge::entity::EntityTemporalMetadata( - decision_time: ?, - transaction_time: ? + temporal_versioning: ::graph::types::knowledge::entity::TemporalMetadata( + decision_time: ::graph::temporal::DecisionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )), + transaction_time: ::graph::temporal::TransactionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )) ) ), properties: ? @@ -300,7 +332,7 @@ edition: ?, inferred: ? ), - record_id: ::graph::types::knowledge::entity::EntityRecordId( + record_id: ::graph::types::knowledge::entity::RecordId( edition_id: ::graph::types::knowledge::entity::EntityEditionId(::core::uuid::Uuid(String)), entity_id: ::graph::types::knowledge::entity::EntityId( draft_id: ::core::option::None(Null) @@ -309,9 +341,17 @@ web_id: ::graph::types::principal::actor_group::web::WebId(::graph::types::principal::actor_group::ActorGroupEntityUuid(::core::uuid::Uuid(String))) ) ), - temporal_versioning: ::graph::types::knowledge::entity::EntityTemporalMetadata( - decision_time: ?, - transaction_time: ? + temporal_versioning: ::graph::types::knowledge::entity::TemporalMetadata( + decision_time: ::graph::temporal::DecisionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )), + transaction_time: ::graph::temporal::TransactionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )) ) ), properties: ? @@ -357,7 +397,7 @@ edition: ?, inferred: ? ), - record_id: ::graph::types::knowledge::entity::EntityRecordId( + record_id: ::graph::types::knowledge::entity::RecordId( edition_id: ::graph::types::knowledge::entity::EntityEditionId(::core::uuid::Uuid(String)), entity_id: ::graph::types::knowledge::entity::EntityId( draft_id: ::core::option::None(Null) @@ -366,9 +406,17 @@ web_id: ::graph::types::principal::actor_group::web::WebId(::graph::types::principal::actor_group::ActorGroupEntityUuid(::core::uuid::Uuid(String))) ) ), - temporal_versioning: ::graph::types::knowledge::entity::EntityTemporalMetadata( - decision_time: ?, - transaction_time: ? + temporal_versioning: ::graph::types::knowledge::entity::TemporalMetadata( + decision_time: ::graph::temporal::DecisionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )), + transaction_time: ::graph::temporal::TransactionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )) ) ), properties: ? @@ -415,7 +463,7 @@ edition: ?, inferred: ? ), - record_id: ::graph::types::knowledge::entity::EntityRecordId( + record_id: ::graph::types::knowledge::entity::RecordId( edition_id: ::graph::types::knowledge::entity::EntityEditionId(::core::uuid::Uuid(String)), entity_id: ::graph::types::knowledge::entity::EntityId( draft_id: ::core::option::None(Null) @@ -424,9 +472,17 @@ web_id: ::graph::types::principal::actor_group::web::WebId(::graph::types::principal::actor_group::ActorGroupEntityUuid(::core::uuid::Uuid(String))) ) ), - temporal_versioning: ::graph::types::knowledge::entity::EntityTemporalMetadata( - decision_time: ?, - transaction_time: ? + temporal_versioning: ::graph::types::knowledge::entity::TemporalMetadata( + decision_time: ::graph::temporal::DecisionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )), + transaction_time: ::graph::temporal::TransactionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )) ) ), properties: ? @@ -434,7 +490,28 @@ ) ┌─ ::graph::head::entities -└→ (::graph::TimeAxis(:)) -> +└→ ( + ::graph::temporal::PinnedTransactionTimeTemporalAxes( + pinned: ::graph::temporal::TransactionTime(::graph::temporal::Timestamp(Integer)), + variable: ::graph::temporal::DecisionTime(::graph::temporal::Interval( + end: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )) + ) + | ::graph::temporal::PinnedDecisionTimeTemporalAxes( + pinned: ::graph::temporal::DecisionTime(::graph::temporal::Timestamp(Integer)), + variable: ::graph::temporal::TransactionTime(::graph::temporal::Interval( + end: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )) + ) + ) -> ::graph::Graph( 'marker: ::graph::types::knowledge::entity::Entity( encodings: ::graph::types::knowledge::entity::EntityEncodings( @@ -474,7 +551,7 @@ edition: ?, inferred: ? ), - record_id: ::graph::types::knowledge::entity::EntityRecordId( + record_id: ::graph::types::knowledge::entity::RecordId( edition_id: ::graph::types::knowledge::entity::EntityEditionId(::core::uuid::Uuid(String)), entity_id: ::graph::types::knowledge::entity::EntityId( draft_id: ::core::option::None(Null) @@ -483,9 +560,17 @@ web_id: ::graph::types::principal::actor_group::web::WebId(::graph::types::principal::actor_group::ActorGroupEntityUuid(::core::uuid::Uuid(String))) ) ), - temporal_versioning: ::graph::types::knowledge::entity::EntityTemporalMetadata( - decision_time: ?, - transaction_time: ? + temporal_versioning: ::graph::types::knowledge::entity::TemporalMetadata( + decision_time: ::graph::temporal::DecisionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )), + transaction_time: ::graph::temporal::TransactionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )) ) ), properties: ? @@ -493,10 +578,49 @@ ) ┌─ ::graph::tmp::decision_time_now() -└→ ::graph::TimeAxis(:) +└→ ::graph::temporal::PinnedTransactionTimeTemporalAxes( + pinned: ::graph::temporal::TransactionTime(::graph::temporal::Timestamp(Integer)), + variable: ::graph::temporal::DecisionTime(::graph::temporal::Interval( + end: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )) + ) + | ::graph::temporal::PinnedDecisionTimeTemporalAxes( + pinned: ::graph::temporal::DecisionTime(::graph::temporal::Timestamp(Integer)), + variable: ::graph::temporal::TransactionTime(::graph::temporal::Interval( + end: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )) + ) ┌─ ::graph::tmp::decision_time_now -└→ () -> ::graph::TimeAxis(:) +└→ () -> + (::graph::temporal::PinnedTransactionTimeTemporalAxes( + pinned: ::graph::temporal::TransactionTime(::graph::temporal::Timestamp(Integer)), + variable: ::graph::temporal::DecisionTime(::graph::temporal::Interval( + end: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )) + ) + | ::graph::temporal::PinnedDecisionTimeTemporalAxes( + pinned: ::graph::temporal::DecisionTime(::graph::temporal::Timestamp(Integer)), + variable: ::graph::temporal::TransactionTime(::graph::temporal::Interval( + end: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )) + )) ┌─ ( │ vertex:0: ::graph::types::knowledge::entity::Entity( @@ -537,7 +661,7 @@ │ edition: ?, │ inferred: ? │ ), -│ record_id: ::graph::types::knowledge::entity::EntityRecordId( +│ record_id: ::graph::types::knowledge::entity::RecordId( │ edition_id: ::graph::types::knowledge::entity::EntityEditionId(::core::uuid::Uuid(String)), │ entity_id: ::graph::types::knowledge::entity::EntityId( │ draft_id: ::core::option::None(Null) @@ -546,9 +670,17 @@ │ web_id: ::graph::types::principal::actor_group::web::WebId(::graph::types::principal::actor_group::ActorGroupEntityUuid(::core::uuid::Uuid(String))) │ ) │ ), -│ temporal_versioning: ::graph::types::knowledge::entity::EntityTemporalMetadata( -│ decision_time: ?, -│ transaction_time: ? +│ temporal_versioning: ::graph::types::knowledge::entity::TemporalMetadata( +│ decision_time: ::graph::temporal::DecisionTime(::graph::temporal::Interval( +│ end: ::graph::temporal::UnboundedTemporalBound(Null) +│ | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), +│ start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) +│ )), +│ transaction_time: ::graph::temporal::TransactionTime(::graph::temporal::Interval( +│ end: ::graph::temporal::UnboundedTemporalBound(Null) +│ | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), +│ start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) +│ )) │ ) │ ), │ properties: ? @@ -599,7 +731,7 @@ edition: ?, inferred: ? ), - record_id: ::graph::types::knowledge::entity::EntityRecordId( + record_id: ::graph::types::knowledge::entity::RecordId( edition_id: ::graph::types::knowledge::entity::EntityEditionId(::core::uuid::Uuid(String)), entity_id: ::graph::types::knowledge::entity::EntityId( draft_id: ::core::option::None(Null) @@ -608,9 +740,17 @@ web_id: ::graph::types::principal::actor_group::web::WebId(::graph::types::principal::actor_group::ActorGroupEntityUuid(::core::uuid::Uuid(String))) ) ), - temporal_versioning: ::graph::types::knowledge::entity::EntityTemporalMetadata( - decision_time: ?, - transaction_time: ? + temporal_versioning: ::graph::types::knowledge::entity::TemporalMetadata( + decision_time: ::graph::temporal::DecisionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )), + transaction_time: ::graph::temporal::TransactionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )) ) ), properties: ? @@ -643,7 +783,7 @@ ) ┌─ vertex:0.metadata.record_id -└→ ::graph::types::knowledge::entity::EntityRecordId( +└→ ::graph::types::knowledge::entity::RecordId( edition_id: ::graph::types::knowledge::entity::EntityEditionId(::core::uuid::Uuid(String)), entity_id: ::graph::types::knowledge::entity::EntityId( draft_id: ::core::option::None(Null) @@ -667,7 +807,7 @@ edition: ?, inferred: ? ), - record_id: ::graph::types::knowledge::entity::EntityRecordId( + record_id: ::graph::types::knowledge::entity::RecordId( edition_id: ::graph::types::knowledge::entity::EntityEditionId(::core::uuid::Uuid(String)), entity_id: ::graph::types::knowledge::entity::EntityId( draft_id: ::core::option::None(Null) @@ -676,9 +816,17 @@ web_id: ::graph::types::principal::actor_group::web::WebId(::graph::types::principal::actor_group::ActorGroupEntityUuid(::core::uuid::Uuid(String))) ) ), - temporal_versioning: ::graph::types::knowledge::entity::EntityTemporalMetadata( - decision_time: ?, - transaction_time: ? + temporal_versioning: ::graph::types::knowledge::entity::TemporalMetadata( + decision_time: ::graph::temporal::DecisionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )), + transaction_time: ::graph::temporal::TransactionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )) ) ) @@ -719,7 +867,7 @@ edition: ?, inferred: ? ), - record_id: ::graph::types::knowledge::entity::EntityRecordId( + record_id: ::graph::types::knowledge::entity::RecordId( edition_id: ::graph::types::knowledge::entity::EntityEditionId(::core::uuid::Uuid(String)), entity_id: ::graph::types::knowledge::entity::EntityId( draft_id: ::core::option::None(Null) @@ -728,9 +876,17 @@ web_id: ::graph::types::principal::actor_group::web::WebId(::graph::types::principal::actor_group::ActorGroupEntityUuid(::core::uuid::Uuid(String))) ) ), - temporal_versioning: ::graph::types::knowledge::entity::EntityTemporalMetadata( - decision_time: ?, - transaction_time: ? + temporal_versioning: ::graph::types::knowledge::entity::TemporalMetadata( + decision_time: ::graph::temporal::DecisionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )), + transaction_time: ::graph::temporal::TransactionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )) ) ), properties: ? diff --git a/libs/@local/hashql/hir/tests/ui/lower/checking/minimal-graph.stdout b/libs/@local/hashql/hir/tests/ui/lower/checking/minimal-graph.stdout index d34dc296e9b..01edc5b54df 100644 --- a/libs/@local/hashql/hir/tests/ui/lower/checking/minimal-graph.stdout +++ b/libs/@local/hashql/hir/tests/ui/lower/checking/minimal-graph.stdout @@ -51,7 +51,7 @@ edition: ?, inferred: ? ), - record_id: ::graph::types::knowledge::entity::EntityRecordId( + record_id: ::graph::types::knowledge::entity::RecordId( edition_id: ::graph::types::knowledge::entity::EntityEditionId(::core::uuid::Uuid(String)), entity_id: ::graph::types::knowledge::entity::EntityId( draft_id: ::core::option::None(Null) @@ -60,9 +60,17 @@ web_id: ::graph::types::principal::actor_group::web::WebId(::graph::types::principal::actor_group::ActorGroupEntityUuid(::core::uuid::Uuid(String))) ) ), - temporal_versioning: ::graph::types::knowledge::entity::EntityTemporalMetadata( - decision_time: ?, - transaction_time: ? + temporal_versioning: ::graph::types::knowledge::entity::TemporalMetadata( + decision_time: ::graph::temporal::DecisionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )), + transaction_time: ::graph::temporal::TransactionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )) ) ), properties: ? @@ -109,7 +117,7 @@ edition: ?, inferred: ? ), - record_id: ::graph::types::knowledge::entity::EntityRecordId( + record_id: ::graph::types::knowledge::entity::RecordId( edition_id: ::graph::types::knowledge::entity::EntityEditionId(::core::uuid::Uuid(String)), entity_id: ::graph::types::knowledge::entity::EntityId( draft_id: ::core::option::None(Null) @@ -118,9 +126,17 @@ web_id: ::graph::types::principal::actor_group::web::WebId(::graph::types::principal::actor_group::ActorGroupEntityUuid(::core::uuid::Uuid(String))) ) ), - temporal_versioning: ::graph::types::knowledge::entity::EntityTemporalMetadata( - decision_time: ?, - transaction_time: ? + temporal_versioning: ::graph::types::knowledge::entity::TemporalMetadata( + decision_time: ::graph::temporal::DecisionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )), + transaction_time: ::graph::temporal::TransactionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )) ) ), properties: ? @@ -165,7 +181,7 @@ edition: ?, inferred: ? ), - record_id: ::graph::types::knowledge::entity::EntityRecordId( + record_id: ::graph::types::knowledge::entity::RecordId( edition_id: ::graph::types::knowledge::entity::EntityEditionId(::core::uuid::Uuid(String)), entity_id: ::graph::types::knowledge::entity::EntityId( draft_id: ::core::option::None(Null) @@ -174,9 +190,17 @@ web_id: ::graph::types::principal::actor_group::web::WebId(::graph::types::principal::actor_group::ActorGroupEntityUuid(::core::uuid::Uuid(String))) ) ), - temporal_versioning: ::graph::types::knowledge::entity::EntityTemporalMetadata( - decision_time: ?, - transaction_time: ? + temporal_versioning: ::graph::types::knowledge::entity::TemporalMetadata( + decision_time: ::graph::temporal::DecisionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )), + transaction_time: ::graph::temporal::TransactionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )) ) ), properties: ? @@ -222,7 +246,7 @@ edition: ?, inferred: ? ), - record_id: ::graph::types::knowledge::entity::EntityRecordId( + record_id: ::graph::types::knowledge::entity::RecordId( edition_id: ::graph::types::knowledge::entity::EntityEditionId(::core::uuid::Uuid(String)), entity_id: ::graph::types::knowledge::entity::EntityId( draft_id: ::core::option::None(Null) @@ -231,9 +255,17 @@ web_id: ::graph::types::principal::actor_group::web::WebId(::graph::types::principal::actor_group::ActorGroupEntityUuid(::core::uuid::Uuid(String))) ) ), - temporal_versioning: ::graph::types::knowledge::entity::EntityTemporalMetadata( - decision_time: ?, - transaction_time: ? + temporal_versioning: ::graph::types::knowledge::entity::TemporalMetadata( + decision_time: ::graph::temporal::DecisionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )), + transaction_time: ::graph::temporal::TransactionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )) ) ), properties: ? @@ -241,7 +273,28 @@ ) ┌─ ::graph::head::entities -└→ (::graph::TimeAxis(:)) -> +└→ ( + ::graph::temporal::PinnedTransactionTimeTemporalAxes( + pinned: ::graph::temporal::TransactionTime(::graph::temporal::Timestamp(Integer)), + variable: ::graph::temporal::DecisionTime(::graph::temporal::Interval( + end: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )) + ) + | ::graph::temporal::PinnedDecisionTimeTemporalAxes( + pinned: ::graph::temporal::DecisionTime(::graph::temporal::Timestamp(Integer)), + variable: ::graph::temporal::TransactionTime(::graph::temporal::Interval( + end: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )) + ) + ) -> ::graph::Graph( 'marker: ::graph::types::knowledge::entity::Entity( encodings: ::graph::types::knowledge::entity::EntityEncodings( @@ -281,7 +334,7 @@ edition: ?, inferred: ? ), - record_id: ::graph::types::knowledge::entity::EntityRecordId( + record_id: ::graph::types::knowledge::entity::RecordId( edition_id: ::graph::types::knowledge::entity::EntityEditionId(::core::uuid::Uuid(String)), entity_id: ::graph::types::knowledge::entity::EntityId( draft_id: ::core::option::None(Null) @@ -290,9 +343,17 @@ web_id: ::graph::types::principal::actor_group::web::WebId(::graph::types::principal::actor_group::ActorGroupEntityUuid(::core::uuid::Uuid(String))) ) ), - temporal_versioning: ::graph::types::knowledge::entity::EntityTemporalMetadata( - decision_time: ?, - transaction_time: ? + temporal_versioning: ::graph::types::knowledge::entity::TemporalMetadata( + decision_time: ::graph::temporal::DecisionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )), + transaction_time: ::graph::temporal::TransactionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )) ) ), properties: ? @@ -300,8 +361,47 @@ ) ┌─ ::graph::tmp::decision_time_now() -└→ ::graph::TimeAxis(:) +└→ ::graph::temporal::PinnedTransactionTimeTemporalAxes( + pinned: ::graph::temporal::TransactionTime(::graph::temporal::Timestamp(Integer)), + variable: ::graph::temporal::DecisionTime(::graph::temporal::Interval( + end: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )) + ) + | ::graph::temporal::PinnedDecisionTimeTemporalAxes( + pinned: ::graph::temporal::DecisionTime(::graph::temporal::Timestamp(Integer)), + variable: ::graph::temporal::TransactionTime(::graph::temporal::Interval( + end: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )) + ) ┌─ ::graph::tmp::decision_time_now -└→ () -> ::graph::TimeAxis(:) +└→ () -> + (::graph::temporal::PinnedTransactionTimeTemporalAxes( + pinned: ::graph::temporal::TransactionTime(::graph::temporal::Timestamp(Integer)), + variable: ::graph::temporal::DecisionTime(::graph::temporal::Interval( + end: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )) + ) + | ::graph::temporal::PinnedDecisionTimeTemporalAxes( + pinned: ::graph::temporal::DecisionTime(::graph::temporal::Timestamp(Integer)), + variable: ::graph::temporal::TransactionTime(::graph::temporal::Interval( + end: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )) + )) diff --git a/libs/@local/hashql/hir/tests/ui/lower/inference/bind-arguments.stdout b/libs/@local/hashql/hir/tests/ui/lower/inference/bind-arguments.stdout index a7c21930b83..ef79b55265a 100644 --- a/libs/@local/hashql/hir/tests/ui/lower/inference/bind-arguments.stdout +++ b/libs/@local/hashql/hir/tests/ui/lower/inference/bind-arguments.stdout @@ -12,10 +12,10 @@ └→ _0«Number» ┌─ ::core::math::add -└→ [?25 = Number, ?26 = Integer] ( - T?25«Number», - U?26«Integer» - ) -> (T?25«Number» | U?26«Integer») +└→ [?29 = Number, ?30 = Integer] ( + T?29«Number», + U?30«Integer» + ) -> (T?29«Number» | U?30«Integer») ┌─ 42.12 └→ Number diff --git a/libs/@local/hashql/hir/tests/ui/lower/inference/call.stdout b/libs/@local/hashql/hir/tests/ui/lower/inference/call.stdout index 5ac50bd4563..91881d9db86 100644 --- a/libs/@local/hashql/hir/tests/ui/lower/inference/call.stdout +++ b/libs/@local/hashql/hir/tests/ui/lower/inference/call.stdout @@ -12,8 +12,8 @@ └→ _0«Number» ┌─ ::core::math::add -└→ (T?25«Number», U?26«Integer») -> - (T?25«Number» | U?26«Integer») +└→ (T?29«Number», U?30«Integer») -> + (T?29«Number» | U?30«Integer») ┌─ 42.12 └→ Number diff --git a/libs/@local/hashql/hir/tests/ui/lower/inference/closure-call-unconstrained-direct.stdout b/libs/@local/hashql/hir/tests/ui/lower/inference/closure-call-unconstrained-direct.stdout index d43b05c829c..c2ced5b7b27 100644 --- a/libs/@local/hashql/hir/tests/ui/lower/inference/closure-call-unconstrained-direct.stdout +++ b/libs/@local/hashql/hir/tests/ui/lower/inference/closure-call-unconstrained-direct.stdout @@ -1,21 +1,21 @@ ════ Initial HIR ═══════════════════════════════════════════════════════════════ -(a:0: ?26): ?26 -> a:0("1") +(a:0: ?30): ?30 -> a:0("1") ════ HIR after type inference ══════════════════════════════════════════════════ -(a:0: ?27): ?27 -> a:0("1") +(a:0: ?31): ?31 -> a:0("1") ════ Types ═════════════════════════════════════════════════════════════════════ -┌─ (a:0: ?27): ?27 -> a:0("1") +┌─ (a:0: ?31): ?31 -> a:0("1") └→ _0«String» -┌─ (a:0: ?27): ?27 -> a:0 -└→ (T:0?27«String») -> T:0?27«String» +┌─ (a:0: ?31): ?31 -> a:0 +└→ (T:0?31«String») -> T:0?31«String» ┌─ a:0 -└→ ?26«?» +└→ ?30«?» ┌─ "1" └→ String diff --git a/libs/@local/hashql/hir/tests/ui/lower/inference/closure-call-unconstrained.stdout b/libs/@local/hashql/hir/tests/ui/lower/inference/closure-call-unconstrained.stdout index 3da8093edc6..c4d4af037ac 100644 --- a/libs/@local/hashql/hir/tests/ui/lower/inference/closure-call-unconstrained.stdout +++ b/libs/@local/hashql/hir/tests/ui/lower/inference/closure-call-unconstrained.stdout @@ -1,48 +1,48 @@ ════ Initial HIR ═══════════════════════════════════════════════════════════════ -let foo:0 = (a:0: ?26): ?26 -> a:0, - bar:0 = (a:1: ?28): ?28 -> foo:0(a:1) +let foo:0 = (a:0: ?30): ?30 -> a:0, + bar:0 = (a:1: ?32): ?32 -> foo:0(a:1) in bar:0(2) ════ HIR after type inference ══════════════════════════════════════════════════ -let foo:0 = (a:0: ?29): ?29 -> a:0, - bar:0 = (a:1: ?31): ?31 -> foo:0(a:1) +let foo:0 = (a:0: ?33): ?33 -> a:0, + bar:0 = (a:1: ?35): ?35 -> foo:0(a:1) in bar:0(2) ════ Types ═════════════════════════════════════════════════════════════════════ -┌─ let foo:0 = (a:0: ?29): ?29 -> a:0, -│ bar:0 = (a:1: ?31): ?31 -> foo:0(a:1) +┌─ let foo:0 = (a:0: ?33): ?33 -> a:0, +│ bar:0 = (a:1: ?35): ?35 -> foo:0(a:1) │ in │ bar:0(2) └→ _1«Integer» -┌─ (a:0: ?29): ?29 -> a:0 -└→ (T:0?29) -> T:0?29 +┌─ (a:0: ?33): ?33 -> a:0 +└→ (T:0?33) -> T:0?33 ┌─ a:0 -└→ ?26«?» +└→ ?30«?» -┌─ (a:1: ?31): ?31 -> foo:0(a:1) -└→ (T:1?31) -> T:1?31 +┌─ (a:1: ?35): ?35 -> foo:0(a:1) +└→ (T:1?35) -> T:1?35 ┌─ foo:0(a:1) └→ _0«?» ┌─ foo:0 -└→ (T:0?30«?») -> T:0?30«?» +└→ (T:0?34«?») -> T:0?34«?» ┌─ a:1 -└→ ?28«?» +└→ ?32«?» ┌─ bar:0(2) └→ _1«Integer» ┌─ bar:0 -└→ (T:1?32«Integer») -> T:1?32«Integer» +└→ (T:1?36«Integer») -> T:1?36«Integer» ┌─ 2 └→ Integer diff --git a/libs/@local/hashql/hir/tests/ui/lower/inference/closure-constrained.stdout b/libs/@local/hashql/hir/tests/ui/lower/inference/closure-constrained.stdout index ae28568e8f4..865a64cd007 100644 --- a/libs/@local/hashql/hir/tests/ui/lower/inference/closure-constrained.stdout +++ b/libs/@local/hashql/hir/tests/ui/lower/inference/closure-constrained.stdout @@ -1,26 +1,26 @@ ════ Initial HIR ═══════════════════════════════════════════════════════════════ -(a:0: ?26, b:0: ?26): ?26 -> ::core::math::add(a:0, b:0) +(a:0: ?30, b:0: ?30): ?30 -> ::core::math::add(a:0, b:0) ════ HIR after type inference ══════════════════════════════════════════════════ -(a:0: ?29, b:0: ?29): ?29 -> ::core::math::add(a:0, b:0) +(a:0: ?33, b:0: ?33): ?33 -> ::core::math::add(a:0, b:0) ════ Types ═════════════════════════════════════════════════════════════════════ -┌─ (a:0: ?29, b:0: ?29): ?29 -> ::core::math::add(a:0, b:0) -└→ (T:0?29, T:0?29) -> T:0?29 +┌─ (a:0: ?33, b:0: ?33): ?33 -> ::core::math::add(a:0, b:0) +└→ (T:0?33, T:0?33) -> T:0?33 ┌─ ::core::math::add(a:0, b:0) └→ _0«Number» ┌─ ::core::math::add -└→ (T?27«Number», U?28«Number») -> - (T?27«Number» | U?28«Number») +└→ (T?31«Number», U?32«Number») -> + (T?31«Number» | U?32«Number») ┌─ a:0 -└→ ?26«Number» +└→ ?30«Number» ┌─ b:0 -└→ ?26«Number» +└→ ?30«Number» diff --git a/libs/@local/hashql/hir/tests/ui/lower/inference/closure-integer.stdout b/libs/@local/hashql/hir/tests/ui/lower/inference/closure-integer.stdout index e7fe0e27a13..f89fedf61de 100644 --- a/libs/@local/hashql/hir/tests/ui/lower/inference/closure-integer.stdout +++ b/libs/@local/hashql/hir/tests/ui/lower/inference/closure-integer.stdout @@ -1,26 +1,26 @@ ════ Initial HIR ═══════════════════════════════════════════════════════════════ -(a:0: ?26, b:0: ?26): ?26 -> ::core::math::add(a:0, b:0) +(a:0: ?30, b:0: ?30): ?30 -> ::core::math::add(a:0, b:0) ════ HIR after type inference ══════════════════════════════════════════════════ -(a:0: ?29, b:0: ?29): ?29 -> ::core::math::add(a:0, b:0) +(a:0: ?33, b:0: ?33): ?33 -> ::core::math::add(a:0, b:0) ════ Types ═════════════════════════════════════════════════════════════════════ -┌─ (a:0: ?29, b:0: ?29): ?29 -> ::core::math::add(a:0, b:0) -└→ (T:0?29, T:0?29) -> T:0?29 +┌─ (a:0: ?33, b:0: ?33): ?33 -> ::core::math::add(a:0, b:0) +└→ (T:0?33, T:0?33) -> T:0?33 ┌─ ::core::math::add(a:0, b:0) └→ _0«Integer» ┌─ ::core::math::add -└→ (T?27«Integer», U?28«Integer») -> - (T?27«Integer» | U?28«Integer») +└→ (T?31«Integer», U?32«Integer») -> + (T?31«Integer» | U?32«Integer») ┌─ a:0 -└→ ?26«Integer» +└→ ?30«Integer» ┌─ b:0 -└→ ?26«Integer» +└→ ?30«Integer» diff --git a/libs/@local/hashql/hir/tests/ui/lower/inference/ctor.stdout b/libs/@local/hashql/hir/tests/ui/lower/inference/ctor.stdout index efb942d3449..4e12f9ec803 100644 --- a/libs/@local/hashql/hir/tests/ui/lower/inference/ctor.stdout +++ b/libs/@local/hashql/hir/tests/ui/lower/inference/ctor.stdout @@ -12,7 +12,7 @@ └→ _0«::core::option::Some(Integer)» ┌─ ::core::option::Some -└→ (T?25«Integer») -> ::core::option::Some(T?25«Integer») +└→ (T?29«Integer») -> ::core::option::Some(T?29«Integer») ┌─ 2 └→ Integer diff --git a/libs/@local/hashql/hir/tests/ui/lower/inference/if.stdout b/libs/@local/hashql/hir/tests/ui/lower/inference/if.stdout index cd2219bb156..1c32a4393a5 100644 --- a/libs/@local/hashql/hir/tests/ui/lower/inference/if.stdout +++ b/libs/@local/hashql/hir/tests/ui/lower/inference/if.stdout @@ -24,7 +24,7 @@ else ::core::option::None() └→ _0«::core::option::Some(Integer)» ┌─ ::core::option::Some -└→ (T?25«Integer») -> ::core::option::Some(T?25«Integer») +└→ (T?29«Integer») -> ::core::option::Some(T?29«Integer») ┌─ 2 └→ Integer diff --git a/libs/@local/hashql/hir/tests/ui/lower/inference/infer-argument.stdout b/libs/@local/hashql/hir/tests/ui/lower/inference/infer-argument.stdout index 00aa99dbcea..2f134281bbc 100644 --- a/libs/@local/hashql/hir/tests/ui/lower/inference/infer-argument.stdout +++ b/libs/@local/hashql/hir/tests/ui/lower/inference/infer-argument.stdout @@ -18,8 +18,8 @@ └→ _3«Integer» ┌─ ::core::math::add -└→ (T?25«Integer», U?26«Integer») -> - (T?25«Integer» | U?26«Integer») +└→ (T?29«Integer», U?30«Integer») -> + (T?29«Integer» | U?30«Integer») ┌─ lhs:0 └→ _0«Integer» diff --git a/libs/@local/hashql/hir/tests/ui/lower/inference/qualified-variable.stdout b/libs/@local/hashql/hir/tests/ui/lower/inference/qualified-variable.stdout index 334131d8782..88adbaa4421 100644 --- a/libs/@local/hashql/hir/tests/ui/lower/inference/qualified-variable.stdout +++ b/libs/@local/hashql/hir/tests/ui/lower/inference/qualified-variable.stdout @@ -12,8 +12,8 @@ └→ _0«Integer» ┌─ ::core::math::add -└→ (T?25«Integer», U?26«Integer») -> - (T?25«Integer» | U?26«Integer») +└→ (T?29«Integer», U?30«Integer») -> + (T?29«Integer» | U?30«Integer») ┌─ 123 └→ Integer diff --git a/libs/@local/hashql/hir/tests/ui/lower/specialization/collect-custom-collect.stderr b/libs/@local/hashql/hir/tests/ui/lower/specialization/collect-custom-collect.stderr index 4100f56b8a8..f999276d515 100644 --- a/libs/@local/hashql/hir/tests/ui/lower/specialization/collect-custom-collect.stderr +++ b/libs/@local/hashql/hir/tests/ui/lower/specialization/collect-custom-collect.stderr @@ -43,7 +43,7 @@ error[lower::specialization::non-intrinsic-graph-operation]: Non-intrinsic funct │ edition: ?, │ inferred: ? │ ), - │ record_id: ::graph::types::knowledge::entity::EntityRecordId( + │ record_id: ::graph::types::knowledge::entity::RecordId( │ edition_id: ::graph::types::knowledge::entity::EntityEditionId(::core::uuid::Uuid(String)), │ entity_id: ::graph::types::knowledge::entity::EntityId( │ draft_id: ::core::option::None(Null) @@ -52,9 +52,17 @@ error[lower::specialization::non-intrinsic-graph-operation]: Non-intrinsic funct │ web_id: ::graph::types::principal::actor_group::web::WebId(::graph::types::principal::actor_group::ActorGroupEntityUuid(::core::uuid::Uuid(String))) │ ) │ ), - │ temporal_versioning: ::graph::types::knowledge::entity::EntityTemporalMetadata( - │ decision_time: ?, - │ transaction_time: ? + │ temporal_versioning: ::graph::types::knowledge::entity::TemporalMetadata( + │ decision_time: ::graph::temporal::DecisionTime(::graph::temporal::Interval( + │ end: ::graph::temporal::UnboundedTemporalBound(Null) + │ | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + │ start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + │ )), + │ transaction_time: ::graph::temporal::TransactionTime(::graph::temporal::Interval( + │ end: ::graph::temporal::UnboundedTemporalBound(Null) + │ | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + │ start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + │ )) │ ) │ ), │ properties: ? @@ -99,7 +107,7 @@ error[lower::specialization::non-intrinsic-graph-operation]: Non-intrinsic funct │ edition: ?, │ inferred: ? │ ), - │ record_id: ::graph::types::knowledge::entity::EntityRecordId( + │ record_id: ::graph::types::knowledge::entity::RecordId( │ edition_id: ::graph::types::knowledge::entity::EntityEditionId(::core::uuid::Uuid(String)), │ entity_id: ::graph::types::knowledge::entity::EntityId( │ draft_id: ::core::option::None(Null) @@ -108,9 +116,17 @@ error[lower::specialization::non-intrinsic-graph-operation]: Non-intrinsic funct │ web_id: ::graph::types::principal::actor_group::web::WebId(::graph::types::principal::actor_group::ActorGroupEntityUuid(::core::uuid::Uuid(String))) │ ) │ ), - │ temporal_versioning: ::graph::types::knowledge::entity::EntityTemporalMetadata( - │ decision_time: ?, - │ transaction_time: ? + │ temporal_versioning: ::graph::types::knowledge::entity::TemporalMetadata( + │ decision_time: ::graph::temporal::DecisionTime(::graph::temporal::Interval( + │ end: ::graph::temporal::UnboundedTemporalBound(Null) + │ | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + │ start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + │ )), + │ transaction_time: ::graph::temporal::TransactionTime(::graph::temporal::Interval( + │ end: ::graph::temporal::UnboundedTemporalBound(Null) + │ | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + │ start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + │ )) │ ) │ ), │ properties: ? diff --git a/libs/@local/hashql/hir/tests/ui/lower/specialization/collect-filter-graph.stdout b/libs/@local/hashql/hir/tests/ui/lower/specialization/collect-filter-graph.stdout index 70b5b74655a..ee0df31c049 100644 --- a/libs/@local/hashql/hir/tests/ui/lower/specialization/collect-filter-graph.stdout +++ b/libs/@local/hashql/hir/tests/ui/lower/specialization/collect-filter-graph.stdout @@ -55,7 +55,7 @@ edition: ?, inferred: ? ), - record_id: ::graph::types::knowledge::entity::EntityRecordId( + record_id: ::graph::types::knowledge::entity::RecordId( edition_id: ::graph::types::knowledge::entity::EntityEditionId(::core::uuid::Uuid(String)), entity_id: ::graph::types::knowledge::entity::EntityId( draft_id: ::core::option::None(Null) @@ -64,9 +64,17 @@ web_id: ::graph::types::principal::actor_group::web::WebId(::graph::types::principal::actor_group::ActorGroupEntityUuid(::core::uuid::Uuid(String))) ) ), - temporal_versioning: ::graph::types::knowledge::entity::EntityTemporalMetadata( - decision_time: ?, - transaction_time: ? + temporal_versioning: ::graph::types::knowledge::entity::TemporalMetadata( + decision_time: ::graph::temporal::DecisionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )), + transaction_time: ::graph::temporal::TransactionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )) ) ), properties: ? diff --git a/libs/@local/hashql/hir/tests/ui/lower/specialization/complex.stdout b/libs/@local/hashql/hir/tests/ui/lower/specialization/complex.stdout index 857b8b6159d..f2e17b8f8e4 100644 --- a/libs/@local/hashql/hir/tests/ui/lower/specialization/complex.stdout +++ b/libs/@local/hashql/hir/tests/ui/lower/specialization/complex.stdout @@ -2,7 +2,7 @@ let foo:0 = 1, bar:0 = 1, - equals:0 = (lhs:0: ?26, rhs:0: ?26): Boolean -> + equals:0 = (lhs:0: ?30, rhs:0: ?30): Boolean -> ::core::cmp::eq(lhs:0, rhs:0) in equals:0(foo:0, bar:0) @@ -11,6 +11,6 @@ equals:0(foo:0, bar:0) let foo:0 = 1, bar:0 = 1, - equals:0 = (lhs:0: ?29, rhs:0: ?29): Boolean -> lhs:0 == rhs:0 + equals:0 = (lhs:0: ?33, rhs:0: ?33): Boolean -> lhs:0 == rhs:0 in equals:0(foo:0, bar:0) diff --git a/libs/@local/hashql/hir/tests/ui/lower/specialization/filter-graph.stdout b/libs/@local/hashql/hir/tests/ui/lower/specialization/filter-graph.stdout index 742855c98c0..7188231ca00 100644 --- a/libs/@local/hashql/hir/tests/ui/lower/specialization/filter-graph.stdout +++ b/libs/@local/hashql/hir/tests/ui/lower/specialization/filter-graph.stdout @@ -54,7 +54,7 @@ edition: ?, inferred: ? ), - record_id: ::graph::types::knowledge::entity::EntityRecordId( + record_id: ::graph::types::knowledge::entity::RecordId( edition_id: ::graph::types::knowledge::entity::EntityEditionId(::core::uuid::Uuid(String)), entity_id: ::graph::types::knowledge::entity::EntityId( draft_id: ::core::option::None(Null) @@ -63,9 +63,17 @@ web_id: ::graph::types::principal::actor_group::web::WebId(::graph::types::principal::actor_group::ActorGroupEntityUuid(::core::uuid::Uuid(String))) ) ), - temporal_versioning: ::graph::types::knowledge::entity::EntityTemporalMetadata( - decision_time: ?, - transaction_time: ? + temporal_versioning: ::graph::types::knowledge::entity::TemporalMetadata( + decision_time: ::graph::temporal::DecisionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )), + transaction_time: ::graph::temporal::TransactionTime(::graph::temporal::Interval( + end: ::graph::temporal::UnboundedTemporalBound(Null) + | ::graph::temporal::ExclusiveTemporalBound(::graph::temporal::Timestamp(Integer)), + start: ::graph::temporal::InclusiveTemporalBound(::graph::temporal::Timestamp(Integer)) + )) ) ), properties: ? diff --git a/libs/@local/hashql/hir/tests/ui/reify/closure.stdout b/libs/@local/hashql/hir/tests/ui/reify/closure.stdout index e22641a558f..ef0c2679b52 100644 --- a/libs/@local/hashql/hir/tests/ui/reify/closure.stdout +++ b/libs/@local/hashql/hir/tests/ui/reify/closure.stdout @@ -1 +1 @@ -(foo:0: ?26, bar:0: ?26): ?26 -> ::core::math::add(foo:0, bar:0) \ No newline at end of file +(foo:0: ?30, bar:0: ?30): ?30 -> ::core::math::add(foo:0, bar:0) \ No newline at end of file diff --git a/libs/@local/hashql/mir/src/pass/execution/cost/analysis.rs b/libs/@local/hashql/mir/src/pass/execution/cost/analysis.rs index d7a589654c9..72becc17c3d 100644 --- a/libs/@local/hashql/mir/src/pass/execution/cost/analysis.rs +++ b/libs/@local/hashql/mir/src/pass/execution/cost/analysis.rs @@ -206,6 +206,12 @@ mod tests { TransferCostConfig::new(InformationRange::full()) } + fn make_zero_terminator_costs(block_count: usize) -> TargetArray> { + TargetArray::from_fn(|_| { + TerminatorCostVec::from_costs(&vec![Some(cost!(0)); block_count], Global) + }) + } + fn make_targets(body: &crate::body::Body<'_>, domain: TargetBitSet) -> Vec { body.basic_blocks.iter().map(|_| domain).collect() } @@ -233,10 +239,12 @@ mod tests { let costs: TargetArray> = TargetArray::from_fn(|_| StatementCostVec::from_iter([1].into_iter(), Global)); + let terminator_costs = make_zero_terminator_costs(body.basic_blocks.len()); let analysis = BasicBlockCostAnalysis { vertex: VertexType::Entity, assignments: targets, statement_costs: &costs, + terminator_costs: &terminator_costs, }; let result = analysis.analyze_in(&default_config(), &body.basic_blocks, Global); @@ -274,10 +282,12 @@ mod tests { let costs: TargetArray> = TargetArray::from_fn(|_| StatementCostVec::from_iter([1].into_iter(), Global)); + let terminator_costs = make_zero_terminator_costs(body.basic_blocks.len()); let analysis = BasicBlockCostAnalysis { vertex: VertexType::Entity, assignments: targets, statement_costs: &costs, + terminator_costs: &terminator_costs, }; let config = default_config(); @@ -329,10 +339,12 @@ mod tests { let costs: TargetArray> = TargetArray::from_fn(|_| StatementCostVec::from_iter([1].into_iter(), Global)); + let terminator_costs = make_zero_terminator_costs(body.basic_blocks.len()); let analysis = BasicBlockCostAnalysis { vertex: VertexType::Entity, assignments: targets, statement_costs: &costs, + terminator_costs: &terminator_costs, }; let result = analysis.analyze_in(&default_config(), &body.basic_blocks, Global); @@ -386,10 +398,12 @@ mod tests { let costs: TargetArray> = TargetArray::from_fn(|_| StatementCostVec::from_iter([1].into_iter(), Global)); + let terminator_costs = make_zero_terminator_costs(body.basic_blocks.len()); let analysis = BasicBlockCostAnalysis { vertex: VertexType::Entity, assignments: targets, statement_costs: &costs, + terminator_costs: &terminator_costs, }; // Use a bounded properties size so both premiums are finite and comparable. @@ -445,10 +459,12 @@ mod tests { // Use zero properties size so Properties path doesn't contribute noise let config = TransferCostConfig::new(InformationRange::zero()); + let terminator_costs = make_zero_terminator_costs(body.basic_blocks.len()); let analysis = BasicBlockCostAnalysis { vertex: VertexType::Entity, assignments: targets, statement_costs: &costs, + terminator_costs: &terminator_costs, }; let result = analysis.analyze_in(&config, &body.basic_blocks, Global); @@ -495,10 +511,12 @@ mod tests { let costs: TargetArray> = TargetArray::from_fn(|_| StatementCostVec::from_iter([1].into_iter(), Global)); + let terminator_costs = make_zero_terminator_costs(body.basic_blocks.len()); let analysis = BasicBlockCostAnalysis { vertex: VertexType::Entity, assignments: targets, statement_costs: &costs, + terminator_costs: &terminator_costs, }; let result = analysis.analyze_in(&default_config(), &body.basic_blocks, Global); @@ -548,10 +566,12 @@ mod tests { TargetArray::from_fn(|_| StatementCostVec::from_iter([2, 1, 0].into_iter(), Global)); let config = default_config(); + let terminator_costs = make_zero_terminator_costs(body.basic_blocks.len()); let analysis = BasicBlockCostAnalysis { vertex: VertexType::Entity, assignments: targets, statement_costs: &costs, + terminator_costs: &terminator_costs, }; let result = analysis.analyze_in(&config, &body.basic_blocks, Global); @@ -585,4 +605,55 @@ mod tests { assert_eq!(cost, base, "bb2 target {target:?} should have zero load"); } } + + /// Terminator cost is included in the per-block total. + /// + /// Uses a nonzero terminator cost and verifies the total exceeds the statement-only + /// base. Removing the terminator cost addition would cause this test to fail. + #[test] + fn terminator_cost_included_in_total() { + let heap = Heap::new(); + let interner = Interner::new(&heap); + let env = Environment::new(&heap); + + let body = body!(interner, env; [graph::read::filter]@0/2 -> Int { + decl env: (Int), vertex: [Opaque sym::path::Entity; ?], val: Int; + @proj env_0 = env.0: Int; + + bb0() { + val = load env_0; + return val; + } + }); + + let targets = make_targets(&body, all_targets()); + let targets = BasicBlockSlice::from_raw(&targets); + + let statement_costs: TargetArray> = + TargetArray::from_fn(|_| StatementCostVec::from_iter([1].into_iter(), Global)); + + let terminator_costs: TargetArray> = + TargetArray::from_fn(|_| TerminatorCostVec::from_costs(&[Some(cost!(10))], Global)); + + let analysis = BasicBlockCostAnalysis { + vertex: VertexType::Entity, + assignments: targets, + statement_costs: &statement_costs, + terminator_costs: &terminator_costs, + }; + + let result = analysis.analyze_in(&default_config(), &body.basic_blocks, Global); + let bb0 = BasicBlockId::new(0); + + for target in TargetId::all() { + let total = result.cost(bb0, target); + let statement_base = statement_costs[target].sum_approx(bb0); + + assert!( + total > statement_base, + "target {target:?}: total ({total}) should exceed statement base \ + ({statement_base}) because terminator cost is nonzero" + ); + } + } } diff --git a/libs/@local/hashql/mir/src/pass/execution/cost/mod.rs b/libs/@local/hashql/mir/src/pass/execution/cost/mod.rs index 5332c985c58..ef61a169a54 100644 --- a/libs/@local/hashql/mir/src/pass/execution/cost/mod.rs +++ b/libs/@local/hashql/mir/src/pass/execution/cost/mod.rs @@ -348,6 +348,16 @@ impl TerminatorCostVec { pub(crate) fn new_in(blocks: &BasicBlocks, alloc: A) -> Self { Self(BasicBlockVec::with_capacity_in(blocks.len(), alloc)) } + + /// Creates a cost vector from a slice of optional cost values. + #[cfg(test)] + pub(crate) fn from_costs(costs: &[Option], alloc: A) -> Self { + let mut vec = BasicBlockVec::from_elem_in(None, costs.len(), alloc); + for (i, cost) in costs.iter().enumerate() { + vec[BasicBlockId::from_usize(i)] = *cost; + } + Self(vec) + } } impl TerminatorCostVec { diff --git a/libs/@local/hashql/mir/src/pass/execution/cost/tests.rs b/libs/@local/hashql/mir/src/pass/execution/cost/tests.rs index c91068ea061..ba41a7ffa73 100644 --- a/libs/@local/hashql/mir/src/pass/execution/cost/tests.rs +++ b/libs/@local/hashql/mir/src/pass/execution/cost/tests.rs @@ -4,7 +4,6 @@ use core::num::NonZero; use super::{Cost, StatementCostVec, TerminatorCostVec}; use crate::body::{ basic_block::{BasicBlockId, BasicBlockSlice}, - basic_blocks::BasicBlocks, location::Location, }; @@ -47,6 +46,76 @@ fn cost_new_unchecked_valid() { assert_eq!(Cost::new(100), Some(hundred)); } +macro_rules! nz { + ($value:expr) => { + const { NonZero::new($value).unwrap() } + }; +} + +fn bb(index: u32) -> BasicBlockId { + BasicBlockId::new(index) +} + +/// No splits: region lengths all 1. Output equals input. +#[test] +fn remap_no_splits() { + let mut costs = TerminatorCostVec::from_costs(&[Some(cost!(7)), Some(cost!(3))], Global); + + let regions = [(nz!(1), false), (nz!(1), false)]; + costs.remap(BasicBlockSlice::from_raw(®ions)); + + assert_eq!(costs.of(bb(0)), Some(cost!(7))); + assert_eq!(costs.of(bb(1)), Some(cost!(3))); +} + +/// Single block splits into 2 regions. +#[test] +fn remap_single_split() { + let mut costs = TerminatorCostVec::from_costs(&[Some(cost!(7))], Global); + + let regions = [(nz!(2), true)]; + costs.remap(BasicBlockSlice::from_raw(®ions)); + + // First block gets synthesized Goto: zero cost + assert_eq!(costs.of(bb(0)), Some(cost!(0))); + // Second block holds original terminator + assert_eq!(costs.of(bb(1)), Some(cost!(7))); +} + +/// Mixed splits with None: original None cost preserved on last block of region. +#[test] +fn remap_mixed_with_none() { + let mut costs = TerminatorCostVec::from_costs(&[Some(cost!(4)), None, Some(cost!(8))], Global); + + let regions = [(nz!(2), true), (nz!(1), false), (nz!(3), true)]; + costs.remap(BasicBlockSlice::from_raw(®ions)); + + // Region 0: split into 2 blocks + assert_eq!(costs.of(bb(0)), Some(cost!(0))); + assert_eq!(costs.of(bb(1)), Some(cost!(4))); + // Region 1: no split + assert_eq!(costs.of(bb(2)), None); + // Region 2: split into 3 blocks + assert_eq!(costs.of(bb(3)), Some(cost!(0))); + assert_eq!(costs.of(bb(4)), Some(cost!(0))); + assert_eq!(costs.of(bb(5)), Some(cost!(8))); +} + +/// All blocks split: every non-last block in each region gets zero cost. +#[test] +fn remap_all_split() { + let mut costs = TerminatorCostVec::from_costs(&[Some(cost!(10)), Some(cost!(20))], Global); + + let regions = [(nz!(3), true), (nz!(2), true)]; + costs.remap(BasicBlockSlice::from_raw(®ions)); + + assert_eq!(costs.of(bb(0)), Some(cost!(0))); + assert_eq!(costs.of(bb(1)), Some(cost!(0))); + assert_eq!(costs.of(bb(2)), Some(cost!(10))); + assert_eq!(costs.of(bb(3)), Some(cost!(0))); + assert_eq!(costs.of(bb(4)), Some(cost!(20))); +} + /// `StatementCostVec` uses 1-based `Location` indexing to address the underlying /// 0-based `BlockPartitionedVec`. #[test] diff --git a/libs/@local/hashql/mir/src/pass/execution/placement/solve/tests.rs b/libs/@local/hashql/mir/src/pass/execution/placement/solve/tests.rs index 06581e86a79..ea875739fd1 100644 --- a/libs/@local/hashql/mir/src/pass/execution/placement/solve/tests.rs +++ b/libs/@local/hashql/mir/src/pass/execution/placement/solve/tests.rs @@ -29,7 +29,9 @@ use crate::{ analysis::size_estimation::{InformationRange, InformationUnit}, execution::{ ApproxCost, Cost, VertexType, - cost::{BasicBlockCostAnalysis, BasicBlockCostVec, StatementCostVec}, + cost::{ + BasicBlockCostAnalysis, BasicBlockCostVec, StatementCostVec, TerminatorCostVec, + }, placement::error::PlacementDiagnosticCategory, target::{TargetArray, TargetBitSet, TargetId}, terminator_placement::{TerminatorTransitionCostVec, TransMatrix}, @@ -142,10 +144,14 @@ pub(crate) fn make_block_costs_with_config<'heap>( alloc: &'heap Heap, ) -> BasicBlockCostVec<&'heap Heap> { let assignments = BasicBlockSlice::from_raw(domains); + let terminator_costs: TargetArray> = TargetArray::from_fn(|_| { + TerminatorCostVec::from_costs(&vec![Some(cost!(0)); body.basic_blocks.len()], alloc) + }); BasicBlockCostAnalysis { vertex: VertexType::Entity, assignments, statement_costs: statements, + terminator_costs: &terminator_costs, } .analyze_in(config, &body.basic_blocks, alloc) } diff --git a/libs/@local/hashql/mir/src/pass/execution/splitting/tests.rs b/libs/@local/hashql/mir/src/pass/execution/splitting/tests.rs index 3876f854426..4d033486809 100644 --- a/libs/@local/hashql/mir/src/pass/execution/splitting/tests.rs +++ b/libs/@local/hashql/mir/src/pass/execution/splitting/tests.rs @@ -106,6 +106,28 @@ fn make_all_supported_terminator_costs<'heap>( }) } +/// Creates terminator costs with per-target, per-block support patterns. +/// +/// `patterns[target][block]` is `true` if the target supports the terminator of that block. +fn make_terminator_costs<'heap, const N: usize>( + body: &Body<'heap>, + patterns: TargetArray<[bool; N]>, + heap: &'heap Heap, +) -> TargetArray> { + let mut costs = TargetArray::from_fn(|_| TerminatorCostVec::new_in(&body.basic_blocks, heap)); + + for (target_id, block_patterns) in patterns.iter_enumerated() { + for (block_index, &supported) in block_patterns.iter().enumerate() { + if supported { + let block = BasicBlockId::new(block_index as u32); + costs[target_id].insert(block, cost!(1)); + } + } + } + + costs +} + fn assert_assignment_locals(body: &Body<'_>, block_id: BasicBlockId, expected: &[&str]) { let block = &body.basic_blocks[block_id]; assert_eq!(block.statements.len(), expected.len()); @@ -1218,3 +1240,486 @@ fn split_block_references_updated() { &targets, ); } + +/// One statement, terminator is superset of statement support: no extra region. +#[test] +fn count_regions_terminator_superset_no_split() { + let heap = Heap::new(); + let interner = Interner::new(&heap); + let env = Environment::new(&heap); + + let body = body!(interner, env; fn@0/0 -> Int { + decl x: Int; + + bb0() { + x = load 42; + return x; + } + }); + + // Statement supported on {I, P} + let patterns = TargetArray::from_raw([[[true]], [[true]], [[false]]]); + let costs = make_target_costs(&body, patterns, &heap); + // Terminator supported on {I, P, E} (superset) + let terminator_costs = make_all_supported_terminator_costs(&body, &heap); + let regions = count_regions(&body, &costs, &terminator_costs, Global); + + assert_eq!(regions[BasicBlockId::new(0)].0.get(), 1); + assert!(!regions[BasicBlockId::new(0)].1); +} + +/// One statement, terminator is strict subset: extra region needed. +#[test] +fn count_regions_terminator_subset_splits() { + let heap = Heap::new(); + let interner = Interner::new(&heap); + let env = Environment::new(&heap); + + let body = body!(interner, env; fn@0/0 -> Int { + decl x: Int; + + bb0() { + x = load 42; + return x; + } + }); + + // Statement supported on {I, P} + let patterns = TargetArray::from_raw([[[true]], [[true]], [[false]]]); + let costs = make_target_costs(&body, patterns, &heap); + // Terminator supported only on {I} + let terminator_costs = make_terminator_costs( + &body, + TargetArray::from_raw([[true], [false], [false]]), + &heap, + ); + let regions = count_regions(&body, &costs, &terminator_costs, Global); + + assert_eq!(regions[BasicBlockId::new(0)].0.get(), 2); + assert!(regions[BasicBlockId::new(0)].1); +} + +/// One statement, terminator is incomparable with statement support: extra region needed. +#[test] +fn count_regions_terminator_incomparable_splits() { + let heap = Heap::new(); + let interner = Interner::new(&heap); + let env = Environment::new(&heap); + + let body = body!(interner, env; fn@0/0 -> Int { + decl x: Int; + + bb0() { + x = load 42; + return x; + } + }); + + // Statement supported on {P, I} + let patterns = TargetArray::from_raw([[[true]], [[true]], [[false]]]); + let costs = make_target_costs(&body, patterns, &heap); + // Terminator supported on {E, I} (incomparable with {P, I}) + let terminator_costs = make_terminator_costs( + &body, + TargetArray::from_raw([[true], [false], [true]]), + &heap, + ); + let regions = count_regions(&body, &costs, &terminator_costs, Global); + + assert_eq!(regions[BasicBlockId::new(0)].0.get(), 2); + assert!(regions[BasicBlockId::new(0)].1); +} + +/// Zero statements: always 1 region, no terminator split (block IS the terminator). +#[test] +fn count_regions_zero_statements_no_split() { + let heap = Heap::new(); + let interner = Interner::new(&heap); + let env = Environment::new(&heap); + + let body = body!(interner, env; fn@0/0 -> Int { + decl x: Int; + + bb0() { + return x; + } + }); + + let costs = TargetArray::from_fn(|_| StatementCostVec::new_in(&body.basic_blocks, &heap)); + // Terminator only on {I} + let terminator_costs = make_terminator_costs( + &body, + TargetArray::from_raw([[true], [false], [false]]), + &heap, + ); + let regions = count_regions(&body, &costs, &terminator_costs, Global); + + assert_eq!(regions[BasicBlockId::new(0)].0.get(), 1); + assert!(!regions[BasicBlockId::new(0)].1); +} + +/// Multiple statement runs, terminator doesn't narrow last run: no extra region. +#[test] +fn count_regions_multiple_runs_terminator_superset() { + let heap = Heap::new(); + let interner = Interner::new(&heap); + let env = Environment::new(&heap); + + let body = body!(interner, env; fn@0/0 -> Int { + decl x: Int, y: Int; + + bb0() { + x = load 1; + y = load 2; + return y; + } + }); + + // First stmt: {I, P}, second stmt: {I} + let patterns = TargetArray::from_raw([[[true, true]], [[true, false]], [[false, false]]]); + let costs = make_target_costs(&body, patterns, &heap); + // Terminator on {I, P, E} (superset of last run {I}) + let terminator_costs = make_all_supported_terminator_costs(&body, &heap); + let regions = count_regions(&body, &costs, &terminator_costs, Global); + + // 2 statement runs, no terminator split + assert_eq!(regions[BasicBlockId::new(0)].0.get(), 2); + assert!(!regions[BasicBlockId::new(0)].1); +} + +/// Multiple statement runs, terminator narrows last run: extra region. +#[test] +fn count_regions_multiple_runs_terminator_narrows() { + let heap = Heap::new(); + let interner = Interner::new(&heap); + let env = Environment::new(&heap); + + let body = body!(interner, env; fn@0/0 -> Int { + decl x: Int, y: Int; + + bb0() { + x = load 1; + y = load 2; + return y; + } + }); + + // First stmt: {I, P}, second stmt: {I, P} + let patterns = TargetArray::from_raw([[[true, true]], [[true, true]], [[false, false]]]); + let costs = make_target_costs(&body, patterns, &heap); + // Terminator only on {I} + let terminator_costs = make_terminator_costs( + &body, + TargetArray::from_raw([[true], [false], [false]]), + &heap, + ); + let regions = count_regions(&body, &costs, &terminator_costs, Global); + + // 1 statement run + 1 terminator region + assert_eq!(regions[BasicBlockId::new(0)].0.get(), 2); + assert!(regions[BasicBlockId::new(0)].1); +} + +/// One statement + narrowed terminator produces 2 blocks with correct affinities. +#[test] +fn offset_terminator_narrowing_creates_split() { + let heap = Heap::new(); + let interner = Interner::new(&heap); + let env = Environment::new(&heap); + + let mut body = body!(interner, env; fn@0/0 -> Int { + decl x: Int; + + bb0() { + x = load 42; + return x; + } + }); + + let context = MirContext { + heap: &heap, + env: &env, + interner: &interner, + diagnostics: DiagnosticIssues::new(), + }; + + // Statement supported on {I, P} + let patterns = TargetArray::from_raw([[[true]], [[true]], [[false]]]); + let mut costs = make_target_costs(&body, patterns, &heap); + // Terminator only on {I} + let mut terminator_costs = make_terminator_costs( + &body, + TargetArray::from_raw([[true], [false], [false]]), + &heap, + ); + let regions = count_regions(&body, &costs, &terminator_costs, Global); + + let targets = offset_basic_blocks( + &context, + &mut body, + ®ions, + &mut costs, + &mut terminator_costs, + Global, + Global, + ); + + // Should produce 2 blocks + assert_eq!(body.basic_blocks.len(), 2); + + // First block has the statement, second is empty (terminator only) + assert_assignment_locals(&body, BasicBlockId::new(0), &["x"]); + assert_eq!(body.basic_blocks[BasicBlockId::new(1)].statements.len(), 0); + + // First block has Goto to second, second has the original Return + assert_goto_target(&body, BasicBlockId::new(0), BasicBlockId::new(1)); + assert_return_terminator(&body, BasicBlockId::new(1)); + + // Affinities: first {I, P}, second {I} + let expected_statements = Targets { + interpreter: true, + postgres: true, + embedding: false, + } + .compile(); + let expected_terminator = Targets { + interpreter: true, + postgres: false, + embedding: false, + } + .compile(); + assert_eq!(targets[BasicBlockId::new(0)], expected_statements); + assert_eq!(targets[BasicBlockId::new(1)], expected_terminator); +} + +/// Empty block with restricted terminator gets its affinity from the terminator. +#[test] +fn offset_empty_block_uses_terminator_affinity() { + let heap = Heap::new(); + let interner = Interner::new(&heap); + let env = Environment::new(&heap); + + let mut body = body!(interner, env; fn@0/0 -> Int { + decl x: Int; + + bb0() { + return x; + } + }); + + let context = MirContext { + heap: &heap, + env: &env, + interner: &interner, + diagnostics: DiagnosticIssues::new(), + }; + + let costs = TargetArray::from_fn(|_| StatementCostVec::new_in(&body.basic_blocks, &heap)); + // Only interpreter supports the terminator + let mut terminator_costs = make_terminator_costs( + &body, + TargetArray::from_raw([[true], [false], [false]]), + &heap, + ); + let regions = count_regions(&body, &costs, &terminator_costs, Global); + + let mut costs = costs; + let targets = offset_basic_blocks( + &context, + &mut body, + ®ions, + &mut costs, + &mut terminator_costs, + Global, + Global, + ); + + // Still 1 block, no split + assert_eq!(body.basic_blocks.len(), 1); + + let expected = Targets { + interpreter: true, + postgres: false, + embedding: false, + } + .compile(); + assert_eq!(targets[BasicBlockId::new(0)], expected); +} + +/// Two statement runs + disjoint terminator produces 3 blocks. +#[test] +fn offset_two_runs_plus_terminator_split() { + let heap = Heap::new(); + let interner = Interner::new(&heap); + let env = Environment::new(&heap); + + let mut body = body!(interner, env; fn@0/0 -> Int { + decl x: Int, y: Int; + + bb0() { + x = load 1; + y = load 2; + return y; + } + }); + + let context = MirContext { + heap: &heap, + env: &env, + interner: &interner, + diagnostics: DiagnosticIssues::new(), + }; + + // First stmt: {P} only, second stmt: {E} only + let patterns = TargetArray::from_raw([[[false, false]], [[true, false]], [[false, true]]]); + let mut costs = make_target_costs(&body, patterns, &heap); + // Terminator only on {I} + let mut terminator_costs = make_terminator_costs( + &body, + TargetArray::from_raw([[true], [false], [false]]), + &heap, + ); + let regions = count_regions(&body, &costs, &terminator_costs, Global); + + let targets = offset_basic_blocks( + &context, + &mut body, + ®ions, + &mut costs, + &mut terminator_costs, + Global, + Global, + ); + + assert_eq!(body.basic_blocks.len(), 3); + + // Affinities: {P}, {E}, {I} + let expected_p = Targets { + interpreter: false, + postgres: true, + embedding: false, + } + .compile(); + let expected_e = Targets { + interpreter: false, + postgres: false, + embedding: true, + } + .compile(); + let expected_i = Targets { + interpreter: true, + postgres: false, + embedding: false, + } + .compile(); + assert_eq!(targets[BasicBlockId::new(0)], expected_p); + assert_eq!(targets[BasicBlockId::new(1)], expected_e); + assert_eq!(targets[BasicBlockId::new(2)], expected_i); + + // Last block has the original return, others have gotos + assert_goto_terminator(&body, BasicBlockId::new(0)); + assert_goto_terminator(&body, BasicBlockId::new(1)); + assert_return_terminator(&body, BasicBlockId::new(2)); +} + +/// Terminator cost remap after split: last block gets original cost, Goto blocks get zero. +#[test] +fn terminator_cost_remap_after_split() { + let heap = Heap::new(); + let interner = Interner::new(&heap); + let env = Environment::new(&heap); + + let mut body = body!(interner, env; fn@0/0 -> Int { + decl x: Int, y: Int; + + bb0() { + x = load 1; + y = load 2; + return y; + } + }); + + let context = MirContext { + heap: &heap, + env: &env, + interner: &interner, + diagnostics: DiagnosticIssues::new(), + }; + + // Two statement runs: {I,P} then {I} + let patterns = TargetArray::from_raw([[[true, true]], [[true, false]], [[false, false]]]); + let mut costs = make_target_costs(&body, patterns, &heap); + let mut terminator_costs = make_all_supported_terminator_costs(&body, &heap); + + let splitting = BasicBlockSplitting::new(); + let _targets = splitting.split(&context, &mut body, &mut costs, &mut terminator_costs); + + // After split: 2 blocks. First has Goto (zero cost), second has original Return. + assert_eq!(body.basic_blocks.len(), 2); + + for target in TargetId::all() { + // Goto block gets zero cost + assert_eq!( + terminator_costs[target].of(BasicBlockId::new(0)), + Some(cost!(0)) + ); + // Original terminator block keeps the original cost + assert_eq!( + terminator_costs[target].of(BasicBlockId::new(1)), + Some(cost!(1)) + ); + } +} + +/// Terminator is strict superset of statement support: no split occurs. +#[test] +fn offset_terminator_superset_no_split() { + let heap = Heap::new(); + let interner = Interner::new(&heap); + let env = Environment::new(&heap); + + let mut body = body!(interner, env; fn@0/0 -> Int { + decl x: Int; + + bb0() { + x = load 42; + return x; + } + }); + + let context = MirContext { + heap: &heap, + env: &env, + interner: &interner, + diagnostics: DiagnosticIssues::new(), + }; + + // Statement: {P} only + let patterns = TargetArray::from_raw([[[false]], [[true]], [[false]]]); + let mut costs = make_target_costs(&body, patterns, &heap); + // Terminator: {I, P, E} (superset) + let mut terminator_costs = make_all_supported_terminator_costs(&body, &heap); + let regions = count_regions(&body, &costs, &terminator_costs, Global); + + let targets = offset_basic_blocks( + &context, + &mut body, + ®ions, + &mut costs, + &mut terminator_costs, + Global, + Global, + ); + + // No split + assert_eq!(body.basic_blocks.len(), 1); + + // Affinity comes from statements: {P} + let expected = Targets { + interpreter: false, + postgres: true, + embedding: false, + } + .compile(); + assert_eq!(targets[BasicBlockId::new(0)], expected); +} diff --git a/libs/@local/hashql/mir/tests/ui/pass/administrative_reduction/closure-chain.stdout b/libs/@local/hashql/mir/tests/ui/pass/administrative_reduction/closure-chain.stdout index ec54c5c2065..b8737ef3c01 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/administrative_reduction/closure-chain.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/administrative_reduction/closure-chain.stdout @@ -96,7 +96,7 @@ thunk f4:0() -> (Boolean) -> Boolean { bb0(): { %0 = apply (f4:0 as FnPtr) - %1 = apply %0.0 %0.1 1 + %1 = apply %0.0 %0.1 true return %1 } @@ -284,7 +284,7 @@ thunk f4:0() -> (Boolean) -> Boolean { %2 = closure(({closure#18} as FnPtr), %3) %0 = %2 %4 = %0.1 - %5 = 1 + %5 = true %9 = () %8 = closure(({closure#16} as FnPtr), %9) %6 = %8 diff --git a/libs/@local/hashql/mir/tests/ui/pass/administrative_reduction/forwarding-closure.stdout b/libs/@local/hashql/mir/tests/ui/pass/administrative_reduction/forwarding-closure.stdout index 2461da1e6d2..930d83e63bf 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/administrative_reduction/forwarding-closure.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/administrative_reduction/forwarding-closure.stdout @@ -48,7 +48,7 @@ thunk f2:0() -> (Boolean) -> Boolean { bb0(): { %0 = apply (f2:0 as FnPtr) - %1 = apply %0.0 %0.1 1 + %1 = apply %0.0 %0.1 true return %1 } @@ -124,7 +124,7 @@ thunk f2:0() -> (Boolean) -> Boolean { %2 = closure(({closure#8} as FnPtr), %3) %0 = %2 %4 = %0.1 - %5 = 1 + %5 = true %9 = () %8 = closure(({closure#6} as FnPtr), %9) %6 = %8 diff --git a/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/cascade-switch-then-goto.stdout b/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/cascade-switch-then-goto.stdout index 151cd0c165a..971fd479e45 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/cascade-switch-then-goto.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/cascade-switch-then-goto.stdout @@ -14,7 +14,7 @@ thunk x:0() -> Integer { let %4: Boolean bb0(): { - switchInt(1) -> [0: bb2(), 1: bb1()] + switchInt(true) -> [0: bb2(), 1: bb1()] } bb1(): { diff --git a/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/closure-with-const-branch.stdout b/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/closure-with-const-branch.stdout index b08640bf168..cec6bcdb129 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/closure-with-const-branch.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/closure-with-const-branch.stdout @@ -6,7 +6,7 @@ fn {closure#6}(%0: (), %1: Integer) -> Boolean { let %4: Boolean bb0(): { - switchInt(1) -> [0: bb2(), 1: bb1()] + switchInt(true) -> [0: bb2(), 1: bb1()] } bb1(): { diff --git a/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/const-if-false.stdout b/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/const-if-false.stdout index 465657e22fb..967d64290e4 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/const-if-false.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/const-if-false.stdout @@ -4,7 +4,7 @@ let %0: String bb0(): { - switchInt(0) -> [0: bb2(), 1: bb1()] + switchInt(false) -> [0: bb2(), 1: bb1()] } bb1(): { diff --git a/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/const-if-true.stdout b/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/const-if-true.stdout index 69bc106c5fa..bda9f9759e0 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/const-if-true.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/const-if-true.stdout @@ -4,7 +4,7 @@ let %0: String bb0(): { - switchInt(1) -> [0: bb2(), 1: bb1()] + switchInt(true) -> [0: bb2(), 1: bb1()] } bb1(): { diff --git a/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/const-nested-if.stdout b/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/const-nested-if.stdout index a96d05e1901..2c9874a64dc 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/const-nested-if.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/const-nested-if.stdout @@ -5,11 +5,11 @@ let %1: String bb0(): { - switchInt(1) -> [0: bb5(), 1: bb1()] + switchInt(true) -> [0: bb5(), 1: bb1()] } bb1(): { - switchInt(0) -> [0: bb3(), 1: bb2()] + switchInt(false) -> [0: bb3(), 1: bb2()] } bb2(): { diff --git a/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/dead-block-elimination.aux.svg b/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/dead-block-elimination.aux.svg index 53b98e858aa..7891000b325 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/dead-block-elimination.aux.svg +++ b/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/dead-block-elimination.aux.svg @@ -1,20 +1,20 @@ -Initial MIRMIR after CFG Simplification

thunk {thunk#4}() -> String

thunk {thunk#4}() -> String

-
bb0()
MIR
TswitchInt(0)
bb8()
MIR
Tgoto
bb1()
MIR
0%1 = 1 <= 2
TswitchInt(%1)
bb6()
MIR
Tgoto
bb2()
MIR
0%3 = 3 >= 4
TswitchInt(%3)
bb4()
MIR
Tgoto
bb3()
MIR
Tgoto
bb5(%4)
MIR
Tgoto
bb7(%2)
MIR
Tgoto
bb9(%0)
MIR
Treturn %0
bb0()
MIR
0%0 = "taken"
Treturn %0
()0()1()0()1()0()1("deeply-nested-then")("deeply-nested-else")(%4)("inner-else")(%2)("taken") +
bb0()
MIR
TswitchInt(false)
bb8()
MIR
Tgoto
bb1()
MIR
0%1 = 1 <= 2
TswitchInt(%1)
bb6()
MIR
Tgoto
bb2()
MIR
0%3 = 3 >= 4
TswitchInt(%3)
bb4()
MIR
Tgoto
bb3()
MIR
Tgoto
bb5(%4)
MIR
Tgoto
bb7(%2)
MIR
Tgoto
bb9(%0)
MIR
Treturn %0
bb0()
MIR
0%0 = "taken"
Treturn %0
()0()1()0()1()0()1("deeply-nested-then")("deeply-nested-else")(%4)("inner-else")(%2)("taken") - - + + diff --git a/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/dead-block-elimination.stdout b/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/dead-block-elimination.stdout index 42b1ef1172a..8cf1f126a8b 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/dead-block-elimination.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/dead-block-elimination.stdout @@ -8,7 +8,7 @@ let %4: String bb0(): { - switchInt(0) -> [0: bb8(), 1: bb1()] + switchInt(false) -> [0: bb8(), 1: bb1()] } bb1(): { diff --git a/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/let-in-branch.stdout b/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/let-in-branch.stdout index e62094ae923..e96f5f37813 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/let-in-branch.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/let-in-branch.stdout @@ -6,7 +6,7 @@ let %2: Boolean bb0(): { - switchInt(1) -> [0: bb2(), 1: bb1()] + switchInt(true) -> [0: bb2(), 1: bb1()] } bb1(): { @@ -17,7 +17,7 @@ } bb2(): { - goto -> bb3(0) + goto -> bb3(false) } bb3(%0): { diff --git a/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/mixed-const-runtime-if.stdout b/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/mixed-const-runtime-if.stdout index de40de8866a..fcb1d0d8c4f 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/mixed-const-runtime-if.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/cfg_simplify/mixed-const-runtime-if.stdout @@ -13,7 +13,7 @@ thunk x:0() -> Integer { let %3: String bb0(): { - switchInt(1) -> [0: bb5(), 1: bb1()] + switchInt(true) -> [0: bb5(), 1: bb1()] } bb1(): { diff --git a/libs/@local/hashql/mir/tests/ui/pass/data-dependency/binary-operation.stdout b/libs/@local/hashql/mir/tests/ui/pass/data-dependency/binary-operation.stdout index 367837f42c0..129ac52aa20 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/data-dependency/binary-operation.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/data-dependency/binary-operation.stdout @@ -7,7 +7,7 @@ let %3: Boolean bb0(): { - switchInt(1) -> [0: bb2(), 1: bb1()] + switchInt(true) -> [0: bb2(), 1: bb1()] } bb1(): { @@ -19,7 +19,7 @@ } bb2(): { - goto -> bb3(0) + goto -> bb3(false) } bb3(%0): { @@ -29,7 +29,7 @@ ════ Data Dependency Graph ═════════════════════════════════════════════════════ %0 -> %3 [Param] -%0 -> 0 [Param] +%0 -> false [Param] %1 -> 1 [Load] %2 -> 2 [Load] @@ -37,7 +37,7 @@ ════ Transient Data Dependency Graph ═══════════════════════════════════════════ %0 -> %3 [Param] -%0 -> 0 [Param] +%0 -> false [Param] %1 -> 1 [Load] %2 -> 2 [Load] diff --git a/libs/@local/hashql/mir/tests/ui/pass/data-dependency/closure-construction.stdout b/libs/@local/hashql/mir/tests/ui/pass/data-dependency/closure-construction.stdout index 658bfeff336..b2d1b2be62d 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/data-dependency/closure-construction.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/data-dependency/closure-construction.stdout @@ -17,7 +17,7 @@ fn f:0(%0: (Integer,)) -> Integer { let %3: (Integer,) bb0(): { - switchInt(1) -> [0: bb2(), 1: bb1()] + switchInt(true) -> [0: bb2(), 1: bb1()] } bb1(): { diff --git a/libs/@local/hashql/mir/tests/ui/pass/data-dependency/comparison-operators.stdout b/libs/@local/hashql/mir/tests/ui/pass/data-dependency/comparison-operators.stdout index 5062959e61a..652fdf7cbb5 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/data-dependency/comparison-operators.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/data-dependency/comparison-operators.stdout @@ -7,7 +7,7 @@ let %3: Boolean bb0(): { - switchInt(1) -> [0: bb2(), 1: bb1()] + switchInt(true) -> [0: bb2(), 1: bb1()] } bb1(): { @@ -19,7 +19,7 @@ } bb2(): { - goto -> bb3(0) + goto -> bb3(false) } bb3(%0): { @@ -29,7 +29,7 @@ ════ Data Dependency Graph ═════════════════════════════════════════════════════ %0 -> %3 [Param] -%0 -> 0 [Param] +%0 -> false [Param] %1 -> 3 [Load] %2 -> 2 [Load] @@ -37,7 +37,7 @@ ════ Transient Data Dependency Graph ═══════════════════════════════════════════ %0 -> %3 [Param] -%0 -> 0 [Param] +%0 -> false [Param] %1 -> 3 [Load] %2 -> 2 [Load] diff --git a/libs/@local/hashql/mir/tests/ui/pass/data-dependency/deeply-nested-tuple.stdout b/libs/@local/hashql/mir/tests/ui/pass/data-dependency/deeply-nested-tuple.stdout index e6a6ac20b02..acc6ed392d4 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/data-dependency/deeply-nested-tuple.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/data-dependency/deeply-nested-tuple.stdout @@ -8,7 +8,7 @@ let %4: (((Integer,),),) bb0(): { - switchInt(1) -> [0: bb2(), 1: bb1()] + switchInt(true) -> [0: bb2(), 1: bb1()] } bb1(): { diff --git a/libs/@local/hashql/mir/tests/ui/pass/data-dependency/function-apply.stdout b/libs/@local/hashql/mir/tests/ui/pass/data-dependency/function-apply.stdout index 94f829f2da1..c4d7feef4aa 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/data-dependency/function-apply.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/data-dependency/function-apply.stdout @@ -30,7 +30,7 @@ fn max:0(%0: (), %1: Integer, %2: Integer) -> Integer { let %3: Integer bb0(): { - switchInt(1) -> [0: bb2(), 1: bb1()] + switchInt(true) -> [0: bb2(), 1: bb1()] } bb1(): { diff --git a/libs/@local/hashql/mir/tests/ui/pass/data-dependency/function-multiple-args.stdout b/libs/@local/hashql/mir/tests/ui/pass/data-dependency/function-multiple-args.stdout index 5514c7ccc4b..897cad77778 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/data-dependency/function-multiple-args.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/data-dependency/function-multiple-args.stdout @@ -46,7 +46,7 @@ fn f:0(%0: (), %1: Integer, %2: Integer, %3: Integer) -> Integer { let %3: Integer bb0(): { - switchInt(1) -> [0: bb2(), 1: bb1()] + switchInt(true) -> [0: bb2(), 1: bb1()] } bb1(): { diff --git a/libs/@local/hashql/mir/tests/ui/pass/data-dependency/list-construction.stdout b/libs/@local/hashql/mir/tests/ui/pass/data-dependency/list-construction.stdout index 3423ffa34f5..aa4e2540ee9 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/data-dependency/list-construction.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/data-dependency/list-construction.stdout @@ -8,7 +8,7 @@ let %4: List bb0(): { - switchInt(1) -> [0: bb2(), 1: bb1()] + switchInt(true) -> [0: bb2(), 1: bb1()] } bb1(): { diff --git a/libs/@local/hashql/mir/tests/ui/pass/data-dependency/mixed-projection-chain.stdout b/libs/@local/hashql/mir/tests/ui/pass/data-dependency/mixed-projection-chain.stdout index 20c66f72ad4..012018bc584 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/data-dependency/mixed-projection-chain.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/data-dependency/mixed-projection-chain.stdout @@ -7,7 +7,7 @@ let %3: (field: (Integer,)) bb0(): { - switchInt(1) -> [0: bb2(), 1: bb1()] + switchInt(true) -> [0: bb2(), 1: bb1()] } bb1(): { diff --git a/libs/@local/hashql/mir/tests/ui/pass/data-dependency/multiple-uses.stdout b/libs/@local/hashql/mir/tests/ui/pass/data-dependency/multiple-uses.stdout index 8ca4fd36973..82877ab9d26 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/data-dependency/multiple-uses.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/data-dependency/multiple-uses.stdout @@ -6,7 +6,7 @@ let %2: Boolean bb0(): { - switchInt(1) -> [0: bb2(), 1: bb1()] + switchInt(true) -> [0: bb2(), 1: bb1()] } bb1(): { @@ -17,7 +17,7 @@ } bb2(): { - goto -> bb3(0) + goto -> bb3(false) } bb3(%0): { @@ -27,13 +27,13 @@ ════ Data Dependency Graph ═════════════════════════════════════════════════════ %0 -> %2 [Param] -%0 -> 0 [Param] +%0 -> false [Param] %1 -> 5 [Load] ════ Transient Data Dependency Graph ═══════════════════════════════════════════ %0 -> %2 [Param] -%0 -> 0 [Param] +%0 -> false [Param] %1 -> 5 [Load] diff --git a/libs/@local/hashql/mir/tests/ui/pass/data-dependency/nested-tuple-projection.stdout b/libs/@local/hashql/mir/tests/ui/pass/data-dependency/nested-tuple-projection.stdout index 6859a829e38..d5d59b6e4e6 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/data-dependency/nested-tuple-projection.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/data-dependency/nested-tuple-projection.stdout @@ -7,7 +7,7 @@ let %3: ((Integer, Integer), Integer) bb0(): { - switchInt(1) -> [0: bb2(), 1: bb1()] + switchInt(true) -> [0: bb2(), 1: bb1()] } bb1(): { diff --git a/libs/@local/hashql/mir/tests/ui/pass/data-dependency/struct-construction.stdout b/libs/@local/hashql/mir/tests/ui/pass/data-dependency/struct-construction.stdout index 777ffdc17f1..e717f20b13a 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/data-dependency/struct-construction.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/data-dependency/struct-construction.stdout @@ -7,7 +7,7 @@ let %3: (bar: Integer, foo: Integer) bb0(): { - switchInt(1) -> [0: bb2(), 1: bb1()] + switchInt(true) -> [0: bb2(), 1: bb1()] } bb1(): { diff --git a/libs/@local/hashql/mir/tests/ui/pass/data-dependency/struct-projection.stdout b/libs/@local/hashql/mir/tests/ui/pass/data-dependency/struct-projection.stdout index 50b026f1818..3fa1685fcf4 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/data-dependency/struct-projection.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/data-dependency/struct-projection.stdout @@ -7,7 +7,7 @@ let %3: (bar: Integer, foo: Integer) bb0(): { - switchInt(1) -> [0: bb2(), 1: bb1()] + switchInt(true) -> [0: bb2(), 1: bb1()] } bb1(): { diff --git a/libs/@local/hashql/mir/tests/ui/pass/data-dependency/tuple-construction.stdout b/libs/@local/hashql/mir/tests/ui/pass/data-dependency/tuple-construction.stdout index ba13b6e042c..cf9ff36b065 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/data-dependency/tuple-construction.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/data-dependency/tuple-construction.stdout @@ -7,7 +7,7 @@ let %3: (Integer, Integer) bb0(): { - switchInt(1) -> [0: bb2(), 1: bb1()] + switchInt(true) -> [0: bb2(), 1: bb1()] } bb1(): { diff --git a/libs/@local/hashql/mir/tests/ui/pass/data-dependency/tuple-projection.stdout b/libs/@local/hashql/mir/tests/ui/pass/data-dependency/tuple-projection.stdout index f3f236ed07f..97a45936f11 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/data-dependency/tuple-projection.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/data-dependency/tuple-projection.stdout @@ -7,7 +7,7 @@ let %3: (Integer, Integer) bb0(): { - switchInt(1) -> [0: bb2(), 1: bb1()] + switchInt(true) -> [0: bb2(), 1: bb1()] } bb1(): { diff --git a/libs/@local/hashql/mir/tests/ui/pass/dse/live-in-branch.stdout b/libs/@local/hashql/mir/tests/ui/pass/dse/live-in-branch.stdout index 8833518c770..9b3362268ec 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/dse/live-in-branch.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/dse/live-in-branch.stdout @@ -6,13 +6,13 @@ let %2: Integer bb0(): { - switchInt(1) -> [0: bb5(), 1: bb1()] + switchInt(true) -> [0: bb5(), 1: bb1()] } bb1(): { %1 = 42 - switchInt(1) -> [0: bb3(), 1: bb2()] + switchInt(true) -> [0: bb3(), 1: bb2()] } bb2(): { diff --git a/libs/@local/hashql/mir/tests/ui/pass/dse/nested-tuple-projection.stdout b/libs/@local/hashql/mir/tests/ui/pass/dse/nested-tuple-projection.stdout index 4ebd7c806cb..40a99fde5d0 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/dse/nested-tuple-projection.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/dse/nested-tuple-projection.stdout @@ -7,7 +7,7 @@ let %3: (Integer, Integer) bb0(): { - switchInt(1) -> [0: bb2(), 1: bb1()] + switchInt(true) -> [0: bb2(), 1: bb1()] } bb1(): { diff --git a/libs/@local/hashql/mir/tests/ui/pass/dse/showcase.aux.svg b/libs/@local/hashql/mir/tests/ui/pass/dse/showcase.aux.svg index c5ce3a75f53..890396a5dbf 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/dse/showcase.aux.svg +++ b/libs/@local/hashql/mir/tests/ui/pass/dse/showcase.aux.svg @@ -1,20 +1,20 @@ -Initial MIRMIR after DSE

thunk {thunk#7}() -> Integer

thunk {thunk#7}() -> Integer

-
bb0()
MIR
TswitchInt(1)
bb5()
MIR
Tgoto
bb1()
MIR
0%1 = 10
1%2 = 20
2%3 = %1 == %2
3%4 = %1 < %2
4%5 = %1 > %2
5%6 = 999
TswitchInt(%3)
bb3()
MIR
Tgoto
bb2()
MIR
Tgoto
bb4(%7)
MIR
Tgoto
bb6(%0)
MIR
Treturn %0
bb0()
MIR
0%0 = 0
TswitchInt(%0)
bb1(%1)
MIR
Treturn %1
()0()1()0()1(1)(0)(%7)(0)(0)0(1)1 +
bb0()
MIR
TswitchInt(true)
bb5()
MIR
Tgoto
bb1()
MIR
0%1 = 10
1%2 = 20
2%3 = %1 == %2
3%4 = %1 < %2
4%5 = %1 > %2
5%6 = 999
TswitchInt(%3)
bb3()
MIR
Tgoto
bb2()
MIR
Tgoto
bb4(%7)
MIR
Tgoto
bb6(%0)
MIR
Treturn %0
bb0()
MIR
0%0 = false
TswitchInt(%0)
bb1(%1)
MIR
Treturn %1
()0()1()0()1(1)(0)(%7)(0)(0)0(1)1 - - + + diff --git a/libs/@local/hashql/mir/tests/ui/pass/dse/showcase.stdout b/libs/@local/hashql/mir/tests/ui/pass/dse/showcase.stdout index eb3cbefe936..9682eb28dc7 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/dse/showcase.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/dse/showcase.stdout @@ -11,7 +11,7 @@ let %7: Integer bb0(): { - switchInt(1) -> [0: bb5(), 1: bb1()] + switchInt(true) -> [0: bb5(), 1: bb1()] } bb1(): { @@ -52,7 +52,7 @@ let %1: Integer bb0(): { - %0 = 0 + %0 = false switchInt(%0) -> [0: bb1(0), 1: bb1(1)] } diff --git a/libs/@local/hashql/mir/tests/ui/pass/dse/simple-dead-local.stdout b/libs/@local/hashql/mir/tests/ui/pass/dse/simple-dead-local.stdout index 51be480acc6..9bab20b0019 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/dse/simple-dead-local.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/dse/simple-dead-local.stdout @@ -6,7 +6,7 @@ let %2: Integer bb0(): { - switchInt(1) -> [0: bb2(), 1: bb1()] + switchInt(true) -> [0: bb2(), 1: bb1()] } bb1(): { diff --git a/libs/@local/hashql/mir/tests/ui/pass/dse/used-local-preserved.stdout b/libs/@local/hashql/mir/tests/ui/pass/dse/used-local-preserved.stdout index b05f129d103..1fcab6043ea 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/dse/used-local-preserved.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/dse/used-local-preserved.stdout @@ -5,7 +5,7 @@ let %1: Integer bb0(): { - switchInt(1) -> [0: bb2(), 1: bb1()] + switchInt(true) -> [0: bb2(), 1: bb1()] } bb1(): { diff --git a/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/embedding/only_vectors_projection_supported.snap b/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/embedding/only_vectors_projection_supported.snap index d27a7c6e3c9..643d044182b 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/embedding/only_vectors_projection_supported.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/embedding/only_vectors_projection_supported.snap @@ -8,6 +8,6 @@ fn {graph::read::filter@4294967040}(%0: (), %1: Entity) -> ? { bb0(): { %2 = %1.encodings.vectors // cost: 4 - return %2 + return %2 // cost: 4 } } diff --git a/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/embedding/storage_statements_zero_cost.snap b/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/embedding/storage_statements_zero_cost.snap index 44a6d7cc273..2590b51e724 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/embedding/storage_statements_zero_cost.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/embedding/storage_statements_zero_cost.snap @@ -10,6 +10,6 @@ fn {graph::read::filter@4294967040}(%0: (), %1: Entity) -> ? { %2 = %1.encodings.vectors // cost: 4 drop %2 // cost: 0 - return %2 + return %2 // cost: 4 } } diff --git a/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/interpret/all_statements_supported.snap b/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/interpret/all_statements_supported.snap index b9de54f4bb3..319e93a6956 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/interpret/all_statements_supported.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/interpret/all_statements_supported.snap @@ -28,6 +28,6 @@ fn {graph::read::filter@4294967040}(%0: (Integer,), %1: Entity) -> Boolean { %11 = input LOAD param // cost: 8 %12 = true // cost: 8 - return %12 + return %12 // cost: 8 } } diff --git a/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/interpret/eq_opaque_entity_uuid.snap b/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/interpret/eq_opaque_entity_uuid.snap index 7ff2c1f6db5..f780244f5c4 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/interpret/eq_opaque_entity_uuid.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/interpret/eq_opaque_entity_uuid.snap @@ -1,6 +1,5 @@ --- source: libs/@local/hashql/mir/src/pass/execution/statement_placement/tests.rs -assertion_line: 92 expression: output --- fn {graph::read::filter@4294967040}(%0: (), %1: Entity) -> Boolean { @@ -13,6 +12,6 @@ fn {graph::read::filter@4294967040}(%0: (), %1: Entity) -> Boolean { %4 = opaque(::graph::types::knowledge::entity::EntityUuid, %3) // cost: 8 %2 = %1.id.entity_id.entity_uuid == %4 // cost: 8 - return %2 + return %2 // cost: 8 } } diff --git a/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/interpret/non_traversal_unaffected_by_costs.snap b/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/interpret/non_traversal_unaffected_by_costs.snap index 7fd988b687d..8da5e122828 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/interpret/non_traversal_unaffected_by_costs.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/interpret/non_traversal_unaffected_by_costs.snap @@ -12,6 +12,6 @@ fn {graph::read::filter@4294967040}(%0: (), %1: Entity) -> Boolean { %3 = 42 // cost: 8 %4 = %3 > 10 // cost: 8 - return %4 + return %4 // cost: 8 } } diff --git a/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/interpret/storage_statements_zero_cost.snap b/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/interpret/storage_statements_zero_cost.snap index 0086a9abef8..a1034f365bb 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/interpret/storage_statements_zero_cost.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/interpret/storage_statements_zero_cost.snap @@ -16,6 +16,6 @@ fn {graph::read::filter@4294967040}(%0: (), %1: Entity) -> Integer { drop %2 // cost: 0 drop %3 // cost: 0 - return %4 + return %4 // cost: 8 } } diff --git a/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/interpret/traversal_multiple_paths_cost.snap b/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/interpret/traversal_multiple_paths_cost.snap index 664620f8ba2..3dd4c5d7609 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/interpret/traversal_multiple_paths_cost.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/interpret/traversal_multiple_paths_cost.snap @@ -10,6 +10,6 @@ fn {graph::read::filter@4294967040}(%0: (), %1: Entity) -> (?, Boolean) { %2 = %1.properties // cost: 8 %3 = (%1.properties, %1.metadata.archived) // cost: 8 - return %3 + return %3 // cost: 8 } } diff --git a/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/interpret/traversal_single_path_cost.snap b/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/interpret/traversal_single_path_cost.snap index d51e6ceae90..6bb51b8e1d5 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/interpret/traversal_single_path_cost.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/interpret/traversal_single_path_cost.snap @@ -10,6 +10,6 @@ fn {graph::read::filter@4294967040}(%0: (), %1: Entity) -> Boolean { %2 = %1.metadata.archived // cost: 8 %3 = !%2 // cost: 8 - return %3 + return %3 // cost: 8 } } diff --git a/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/interpret/traversal_swallowing_reduces_cost.snap b/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/interpret/traversal_swallowing_reduces_cost.snap index c43e55a04bd..01aa44dc79a 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/interpret/traversal_swallowing_reduces_cost.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/interpret/traversal_swallowing_reduces_cost.snap @@ -8,6 +8,6 @@ fn {graph::read::filter@4294967040}(%0: (), %1: Entity) -> (?, ?) { bb0(): { %2 = (%1.metadata.record_id.entity_id.web_id, %1.metadata.record_id) // cost: 8 - return %2 + return %2 // cost: 8 } } diff --git a/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/aggregate_closure_rejected.snap b/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/aggregate_closure_rejected.snap index 1f22a24cd1b..2b845759e6d 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/aggregate_closure_rejected.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/aggregate_closure_rejected.snap @@ -12,6 +12,6 @@ fn {graph::read::filter@4294967040}(%0: (Integer,), %1: Entity) -> Boolean { %3 = closure(({def@42} as FnPtr), %2) %4 = true // cost: 4 - return %4 + return %4 // cost: 4 } } diff --git a/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/aggregate_tuple_supported.snap b/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/aggregate_tuple_supported.snap index ca2fefd4973..c1e7c357804 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/aggregate_tuple_supported.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/aggregate_tuple_supported.snap @@ -12,6 +12,6 @@ fn {graph::read::filter@4294967040}(%0: (), %1: Entity) -> Boolean { %3 = (a: 10, b: 20) // cost: 4 %4 = true // cost: 4 - return %4 + return %4 // cost: 4 } } diff --git a/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/binary_unary_ops_supported.snap b/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/binary_unary_ops_supported.snap index 3bff03d7cf2..838217f2e16 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/binary_unary_ops_supported.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/binary_unary_ops_supported.snap @@ -16,6 +16,6 @@ fn {graph::read::filter@4294967040}(%0: (), %1: Entity) -> Boolean { %5 = %4 > 15 // cost: 4 %6 = !%5 // cost: 4 - return %6 + return %6 // cost: 4 } } diff --git a/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/diamond_must_analysis.snap b/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/diamond_must_analysis.snap index 8db2da9a59a..632cdf6cecd 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/diamond_must_analysis.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/diamond_must_analysis.snap @@ -16,7 +16,7 @@ fn {graph::read::filter@4294967040}(%0: (Integer,), %1: Entity) -> Boolean { %4 = (%3) // cost: 4 %5 = closure(({def@77} as FnPtr), %4) - switchInt(%2) -> [0: bb2(), 1: bb1()] + switchInt(%2) -> [0: bb2(), 1: bb1()] // cost: 4 } bb1(): { diff --git a/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/entity_projection_column.snap b/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/entity_projection_column.snap index a18c0b1b663..e2ecac8d9a2 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/entity_projection_column.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/entity_projection_column.snap @@ -4,6 +4,6 @@ expression: output --- fn {graph::read::filter@4294967040}(%0: (), %1: Entity) -> Boolean { bb0(): { - return %1.metadata.archived + return %1.metadata.archived // cost: 4 } } diff --git a/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/entity_projection_jsonb.snap b/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/entity_projection_jsonb.snap index d49c49e03cd..8c9dc6e3e0e 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/entity_projection_jsonb.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/entity_projection_jsonb.snap @@ -8,6 +8,6 @@ fn {graph::read::filter@4294967040}(%0: (), %1: Entity) -> ? { bb0(): { %2 = %1.properties // cost: 4 - return %2 + return %2 // cost: 4 } } diff --git a/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/env_closure_field_rejected_other_accepted.snap b/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/env_closure_field_rejected_other_accepted.snap index c60090e59c5..d759926c979 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/env_closure_field_rejected_other_accepted.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/env_closure_field_rejected_other_accepted.snap @@ -12,6 +12,6 @@ fn {graph::read::filter@4294967040}(%0: (Integer, (Integer) -> Integer), %1: Ent %3 = %0.1 %4 = %2 == 42 // cost: 4 - return %4 + return %4 // cost: 4 } } diff --git a/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/env_dict_non_string_key_rejected.snap b/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/env_dict_non_string_key_rejected.snap index bcceac667eb..a45b4dff025 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/env_dict_non_string_key_rejected.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/env_dict_non_string_key_rejected.snap @@ -10,6 +10,6 @@ fn {graph::read::filter@4294967040}(%0: (Dict,), %1: Entity) - %2 = %0.0 %3 = true // cost: 4 - return %3 + return %3 // cost: 4 } } diff --git a/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/env_dict_opaque_string_key_accepted.snap b/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/env_dict_opaque_string_key_accepted.snap index 2344681e1dd..d6506127e72 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/env_dict_opaque_string_key_accepted.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/env_dict_opaque_string_key_accepted.snap @@ -10,6 +10,6 @@ fn {graph::read::filter@4294967040}(%0: (Dict,), %1: Entity) -> %2 = %0.0 // cost: 4 %3 = true // cost: 4 - return %3 + return %3 // cost: 4 } } diff --git a/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/env_dict_string_key_accepted.snap b/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/env_dict_string_key_accepted.snap index 7f68af1af40..2f61ca5cdc2 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/env_dict_string_key_accepted.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/env_dict_string_key_accepted.snap @@ -10,6 +10,6 @@ fn {graph::read::filter@4294967040}(%0: (Dict,), %1: Entity) -> %2 = %0.0 // cost: 4 %3 = true // cost: 4 - return %3 + return %3 // cost: 4 } } diff --git a/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/env_with_closure_type_rejected.snap b/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/env_with_closure_type_rejected.snap index b8a99b82d85..584c758b71b 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/env_with_closure_type_rejected.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/env_with_closure_type_rejected.snap @@ -10,6 +10,6 @@ fn {graph::read::filter@4294967040}(%0: (Integer, (Integer) -> Integer), %1: Ent %2 = %0.0 // cost: 4 %3 = %2 == 42 // cost: 4 - return %3 + return %3 // cost: 4 } } diff --git a/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/env_without_closure_accepted.snap b/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/env_without_closure_accepted.snap index 250a2822c48..bfd25139c57 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/env_without_closure_accepted.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/env_without_closure_accepted.snap @@ -10,6 +10,6 @@ fn {graph::read::filter@4294967040}(%0: (Integer, Boolean), %1: Entity) -> Boole %2 = %0.0 // cost: 4 %3 = %2 == 42 // cost: 4 - return %3 + return %3 // cost: 4 } } diff --git a/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/eq_place_vs_constant_accepted.snap b/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/eq_place_vs_constant_accepted.snap index d2479908f24..a154d08e48f 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/eq_place_vs_constant_accepted.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/eq_place_vs_constant_accepted.snap @@ -10,6 +10,6 @@ fn {graph::read::filter@4294967040}(%0: (Dict,), %1: Entity) -> %2 = %0.0 // cost: 4 %3 = %2 == 42 // cost: 4 - return %3 + return %3 // cost: 4 } } diff --git a/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/eq_same_type_accepted.snap b/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/eq_same_type_accepted.snap index 1cf9b7ba0b5..bbe4060e792 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/eq_same_type_accepted.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/eq_same_type_accepted.snap @@ -12,6 +12,6 @@ fn {graph::read::filter@4294967040}(%0: (Integer, Integer), %1: Entity) -> Boole %3 = %0.1 // cost: 4 %4 = %2 == %3 // cost: 4 - return %4 + return %4 // cost: 4 } } diff --git a/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/fnptr_constant_rejected.snap b/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/fnptr_constant_rejected.snap index 2d8920c74a4..2295838d4cf 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/fnptr_constant_rejected.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/fnptr_constant_rejected.snap @@ -10,6 +10,6 @@ fn {graph::read::filter@4294967040}(%0: (), %1: Entity) -> Boolean { %2 = ({def@99} as FnPtr) %3 = true // cost: 4 - return %3 + return %3 // cost: 4 } } diff --git a/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/input_supported.snap b/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/input_supported.snap index 6494ccad9ef..1fc775ccfc9 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/input_supported.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/input_supported.snap @@ -10,6 +10,6 @@ fn {graph::read::filter@4294967040}(%0: (), %1: Entity) -> Boolean { %2 = input LOAD threshold // cost: 4 %3 = %2 > 100 // cost: 4 - return %3 + return %3 // cost: 4 } } diff --git a/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/serialization_unsafe_edge_propagates.snap b/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/serialization_unsafe_edge_propagates.snap index 1c479bb79cc..b2076f709c6 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/serialization_unsafe_edge_propagates.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/serialization_unsafe_edge_propagates.snap @@ -19,6 +19,6 @@ fn {graph::read::filter@4294967040}(%0: (Uuid | String, Integer), %1: Entity) -> %4 = %2 %5 = %3 > 42 // cost: 4 - return %5 + return %5 // cost: 4 } } diff --git a/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/serialization_unsafe_statement_no_cost.snap b/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/serialization_unsafe_statement_no_cost.snap index faab5b071f2..3b0be3ed775 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/serialization_unsafe_statement_no_cost.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/serialization_unsafe_statement_no_cost.snap @@ -14,6 +14,6 @@ fn {graph::read::filter@4294967040}(%0: (Uuid | String, Integer), %1: Entity) -> %4 = %2 %5 = %3 > 42 // cost: 4 - return %5 + return %5 // cost: 4 } } diff --git a/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/storage_statements_zero_cost.snap b/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/storage_statements_zero_cost.snap index 4773d151019..d40228522e5 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/storage_statements_zero_cost.snap +++ b/libs/@local/hashql/mir/tests/ui/pass/execution/statement_placement/postgres/storage_statements_zero_cost.snap @@ -16,6 +16,6 @@ fn {graph::read::filter@4294967040}(%0: (), %1: Entity) -> Integer { drop %2 // cost: 0 drop %3 // cost: 0 - return %4 + return %4 // cost: 4 } } diff --git a/libs/@local/hashql/mir/tests/ui/pass/forward_substitution/chained-projection.stdout b/libs/@local/hashql/mir/tests/ui/pass/forward_substitution/chained-projection.stdout index f9a82ff63c0..a81b474d8b6 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/forward_substitution/chained-projection.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/forward_substitution/chained-projection.stdout @@ -6,7 +6,7 @@ let %2: ((Integer, Integer), Integer) bb0(): { - switchInt(1) -> [0: bb2(), 1: bb1()] + switchInt(true) -> [0: bb2(), 1: bb1()] } bb1(): { diff --git a/libs/@local/hashql/mir/tests/ui/pass/forward_substitution/closure-env-capture.aux.svg b/libs/@local/hashql/mir/tests/ui/pass/forward_substitution/closure-env-capture.aux.svg index fde2ae74498..d4c00dd3e03 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/forward_substitution/closure-env-capture.aux.svg +++ b/libs/@local/hashql/mir/tests/ui/pass/forward_substitution/closure-env-capture.aux.svg @@ -1,20 +1,20 @@ -Initial MIRMIR after Forward Substitution

fn f:0(%0: (Integer,)) -> Integer

thunk {thunk#3}() -> Integer

fn f:0(%0: (Integer,)) -> Integer

thunk {thunk#3}() -> Integer

-
bb0()
MIR
0%1 = %0.0
Treturn %1
bb0()
MIR
TswitchInt(1)
bb2()
MIR
Tgoto
bb1()
MIR
0%1 = 42
1%3 = (%1)
2%2 = closure((f:0 as FnPtr), %3)
3%4 = apply %2.0 %2.1
Tgoto
bb3(%0)
MIR
Treturn %0
bb0()
MIR
0%1 = %0.0
Treturn %0.0
bb0()
MIR
0%1 = 42
1%3 = (42)
2%2 = closure((f:0 as FnPtr), %3)
3%4 = apply (f:0 as FnPtr) %3
4%0 = %4
Treturn %4
()0()1(%4)(0) +
bb0()
MIR
0%1 = %0.0
Treturn %1
bb0()
MIR
TswitchInt(true)
bb2()
MIR
Tgoto
bb1()
MIR
0%1 = 42
1%3 = (%1)
2%2 = closure((f:0 as FnPtr), %3)
3%4 = apply %2.0 %2.1
Tgoto
bb3(%0)
MIR
Treturn %0
bb0()
MIR
0%1 = %0.0
Treturn %0.0
bb0()
MIR
0%1 = 42
1%3 = (42)
2%2 = closure((f:0 as FnPtr), %3)
3%4 = apply (f:0 as FnPtr) %3
4%0 = %4
Treturn %4
()0()1(%4)(0) - - + +
diff --git a/libs/@local/hashql/mir/tests/ui/pass/forward_substitution/closure-env-capture.stdout b/libs/@local/hashql/mir/tests/ui/pass/forward_substitution/closure-env-capture.stdout index eed6d71dda2..7ce121cada7 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/forward_substitution/closure-env-capture.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/forward_substitution/closure-env-capture.stdout @@ -18,7 +18,7 @@ fn f:0(%0: (Integer,)) -> Integer { let %4: Integer bb0(): { - switchInt(1) -> [0: bb2(), 1: bb1()] + switchInt(true) -> [0: bb2(), 1: bb1()] } bb1(): { diff --git a/libs/@local/hashql/mir/tests/ui/pass/forward_substitution/nested.stdout b/libs/@local/hashql/mir/tests/ui/pass/forward_substitution/nested.stdout index 53dae269b67..16ff1730f33 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/forward_substitution/nested.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/forward_substitution/nested.stdout @@ -8,7 +8,7 @@ let %4: String bb0(): { - switchInt(0) -> [0: bb8(), 1: bb1()] + switchInt(false) -> [0: bb8(), 1: bb1()] } bb1(): { diff --git a/libs/@local/hashql/mir/tests/ui/pass/forward_substitution/param-const-agree.stdout b/libs/@local/hashql/mir/tests/ui/pass/forward_substitution/param-const-agree.stdout index 3355a32d5cf..43729ea555d 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/forward_substitution/param-const-agree.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/forward_substitution/param-const-agree.stdout @@ -7,7 +7,7 @@ let %3: (Integer,) bb0(): { - switchInt(1) -> [0: bb5(), 1: bb1()] + switchInt(true) -> [0: bb5(), 1: bb1()] } bb1(): { diff --git a/libs/@local/hashql/mir/tests/ui/pass/forward_substitution/param-const-diverge.stdout b/libs/@local/hashql/mir/tests/ui/pass/forward_substitution/param-const-diverge.stdout index ed77911f70b..01d866e87d0 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/forward_substitution/param-const-diverge.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/forward_substitution/param-const-diverge.stdout @@ -7,7 +7,7 @@ let %3: (Integer,) bb0(): { - switchInt(1) -> [0: bb5(), 1: bb1()] + switchInt(true) -> [0: bb5(), 1: bb1()] } bb1(): { diff --git a/libs/@local/hashql/mir/tests/ui/pass/forward_substitution/tuple-projection.stdout b/libs/@local/hashql/mir/tests/ui/pass/forward_substitution/tuple-projection.stdout index bce38641714..4a2a595ff75 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/forward_substitution/tuple-projection.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/forward_substitution/tuple-projection.stdout @@ -6,7 +6,7 @@ let %2: (Integer,) bb0(): { - switchInt(1) -> [0: bb2(), 1: bb1()] + switchInt(true) -> [0: bb2(), 1: bb1()] } bb1(): { diff --git a/libs/@local/hashql/mir/tests/ui/pass/inline/heuristic-inline.stdout b/libs/@local/hashql/mir/tests/ui/pass/inline/heuristic-inline.stdout index a4cb383a913..1baf94ea0b9 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/inline/heuristic-inline.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/inline/heuristic-inline.stdout @@ -44,7 +44,7 @@ fn {closure#10}(%0: ()) -> Boolean { } bb2(): { - goto -> bb3(0) + goto -> bb3(false) } bb3(%3): { @@ -115,7 +115,7 @@ fn {closure#10}(%0: ()) -> Boolean { } bb2(): { - return 0 + return false } } @@ -182,7 +182,7 @@ fn {closure#10}(%0: ()) -> Boolean { } bb2(): { - return 0 + return false } bb3(%2): { @@ -249,7 +249,7 @@ thunk use_flag:0() -> () -> Boolean { } bb4(): { - goto -> bb1(0) + goto -> bb1(false) } bb5(%3): { diff --git a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/annihilator-and-false.stdout b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/annihilator-and-false.stdout index 9caa65ae28a..d45548d02ea 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/annihilator-and-false.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/annihilator-and-false.stdout @@ -6,18 +6,18 @@ let %2: Boolean bb0(): { - switchInt(1) -> [0: bb2(), 1: bb1()] + switchInt(true) -> [0: bb2(), 1: bb1()] } bb1(): { %1 = 1 == 1 - %2 = %1 & 0 + %2 = %1 & false goto -> bb3(%2) } bb2(): { - goto -> bb3(1) + goto -> bb3(true) } bb3(%0): { @@ -32,8 +32,8 @@ let %2: Boolean bb0(): { - %1 = 1 - %2 = 0 + %1 = true + %2 = false %0 = %2 return %2 diff --git a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/annihilator-or-true.stdout b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/annihilator-or-true.stdout index 659b50f806b..5f208a87668 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/annihilator-or-true.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/annihilator-or-true.stdout @@ -6,18 +6,18 @@ let %2: Boolean bb0(): { - switchInt(1) -> [0: bb2(), 1: bb1()] + switchInt(true) -> [0: bb2(), 1: bb1()] } bb1(): { %1 = 1 == 2 - %2 = %1 | 1 + %2 = %1 | true goto -> bb3(%2) } bb2(): { - goto -> bb3(0) + goto -> bb3(false) } bb3(%0): { @@ -32,8 +32,8 @@ let %2: Boolean bb0(): { - %1 = 0 - %2 = 1 + %1 = false + %2 = true %0 = %2 return %2 diff --git a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/chained-const-fold.stdout b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/chained-const-fold.stdout index df3c51fa9a1..b8d5d5253a8 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/chained-const-fold.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/chained-const-fold.stdout @@ -6,18 +6,18 @@ let %2: Boolean bb0(): { - switchInt(1) -> [0: bb2(), 1: bb1()] + switchInt(true) -> [0: bb2(), 1: bb1()] } bb1(): { %1 = 1 == 2 - %2 = %1 == 0 + %2 = %1 == false goto -> bb3(%2) } bb2(): { - goto -> bb3(0) + goto -> bb3(false) } bb3(%0): { @@ -32,8 +32,8 @@ let %2: Boolean bb0(): { - %1 = 0 - %2 = 1 + %1 = false + %2 = true %0 = %2 return %2 diff --git a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/const-fold-eq.stdout b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/const-fold-eq.stdout index 99d9962fab4..651015cc1b4 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/const-fold-eq.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/const-fold-eq.stdout @@ -5,7 +5,7 @@ let %1: Boolean bb0(): { - switchInt(1) -> [0: bb2(), 1: bb1()] + switchInt(true) -> [0: bb2(), 1: bb1()] } bb1(): { @@ -15,7 +15,7 @@ } bb2(): { - goto -> bb3(0) + goto -> bb3(false) } bb3(%0): { @@ -29,7 +29,7 @@ let %1: Boolean bb0(): { - %1 = 0 + %1 = false %0 = %1 return %1 diff --git a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/const-fold-gt.stdout b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/const-fold-gt.stdout index 6119322d227..fa453f665e4 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/const-fold-gt.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/const-fold-gt.stdout @@ -5,7 +5,7 @@ let %1: Boolean bb0(): { - switchInt(1) -> [0: bb2(), 1: bb1()] + switchInt(true) -> [0: bb2(), 1: bb1()] } bb1(): { @@ -15,7 +15,7 @@ } bb2(): { - goto -> bb3(0) + goto -> bb3(false) } bb3(%0): { @@ -29,7 +29,7 @@ let %1: Boolean bb0(): { - %1 = 1 + %1 = true %0 = %1 return %1 diff --git a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/const-fold-gte.stdout b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/const-fold-gte.stdout index 800a6493c6b..5d70454773b 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/const-fold-gte.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/const-fold-gte.stdout @@ -5,7 +5,7 @@ let %1: Boolean bb0(): { - switchInt(1) -> [0: bb2(), 1: bb1()] + switchInt(true) -> [0: bb2(), 1: bb1()] } bb1(): { @@ -15,7 +15,7 @@ } bb2(): { - goto -> bb3(0) + goto -> bb3(false) } bb3(%0): { @@ -29,7 +29,7 @@ let %1: Boolean bb0(): { - %1 = 1 + %1 = true %0 = %1 return %1 diff --git a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/const-fold-lt.stdout b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/const-fold-lt.stdout index dfd17f5efb1..7b6dfbb428d 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/const-fold-lt.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/const-fold-lt.stdout @@ -5,7 +5,7 @@ let %1: Boolean bb0(): { - switchInt(1) -> [0: bb2(), 1: bb1()] + switchInt(true) -> [0: bb2(), 1: bb1()] } bb1(): { @@ -15,7 +15,7 @@ } bb2(): { - goto -> bb3(0) + goto -> bb3(false) } bb3(%0): { @@ -29,7 +29,7 @@ let %1: Boolean bb0(): { - %1 = 1 + %1 = true %0 = %1 return %1 diff --git a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/const-fold-lte.stdout b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/const-fold-lte.stdout index 31efd47a78a..00799124358 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/const-fold-lte.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/const-fold-lte.stdout @@ -5,7 +5,7 @@ let %1: Boolean bb0(): { - switchInt(1) -> [0: bb2(), 1: bb1()] + switchInt(true) -> [0: bb2(), 1: bb1()] } bb1(): { @@ -15,7 +15,7 @@ } bb2(): { - goto -> bb3(0) + goto -> bb3(false) } bb3(%0): { @@ -29,7 +29,7 @@ let %1: Boolean bb0(): { - %1 = 1 + %1 = true %0 = %1 return %1 diff --git a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/const-fold-ne.stdout b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/const-fold-ne.stdout index 83f22bbc9be..a53a7953bd9 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/const-fold-ne.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/const-fold-ne.stdout @@ -5,7 +5,7 @@ let %1: Boolean bb0(): { - switchInt(1) -> [0: bb2(), 1: bb1()] + switchInt(true) -> [0: bb2(), 1: bb1()] } bb1(): { @@ -15,7 +15,7 @@ } bb2(): { - goto -> bb3(0) + goto -> bb3(false) } bb3(%0): { @@ -29,7 +29,7 @@ let %1: Boolean bb0(): { - %1 = 1 + %1 = true %0 = %1 return %1 diff --git a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/const-propagation-locals.stdout b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/const-propagation-locals.stdout index f1497ac6368..87c63fa0da7 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/const-propagation-locals.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/const-propagation-locals.stdout @@ -7,7 +7,7 @@ let %3: Boolean bb0(): { - switchInt(1) -> [0: bb2(), 1: bb1()] + switchInt(true) -> [0: bb2(), 1: bb1()] } bb1(): { @@ -19,7 +19,7 @@ } bb2(): { - goto -> bb3(1) + goto -> bb3(true) } bb3(%0): { @@ -37,7 +37,7 @@ bb0(): { %1 = 5 %2 = 3 - %3 = 0 + %3 = false %0 = %3 return %3 diff --git a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/identical-operand-eq.stdout b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/identical-operand-eq.stdout index 47b282f0974..b5a5ad65590 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/identical-operand-eq.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/identical-operand-eq.stdout @@ -6,7 +6,7 @@ let %2: Boolean bb0(): { - switchInt(1) -> [0: bb2(), 1: bb1()] + switchInt(true) -> [0: bb2(), 1: bb1()] } bb1(): { @@ -17,7 +17,7 @@ } bb2(): { - goto -> bb3(0) + goto -> bb3(false) } bb3(%0): { @@ -33,7 +33,7 @@ bb0(): { %1 = 42 - %2 = 1 + %2 = true %0 = %2 return %2 diff --git a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/identical-operand-gt.stdout b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/identical-operand-gt.stdout index 87ce2f08dd9..9def0cf9661 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/identical-operand-gt.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/identical-operand-gt.stdout @@ -6,7 +6,7 @@ let %2: Boolean bb0(): { - switchInt(1) -> [0: bb2(), 1: bb1()] + switchInt(true) -> [0: bb2(), 1: bb1()] } bb1(): { @@ -17,7 +17,7 @@ } bb2(): { - goto -> bb3(1) + goto -> bb3(true) } bb3(%0): { @@ -33,7 +33,7 @@ bb0(): { %1 = 42 - %2 = 0 + %2 = false %0 = %2 return %2 diff --git a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/identical-operand-gte.stdout b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/identical-operand-gte.stdout index 5e8779c91ff..21d87c8319f 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/identical-operand-gte.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/identical-operand-gte.stdout @@ -6,7 +6,7 @@ let %2: Boolean bb0(): { - switchInt(1) -> [0: bb2(), 1: bb1()] + switchInt(true) -> [0: bb2(), 1: bb1()] } bb1(): { @@ -17,7 +17,7 @@ } bb2(): { - goto -> bb3(0) + goto -> bb3(false) } bb3(%0): { @@ -33,7 +33,7 @@ bb0(): { %1 = 42 - %2 = 1 + %2 = true %0 = %2 return %2 diff --git a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/identical-operand-lt.stdout b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/identical-operand-lt.stdout index dcc74bb2a59..e2fc225ae45 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/identical-operand-lt.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/identical-operand-lt.stdout @@ -6,7 +6,7 @@ let %2: Boolean bb0(): { - switchInt(1) -> [0: bb2(), 1: bb1()] + switchInt(true) -> [0: bb2(), 1: bb1()] } bb1(): { @@ -17,7 +17,7 @@ } bb2(): { - goto -> bb3(1) + goto -> bb3(true) } bb3(%0): { @@ -33,7 +33,7 @@ bb0(): { %1 = 42 - %2 = 0 + %2 = false %0 = %2 return %2 diff --git a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/identical-operand-lte.stdout b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/identical-operand-lte.stdout index a582e4b8621..7b1b899d3af 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/identical-operand-lte.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/identical-operand-lte.stdout @@ -6,7 +6,7 @@ let %2: Boolean bb0(): { - switchInt(1) -> [0: bb2(), 1: bb1()] + switchInt(true) -> [0: bb2(), 1: bb1()] } bb1(): { @@ -17,7 +17,7 @@ } bb2(): { - goto -> bb3(0) + goto -> bb3(false) } bb3(%0): { @@ -33,7 +33,7 @@ bb0(): { %1 = 42 - %2 = 1 + %2 = true %0 = %2 return %2 diff --git a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/identical-operand-ne.stdout b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/identical-operand-ne.stdout index f0ee0186aab..2691a09a28d 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/identical-operand-ne.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/identical-operand-ne.stdout @@ -6,7 +6,7 @@ let %2: Boolean bb0(): { - switchInt(1) -> [0: bb2(), 1: bb1()] + switchInt(true) -> [0: bb2(), 1: bb1()] } bb1(): { @@ -17,7 +17,7 @@ } bb2(): { - goto -> bb3(1) + goto -> bb3(true) } bb3(%0): { @@ -33,7 +33,7 @@ bb0(): { %1 = 42 - %2 = 0 + %2 = false %0 = %2 return %2 diff --git a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/identity-and-true.stdout b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/identity-and-true.stdout index f66fb763a75..14620b2ae12 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/identity-and-true.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/identity-and-true.stdout @@ -6,18 +6,18 @@ let %2: Boolean bb0(): { - switchInt(1) -> [0: bb2(), 1: bb1()] + switchInt(true) -> [0: bb2(), 1: bb1()] } bb1(): { %1 = 1 == 1 - %2 = %1 & 1 + %2 = %1 & true goto -> bb3(%2) } bb2(): { - goto -> bb3(0) + goto -> bb3(false) } bb3(%0): { @@ -32,8 +32,8 @@ let %2: Boolean bb0(): { - %1 = 1 - %2 = 1 + %1 = true + %2 = true %0 = %2 return %2 diff --git a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/identity-or-false.stdout b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/identity-or-false.stdout index 81aae683325..999e55245c5 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/identity-or-false.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/identity-or-false.stdout @@ -6,18 +6,18 @@ let %2: Boolean bb0(): { - switchInt(1) -> [0: bb2(), 1: bb1()] + switchInt(true) -> [0: bb2(), 1: bb1()] } bb1(): { %1 = 1 == 1 - %2 = %1 | 0 + %2 = %1 | false goto -> bb3(%2) } bb2(): { - goto -> bb3(0) + goto -> bb3(false) } bb3(%0): { @@ -32,8 +32,8 @@ let %2: Boolean bb0(): { - %1 = 1 - %2 = 1 + %1 = true + %2 = true %0 = %2 return %2 diff --git a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/showcase.aux.svg b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/showcase.aux.svg index 5d18449c258..fbab39c449e 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/showcase.aux.svg +++ b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/showcase.aux.svg @@ -1,20 +1,20 @@ -Initial MIRMIR after InstSimplify

thunk {thunk#7}() -> Boolean

-

thunk {thunk#7}() -> Boolean

-
bb0()
MIR
TswitchInt(1)
bb2()
MIR
Tgoto
bb1()
MIR
0%1 = 1 == 2
1%2 = 3 < 5
2%3 = %2 & 1
3%4 = 42
4%5 = %4 == %4
5%6 = %1 | %3
6%7 = %6 & %5
Tgoto
bb3(%0)
MIR
Treturn %0
bb0()
MIR
0%1 = 0
1%2 = 1
2%3 = 1
3%4 = 42
4%5 = 1
5%6 = 1
6%7 = 1
7%0 = %7
Treturn %7
()0()1(%7)(0) - - - +Initial MIRMIR after InstSimplify

thunk {thunk#7}() -> Boolean

+

thunk {thunk#7}() -> Boolean

+
bb0()
MIR
TswitchInt(true)
bb2()
MIR
Tgoto
bb1()
MIR
0%1 = 1 == 2
1%2 = 3 < 5
2%3 = %2 & true
3%4 = 42
4%5 = %4 == %4
5%6 = %1 | %3
6%7 = %6 & %5
Tgoto
bb3(%0)
MIR
Treturn %0
bb0()
MIR
0%1 = false
1%2 = true
2%3 = true
3%4 = 42
4%5 = true
5%6 = true
6%7 = true
7%0 = %7
Treturn %7
()0()1(%7)(false) + + + - +
diff --git a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/showcase.stdout b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/showcase.stdout index 04d56dc87fc..21593fd4883 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/showcase.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/inst_simplify/showcase.stdout @@ -11,13 +11,13 @@ let %7: Boolean bb0(): { - switchInt(1) -> [0: bb2(), 1: bb1()] + switchInt(true) -> [0: bb2(), 1: bb1()] } bb1(): { %1 = 1 == 2 %2 = 3 < 5 - %3 = %2 & 1 + %3 = %2 & true %4 = 42 %5 = %4 == %4 %6 = %1 | %3 @@ -27,7 +27,7 @@ } bb2(): { - goto -> bb3(0) + goto -> bb3(false) } bb3(%0): { @@ -47,13 +47,13 @@ let %7: Boolean bb0(): { - %1 = 0 - %2 = 1 - %3 = 1 + %1 = false + %2 = true + %3 = true %4 = 42 - %5 = 1 - %6 = 1 - %7 = 1 + %5 = true + %6 = true + %7 = true %0 = %7 return %7 diff --git a/libs/@local/hashql/mir/tests/ui/pass/post_inline/cascading-simplification.stdout b/libs/@local/hashql/mir/tests/ui/pass/post_inline/cascading-simplification.stdout index f1ce901c23a..e2bf218f858 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/post_inline/cascading-simplification.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/post_inline/cascading-simplification.stdout @@ -354,18 +354,18 @@ thunk check_both:0() -> (Boolean, Boolean) -> Boolean { thunk {thunk#7}() -> Boolean { bb0(): { - return 1 + return true } } thunk {thunk#8}() -> Boolean { bb0(): { - return 1 + return true } } *thunk {thunk#9}() -> Boolean { bb0(): { - return 1 + return true } } \ No newline at end of file diff --git a/libs/@local/hashql/mir/tests/ui/pass/post_inline/closure-env-cleanup.stdout b/libs/@local/hashql/mir/tests/ui/pass/post_inline/closure-env-cleanup.stdout index 216c8f925b6..73938de717e 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/post_inline/closure-env-cleanup.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/post_inline/closure-env-cleanup.stdout @@ -246,6 +246,6 @@ thunk checker:0() -> (Integer) -> Boolean { *thunk {thunk#6}() -> Boolean { bb0(): { - return 1 + return true } } \ No newline at end of file diff --git a/libs/@local/hashql/mir/tests/ui/pass/post_inline/constant-propagation-after-inline.stdout b/libs/@local/hashql/mir/tests/ui/pass/post_inline/constant-propagation-after-inline.stdout index c0fce5dcfd5..b81e60f02af 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/post_inline/constant-propagation-after-inline.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/post_inline/constant-propagation-after-inline.stdout @@ -136,6 +136,6 @@ thunk is_positive:0() -> (Integer) -> Boolean { *thunk {thunk#3}() -> Boolean { bb0(): { - return 1 + return true } } \ No newline at end of file diff --git a/libs/@local/hashql/mir/tests/ui/pass/post_inline/dead-code-from-inline.stdout b/libs/@local/hashql/mir/tests/ui/pass/post_inline/dead-code-from-inline.stdout index 2d995977c96..06c6d41ace6 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/post_inline/dead-code-from-inline.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/post_inline/dead-code-from-inline.stdout @@ -38,7 +38,7 @@ thunk select_branch:0() -> (Boolean) -> String { bb0(): { %0 = apply (select_branch:0 as FnPtr) - %1 = apply %0.0 %0.1 1 + %1 = apply %0.0 %0.1 true return %1 } @@ -74,7 +74,7 @@ thunk select_branch:0() -> (Boolean) -> String { let %0: String bb0(): { - %0 = apply ({closure#4} as FnPtr) () 1 + %0 = apply ({closure#4} as FnPtr) () true return %0 } @@ -113,7 +113,7 @@ thunk select_branch:0() -> (Boolean) -> String { bb0(): { %1 = () - %2 = 1 + %2 = true goto -> bb2() } diff --git a/libs/@local/hashql/mir/tests/ui/pass/post_inline/nested-branch-elimination.stdout b/libs/@local/hashql/mir/tests/ui/pass/post_inline/nested-branch-elimination.stdout index 58d5b807f80..122a85c7110 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/post_inline/nested-branch-elimination.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/post_inline/nested-branch-elimination.stdout @@ -339,7 +339,7 @@ thunk check_low:0() -> (Integer) -> Boolean { thunk {thunk#8}() -> Boolean { bb0(): { - return 0 + return false } } diff --git a/libs/@local/hashql/mir/tests/ui/pass/pre_inline/basic-constant-folding.stdout b/libs/@local/hashql/mir/tests/ui/pass/pre_inline/basic-constant-folding.stdout index 2c28db7b180..23571c37f50 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/pre_inline/basic-constant-folding.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/pre_inline/basic-constant-folding.stdout @@ -4,7 +4,7 @@ let %0: String bb0(): { - switchInt(1) -> [0: bb2(), 1: bb1()] + switchInt(true) -> [0: bb2(), 1: bb1()] } bb1(): { diff --git a/libs/@local/hashql/mir/tests/ui/pass/pre_inline/chain-simplification.stdout b/libs/@local/hashql/mir/tests/ui/pass/pre_inline/chain-simplification.stdout index f11d588671d..5fb4ccb993a 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/pre_inline/chain-simplification.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/pre_inline/chain-simplification.stdout @@ -8,21 +8,21 @@ let %4: String bb0(): { - switchInt(1) -> [0: bb11(), 1: bb1()] + switchInt(true) -> [0: bb11(), 1: bb1()] } bb1(): { - %1 = 1 + %1 = true switchInt(%1) -> [0: bb3(), 1: bb2()] } bb2(): { - goto -> bb4(1) + goto -> bb4(true) } bb3(): { - goto -> bb4(0) + goto -> bb4(false) } bb4(%2): { @@ -30,11 +30,11 @@ } bb5(): { - goto -> bb7(1) + goto -> bb7(true) } bb6(): { - goto -> bb7(0) + goto -> bb7(false) } bb7(%3): { diff --git a/libs/@local/hashql/mir/tests/ui/pass/pre_inline/closure-with-dead-branch.stdout b/libs/@local/hashql/mir/tests/ui/pass/pre_inline/closure-with-dead-branch.stdout index 8f3929550d0..e79b71e2c40 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/pre_inline/closure-with-dead-branch.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/pre_inline/closure-with-dead-branch.stdout @@ -24,7 +24,7 @@ thunk {thunk#2}() -> Boolean { bb0(): { %0 = apply (identity:0 as FnPtr) - %1 = apply %0.0 %0.1 1 + %1 = apply %0.0 %0.1 true return %1 } @@ -73,7 +73,7 @@ thunk identity:0() -> (Boolean) -> Boolean { thunk {thunk#2}() -> Boolean { bb0(): { - return 1 + return true } } diff --git a/libs/@local/hashql/mir/tests/ui/pass/pre_inline/dead-code-after-propagation.stdout b/libs/@local/hashql/mir/tests/ui/pass/pre_inline/dead-code-after-propagation.stdout index 5fb3924f24d..20503ff7ed5 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/pre_inline/dead-code-after-propagation.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/pre_inline/dead-code-after-propagation.stdout @@ -6,7 +6,7 @@ let %2: Integer bb0(): { - switchInt(1) -> [0: bb2(), 1: bb1()] + switchInt(true) -> [0: bb2(), 1: bb1()] } bb1(): { diff --git a/libs/@local/hashql/mir/tests/ui/pass/pre_inline/inst-simplify-with-propagation.stdout b/libs/@local/hashql/mir/tests/ui/pass/pre_inline/inst-simplify-with-propagation.stdout index 896c41dacba..8af07a3e767 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/pre_inline/inst-simplify-with-propagation.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/pre_inline/inst-simplify-with-propagation.stdout @@ -2,7 +2,7 @@ thunk x:0() -> Boolean { bb0(): { - return 1 + return true } } @@ -33,7 +33,7 @@ thunk x:0() -> Boolean { thunk x:0() -> Boolean { bb0(): { - return 1 + return true } } diff --git a/libs/@local/hashql/mir/tests/ui/pass/pre_inline/nested-if-constant.stdout b/libs/@local/hashql/mir/tests/ui/pass/pre_inline/nested-if-constant.stdout index de1185c8bc2..ea8c79c10cd 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/pre_inline/nested-if-constant.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/pre_inline/nested-if-constant.stdout @@ -6,15 +6,15 @@ let %2: String bb0(): { - switchInt(1) -> [0: bb8(), 1: bb1()] + switchInt(true) -> [0: bb8(), 1: bb1()] } bb1(): { - switchInt(0) -> [0: bb2(), 1: bb5()] + switchInt(false) -> [0: bb2(), 1: bb5()] } bb2(): { - switchInt(1) -> [0: bb4(), 1: bb3()] + switchInt(true) -> [0: bb4(), 1: bb3()] } bb3(): { diff --git a/libs/@local/hashql/mir/tests/ui/pass/pre_inline/nested-let-cleanup.stdout b/libs/@local/hashql/mir/tests/ui/pass/pre_inline/nested-let-cleanup.stdout index 152ef88be46..1f773d15ae3 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/pre_inline/nested-let-cleanup.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/pre_inline/nested-let-cleanup.stdout @@ -7,7 +7,7 @@ let %3: Integer bb0(): { - switchInt(1) -> [0: bb2(), 1: bb1()] + switchInt(true) -> [0: bb2(), 1: bb1()] } bb1(): { diff --git a/libs/@local/hashql/mir/tests/ui/pass/pre_inline/thunk-with-dead-code.stdout b/libs/@local/hashql/mir/tests/ui/pass/pre_inline/thunk-with-dead-code.stdout index c23b973b61c..d0802f2d6ba 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/pre_inline/thunk-with-dead-code.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/pre_inline/thunk-with-dead-code.stdout @@ -2,7 +2,7 @@ fn {closure#4}(%0: ()) -> Boolean { bb0(): { - return 1 + return true } } @@ -63,7 +63,7 @@ thunk unused:0() -> String { fn {closure#4}(%0: ()) -> Boolean { bb0(): { - return 1 + return true } } @@ -79,7 +79,7 @@ thunk get_flag:0() -> () -> Boolean { thunk flag:0() -> Boolean { bb0(): { - return 1 + return true } } diff --git a/libs/@local/hashql/mir/tests/ui/reify/closure-captured-var.stdout b/libs/@local/hashql/mir/tests/ui/reify/closure-captured-var.stdout index 3c40b9af226..fc4c68ce055 100644 --- a/libs/@local/hashql/mir/tests/ui/reify/closure-captured-var.stdout +++ b/libs/@local/hashql/mir/tests/ui/reify/closure-captured-var.stdout @@ -55,7 +55,7 @@ fn {ctor#::core::option::None}(%0: ()) -> ::core::option::None { let %8: ::core::option::None bb0(): { - switchInt(1) -> [0: bb2(), 1: bb1()] + switchInt(true) -> [0: bb2(), 1: bb1()] } bb1(): { diff --git a/libs/@local/hashql/mir/tests/ui/reify/dict-computed-key.stdout b/libs/@local/hashql/mir/tests/ui/reify/dict-computed-key.stdout index fb5d0471fc3..5b5d74cd674 100644 --- a/libs/@local/hashql/mir/tests/ui/reify/dict-computed-key.stdout +++ b/libs/@local/hashql/mir/tests/ui/reify/dict-computed-key.stdout @@ -16,7 +16,7 @@ thunk foo:0() -> Boolean { bb0(): { %0 = apply (foo:0 as FnPtr) %1 = apply (foo:0 as FnPtr) - %2 = dict(%0: 42, 1: %1) + %2 = dict(%0: 42, true: %1) return %2 } diff --git a/libs/@local/hashql/mir/tests/ui/reify/nested-if.aux.svg b/libs/@local/hashql/mir/tests/ui/reify/nested-if.aux.svg index c62ff49a4b6..67d7bfaa53b 100644 --- a/libs/@local/hashql/mir/tests/ui/reify/nested-if.aux.svg +++ b/libs/@local/hashql/mir/tests/ui/reify/nested-if.aux.svg @@ -1,20 +1,20 @@ -

fn {ctor#::core::option::Some}(%0: (), %1: String) -> ::core::option::Some

fn {ctor#::core::option::None}(%0: ()) -> ::core::option::None

thunk {thunk#8}() -> ::core::option::None | ::core::option::Some

-
bb0()
MIR
0%2 = opaque(::core::option::Some, %1)
Treturn %2
bb0()
MIR
0%1 = opaque(::core::option::None, ())
Treturn %1
bb0()
MIR
TswitchInt(1)
bb8()
MIR
0%7 = closure(({ctor#::core::option::None} as FnPtr), ())
1%8 = apply %7.0 %7.1
Tgoto
bb1()
MIR
0%1 = 2 <= 3
TswitchInt(%1)
bb6()
MIR
Tgoto
bb2()
MIR
0%3 = 2 >= 3
TswitchInt(%3)
bb4()
MIR
Tgoto
bb3()
MIR
Tgoto
bb5(%4)
MIR
Tgoto
bb7(%2)
MIR
0%5 = closure(({ctor#::core::option::Some} as FnPtr), ())
1%6 = apply %5.0 %5.1 %2
Tgoto
bb9(%0)
MIR
Treturn %0
()0()1()0()1()0()1("baz")("qux")(%4)("bar")(%6)(%8) +
bb0()
MIR
0%2 = opaque(::core::option::Some, %1)
Treturn %2
bb0()
MIR
0%1 = opaque(::core::option::None, ())
Treturn %1
bb0()
MIR
TswitchInt(true)
bb8()
MIR
0%7 = closure(({ctor#::core::option::None} as FnPtr), ())
1%8 = apply %7.0 %7.1
Tgoto
bb1()
MIR
0%1 = 2 <= 3
TswitchInt(%1)
bb6()
MIR
Tgoto
bb2()
MIR
0%3 = 2 >= 3
TswitchInt(%3)
bb4()
MIR
Tgoto
bb3()
MIR
Tgoto
bb5(%4)
MIR
Tgoto
bb7(%2)
MIR
0%5 = closure(({ctor#::core::option::Some} as FnPtr), ())
1%6 = apply %5.0 %5.1 %2
Tgoto
bb9(%0)
MIR
Treturn %0
()0()1()0()1()0()1("baz")("qux")(%4)("bar")(%6)(%8) - - + + diff --git a/libs/@local/hashql/mir/tests/ui/reify/nested-if.stdout b/libs/@local/hashql/mir/tests/ui/reify/nested-if.stdout index e879da300d5..23055c69c41 100644 --- a/libs/@local/hashql/mir/tests/ui/reify/nested-if.stdout +++ b/libs/@local/hashql/mir/tests/ui/reify/nested-if.stdout @@ -30,7 +30,7 @@ fn {ctor#::core::option::None}(%0: ()) -> ::core::option::None { let %8: ::core::option::None bb0(): { - switchInt(1) -> [0: bb8(), 1: bb1()] + switchInt(true) -> [0: bb8(), 1: bb1()] } bb1(): { diff --git a/libs/@local/hashql/mir/tests/ui/reify/nested-let.stdout b/libs/@local/hashql/mir/tests/ui/reify/nested-let.stdout index 9ced4555614..d8f4f4c48ae 100644 --- a/libs/@local/hashql/mir/tests/ui/reify/nested-let.stdout +++ b/libs/@local/hashql/mir/tests/ui/reify/nested-let.stdout @@ -28,7 +28,7 @@ fn {ctor#::core::option::None}(%0: ()) -> ::core::option::None { let %6: ::core::option::None bb0(): { - switchInt(1) -> [0: bb2(), 1: bb1()] + switchInt(true) -> [0: bb2(), 1: bb1()] } bb1(): { diff --git a/libs/@local/hashql/mir/tests/ui/reify/reassign.stdout b/libs/@local/hashql/mir/tests/ui/reify/reassign.stdout index cadac5f3edc..ffa9c0f1aaa 100644 --- a/libs/@local/hashql/mir/tests/ui/reify/reassign.stdout +++ b/libs/@local/hashql/mir/tests/ui/reify/reassign.stdout @@ -28,7 +28,7 @@ fn {ctor#::core::option::None}(%0: ()) -> ::core::option::None { let %6: ::core::option::None bb0(): { - switchInt(1) -> [0: bb2(), 1: bb1()] + switchInt(true) -> [0: bb2(), 1: bb1()] } bb1(): { From 591383fff43055ad511c1b906bc93c83dcadecd1 Mon Sep 17 00:00:00 2001 From: Bilal Mahmoud Date: Sun, 22 Mar 2026 19:37:30 +0100 Subject: [PATCH 6/6] feat: tests --- .../data-dependency/graph-read-filter.jsonc | 2 +- .../data-dependency/graph-read-filter.stdout | 4 +- .../data-dependency/graph-read-head.jsonc | 2 +- .../data-dependency/graph-read-head.stdout | 6 +-- .../tests/ui/pass/inline/closure-inline.jsonc | 4 +- .../ui/pass/inline/closure-inline.stdout | 40 +++++++++---------- .../ui/pass/inline/excessive-depth.jsonc | 2 +- .../ui/pass/inline/filter-aggressive.jsonc | 2 +- .../ui/pass/inline/filter-aggressive.stdout | 20 +++++----- .../ui/pass/inline/filter-with-ctor.jsonc | 2 +- .../ui/pass/inline/filter-with-ctor.stdout | 20 +++++----- .../mir/tests/ui/reify/graph-read.jsonc | 2 +- .../mir/tests/ui/reify/graph-read.stdout | 6 +-- 13 files changed, 56 insertions(+), 56 deletions(-) diff --git a/libs/@local/hashql/mir/tests/ui/pass/data-dependency/graph-read-filter.jsonc b/libs/@local/hashql/mir/tests/ui/pass/data-dependency/graph-read-filter.jsonc index 468b578f841..e23e824d10b 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/data-dependency/graph-read-filter.jsonc +++ b/libs/@local/hashql/mir/tests/ui/pass/data-dependency/graph-read-filter.jsonc @@ -13,7 +13,7 @@ "::graph::body::filter", [ "::graph::head::entities", - ["input", "axis", "::graph::QueryTemporalAxes"] + ["input", "axis", "_"] ], [ "fn", diff --git a/libs/@local/hashql/mir/tests/ui/pass/data-dependency/graph-read-filter.stdout b/libs/@local/hashql/mir/tests/ui/pass/data-dependency/graph-read-filter.stdout index 040e4c2ebad..e7f6d50da7d 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/data-dependency/graph-read-filter.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/data-dependency/graph-read-filter.stdout @@ -13,13 +13,13 @@ fn {graph::read::filter@11}(%0: (Boolean,), %1: ::graph::types::knowledge::entit *thunk {thunk#5}() -> Integer | List<::graph::types::knowledge::entity::Entity> { let %0: Integer | List<::graph::types::knowledge::entity::Entity> let %1: Integer - let %2: ::graph::TimeAxis + let %2: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes let %3: Boolean let %4: List<::graph::types::knowledge::entity::Entity> let %5: (Boolean,) bb0(): { - switchInt(1) -> [0: bb3(), 1: bb1()] + switchInt(true) -> [0: bb3(), 1: bb1()] } bb1(): { diff --git a/libs/@local/hashql/mir/tests/ui/pass/data-dependency/graph-read-head.jsonc b/libs/@local/hashql/mir/tests/ui/pass/data-dependency/graph-read-head.jsonc index 6d63105cbdd..bf14cd410bd 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/data-dependency/graph-read-head.jsonc +++ b/libs/@local/hashql/mir/tests/ui/pass/data-dependency/graph-read-head.jsonc @@ -2,5 +2,5 @@ //@ description: Graph read head creates GraphReadHeadAxis edge [ "::graph::tail::collect", - ["::graph::head::entities", ["input", "axis", "::graph::QueryTemporalAxes"]] + ["::graph::head::entities", ["input", "axis", "_"]] ] diff --git a/libs/@local/hashql/mir/tests/ui/pass/data-dependency/graph-read-head.stdout b/libs/@local/hashql/mir/tests/ui/pass/data-dependency/graph-read-head.stdout index 1d758058f5a..d6b23bcafe8 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/data-dependency/graph-read-head.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/data-dependency/graph-read-head.stdout @@ -1,7 +1,7 @@ ════ MIR ═══════════════════════════════════════════════════════════════════════ -thunk {thunk#0}() -> ::graph::TimeAxis { - let %0: ::graph::TimeAxis +thunk {thunk#0}() -> ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes { + let %0: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes bb0(): { %0 = input LOAD axis @@ -11,7 +11,7 @@ thunk {thunk#0}() -> ::graph::TimeAxis { } *thunk {thunk#1}() -> List<::graph::types::knowledge::entity::Entity> { - let %0: ::graph::TimeAxis + let %0: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes let %1: List<::graph::types::knowledge::entity::Entity> bb0(): { diff --git a/libs/@local/hashql/mir/tests/ui/pass/inline/closure-inline.jsonc b/libs/@local/hashql/mir/tests/ui/pass/inline/closure-inline.jsonc index ad27820f419..f1b3c3b5a0a 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/inline/closure-inline.jsonc +++ b/libs/@local/hashql/mir/tests/ui/pass/inline/closure-inline.jsonc @@ -7,8 +7,8 @@ "fn", { "#tuple": [] }, { "#struct": {} }, - "::graph::QueryTemporalAxes", - ["input", "axis", "::graph::QueryTemporalAxes"] + "::graph::temporal::QueryTemporalAxes", + ["input", "axis", "_"] ], ["get_axis"] ] diff --git a/libs/@local/hashql/mir/tests/ui/pass/inline/closure-inline.stdout b/libs/@local/hashql/mir/tests/ui/pass/inline/closure-inline.stdout index 1ea3c9650a0..a346854964d 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/inline/closure-inline.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/inline/closure-inline.stdout @@ -1,7 +1,7 @@ ════ Initial MIR ═══════════════════════════════════════════════════════════════ -fn {closure#3}(%0: ()) -> ::graph::TimeAxis { - let %1: ::graph::TimeAxis +fn {closure#3}(%0: ()) -> ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes { + let %1: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes bb0(): { %1 = input LOAD axis @@ -10,8 +10,8 @@ fn {closure#3}(%0: ()) -> ::graph::TimeAxis { } } -thunk get_axis:0() -> () -> ::graph::TimeAxis { - let %0: () -> ::graph::TimeAxis +thunk get_axis:0() -> () -> (::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes) { + let %0: () -> (::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes) let %1: () bb0(): { @@ -22,9 +22,9 @@ thunk get_axis:0() -> () -> ::graph::TimeAxis { } } -*thunk {thunk#2}() -> ::graph::TimeAxis { - let %0: () -> ::graph::TimeAxis - let %1: ::graph::TimeAxis +*thunk {thunk#2}() -> ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes { + let %0: () -> (::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes) + let %1: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes bb0(): { %0 = apply (get_axis:0 as FnPtr) @@ -36,8 +36,8 @@ thunk get_axis:0() -> () -> ::graph::TimeAxis { ════ Pre-inlining MIR ══════════════════════════════════════════════════════════ -fn {closure#3}(%0: ()) -> ::graph::TimeAxis { - let %1: ::graph::TimeAxis +fn {closure#3}(%0: ()) -> ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes { + let %1: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes bb0(): { %1 = input LOAD axis @@ -46,8 +46,8 @@ fn {closure#3}(%0: ()) -> ::graph::TimeAxis { } } -thunk get_axis:0() -> () -> ::graph::TimeAxis { - let %0: () -> ::graph::TimeAxis +thunk get_axis:0() -> () -> (::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes) { + let %0: () -> (::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes) bb0(): { %0 = closure(({closure#3} as FnPtr), ()) @@ -56,8 +56,8 @@ thunk get_axis:0() -> () -> ::graph::TimeAxis { } } -*thunk {thunk#2}() -> ::graph::TimeAxis { - let %0: ::graph::TimeAxis +*thunk {thunk#2}() -> ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes { + let %0: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes bb0(): { %0 = apply ({closure#3} as FnPtr) () @@ -68,8 +68,8 @@ thunk get_axis:0() -> () -> ::graph::TimeAxis { ════ Inlined MIR ═══════════════════════════════════════════════════════════════ -fn {closure#3}(%0: ()) -> ::graph::TimeAxis { - let %1: ::graph::TimeAxis +fn {closure#3}(%0: ()) -> ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes { + let %1: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes bb0(): { %1 = input LOAD axis @@ -78,8 +78,8 @@ fn {closure#3}(%0: ()) -> ::graph::TimeAxis { } } -thunk get_axis:0() -> () -> ::graph::TimeAxis { - let %0: () -> ::graph::TimeAxis +thunk get_axis:0() -> () -> (::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes) { + let %0: () -> (::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes) bb0(): { %0 = closure(({closure#3} as FnPtr), ()) @@ -88,10 +88,10 @@ thunk get_axis:0() -> () -> ::graph::TimeAxis { } } -*thunk {thunk#2}() -> ::graph::TimeAxis { - let %0: ::graph::TimeAxis +*thunk {thunk#2}() -> ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes { + let %0: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes let %1: () - let %2: ::graph::TimeAxis + let %2: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes bb0(): { %1 = () diff --git a/libs/@local/hashql/mir/tests/ui/pass/inline/excessive-depth.jsonc b/libs/@local/hashql/mir/tests/ui/pass/inline/excessive-depth.jsonc index fff9af5cfe4..89593f029fa 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/inline/excessive-depth.jsonc +++ b/libs/@local/hashql/mir/tests/ui/pass/inline/excessive-depth.jsonc @@ -12,7 +12,7 @@ "::graph::body::filter", [ "::graph::head::entities", - ["input", "axis", "::graph::QueryTemporalAxes"] + ["input", "axis", "_"] ], [ "fn", diff --git a/libs/@local/hashql/mir/tests/ui/pass/inline/filter-aggressive.jsonc b/libs/@local/hashql/mir/tests/ui/pass/inline/filter-aggressive.jsonc index db62c30004d..15c21466b2b 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/inline/filter-aggressive.jsonc +++ b/libs/@local/hashql/mir/tests/ui/pass/inline/filter-aggressive.jsonc @@ -6,7 +6,7 @@ "::graph::body::filter", [ "::graph::head::entities", - ["input", "axis", "::graph::QueryTemporalAxes"] + ["input", "axis", "_"] ], [ "fn", diff --git a/libs/@local/hashql/mir/tests/ui/pass/inline/filter-aggressive.stdout b/libs/@local/hashql/mir/tests/ui/pass/inline/filter-aggressive.stdout index ec3eaf48466..b0abcece659 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/inline/filter-aggressive.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/inline/filter-aggressive.stdout @@ -1,7 +1,7 @@ ════ Initial MIR ═══════════════════════════════════════════════════════════════ -thunk {thunk#1}() -> ::graph::TimeAxis { - let %0: ::graph::TimeAxis +thunk {thunk#1}() -> ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes { + let %0: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes bb0(): { %0 = input LOAD axis @@ -21,7 +21,7 @@ fn {graph::read::filter@7}(%0: (), %1: ::graph::types::knowledge::entity::Entity } *thunk {thunk#3}() -> List<::graph::types::knowledge::entity::Entity> { - let %0: ::graph::TimeAxis + let %0: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes let %1: List<::graph::types::knowledge::entity::Entity> let %2: () @@ -41,8 +41,8 @@ fn {graph::read::filter@7}(%0: (), %1: ::graph::types::knowledge::entity::Entity ════ Pre-inlining MIR ══════════════════════════════════════════════════════════ -thunk {thunk#1}() -> ::graph::TimeAxis { - let %0: ::graph::TimeAxis +thunk {thunk#1}() -> ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes { + let %0: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes bb0(): { %0 = input LOAD axis @@ -62,7 +62,7 @@ fn {graph::read::filter@7}(%0: (), %1: ::graph::types::knowledge::entity::Entity } *thunk {thunk#3}() -> List<::graph::types::knowledge::entity::Entity> { - let %0: ::graph::TimeAxis + let %0: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes let %1: List<::graph::types::knowledge::entity::Entity> let %2: () @@ -82,8 +82,8 @@ fn {graph::read::filter@7}(%0: (), %1: ::graph::types::knowledge::entity::Entity ════ Inlined MIR ═══════════════════════════════════════════════════════════════ -thunk {thunk#1}() -> ::graph::TimeAxis { - let %0: ::graph::TimeAxis +thunk {thunk#1}() -> ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes { + let %0: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes bb0(): { %0 = input LOAD axis @@ -103,10 +103,10 @@ fn {graph::read::filter@7}(%0: (), %1: ::graph::types::knowledge::entity::Entity } *thunk {thunk#3}() -> List<::graph::types::knowledge::entity::Entity> { - let %0: ::graph::TimeAxis + let %0: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes let %1: List<::graph::types::knowledge::entity::Entity> let %2: () - let %3: ::graph::TimeAxis + let %3: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes bb0(): { goto -> bb3() diff --git a/libs/@local/hashql/mir/tests/ui/pass/inline/filter-with-ctor.jsonc b/libs/@local/hashql/mir/tests/ui/pass/inline/filter-with-ctor.jsonc index da71b8f06ab..b723372adb0 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/inline/filter-with-ctor.jsonc +++ b/libs/@local/hashql/mir/tests/ui/pass/inline/filter-with-ctor.jsonc @@ -6,7 +6,7 @@ "::graph::body::filter", [ "::graph::head::entities", - ["input", "axis", "::graph::QueryTemporalAxes"] + ["input", "axis", "_"] ], [ "fn", diff --git a/libs/@local/hashql/mir/tests/ui/pass/inline/filter-with-ctor.stdout b/libs/@local/hashql/mir/tests/ui/pass/inline/filter-with-ctor.stdout index 34b1520b153..e58715e7cbe 100644 --- a/libs/@local/hashql/mir/tests/ui/pass/inline/filter-with-ctor.stdout +++ b/libs/@local/hashql/mir/tests/ui/pass/inline/filter-with-ctor.stdout @@ -1,7 +1,7 @@ ════ Initial MIR ═══════════════════════════════════════════════════════════════ -thunk {thunk#1}() -> ::graph::TimeAxis { - let %0: ::graph::TimeAxis +thunk {thunk#1}() -> ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes { + let %0: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes bb0(): { %0 = input LOAD axis @@ -89,7 +89,7 @@ fn {graph::read::filter@7}(%0: (), %1: ::graph::types::knowledge::entity::Entity } *thunk {thunk#7}() -> List<::graph::types::knowledge::entity::Entity> { - let %0: ::graph::TimeAxis + let %0: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes let %1: List<::graph::types::knowledge::entity::Entity> let %2: () @@ -109,8 +109,8 @@ fn {graph::read::filter@7}(%0: (), %1: ::graph::types::knowledge::entity::Entity ════ Pre-inlining MIR ══════════════════════════════════════════════════════════ -thunk {thunk#1}() -> ::graph::TimeAxis { - let %0: ::graph::TimeAxis +thunk {thunk#1}() -> ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes { + let %0: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes bb0(): { %0 = input LOAD axis @@ -196,7 +196,7 @@ fn {graph::read::filter@7}(%0: (), %1: ::graph::types::knowledge::entity::Entity } *thunk {thunk#7}() -> List<::graph::types::knowledge::entity::Entity> { - let %0: ::graph::TimeAxis + let %0: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes let %1: List<::graph::types::knowledge::entity::Entity> let %2: () @@ -216,8 +216,8 @@ fn {graph::read::filter@7}(%0: (), %1: ::graph::types::knowledge::entity::Entity ════ Inlined MIR ═══════════════════════════════════════════════════════════════ -thunk {thunk#1}() -> ::graph::TimeAxis { - let %0: ::graph::TimeAxis +thunk {thunk#1}() -> ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes { + let %0: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes bb0(): { %0 = input LOAD axis @@ -303,10 +303,10 @@ fn {graph::read::filter@7}(%0: (), %1: ::graph::types::knowledge::entity::Entity } *thunk {thunk#7}() -> List<::graph::types::knowledge::entity::Entity> { - let %0: ::graph::TimeAxis + let %0: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes let %1: List<::graph::types::knowledge::entity::Entity> let %2: () - let %3: ::graph::TimeAxis + let %3: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes bb0(): { goto -> bb3() diff --git a/libs/@local/hashql/mir/tests/ui/reify/graph-read.jsonc b/libs/@local/hashql/mir/tests/ui/reify/graph-read.jsonc index 57decdd1e6b..7c7b43ee7d1 100644 --- a/libs/@local/hashql/mir/tests/ui/reify/graph-read.jsonc +++ b/libs/@local/hashql/mir/tests/ui/reify/graph-read.jsonc @@ -6,7 +6,7 @@ "::graph::body::filter", [ "::graph::head::entities", - ["input", "axis", "::graph::QueryTemporalAxes"] + ["input", "axis", "_"] ], [ "fn", diff --git a/libs/@local/hashql/mir/tests/ui/reify/graph-read.stdout b/libs/@local/hashql/mir/tests/ui/reify/graph-read.stdout index dea77dc30ef..f9e09102564 100644 --- a/libs/@local/hashql/mir/tests/ui/reify/graph-read.stdout +++ b/libs/@local/hashql/mir/tests/ui/reify/graph-read.stdout @@ -1,5 +1,5 @@ -thunk {thunk#1}() -> ::graph::TimeAxis { - let %0: ::graph::TimeAxis +thunk {thunk#1}() -> ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes { + let %0: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes bb0(): { %0 = input LOAD axis @@ -87,7 +87,7 @@ fn {graph::read::filter@7}(%0: (), %1: ::graph::types::knowledge::entity::Entity } *thunk {thunk#7}() -> List<::graph::types::knowledge::entity::Entity> { - let %0: ::graph::TimeAxis + let %0: ::graph::temporal::PinnedTransactionTimeTemporalAxes | ::graph::temporal::PinnedDecisionTimeTemporalAxes let %1: List<::graph::types::knowledge::entity::Entity> let %2: ()