pub struct ControlRegion(/* private fields */);
Expand description
Entity handle for a ControlRegionDef
(a control-flow region).
A ControlRegion
(“control-flow region”) is a linear chain of ControlNode
s,
describing a single-entry single-exit (SESE) control-flow “region” (subgraph)
in a function’s control-flow graph (CFG).
§Control-flow
In SPIR-T, two forms of control-flow are used:
- “structured”:
ControlRegion
s andControlNode
s in a “mutual tree”- i.e. each such
ControlRegion
can only appear in exactly oneControlNode
, and eachControlNode
can only appear in exactly oneControlRegion
- a region is either the function’s body, or used as part of
ControlNode
(e.g. the “then” case of anif
-else
), itself part of a larger region - when inside a region, reaching any other part of the function (or any
other function on call stack) requires leaving through the region’s
single exit (also called “merge”) point, i.e. its execution is either:
- “convergent”: the region completes and continues into its parent
ControlNode
, or function (the latter being a “structured return”) - “divergent”: execution gets stuck in the region (an infinite loop),
or is aborted (e.g.
OpTerminateInvocation
from SPIR-V)
- “convergent”: the region completes and continues into its parent
- i.e. each such
- “unstructured”:
ControlRegion
s which connect to otherControlRegion
s usingcfg::ControlInst
s (as described by acfg::ControlFlowGraph
)
When a function’s entire body can be described by a single ControlRegion
,
that function is said to have (entirely) “structured control-flow”.
Mixing “structured” and “unstructured” control-flow is supported because:
- during structurization, it allows structured subgraphs to remain connected
by the same CFG edges that were connecting smaller
ControlRegion
s before - structurization doesn’t have to fail in the cases it doesn’t fully support yet, but can instead result in a “maximally structured” function
Other IRs may use different “structured control-flow” definitions, notably:
- SPIR-V uses a laxer definition, that corresponds more to the constraints
of the GLSL language, and is single-entry multiple-exit (SEME) with
“alternate exits” consisting of
break
s out ofswitch
es and loops, andreturn
s (making it non-trivial to inline one function into another) - RVSDG inspired SPIR-T’s design, but its regions are (acyclic) graphs, it makes no distinction between control-flow and “computational” nodes, and its execution order is determined by value/state dependencies alone (SPIR-T may get closer to it in the future, but the initial compromise was chosen to limit the effort of lowering/lifting from/to SPIR-V)
§Data-flow interactions
SPIR-T Value
s follow “single static assignment” (SSA), just like SPIR-V:
- inside a function, any new value is produced (or “defined”) as an output
of
DataInst
/ControlNode
, and “uses” of that value areValue
s variants which refer to the definingDataInst
/ControlNode
directly (guaranteeing the “single” and “static” of “SSA”, by construction) - the definition of a value must “dominate” all of its uses (i.e. in all possible execution paths, the definition precedes all uses)
But unlike SPIR-V, SPIR-T’s structured control-flow has implications for SSA:
- dominance is simpler, so values defined in a
ControlRegion
can be used:- later in that region, including in the region’s
outputs
(which allows “exporting” values out to the rest of the function) - outside that region, but only if the parent
ControlNode
is aLoop
(that is, when the region is a loop’s body)- this is an “emergent” property, stemming from the region having to
execute (at least once) before the parent
ControlNode
can complete, but is not is not ideal and should eventually be replaced with passing all such values through loop (body)outputs
- this is an “emergent” property, stemming from the region having to
execute (at least once) before the parent
- later in that region, including in the region’s
- instead of φ (“phi”) nodes, SPIR-T uses region
outputs
to merge values coming from separate control-flow paths (i.e. the cases of aSelect
), and regioninputs
for passing values back along loop backedges (additionally, the body’sinputs
are used for function parameters)- like the “block arguments” alternative to SSA phi nodes (which some other SSA IRs use), this has the advantage of keeping the uses of the “source” values in their respective paths (where they’re dominated), instead of in the merge (where phi nodes require special-casing, as their “uses” of all the “source” values would normally be illegal)
- in unstructured control-flow, region
inputs
are additionally used for representing phi nodes, ascfg::ControlInst
s passing values to their target regions- all value uses across unstructured control-flow edges (i.e. not in the
same region containing the value definition) require explicit passing,
as unstructured control-flow
ControlRegion
s do not themselves get any implied dominance relations from the shape of the control-flow graph (unlike most typical CFG+SSA IRs)
- all value uses across unstructured control-flow edges (i.e. not in the
same region containing the value definition) require explicit passing,
as unstructured control-flow
Trait Implementations§
source§impl Clone for ControlRegion
impl Clone for ControlRegion
source§fn clone(&self) -> ControlRegion
fn clone(&self) -> ControlRegion
Returns a copy of the value. Read more
1.0.0 · source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
Performs copy-assignment from
source
. Read moresource§impl Entity for ControlRegion
impl Entity for ControlRegion
const CHUNK_SIZE: u32 = 4_096u32
type Def = ControlRegionDef
fn from_non_zero_u32(i: NonZeroU32) -> Self
fn to_non_zero_u32(self) -> NonZeroU32
fn cx_entity_alloc(cx: &Context) -> &EntityAlloc<Self>
const CHUNK_MASK: u32 = _
fn to_chunk_start_and_intra_chunk_idx(self) -> (Self, usize)
source§impl Hash for ControlRegion
impl Hash for ControlRegion
source§impl PartialEq for ControlRegion
impl PartialEq for ControlRegion
impl Copy for ControlRegion
impl Eq for ControlRegion
impl StructuralPartialEq for ControlRegion
Auto Trait Implementations§
impl Freeze for ControlRegion
impl RefUnwindSafe for ControlRegion
impl Send for ControlRegion
impl Sync for ControlRegion
impl Unpin for ControlRegion
impl UnwindSafe for ControlRegion
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
Mutably borrows from an owned value. Read more
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)
🔬This is a nightly-only experimental API. (
clone_to_uninit
)source§impl<E, V> EntityOrientedMapKey<V> for Ewhere
E: Entity,
impl<E, V> EntityOrientedMapKey<V> for Ewhere
E: Entity,
source§type DenseValueSlots = Option<V>
type DenseValueSlots = Option<V>
A type holding enough different
Option<V>
slots, for all possible
values of Self
, for a given Self::Entity
value contained inside.fn to_entity(key: E) -> E
fn get_dense_value_slot(_: E, slot: &Option<V>) -> &Option<V>
fn get_dense_value_slot_mut(_: E, slot: &mut Option<V>) -> &mut Option<V>
source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
Compare self to
key
and return true
if they are equal.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>
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 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>
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