Struct spirt::cfg::Structurizer

source ·
pub struct Structurizer<'a> {
    cx: &'a Context,
    type_bool: Type,
    const_true: Const,
    const_false: Const,
    func_def_body: &'a mut FuncDefBody,
    loop_header_to_exit_targets: IndexMap<ControlRegion, IndexSet<ControlRegion, BuildHasherDefault<FxHasher>>, BuildHasherDefault<FxHasher>>,
    incoming_edge_counts_including_loop_exits: EntityOrientedDenseMap<ControlRegion, IncomingEdgeCount>,
    structurize_region_state: IndexMap<ControlRegion, StructurizeRegionState, BuildHasherDefault<FxHasher>>,
    control_region_input_replacements: EntityOrientedDenseMap<ControlRegion, SmallVec<[Value; 2]>>,
}
Expand description

Control-flow “structurizer”, which attempts to convert as much of the CFG as possible into structural control-flow (regions).

See StructurizeRegionState’s docs for more details on the algorithm.

Fields§

§cx: &'a Context§type_bool: Type

Scrutinee type for SelectionKind::BoolCond.

§const_true: Const

Scrutinee value for SelectionKind::BoolCond, for the “then” case.

§const_false: Const

Scrutinee value for SelectionKind::BoolCond, for the “else” case.

§func_def_body: &'a mut FuncDefBody§loop_header_to_exit_targets: IndexMap<ControlRegion, IndexSet<ControlRegion, BuildHasherDefault<FxHasher>>, BuildHasherDefault<FxHasher>>§incoming_edge_counts_including_loop_exits: EntityOrientedDenseMap<ControlRegion, IncomingEdgeCount>§structurize_region_state: IndexMap<ControlRegion, StructurizeRegionState, BuildHasherDefault<FxHasher>>

Keyed by the input to structurize_region_from (the start ControlRegion), and describing the state of that partial structurization step.

See also StructurizeRegionState’s docs.

§control_region_input_replacements: EntityOrientedDenseMap<ControlRegion, SmallVec<[Value; 2]>>

Accumulated replacements (caused by target_inputss), i.e.: Value::ControlRegionInput { region, input_idx } must be replaced with control_region_input_replacements[region][input_idx], as the original region cannot have be directly reused.

Implementations§

source§

impl<'a> Structurizer<'a>

source

pub fn new(cx: &'a Context, func_def_body: &'a mut FuncDefBody) -> Self

source

pub fn structurize_func(self)

source

fn apply_value_replacements(self)

The last step of structurization is processing bulk replacements collected while structurizing (like control_region_input_replacements).

source

fn claim_or_defer_single_edge( &mut self, target: ControlRegion, target_inputs: SmallVec<[Value; 2]> ) -> PartialControlRegion

source

fn try_claim_edge_bundle( &mut self, edge_bundle: IncomingEdgeBundle<ControlRegion> ) -> Result<PartialControlRegion, DeferredEdgeBundle<ControlRegion>>

source

fn structurize_region_from(&mut self, unstructured_region: ControlRegion)

Structurize a region starting from unstructured_region, and extending it (by combining the smaller ControlRegions) as much as possible into the CFG (likely everything dominated by unstructured_region).

The output of this process is stored in, and any other bookkeeping is done through, self.structurize_region_state[unstructured_region].

See also StructurizeRegionState’s docs.

source

fn structurize_select( &mut self, kind: SelectionKind, scrutinee: Value, cases: SmallVec<[PartialControlRegion; 8]> ) -> PartialControlRegion

Build a Select ControlNode, from partially structured cases, merging all of their deferred_{edges,returns} together.

source

fn materialize_lazy_cond(&mut self, cond: LazyCond) -> Value

source

fn repair_unclaimed_region( &mut self, unstructured_region: ControlRegion, partial_control_region: PartialControlRegion )

When structurization is only partial, and there remain unclaimed regions, they have to be reintegrated into the CFG, putting back ControlInsts where structurize_region_from has taken them from.

This function handles one region at a time to make it more manageable, despite it having a single call site (in a loop in structurize_func).

source

fn const_undef(&self, ty: Type) -> Const

Create an undefined constant (as a placeholder where a value needs to be present, but won’t actually be used), of type ty.

Auto Trait Implementations§

§

impl<'a> !RefUnwindSafe for Structurizer<'a>

§

impl<'a> !Send for Structurizer<'a>

§

impl<'a> !Sync for Structurizer<'a>

§

impl<'a> Unpin for Structurizer<'a>

§

impl<'a> !UnwindSafe for Structurizer<'a>

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> 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, U> TryFrom<U> for T
where U: Into<T>,

§

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>,

§

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.