Skip to content

Commit f64960d

Browse files
authored
BE-235: HashQL: Rewrite data dependency resolution with constant propagation and fix field resolution (#8182)
1 parent 3a7cffc commit f64960d

35 files changed

+1952
-558
lines changed

libs/@local/hashql/mir/src/body/constant/mod.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
3030
mod int;
3131

32+
use core::fmt;
33+
3234
use hashql_core::value::Primitive;
3335

3436
pub use self::int::{Int, TryFromIntegerError, TryFromPrimitiveError};
@@ -97,3 +99,14 @@ pub enum Constant<'heap> {
9799
/// as first-class values.
98100
FnPtr(DefId),
99101
}
102+
103+
impl fmt::Display for Constant<'_> {
104+
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
105+
match self {
106+
Self::Int(int) => fmt::Display::fmt(int, fmt),
107+
Self::Primitive(primitive) => fmt::Display::fmt(primitive, fmt),
108+
Self::Unit => fmt.write_str("()"),
109+
Self::FnPtr(def_id) => write!(fmt, "fn({def_id})"),
110+
}
111+
}
112+
}

libs/@local/hashql/mir/src/body/place.rs

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,12 @@
33
//! Places represent storage locations in the MIR, including local variables and complex paths
44
//! through data structures. Projections allow accessing nested data within structured types.
55
6-
use core::{alloc::Allocator, fmt};
6+
use alloc::{alloc::Global, collections::VecDeque};
7+
use core::{
8+
alloc::Allocator,
9+
fmt,
10+
hash::{Hash, Hasher},
11+
};
712

813
use hashql_core::{id, intern::Interned, symbol::Symbol, r#type::TypeId};
914

@@ -210,6 +215,7 @@ pub enum DefUse {
210215
/// For a place like `local_0.field_1.field_2`:
211216
/// - At projection 0: `PlaceRef { local: local_0, projections: [] }`
212217
/// - At projection 1: `PlaceRef { local: local_0, projections: [field_1] }`
218+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
213219
pub struct PlaceRef<'proj, 'heap> {
214220
/// The root local variable that this place reference starts from.
215221
pub local: Local,
@@ -221,6 +227,52 @@ pub struct PlaceRef<'proj, 'heap> {
221227
pub projections: &'proj [Projection<'heap>],
222228
}
223229

230+
impl<'heap> PlaceRef<'_, 'heap> {
231+
/// Interns the borrowed projection slice and returns an owned [`Place`].
232+
///
233+
/// Converts this borrowed reference into an interned place suitable for storage in MIR.
234+
pub fn intern(&self, interner: &Interner<'heap>) -> Place<'heap> {
235+
Place {
236+
local: self.local,
237+
projections: interner.projections.intern_slice(self.projections),
238+
}
239+
}
240+
}
241+
242+
/// An intermediate place representation used during dependency resolution.
243+
///
244+
/// Represents a partially-resolved place where the projection sequence may still grow
245+
/// as resolution traverses through the dependency graph. Convert to [`Place`] via
246+
/// [`PlaceRef::intern`] once resolution completes.
247+
#[derive(Debug, Clone)]
248+
pub struct PlaceMut<'heap, A: Allocator = Global> {
249+
/// The current root local after partial resolution.
250+
pub local: Local,
251+
252+
/// Accumulated projections that could not yet be resolved.
253+
///
254+
/// During resolution, projections are prepended from edge targets and appended
255+
/// from the original place being resolved.
256+
pub projections: VecDeque<Projection<'heap>, A>,
257+
}
258+
259+
impl<A: Allocator> PartialEq for PlaceMut<'_, A> {
260+
fn eq(&self, other: &Self) -> bool {
261+
let Self { local, projections } = self;
262+
263+
*local == other.local && *projections == other.projections
264+
}
265+
}
266+
267+
impl<A: Allocator> Eq for PlaceMut<'_, A> {}
268+
269+
impl<A: Allocator> Hash for PlaceMut<'_, A> {
270+
fn hash<H: Hasher>(&self, state: &mut H) {
271+
self.local.hash(state);
272+
self.projections.hash(state);
273+
}
274+
}
275+
224276
/// A storage location that can be read from or written to in the MIR.
225277
///
226278
/// A [`Place`] represents a path to a storage location, starting from a [`Local`] variable and
@@ -331,6 +383,15 @@ impl<'heap> Place<'heap> {
331383
.last()
332384
.map_or_else(|| decl[self.local].r#type, |projection| projection.r#type)
333385
}
386+
387+
/// Returns a borrowed reference to this place.
388+
#[must_use]
389+
pub const fn as_ref(&self) -> PlaceRef<'heap, 'heap> {
390+
PlaceRef {
391+
local: self.local,
392+
projections: self.projections.0,
393+
}
394+
}
334395
}
335396

336397
/// A single projection step that navigates into structured data, carrying its result type.

libs/@local/hashql/mir/src/lib.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@
1616
array_windows,
1717
assert_matches,
1818
const_type_name,
19-
formatting_options,
20-
int_roundings,
2119
iter_array_chunks,
2220
iter_collect_into,
2321
iter_intersperse,

0 commit comments

Comments
 (0)