pub struct SsaVariable<T: Target> {
id: SsaVarId,
origin: VariableOrigin,
version: u32,
def_site: DefSite,
var_type: T::Type,
uses: Vec<UseSite>,
address_taken: bool,
}Expand description
Complete metadata for an SSA variable.
Each SSA variable has exactly one definition and zero or more uses. This structure bundles all metadata needed for analysis, optimization, and code generation.
§Invariants
id.index()equals the variable’s position inSsaFunction::variables(maintained bycreate_variableandcompact_variables)- Version 0 of arguments/locals is typically the value at function entry
def_siteisNone-instruction for phi nodes (definition at block entry)
§Construction
Variables are created through SsaFunction::create_variable(),
which ensures dense ID allocation, origin registration, and type tracking.
Fields§
§id: SsaVarIdDense unique identifier within the owning function.
Invariant: id.index() == position in SsaFunction.variables.
origin: VariableOriginCIL origin of this variable: method argument, local, or phi node result. Used for rename grouping and debug display.
version: u32SSA version number for this variable.
For arguments and locals, each assignment creates a new version. Version 0 is the initial value at method entry (argument values, zero-initialized locals). Higher versions correspond to later assignments.
def_site: DefSiteLocation in the SSA function where this variable is defined.
DefSite::instruction(block, idx)for instruction-defined variablesDefSite::phi(block)for phi node resultsDefSite::entry()for arguments and initialized locals (implicit def)
var_type: T::TypeThe type of this variable, resolved during SSA construction.
Inferred from the defining instruction’s result type or the origin’s
canonical type. T::unknown_type() if type inference is pending.
uses: Vec<UseSite>All use sites where this variable is referenced as an operand.
Populated during SSA construction by
crate::ir::function::SsaFunction::recompute_uses.
Enables dead code elimination (empty uses = dead) and use-based
analyses.
address_taken: boolWhether this variable’s address has been taken via ldarga/ldloca.
Address-taken variables may be modified through pointers, making them ineligible for copy propagation, dead store elimination, and other optimizations that assume single-assignment immutability.
Implementations§
Source§impl<T: Target> SsaVariable<T>
impl<T: Target> SsaVariable<T>
Sourcepub fn new(
id: SsaVarId,
origin: VariableOrigin,
version: u32,
def_site: DefSite,
var_type: T::Type,
) -> Self
pub fn new( id: SsaVarId, origin: VariableOrigin, version: u32, def_site: DefSite, var_type: T::Type, ) -> Self
Creates a new SSA variable with a pre-allocated ID and type.
Note: prefer creating variables through SsaFunction::create_variable
(in the host crate), which ensures dense ID allocation via
FunctionVarAllocator. This constructor is pub only because the host
crate’s SsaFunction lives outside analyssa and needs to call it.
§Arguments
id- The dense variable ID fromFunctionVarAllocatororigin- Where this variable came from in the hostversion- SSA version numberdef_site- Where this variable is definedvar_type- The type of this variable
Sourcepub const fn origin(&self) -> VariableOrigin
pub const fn origin(&self) -> VariableOrigin
Returns where this variable originated in the CIL.
Sourcepub fn var_type(&self) -> &T::Type
pub fn var_type(&self) -> &T::Type
Returns the type of this variable.
Returns the host’s “unknown” type if type inference hasn’t been performed.
Sourcepub fn set_def_site(&mut self, site: DefSite)
pub fn set_def_site(&mut self, site: DefSite)
Updates where this variable is defined.
Sourcepub fn set_type(&mut self, var_type: T::Type)
pub fn set_type(&mut self, var_type: T::Type)
Sets the type of this variable.
This is typically called during type inference or when resolving phi node types.
Sourcepub fn has_known_type(&self) -> bool
pub fn has_known_type(&self) -> bool
Returns true if the variable’s type is known (not the host’s “unknown” type).
Sourcepub const fn is_address_taken(&self) -> bool
pub const fn is_address_taken(&self) -> bool
Returns true if this variable’s address has been taken.
Sourcepub fn retain_uses<F>(&mut self, keep: F)
pub fn retain_uses<F>(&mut self, keep: F)
Drops the use sites for which keep returns false.
Lets a caller that knows exactly which uses it rewrote keep this list exact without a whole-function rescan — the difference between an O(1) index update and an O(function) walk per replacement.
Sourcepub fn clear_uses(&mut self)
pub fn clear_uses(&mut self)
Clears all use sites for this variable.
This is used when recomputing use information after SSA transformations that may have invalidated the use tracking.
Sourcepub fn set_address_taken(&mut self)
pub fn set_address_taken(&mut self)
Marks this variable as having its address taken.
Sourcepub fn set_origin(&mut self, origin: VariableOrigin)
pub fn set_origin(&mut self, origin: VariableOrigin)
Sets the origin of this variable.
This is used during local variable optimization to update indices after unused locals are removed.
Trait Implementations§
Source§impl<T: Target> Clone for SsaVariable<T>
impl<T: Target> Clone for SsaVariable<T>
Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
Overwrites self from source, reusing this variable’s existing
uses 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 uses
vector on every call. Because Vec::clone_from calls clone_from
element-wise, specializing here is what lets a whole-function snapshot
reuse every per-variable use-list buffer instead of stopping at the
variables spine. Functions carry one such vector per SSA variable, so
this is the largest count of small allocations the optimization
pipeline’s repeated rollback snapshots would otherwise re-make.
The exhaustive destructure is deliberate: adding a field makes this fail to compile rather than silently producing a stale-in-one-field clone.
Source§impl<'de, T: Target> Deserialize<'de> for SsaVariable<T>where
T::Type: Deserialize<'de>,
impl<'de, T: Target> Deserialize<'de> for SsaVariable<T>where
T::Type: Deserialize<'de>,
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Source§impl<T: Target> Display for SsaVariable<T>
impl<T: Target> Display for SsaVariable<T>
Auto Trait Implementations§
impl<T> Freeze for SsaVariable<T>
impl<T> RefUnwindSafe for SsaVariable<T>
impl<T> Send for SsaVariable<T>
impl<T> Sync for SsaVariable<T>
impl<T> Unpin for SsaVariable<T>
impl<T> UnsafeUnpin for SsaVariable<T>
impl<T> UnwindSafe for SsaVariable<T>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
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