Skip to content
4 changes: 3 additions & 1 deletion crates/kirin-ir/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@ pub use node::{
pub use pipeline::Pipeline;
pub use product::{HasProduct, Product};
pub use project::{Project, ProjectError, TryProject, TryProjectTo};
pub use rewrite::{MutationEvent, QuarantineCause, Quarantined, RewriteError, Rewriter};
pub use rewrite::{
InsertionPoint, MutationEvent, QuarantineCause, Quarantined, RewriteError, Rewriter,
};
pub use signature::{
ExactSemantics, HasSignature, LatticeSemantics, Signature, SignatureCmp, SignatureSemantics,
};
Expand Down
61 changes: 0 additions & 61 deletions crates/kirin-ir/src/rewrite/alloc.rs

This file was deleted.

26 changes: 24 additions & 2 deletions crates/kirin-ir/src/rewrite/bodies.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
//! Bodies owned by a statement, for [`Rewriter::replace_statement`] and
//! statement erasure.
//! Bodies owned by a statement, for [`Rewriter::replace_statement`],
//! statement erasure, and the checks that keep a statement out of its own
//! bodies.

use smallvec::SmallVec;

use crate::arena::{GetInfo, GetInfoMut};
use crate::rewrite::walk::tree;
use crate::{BlockParent, Body, Dialect, RewriteError, Rewriter, Statement, StatementParent};

impl<L: Dialect> Rewriter<'_, L> {
Expand Down Expand Up @@ -97,6 +99,26 @@ impl<L: Dialect> Rewriter<'_, L> {
false
}

/// Whether `stmt` is `owner` or encloses it, at any depth. `owner` is the
/// statement whose body holds a place, so `true` means placing `stmt`
/// there would make it its own ancestor.
///
/// Only a statement owning a body can enclose anything, so for the many
/// that own none this skips the walk up from `owner`.
pub(super) fn encloses(&self, stmt: Statement, owner: Option<Statement>) -> bool {
if !tree::owns_bodies(self.stage, stmt) {
return false;
}
let mut current = owner;
while let Some(outer) = current {
if outer == stmt {
return true;
}
current = tree::parent(self.stage, outer);
}
false
}

/// Make `owner` the parent of `body`.
pub(super) fn adopt_body(&mut self, body: Body, owner: Statement) {
match body {
Expand Down
6 changes: 3 additions & 3 deletions crates/kirin-ir/src/rewrite/cfg/split.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ impl<'a, L: Dialect> Rewriter<'a, L> {
///
/// The original block is left **without a terminator**; the caller closes
/// it, typically with a branch to the new block, through
/// [`Rewriter::insert_terminator`]. The new block has no arguments.
/// Splitting at the terminator moves only the terminator. Statement ids,
/// results, and uses are unchanged.
/// [`InsertionPoint::Terminator`](crate::InsertionPoint::Terminator). The
/// new block has no arguments. Splitting at the terminator moves only the
/// terminator. Statement ids, results, and uses are unchanged.
///
/// Rejects, leaving the stage untouched, if `at` is unknown or not in a
/// CFG block.
Expand Down
4 changes: 2 additions & 2 deletions crates/kirin-ir/src/rewrite/digraph/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
//! A `DiGraph`'s petgraph mirrors its members' operands: one edge
//! `producer → consumer` per operand slot whose value is a result of another
//! member. The rewriter keeps it (and the member map beside it)
//! correct incrementally; there is no public edge API. Members are added with
//! [`Rewriter::insert_node`](super::Rewriter::insert_node) and erased through
//! correct incrementally; there is no public edge API. Members are added at
//! [`InsertionPoint::DiGraph`](crate::InsertionPoint::DiGraph) and erased through
//! [`Rewriter::erase_statement`](super::Rewriter::erase_statement); yields are
//! edited with [`Rewriter::replace_yield`](super::Rewriter::replace_yield).

Expand Down
53 changes: 2 additions & 51 deletions crates/kirin-ir/src/rewrite/digraph/surgery.rs
Original file line number Diff line number Diff line change
@@ -1,59 +1,10 @@
use crate::arena::{GetInfo, GetInfoMut};
use crate::{DiGraph, DiGraphInfo, Dialect, SSAValue, Statement, StatementParent, Use};
use crate::{DiGraph, DiGraphInfo, Dialect, SSAValue, Statement, Use};

use crate::rewrite::rewriter::{MutationEvent, RewriteError, Rewriter, add_use, remove_use};

/// Adding, erasing, and tombstoning `DiGraph` members, and editing yields.
/// Erasing and tombstoning `DiGraph` members, and editing yields.
impl<'a, L: Dialect> Rewriter<'a, L> {
/// Add `definition` to `graph` as a new member statement and node.
///
/// `definition` must be a non-terminator (a `DiGraph` has none) with no
/// successors (only a terminator may transfer control). Every
/// operand must be live, and every result a fresh
/// [`Rewriter::new_result`] value, which becomes a result of the new
/// statement. Each operand slot reading a result of another member gets an
/// edge from that member; operands from outside the graph get none.
///
/// Rejects, leaving the stage untouched, if `graph` is unknown, or
/// `definition` is a terminator or fails the operand/result checks.
/// Records [`MutationEvent::InsertedStatement`] then
/// [`MutationEvent::ChangedDiGraphTopology`].
pub fn insert_node(
&mut self,
graph: DiGraph,
definition: L,
) -> Result<Statement, RewriteError> {
self.live_digraph(graph)?;
if definition.is_terminator() {
return Err(RewriteError::UnexpectedTerminator);
}
if definition.successors().next().is_some() {
return Err(RewriteError::NonTerminatorWithSuccessors);
}
let (results, operands) = self.prepare_insert(&definition)?;

let stmt = self.alloc_statement(
definition,
StatementParent::DiGraph(graph),
None,
None,
results,
&operands,
);
graph
.get_info_mut(self.stage)
.expect("graph is live in this stage")
.add_node(stmt);
for &operand in &operands {
self.add_operand_edge(graph, stmt, operand);
}

self.events.push(MutationEvent::InsertedStatement { stmt });
self.events
.push(MutationEvent::ChangedDiGraphTopology { graph });
Ok(stmt)
}

/// The `DiGraph` arm of [`Rewriter::erase_statement`]: `stmt` is a live
/// member of `graph`.
pub(in crate::rewrite) fn erase_digraph_member(
Expand Down
Loading