waffle

Struct FunctionBody

Source
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

Source

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.

Source

pub fn optimize(&mut self, opts: &OptOptions)

Optimize this function given the options in opts.

Source

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.

Source

pub fn add_block(&mut self) -> Block

Add a new, empty block and return its ID.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

pub fn set_alias(&mut self, value: Value, to: Value)

Make one value an alias to another. Panics on cycles.

Source

pub fn resolve_alias(&self, value: Value) -> Value

Resolve the value through any alias references to the original value.

Source

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.

Source

pub fn add_blockparam(&mut self, block: Block, ty: Type) -> Value

Add a new blockparam to the given block, returning its SSA value number.

Source

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.

Source

pub fn replace_placeholder_with_blockparam( &mut self, block: Block, value: Value, )

Convert a Placeholder value into a blockparam on the given block.

Source

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.

Source

pub fn append_to_block(&mut self, block: Block, value: Value)

Append a value to the instruction list in a block.

Source

pub fn set_terminator(&mut self, block: Block, terminator: Terminator)

Set the terminator instruction on a block, updating the edge lists as well.

Source

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.

Source

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.)

Source

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.
Source

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.)

Source

pub fn compile(&self) -> Result<Function>

Compile this function to Wasm bytecode. See Module::to_wasm_bytes() for the Wasm-level compilation entry point. This is mostly useful for custom per-function compilation flows, e.g. per-function caching.

Trait Implementations§

Source§

impl Block<FunctionBody> for BlockDef

Source§

type Terminator = Terminator

Source§

fn term(&self) -> &Self::Terminator

Source§

fn term_mut(&mut self) -> &mut Self::Terminator

Source§

impl Block<FunctionBody> for BlockDef

Source§

fn insts(&self) -> impl Iterator<Item = <FunctionBody as Func>::Value>

Source§

fn add_inst( func: &mut FunctionBody, key: <FunctionBody as Func>::Block, v: <FunctionBody as Func>::Value, )

Source§

impl Clone for FunctionBody

Source§

fn clone(&self) -> FunctionBody

Returns a copy of the value. Read more
1.0.0 · Source§

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

Performs copy-assignment from source. Read more
Source§

impl Debug for FunctionBody

Source§

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

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

impl Default for FunctionBody

Source§

fn default() -> FunctionBody

Returns the “default value” for a type. Read more
Source§

impl<'de> Deserialize<'de> for FunctionBody

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl Func for FunctionBody

Source§

type Block = Block

Source§

type Blocks = EntityVec<Block, BlockDef>

Source§

fn blocks(&self) -> &Self::Blocks

Source§

fn blocks_mut(&mut self) -> &mut Self::Blocks

Source§

fn entry(&self) -> Self::Block

Source§

impl Func for FunctionBody

Source§

type Value = Value

Source§

type Values = EntityVec<Value, ValueDef>

Source§

fn values(&self) -> &Self::Values

Source§

fn values_mut(&mut self) -> &mut Self::Values

Source§

impl HasValues<FunctionBody> for BlockTarget

Source§

fn values<'a>( &'a self, f: &'a FunctionBody, ) -> Box<dyn Iterator<Item = <FunctionBody as Func>::Value> + 'a>

Source§

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>

Source§

fn values<'a>( &'a self, f: &'a FunctionBody, ) -> Box<dyn Iterator<Item = <FunctionBody as Func>::Value> + 'a>

Source§

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

Source§

fn values<'a>( &'a self, f: &'a FunctionBody, ) -> Box<dyn Iterator<Item = <FunctionBody as Func>::Value> + 'a>

Source§

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

Source§

fn values<'a>( &'a self, f: &'a FunctionBody, ) -> Box<dyn Iterator<Item = <FunctionBody as Func>::Value> + 'a>

Source§

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

Source§

type Residue = ValueDef

Source§

type Capture = ListRef<Value>

Source§

type Spit = Vec<Type>

Source§

fn disasm( self, f: &mut FunctionBody, ) -> Result<(Operator, Self::Capture, Self::Spit), Self::Residue>

Source§

fn of( f: &mut FunctionBody, o: Operator, c: Self::Capture, s: Self::Spit, ) -> Option<Self>

Source§

fn lift(f: &mut FunctionBody, r: Self::Residue) -> Option<Self>

Source§

impl OpValue<FunctionBody, u32> for ValueDef

Source§

type Residue = ValueDef

Source§

type Capture = Val<FunctionBody>

Source§

type Spit = Type

Source§

fn disasm( self, f: &mut FunctionBody, ) -> Result<(u32, Self::Capture, Self::Spit), Self::Residue>

Source§

fn of( f: &mut FunctionBody, o: u32, c: Self::Capture, s: Self::Spit, ) -> Option<Self>

Source§

fn lift(f: &mut FunctionBody, r: Self::Residue) -> Option<Self>

Source§

impl Serialize for FunctionBody

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl Target<FunctionBody> for BlockTarget

Source§

fn block(&self) -> <FunctionBody as Func>::Block

Source§

fn block_mut(&mut self) -> &mut <FunctionBody as Func>::Block

Source§

impl Target<FunctionBody> for BlockTarget

Source§

fn push_value(&mut self, v: <FunctionBody as Func>::Value)

Source§

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

Source§

type Target = BlockTarget

Source§

fn targets<'a>(&'a self) -> Box<dyn Iterator<Item = &'a BlockTarget> + 'a>
where FunctionBody: 'a,

Source§

fn targets_mut<'a>( &'a mut self, ) -> Box<dyn Iterator<Item = &'a mut BlockTarget> + 'a>
where FunctionBody: 'a,

Source§

impl Term<FunctionBody> for Terminator

Source§

type Target = BlockTarget

Source§

fn targets<'a>(&'a self) -> Box<dyn Iterator<Item = &'a BlockTarget> + 'a>
where FunctionBody: 'a,

Source§

fn targets_mut<'a>( &'a mut self, ) -> Box<dyn Iterator<Item = &'a mut BlockTarget> + 'a>
where FunctionBody: 'a,

Source§

impl Value<FunctionBody> for ValueDef

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> 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<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dst: *mut T)

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

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

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> 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, A, B, T> OpValue<F, Either<A, B>> for T
where F: Func, T: OpValue<F, A>, <T as OpValue<F, A>>::Residue: OpValue<F, B>,

Source§

type Residue = <<T as OpValue<F, A>>::Residue as OpValue<F, B>>::Residue

Source§

type Capture = Either<<T as OpValue<F, A>>::Capture, <<T as OpValue<F, A>>::Residue as OpValue<F, B>>::Capture>

Source§

type Spit = Either<<T as OpValue<F, A>>::Spit, <<T as OpValue<F, A>>::Residue as OpValue<F, B>>::Spit>

Source§

fn disasm( self, f: &mut F, ) -> Result<(Either<A, B>, <T as OpValue<F, Either<A, B>>>::Capture, <T as OpValue<F, Either<A, B>>>::Spit), <T as OpValue<F, Either<A, B>>>::Residue>

Source§

fn of( f: &mut F, o: Either<A, B>, c: <T as OpValue<F, Either<A, B>>>::Capture, s: <T as OpValue<F, Either<A, B>>>::Spit, ) -> Option<T>

Source§

fn lift(f: &mut F, r: <T as OpValue<F, Either<A, B>>>::Residue) -> Option<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> 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, 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<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,