pub trait CFGToSCFInterface {
// Required methods
fn create_structured_branch_region_op(
&self,
builder: &mut OpBuilder,
control_flow_cond_op: OperationRef,
result_types: &[Type],
regions: &mut SmallVec<[RegionRef; 2]>,
) -> Result<OperationRef, Report>;
fn create_structured_branch_region_terminator_op(
&self,
span: SourceSpan,
builder: &mut OpBuilder,
branch_region_op: OperationRef,
replaced_control_flow_op: Option<OperationRef>,
results: ValueRange<'_, 2>,
) -> Result<(), Report>;
fn create_structured_do_while_loop_op(
&self,
builder: &mut OpBuilder,
replaced_op: OperationRef,
loop_values_init: ValueRange<'_, 2>,
condition: ValueRef,
loop_values_next_iter: ValueRange<'_, 2>,
loop_body: RegionRef,
) -> Result<OperationRef, Report>;
fn get_cfg_switch_value(
&self,
span: SourceSpan,
builder: &mut OpBuilder,
value: u32,
) -> ValueRef;
fn create_cfg_switch_op(
&self,
span: SourceSpan,
builder: &mut OpBuilder,
flag: ValueRef,
case_values: &[u32],
case_destinations: &[BlockRef],
case_arguments: &[ValueRange<'_, 2>],
default_dest: BlockRef,
default_args: ValueRange<'_, 2>,
) -> Result<(), Report>;
fn get_undef_value(
&self,
span: SourceSpan,
builder: &mut OpBuilder,
ty: Type,
) -> ValueRef;
fn create_unreachable_terminator(
&self,
span: SourceSpan,
builder: &mut OpBuilder,
region: RegionRef,
) -> Result<OperationRef, Report>;
// Provided methods
fn create_single_destination_branch(
&self,
span: SourceSpan,
builder: &mut OpBuilder,
dummy_flag: ValueRef,
destination: BlockRef,
arguments: ValueRange<'_, 2>,
) -> Result<(), Report> { ... }
fn create_conditional_branch(
&self,
span: SourceSpan,
builder: &mut OpBuilder,
condition: ValueRef,
true_dest: BlockRef,
true_args: ValueRange<'_, 2>,
false_dest: BlockRef,
false_args: ValueRange<'_, 2>,
) -> Result<(), Report> { ... }
}Expand description
This trait is used to abstract over the dialect-specific aspects of the control flow lifting transformation performed by transform_cfg_to_scf.
Implementations must be able to create switch-like control flow operations in order to
facilitate intermediate transformations; as well as the various structured control flow ops
represented by each method (e.g. scf.if, scf.while).
Required Methods§
Sourcefn create_structured_branch_region_op(
&self,
builder: &mut OpBuilder,
control_flow_cond_op: OperationRef,
result_types: &[Type],
regions: &mut SmallVec<[RegionRef; 2]>,
) -> Result<OperationRef, Report>
fn create_structured_branch_region_op( &self, builder: &mut OpBuilder, control_flow_cond_op: OperationRef, result_types: &[Type], regions: &mut SmallVec<[RegionRef; 2]>, ) -> Result<OperationRef, Report>
Creates a structured control flow operation branching to one of regions.
It replaces control_flow_cond_op and must produce result_types as results.
regions contains the list of branch regions corresponding to each successor of
control_flow_cond_op. Their bodies must simply be taken and left as is.
Returns Err if incapable of converting the control flow graph operation.
Sourcefn create_structured_branch_region_terminator_op(
&self,
span: SourceSpan,
builder: &mut OpBuilder,
branch_region_op: OperationRef,
replaced_control_flow_op: Option<OperationRef>,
results: ValueRange<'_, 2>,
) -> Result<(), Report>
fn create_structured_branch_region_terminator_op( &self, span: SourceSpan, builder: &mut OpBuilder, branch_region_op: OperationRef, replaced_control_flow_op: Option<OperationRef>, results: ValueRange<'_, 2>, ) -> Result<(), Report>
Creates a return-like terminator for a branch region of the op returned by CFGToSCFInterface::create_structured_branch_region_op.
branch_region_opis the operation returned bycreate_structured_branch_region_op.replaced_control_flow_opis the control flow op being replaced by the terminator orNoneif the terminator is not replacing any existing control flow op.resultsare the values that should be returned by the branch region.
Sourcefn create_structured_do_while_loop_op(
&self,
builder: &mut OpBuilder,
replaced_op: OperationRef,
loop_values_init: ValueRange<'_, 2>,
condition: ValueRef,
loop_values_next_iter: ValueRange<'_, 2>,
loop_body: RegionRef,
) -> Result<OperationRef, Report>
fn create_structured_do_while_loop_op( &self, builder: &mut OpBuilder, replaced_op: OperationRef, loop_values_init: ValueRange<'_, 2>, condition: ValueRef, loop_values_next_iter: ValueRange<'_, 2>, loop_body: RegionRef, ) -> Result<OperationRef, Report>
Creates a structured control flow operation representing a do-while loop.
The do-while loop is expected to have the exact same result types as the types of the
iteration values. loop_body is the body of the loop.
Implementations must create a suitable terminator op at the end of the last block in
loop_body which continues the loop if condition is 1, and exits the loop if 0.
loop_values_next_iter are the values that have to be passed as the iteration values for
the next iteration if continuing, or the result of the loop if exiting.
condition is guaranteed to be of the same type as values returned by
get_cfg_switch_value with either 0 or 1 as value.
loop_values_init are the values used to initialize the iteration values of the loop.
Returns Err if incapable of creating a loop op.
Sourcefn get_cfg_switch_value(
&self,
span: SourceSpan,
builder: &mut OpBuilder,
value: u32,
) -> ValueRef
fn get_cfg_switch_value( &self, span: SourceSpan, builder: &mut OpBuilder, value: u32, ) -> ValueRef
Creates a constant operation with a result representing value that is suitable as flag
for create_cfg_switch_op.
Sourcefn create_cfg_switch_op(
&self,
span: SourceSpan,
builder: &mut OpBuilder,
flag: ValueRef,
case_values: &[u32],
case_destinations: &[BlockRef],
case_arguments: &[ValueRange<'_, 2>],
default_dest: BlockRef,
default_args: ValueRange<'_, 2>,
) -> Result<(), Report>
fn create_cfg_switch_op( &self, span: SourceSpan, builder: &mut OpBuilder, flag: ValueRef, case_values: &[u32], case_destinations: &[BlockRef], case_arguments: &[ValueRange<'_, 2>], default_dest: BlockRef, default_args: ValueRange<'_, 2>, ) -> Result<(), Report>
Creates a switch-like unstructured branch operation, branching to one of case_destinations
or default_dest.
This is used by [transform_cfg_to_scfg] for intermediate transformations before lifting to structured control flow.
The switch op branches based on flag which is guaranteed to be of the same type as values
returned by get_cfg_switch_value. The insertion block of the builder is guaranteed to have
its predecessors already set to create an equivalent CFG after this operation.
NOTE: case_values and other related slices may be empty to represent an unconditional
branch.
Sourcefn get_undef_value(
&self,
span: SourceSpan,
builder: &mut OpBuilder,
ty: Type,
) -> ValueRef
fn get_undef_value( &self, span: SourceSpan, builder: &mut OpBuilder, ty: Type, ) -> ValueRef
Creates a constant operation returning an undefined instance of type.
This is required by the transformation as the lifting process might create control flow paths where an SSA-value is undefined.
Sourcefn create_unreachable_terminator(
&self,
span: SourceSpan,
builder: &mut OpBuilder,
region: RegionRef,
) -> Result<OperationRef, Report>
fn create_unreachable_terminator( &self, span: SourceSpan, builder: &mut OpBuilder, region: RegionRef, ) -> Result<OperationRef, Report>
Creates a return-like terminator indicating unreachable.
This is required when the transformation encounters a statically known infinite loop. Since structured control flow ops are not terminators, after lifting an infinite loop, a terminator has to be placed after to possibly satisfy the terminator requirement of the region originally passed to transform_cfg_to_scf.
region is guaranteed to be the region originally passed to transform_cfg_to_scf and the
op is guaranteed to always be an op in a block directly nested under region after the
transformation.
Returns Err if incapable of creating an unreachable terminator.
Provided Methods§
Sourcefn create_single_destination_branch(
&self,
span: SourceSpan,
builder: &mut OpBuilder,
dummy_flag: ValueRef,
destination: BlockRef,
arguments: ValueRange<'_, 2>,
) -> Result<(), Report>
fn create_single_destination_branch( &self, span: SourceSpan, builder: &mut OpBuilder, dummy_flag: ValueRef, destination: BlockRef, arguments: ValueRange<'_, 2>, ) -> Result<(), Report>
Helper function to create an unconditional branch using [create_cfg_switch_op].
Sourcefn create_conditional_branch(
&self,
span: SourceSpan,
builder: &mut OpBuilder,
condition: ValueRef,
true_dest: BlockRef,
true_args: ValueRange<'_, 2>,
false_dest: BlockRef,
false_args: ValueRange<'_, 2>,
) -> Result<(), Report>
fn create_conditional_branch( &self, span: SourceSpan, builder: &mut OpBuilder, condition: ValueRef, true_dest: BlockRef, true_args: ValueRange<'_, 2>, false_dest: BlockRef, false_args: ValueRange<'_, 2>, ) -> Result<(), Report>
Helper function to create a conditional branch using [create_cfg_switch_op].