pub struct FunctionBody {
pub n_params: usize,
pub rets: Vec<Type>,
pub locals: EntityVec<Local, Type>,
pub entry: Block,
pub blocks: EntityVec<Block, BlockDef>,
pub values: EntityVec<Value, ValueDef>,
pub type_pool: ListPool<Type>,
pub single_type_dedup: FxHashMap<Type, ListRef<Type>>,
pub arg_pool: ListPool<Value>,
pub value_blocks: PerEntity<Value, Block>,
pub value_locals: PerEntity<Value, Option<Local>>,
pub source_locs: PerEntity<Value, SourceLoc>,
}
Expand description
The body of a function, as an SSA-based intermediate representation.
Fields§
§n_params: usize
How many parameters the function has. (Their types are the
first n_params
values in locals
.)
rets: Vec<Type>
Return types of the function.
locals: EntityVec<Local, Type>
Local types, including args.
entry: Block
Entry block.
blocks: EntityVec<Block, BlockDef>
Block bodies.
values: EntityVec<Value, ValueDef>
Value definitions, indexed by Value
.
type_pool: ListPool<Type>
Pool of types for ValueDefs’ result type lists.
single_type_dedup: FxHashMap<Type, ListRef<Type>>
Deduplication for type-lists of single types.
arg_pool: ListPool<Value>
Pool of values for ValueDefs’ arg lists.
value_blocks: PerEntity<Value, Block>
Blocks in which values are computed. Each may be Block::invalid()
if not placed.
value_locals: PerEntity<Value, Option<Local>>
Wasm locals that values correspond to, if any.
source_locs: PerEntity<Value, SourceLoc>
Debug source locations of each value.
Implementations§
Source§impl FunctionBody
impl FunctionBody
Sourcepub fn new(module: &Module<'_>, sig: Signature) -> FunctionBody
pub fn new(module: &Module<'_>, sig: Signature) -> FunctionBody
Create a new function body with the given signature. The body
will have an entry block with blockparams defined that match
the function parameters in the signature, but no
contents. module
is necessary to look up the signature.
Sourcepub fn optimize(&mut self, opts: &OptOptions)
pub fn optimize(&mut self, opts: &OptOptions)
Optimize this function given the options in opts
.
Sourcepub fn convert_to_max_ssa(&mut self, cut_blocks: Option<HashSet<Block>>)
pub fn convert_to_max_ssa(&mut self, cut_blocks: Option<HashSet<Block>>)
Perform a maximal-SSA transform on this function. See comments
on FuncDecl::convert_to_max_ssa()
for more.
Sourcepub fn single_type_list(&mut self, ty: Type) -> ListRef<Type>
pub fn single_type_list(&mut self, ty: Type) -> ListRef<Type>
Convenience: intern a single type as a result-type-list. Caches and deduplicates to minimize type-pool growth.
Sourcepub fn add_edge(&mut self, from: Block, to: Block)
pub fn add_edge(&mut self, from: Block, to: Block)
Add an edge in the succs/preds lists of the respective
blocks. These edges must exist once a function has been built;
they can be (re)computed in bulk with
FunctionBody::recompute_edges()
if necessary.
Sourcepub fn split_edge(&mut self, from: Block, to: Block, succ_idx: usize) -> Block
pub fn split_edge(&mut self, from: Block, to: Block, succ_idx: usize) -> Block
Split a given edge (disambiguated with succ_idx
since there
may be multiple edges from from
to to
), creating an
intermediate block with an unconditional branch and carrying
through all blockparams.
Sourcepub fn recompute_edges(&mut self)
pub fn recompute_edges(&mut self)
Recompute all successor/predecessor lists according to the edges implied by terminator instructions. Must be updated after building a function body or mutating its CFG and prior to analyses.
Sourcepub fn add_value(&mut self, value: ValueDef) -> Value
pub fn add_value(&mut self, value: ValueDef) -> Value
Add a new value node to the function (not yet in any block) and return its SSA value number.
Sourcepub fn add_op(
&mut self,
block: Block,
op: Operator,
args: &[Value],
tys: &[Type],
) -> Value
pub fn add_op( &mut self, block: Block, op: Operator, args: &[Value], tys: &[Type], ) -> Value
Convenience method: add an operator value to the function in the given block. Creates the argument and type list(s), adds the value node, and appends the value node to the given block.
Sourcepub fn set_alias(&mut self, value: Value, to: Value)
pub fn set_alias(&mut self, value: Value, to: Value)
Make one value an alias to another. Panics on cycles.
Sourcepub fn resolve_alias(&self, value: Value) -> Value
pub fn resolve_alias(&self, value: Value) -> Value
Resolve the value through any alias references to the original value.
Sourcepub fn resolve_and_update_alias(&mut self, value: Value) -> Value
pub fn resolve_and_update_alias(&mut self, value: Value) -> Value
Resolve a value through alias references, updating the value definition to short-circuit the (arbitrarily long) alias chain afterward.
Sourcepub fn add_blockparam(&mut self, block: Block, ty: Type) -> Value
pub fn add_blockparam(&mut self, block: Block, ty: Type) -> Value
Add a new blockparam to the given block, returning its SSA value number.
Sourcepub fn add_placeholder(&mut self, ty: Type) -> Value
pub fn add_placeholder(&mut self, ty: Type) -> Value
Add a new Placeholder
value that can be replaced with an
actual definition later. Useful in some algorithms that
follow or resolve cycles.
Sourcepub fn replace_placeholder_with_blockparam(
&mut self,
block: Block,
value: Value,
)
pub fn replace_placeholder_with_blockparam( &mut self, block: Block, value: Value, )
Convert a Placeholder
value into a blockparam on the given
block.
Sourcepub fn mark_value_as_local(&mut self, value: Value, local: Local)
pub fn mark_value_as_local(&mut self, value: Value, local: Local)
Mark an SSA value as carrying the Wasm local local
. This is
useful for debugging and manually reading the IR.
Sourcepub fn append_to_block(&mut self, block: Block, value: Value)
pub fn append_to_block(&mut self, block: Block, value: Value)
Append a value to the instruction list in a block.
Sourcepub fn set_terminator(&mut self, block: Block, terminator: Terminator)
pub fn set_terminator(&mut self, block: Block, terminator: Terminator)
Set the terminator instruction on a block, updating the edge lists as well.
Sourcepub fn display<'a>(
&'a self,
indent: &'a str,
module: Option<&'a Module<'_>>,
) -> FunctionBodyDisplay<'a>
pub fn display<'a>( &'a self, indent: &'a str, module: Option<&'a Module<'_>>, ) -> FunctionBodyDisplay<'a>
Prety-print this function body. indent
is prepended to each
line of output. module
, if provided, allows printing source
locations as comments at each operator.
Sourcepub fn display_verbose<'a>(
&'a self,
indent: &'a str,
module: Option<&'a Module<'_>>,
) -> FunctionBodyDisplay<'a>
pub fn display_verbose<'a>( &'a self, indent: &'a str, module: Option<&'a Module<'_>>, ) -> FunctionBodyDisplay<'a>
Pretty-print this function body, with “verbose” format: includes all value nodes, even those not listed in a block’s instruction list. (Roughly doubles output size.)
Sourcepub fn validate(&self) -> Result<()>
pub fn validate(&self) -> Result<()>
Validate consistency of the IR against required invariants and properties:
- Block successor and predecessor lists are accurate with respect to terminator instructions.
- SSA is valid: values are used in locations dominated by their uses.
Sourcepub fn verify_reducible(&self) -> Result<()>
pub fn verify_reducible(&self) -> Result<()>
Verify that the CFG of this function is reducible. (This is not necessary to produce Wasm, as the backend can turn irreducible control flow into reducible control flow via the Reducifier. However, it is a useful property in other situations, so one may want to test for or verify it.)
Trait Implementations§
Source§impl Block<FunctionBody> for BlockDef
impl Block<FunctionBody> for BlockDef
type Terminator = Terminator
fn term(&self) -> &Self::Terminator
fn term_mut(&mut self) -> &mut Self::Terminator
Source§impl Block<FunctionBody> for BlockDef
impl Block<FunctionBody> for BlockDef
fn insts(&self) -> impl Iterator<Item = <FunctionBody as Func>::Value>
fn add_inst( func: &mut FunctionBody, key: <FunctionBody as Func>::Block, v: <FunctionBody as Func>::Value, )
Source§impl Clone for FunctionBody
impl Clone for FunctionBody
Source§fn clone(&self) -> FunctionBody
fn clone(&self) -> FunctionBody
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read moreSource§impl Debug for FunctionBody
impl Debug for FunctionBody
Source§impl Default for FunctionBody
impl Default for FunctionBody
Source§fn default() -> FunctionBody
fn default() -> FunctionBody
Source§impl<'de> Deserialize<'de> for FunctionBody
impl<'de> Deserialize<'de> for FunctionBody
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 Func for FunctionBody
impl Func for FunctionBody
Source§impl Func for FunctionBody
impl Func for FunctionBody
Source§impl HasValues<FunctionBody> for BlockTarget
impl HasValues<FunctionBody> for BlockTarget
fn values<'a>( &'a self, f: &'a FunctionBody, ) -> Box<dyn Iterator<Item = <FunctionBody as Func>::Value> + 'a>
fn values_mut<'a>(
&'a mut self,
g: &'a mut FunctionBody,
) -> Box<dyn Iterator<Item = &'a mut Value> + 'a>where
FunctionBody: 'a,
Source§impl HasValues<FunctionBody> for ListRef<Value>
impl HasValues<FunctionBody> for ListRef<Value>
fn values<'a>( &'a self, f: &'a FunctionBody, ) -> Box<dyn Iterator<Item = <FunctionBody as Func>::Value> + 'a>
fn values_mut<'a>(
&'a mut self,
g: &'a mut FunctionBody,
) -> Box<dyn Iterator<Item = &'a mut <FunctionBody as Func>::Value> + 'a>where
FunctionBody: 'a,
Source§impl HasValues<FunctionBody> for Terminator
impl HasValues<FunctionBody> for Terminator
fn values<'a>( &'a self, f: &'a FunctionBody, ) -> Box<dyn Iterator<Item = <FunctionBody as Func>::Value> + 'a>
fn values_mut<'a>(
&'a mut self,
g: &'a mut FunctionBody,
) -> Box<dyn Iterator<Item = &'a mut Value> + 'a>where
FunctionBody: 'a,
Source§impl HasValues<FunctionBody> for ValueDef
impl HasValues<FunctionBody> for ValueDef
fn values<'a>( &'a self, f: &'a FunctionBody, ) -> Box<dyn Iterator<Item = <FunctionBody as Func>::Value> + 'a>
fn values_mut<'a>(
&'a mut self,
g: &'a mut FunctionBody,
) -> Box<dyn Iterator<Item = &'a mut <FunctionBody as Func>::Value> + 'a>where
FunctionBody: 'a,
Source§impl OpValue<FunctionBody, Operator> for ValueDef
impl OpValue<FunctionBody, Operator> for ValueDef
type Residue = ValueDef
type Capture = ListRef<Value>
type Spit = Vec<Type>
fn disasm( self, f: &mut FunctionBody, ) -> Result<(Operator, Self::Capture, Self::Spit), Self::Residue>
fn of( f: &mut FunctionBody, o: Operator, c: Self::Capture, s: Self::Spit, ) -> Option<Self>
fn lift(f: &mut FunctionBody, r: Self::Residue) -> Option<Self>
Source§impl OpValue<FunctionBody, u32> for ValueDef
impl OpValue<FunctionBody, u32> for ValueDef
type Residue = ValueDef
type Capture = Val<FunctionBody>
type Spit = Type
fn disasm( self, f: &mut FunctionBody, ) -> Result<(u32, Self::Capture, Self::Spit), Self::Residue>
fn of( f: &mut FunctionBody, o: u32, c: Self::Capture, s: Self::Spit, ) -> Option<Self>
fn lift(f: &mut FunctionBody, r: Self::Residue) -> Option<Self>
Source§impl Serialize for FunctionBody
impl Serialize for FunctionBody
Source§impl Target<FunctionBody> for BlockTarget
impl Target<FunctionBody> for BlockTarget
Source§impl Target<FunctionBody> for BlockTarget
impl Target<FunctionBody> for BlockTarget
fn push_value(&mut self, v: <FunctionBody as Func>::Value)
fn from_values_and_block( a: impl Iterator<Item = <FunctionBody as Func>::Value>, k: <FunctionBody as Func>::Block, ) -> Self
Source§impl Term<FunctionBody> for BlockTarget
impl Term<FunctionBody> for BlockTarget
type Target = BlockTarget
fn targets<'a>(&'a self) -> Box<dyn Iterator<Item = &'a BlockTarget> + 'a>where
FunctionBody: 'a,
fn targets_mut<'a>(
&'a mut self,
) -> Box<dyn Iterator<Item = &'a mut BlockTarget> + 'a>where
FunctionBody: 'a,
Source§impl Term<FunctionBody> for Terminator
impl Term<FunctionBody> for Terminator
type Target = BlockTarget
fn targets<'a>(&'a self) -> Box<dyn Iterator<Item = &'a BlockTarget> + 'a>where
FunctionBody: 'a,
fn targets_mut<'a>(
&'a mut self,
) -> Box<dyn Iterator<Item = &'a mut BlockTarget> + 'a>where
FunctionBody: 'a,
impl Value<FunctionBody> for ValueDef
Auto Trait Implementations§
impl Freeze for FunctionBody
impl RefUnwindSafe for FunctionBody
impl Send for FunctionBody
impl Sync for FunctionBody
impl Unpin for FunctionBody
impl UnwindSafe for FunctionBody
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,
Source§unsafe fn clone_to_uninit(&self, dst: *mut T)
unsafe fn clone_to_uninit(&self, dst: *mut T)
clone_to_uninit
)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