Skip to main content

RegionBranchOpInterface

Trait RegionBranchOpInterface 

Source
pub trait RegionBranchOpInterface: Op {
    // Required methods
    fn successor_regions(
        &self,
        ctx: &Context,
        pred: RegionPredecessor,
    ) -> Vec<RegionSuccessor>;
    fn successor_inputs(
        &self,
        ctx: &Context,
        successor: RegionSuccessor,
    ) -> Vec<Value>;

    // Provided methods
    fn verify(_op: &dyn Op, _ctx: &Context) -> Result<()>
       where Self: Sized { ... }
    fn entry_successor_operands(
        &self,
        ctx: &Context,
        successor: RegionSuccessor,
    ) -> Vec<Use<Value>> { ... }
    fn entry_successor_regions(
        &self,
        ctx: &Context,
        operands: &[Option<AttrObj>],
    ) -> Vec<RegionSuccessor> { ... }
    fn all_successor_regions_of_region(
        &self,
        ctx: &Context,
        region: Ptr<Region>,
    ) -> Vec<RegionSuccessor> { ... }
    fn predecessors(
        &self,
        ctx: &Context,
        successor: RegionSuccessor,
    ) -> Vec<RegionPredecessor> { ... }
    fn predecessor_values(
        &self,
        ctx: &Context,
        successor: RegionSuccessor,
        index: usize,
    ) -> Vec<Use<Value>> { ... }
    fn region_invocation_bounds(
        &self,
        ctx: &Context,
        operands: &[Option<AttrObj>],
    ) -> Vec<InvocationBounds> { ... }
    fn are_types_compatible(
        &self,
        ctx: &Context,
        lhs: TypeHandle,
        rhs: TypeHandle,
    ) -> bool { ... }
}
Expand description

This interface provides information for region-holding operations that exhibit branching behavior between held regions. It models the control flow edges between regions (and between the op and its regions), as well as the data flow (value propagation) that occurs along those control flow edges.

This interface is meant to model well-defined cases of control-flow and value propagation, where what occurs along control-flow edges is assumed to be side-effect free.

A “region branch point” indicates the point from which a branch (edge) originates. It can indicate:

  1. A RegionBranchTerminatorOpInterface terminator in any of the immediately nested regions of this op.
  2. RegionBranchPoint::parent(): the branch originates from outside of the op, i.e., when first executing this op.

When branching from a region branch point to a region successor, the “successor operands” to be forwarded from the region branch point can be specified with getEntrySuccessorOperands / RegionBranchTerminatorOpInterface::getSuccessorOperands.

A “region successor” indicates the target of a branch. It can indicate:

  1. A region of this op.
  2. A parent operation, i.e., the control flow leaves/resumes after that op.

The SSA values to which successor operands are forwarded are called “successor inputs”.

By default, successor operands and successor block arguments/successor results must have the same type. areTypesCompatible can be implemented to allow non-equal types.

Note: This interface works in conjunction with RegionBranchTerminatorOpInterface. All immediately nested block terminators that model branching between regions must implement the RegionBranchTerminatorOpInterface. Otherwise, analyses/transformations may miss control flow edges and produce incorrect results. Not every block terminator is necessarily a region branch terminator: e.g., in the presence of unstructured control flow, a block terminator could indicate a branch to a different block within the same region.

Example:

ⓘ
%r = scf.for %iv = %lb to %ub step %step iter_args(%a = %b)
    -> tensor<5xf32> {
  ...
  scf.yield %c : tensor<5xf32>
}

scf.for has one region. There are two region branch points with two identical region successors:

  • parent => op(%r), region0(%a)
  • scf.yield => op(%r), region0(%a)

%a and %r are successor inputs. %b is an entry successor operand. %c is a successor operand.

Required Methods§

Source

fn successor_regions( &self, ctx: &Context, pred: RegionPredecessor, ) -> Vec<RegionSuccessor>

Returns all potential region successors when branching from predecessor. These are the regions that may be selected during the flow of control.

When pred = RegionPredecessor::Parent, this method returns the region successors when entering the operation. Otherwise, this method returns the successor regions when branching from the region indicated by pred.

Example: In the above example, this method returns the region of the scf.for and parent for either region branch point. An implementation may choose to filter out region successors when it is statically known (e.g., by examining the operands of this op) that those successors are not branched to.

Source

fn successor_inputs( &self, ctx: &Context, successor: RegionSuccessor, ) -> Vec<Value>

Return all successor inputs for the given region successor. If the given region successor is a region, then the returned values are block arguments. Otherwise, if the given region successor is an operation, the returned values are op results.

Provided Methods§

Source

