Skip to main content

PhiNode

Struct PhiNode 

pub struct PhiNode { /* private fields */ }
Expand description

A phi node that merges values from multiple control flow predecessors.

Placed at the beginning of basic blocks with multiple predecessors. Each phi node has one PhiOperand per predecessor, linking the predecessor block to the SSA variable providing the value along that edge.

§Invariants

  • Each phi has at most one operand per predecessor (enforced by set_operand)
  • The result variable is defined by this phi node at the block entry
  • Phi nodes appear before all regular instructions in a block

§Examples

use analyssa::ir::{phi::{PhiNode, PhiOperand}, variable::{SsaVarId, VariableOrigin}};

let v1 = SsaVarId::from_index(0);
let v2 = SsaVarId::from_index(1);
let result = SsaVarId::from_index(2);
let mut phi = PhiNode::new(result, VariableOrigin::Local(0));
phi.add_operand(PhiOperand::new(v1, 1));
phi.add_operand(PhiOperand::new(v2, 2));
assert_eq!(phi.result(), result);
assert_eq!(phi.operand_count(), 2);

Implementations§

Source§

impl PhiNode

Source

pub fn new(result: SsaVarId, origin: VariableOrigin) -> PhiNode

Creates a new phi node for the given variable origin.

The phi node is created with no operands - they must be added during SSA construction as predecessor blocks are processed.

§Arguments
  • result - The SSA variable that this phi node defines
  • origin - The original variable (Argument or Local) this phi merges
Source

pub fn with_capacity( result: SsaVarId, origin: VariableOrigin, predecessor_count: usize, ) -> PhiNode

Creates a new phi node with pre-allocated operand capacity.

Use this when the number of predecessors is known in advance to avoid reallocations.

§Arguments
  • result - The SSA variable that this phi node defines
  • origin - The original variable this phi merges
  • predecessor_count - Expected number of predecessor blocks
Source

pub const fn result(&self) -> SsaVarId

Returns the SSA variable defined by this phi node.

Source

pub const fn origin(&self) -> VariableOrigin

Returns the original variable origin this phi merges.

Source

pub fn set_result(&mut self, var: SsaVarId)

Sets the SSA variable defined by this phi node.

Used during SSA construction when renaming variables.

Source

pub fn operands(&self) -> &[PhiOperand]

Returns the operands of this phi node.

Source

pub fn operands_mut(&mut self) -> &mut Vec<PhiOperand>

Returns a mutable reference to the operands.

Source

pub fn add_operand(&mut self, operand: PhiOperand)

Adds an operand to this phi node.

Unchecked: this does not verify that the operand’s predecessor is a real CFG predecessor, nor that no operand already names it. A phi with two operands on one edge has no defined meaning — Self::operand_from returns the first and discards the rest, while SCCP meets them all and yields Bottom — and the verifier reports it as VerifierError::DuplicatePhiOperand. Callers redirecting an existing edge should use SsaEditor::replace_phi_predecessor, which reconciles the collision instead of creating one.

§Arguments
  • operand - The phi operand to add
Source

pub fn operand_count(&self) -> usize

Returns the number of operands.

Source

pub fn is_empty(&self) -> bool

Returns true if this phi node has no operands.

A phi node with no operands is incomplete and should not appear in a fully-constructed SSA form.

Source

pub fn operand_from(&self, predecessor: usize) -> Option<&PhiOperand>

Finds the operand coming from the specified predecessor block.

§Arguments
  • predecessor - The block index to look up
§Returns

The phi operand if found, or None if no operand comes from that predecessor.

Source

pub fn used_variables(&self) -> impl Iterator<Item = SsaVarId>

Returns all the SSA variables used by this phi node.

This is useful for building def-use chains and liveness analysis.

Source

pub fn retain_operands<F>(&mut self, pred: F)
where F: Fn(usize) -> bool,

Retains only operands whose predecessor satisfies the predicate.

Source

pub fn set_origin(&mut self, origin: VariableOrigin)

Sets the origin of this phi node.

This is used during local variable optimization to update indices after unused locals are removed.

Source

pub fn set_operand(&mut self, predecessor: usize, value: SsaVarId)

Sets the operand value for a specific predecessor.

If an operand from that predecessor already exists, it is updated. Otherwise, a new operand is added.

§Arguments
  • predecessor - The predecessor block index
  • value - The SSA variable value from that predecessor

Trait Implementations§

Source§

impl Clone for PhiNode

Source§

fn clone_from(&mut self, source: &PhiNode)

Overwrites self from source, reusing the existing operands allocation.

Hand-written for the same reason as SsaFunction::clone_from: the derived Clone supplies only the default clone_from (*self = source.clone()), which drops and reallocates the operand vector on every call. Specializing here lets a whole-function snapshot’s capacity reuse reach each phi’s operand list rather than stopping at the owning block’s phi_nodes spine.

The exhaustive destructure is deliberate: adding a field makes this fail to compile rather than silently producing a stale-in-one-field clone.

Source§

fn clone(&self) -> PhiNode

Returns a duplicate of the value. Read more
Source§

impl Debug for PhiNode

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl Display for PhiNode

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> AsAny for T
where T: Any,

Source§

fn as_any(&self) -> &(dyn Any + 'static)

Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Source§

fn type_name(&self) -> &'static str

Gets the type name of self
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> Downcast for T
where T: AsAny + ?Sized,

Source§

fn is<T>(&self) -> bool
where T: AsAny,

Returns true if the boxed type is the same as T. Read more
Source§

fn downcast_ref<T>(&self) -> Option<&T>
where T: AsAny,

Forward to the method defined on the type Any.
Source§

fn downcast_mut<T>(&mut self) -> Option<&mut T>
where T: AsAny,

Forward to the method defined on the type Any.
Source§

impl<T> DynClone for T
where T: Clone,

Source§

fn __clone_box(&self, _: Private) -> *mut ()

Source§

impl<T> ErasedDestructor for T
where T: 'static,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, A> IntoAst<A> for T
where T: Into<A>, A: Ast,

Source§

fn into_ast(self, _a: &A) -> A

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<F, T> IntoSample<T> for F
where T: FromSample<F>,

Source§

fn into_sample(self) -> T

Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<SS, SP> SupersetOf<SS> for SP
where SS: SubsetOf<SP>,

Source§

fn to_subset(&self) -> Option<SS>

The inverse inclusion map: attempts to construct self from the equivalent element of its superset. Read more
Source§

fn is_in_subset(&self) -> bool

Checks if self is actually part of its subset T (and can be converted to it).
Source§

fn to_subset_unchecked(&self) -> SS

Use with care! Same as self.to_subset but without any property checks. Always succeeds.
Source§

fn from_subset(element: &SS) -> SP

The inclusion map: converts self to the equivalent element of its superset.
Source§

impl<T> ToCompactString for T
where T: Display,

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T> TryClone for T
where T: Clone,

Source§

fn try_clone(&self) -> Result<T, Error>

Clones self, possibly returning an error.
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more