pub(super) struct Selection<'b, M: MergeTuple> {
block: &'b mut Block,
merge_label: Option<Word>,
values: Vec<(M, Word)>,
merge_types: M,
}
Expand description
A private struct recording what we know about the selection construct so far.
Fields§
§block: &'b mut Block
The block pointer we’re emitting code into.
merge_label: Option<Word>
The label of the selection construct’s merge block, or None
if we
haven’t yet written the OpSelectionMerge
merge instruction.
values: Vec<(M, Word)>
A set of (VALUES, PARENT)
pairs, used to build OpPhi
instructions in
the merge block. Each PARENT
is the label of a predecessor block of
the merge block. The corresponding VALUES
holds the ids of the values
that PARENT
contributes to the merged values.
We emit all branches to the merge block, so we know all its predecessors. And we refuse to emit a branch unless we’re given the values the branching block contributes to the merge, so we always have everything we need to emit the correct phis, by construction.
merge_types: M
The types of the values in each element of values
.
Implementations§
source§impl<'b, M: MergeTuple> Selection<'b, M>
impl<'b, M: MergeTuple> Selection<'b, M>
sourcepub(super) fn start(block: &'b mut Block, merge_types: M) -> Self
pub(super) fn start(block: &'b mut Block, merge_types: M) -> Self
Start a new selection construct.
The block
argument indicates the selection’s header block.
The merge_types
argument should be a Word
or tuple of Word
s, each
value being the SPIR-V result type id of an OpPhi
instruction that
will be written to the selection’s merge block when this selection’s
finish
method is called. This argument may also be ()
, for
selections that produce no values.
(This function writes no code to block
itself; it simply constructs a
fresh Selection
.)
pub(super) fn block(&mut self) -> &mut Block
sourcepub(super) fn if_true(
&mut self,
ctx: &mut BlockContext<'_>,
cond: Word,
values: M,
)
pub(super) fn if_true( &mut self, ctx: &mut BlockContext<'_>, cond: Word, values: M, )
Branch to a successor block if cond
is true, otherwise merge.
If cond
is false, branch to the merge block, using values
as the
merged values. Otherwise, proceed to a new block.
The values
argument must be the same shape as the merge_types
argument passed to Selection::start
.
sourcepub(super) fn finish(self, ctx: &mut BlockContext<'_>, final_values: M) -> M
pub(super) fn finish(self, ctx: &mut BlockContext<'_>, final_values: M) -> M
Emit an unconditional branch to the merge block, and compute merged values.
Use final_values
as the merged values contributed by the current
block, and transition to the merge block, emitting OpPhi
instructions
to produce the merged values. This must be the same shape as the
merge_types
argument passed to Selection::start
.
Return the SPIR-V ids of the merged values. This value has the same
shape as the merge_types
argument passed to Selection::start
.
sourcefn make_merge_label(&mut self, ctx: &mut BlockContext<'_>) -> Word
fn make_merge_label(&mut self, ctx: &mut BlockContext<'_>) -> Word
Return the id of the merge block, writing a merge instruction if needed.