fn verify(_op: &dyn Op, _ctx: &Context) -> Result<()>
where Self: Sized,

Source

fn entry_successor_operands( &self, ctx: &Context, successor: RegionSuccessor, ) -> Vec<Use<Value>>

Returns the operands of this operation that are forwarded to the successor inputs when branching to successor. successor is guaranteed to be among the successors that are returned by entry_successor_regions/successor_regions(parent()).

Example: In the above example, this method returns the operand %b of the scf.for op, regardless of the value of successor. I.e., this op always forwards the same operands, regardless of whether the loop has 0 or more iterations.

Source

fn entry_successor_regions( &self, ctx: &Context, operands: &[Option<AttrObj>], ) -> Vec<RegionSuccessor>

Returns all potential region successors when first executing the op.

Unlike successor_regions, this method also receives the constant operands of this op (one entry per operand, None if the operand has no/unknown constant value). The implementation may use this information to filter out successors. By default, it simply dispatches to successor_regions.

Note: The control flow does not necessarily have to enter any region of this op.

Example: In the above example, this method may return two region region successors: the single region of the scf.for op and the scf.for operation (that implements this interface). If %lb, %ub, %step are constants and it can be determined the loop does not have any iterations, this method may choose to return only this operation. Similarly, if it can be determined that the loop has at least one iteration, this method may choose to return only the region of the loop.

Source

fn all_successor_regions_of_region( &self, ctx: &Context, region: Ptr<Region>, ) -> Vec<RegionSuccessor>

Returns all potential region successors when branching from any terminator in region.

Source

fn predecessors( &self, ctx: &Context, successor: RegionSuccessor, ) -> Vec<RegionPredecessor>

Returns all potential branching points (predecessors) for a given region successor.

Source

fn predecessor_values( &self, ctx: &Context, successor: RegionSuccessor, index: usize, ) -> Vec<Use<Value>>

Returns all potential values across all (predecessors) for a given successor input.

Source

fn region_invocation_bounds( &self, ctx: &Context, operands: &[Option<AttrObj>], ) -> Vec<InvocationBounds>

Populates invocationBounds with the minimum and maximum number of times this operation will invoke the attached regions (assuming the regions yield normally, i.e. do not abort or invoke an infinite loop). The minimum number of invocations is at least 0. If the maximum number of invocations cannot be statically determined, then it will be set to InvocationBounds::getUnknown().

This method also passes along the constant operands of this op. operands contains an entry for every operand of this op, with a null attribute if the operand has no constant value.

This method may be called speculatively on operations where the provided operands are not necessarily the same as the operation’s current operands. This may occur in analyses that wish to determine “what would be the region invocations if these were the operands?”

Source

fn are_types_compatible( &self, ctx: &Context, lhs: TypeHandle, rhs: TypeHandle, ) -> bool

This method is called to compare types along control-flow edges. By default, the types are checked as equal.

Implementations§

Source§

impl dyn RegionBranchOpInterface

Source

pub fn successor_operands( &self, ctx: &Context, src: RegionPredecessor, dest: RegionSuccessor, ) -> Vec<Use<Value>>

Return the successor operands from the source branch point to the destination region successor.

If the branch point is the parent op, this function returns entry successor operands of this op. Otherwise, it returns successor operands of the respective terminator.

Source

pub fn non_successor_inputs( &self, ctx: &Context, successor: RegionSuccessor, ) -> Vec<Value>

Return all successor inputs for the given region successor.

If the “successor” is a region, it will return non-forwarded arguments, if it is a “parent”, it will return non-forwarded results.

Source

pub fn all_region_predecessors(&self, ctx: &Context) -> Vec<RegionPredecessor>

Return all possible region branch points: the region branch op itself and all region branch terminators.

Source

pub fn successor_operand_input_mapping( &self, ctx: &Context, src: RegionPredecessor, ) -> IMap<Use<Value>, SmallVec<[Value; 4]>>

Trait Implementations§

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§

Source§

impl RegionBranchOpInterface for ForOp

Source§

impl RegionBranchOpInterface for cubecl_ir::dialect::branch::IfOp

Source§

impl RegionBranchOpInterface for cubecl_ir::dialect::scf::IfOp

Source§

impl RegionBranchOpInterface for RangeLoopOp

Source§

impl RegionBranchOpInterface for cubecl_ir::dialect::branch::SwitchOp

Source§

impl RegionBranchOpInterface for cubecl_ir::dialect::scf::SwitchOp

Source§

impl RegionBranchOpInterface for cubecl_ir::dialect::branch::WhileOp

Source§

impl RegionBranchOpInterface for cubecl_ir::dialect::scf::WhileOp