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:
- A
RegionBranchTerminatorOpInterfaceterminator in any of the immediately nested regions of this op. 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:
- A region of this op.
- 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§
Sourcefn successor_regions(
&self,
ctx: &Context,
pred: RegionPredecessor,
) -> Vec<RegionSuccessor>
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.
Sourcefn successor_inputs(
&self,
ctx: &Context,
successor: RegionSuccessor,
) -> Vec<Value>
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§
fn verify(_op: &dyn Op, _ctx: &Context) -> Result<()>where
Self: Sized,
Sourcefn entry_successor_operands(
&self,
ctx: &Context,
successor: RegionSuccessor,
) -> Vec<Use<Value>>
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.
Sourcefn entry_successor_regions(
&self,
ctx: &Context,
operands: &[Option<AttrObj>],
) -> Vec<RegionSuccessor>
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.
Sourcefn all_successor_regions_of_region(
&self,
ctx: &Context,
region: Ptr<Region>,
) -> Vec<RegionSuccessor>
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.
Sourcefn predecessors(
&self,
ctx: &Context,
successor: RegionSuccessor,
) -> Vec<RegionPredecessor>
fn predecessors( &self, ctx: &Context, successor: RegionSuccessor, ) -> Vec<RegionPredecessor>
Returns all potential branching points (predecessors) for a given region successor.
Sourcefn predecessor_values(
&self,
ctx: &Context,
successor: RegionSuccessor,
index: usize,
) -> Vec<Use<Value>>
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.
Sourcefn region_invocation_bounds(
&self,
ctx: &Context,
operands: &[Option<AttrObj>],
) -> Vec<InvocationBounds>
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?”
Sourcefn are_types_compatible(
&self,
ctx: &Context,
lhs: TypeHandle,
rhs: TypeHandle,
) -> bool
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
impl dyn RegionBranchOpInterface
Sourcepub fn successor_operands(
&self,
ctx: &Context,
src: RegionPredecessor,
dest: RegionSuccessor,
) -> Vec<Use<Value>>
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.
Sourcepub fn non_successor_inputs(
&self,
ctx: &Context,
successor: RegionSuccessor,
) -> Vec<Value>
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.
Sourcepub fn all_region_predecessors(&self, ctx: &Context) -> Vec<RegionPredecessor>
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.
pub fn successor_operand_input_mapping( &self, ctx: &Context, src: RegionPredecessor, ) -> IMap<Use<Value>, SmallVec<[Value; 4]>>
Trait Implementations§
impl OpInterfaceMarker for dyn RegionBranchOpInterface
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".