pub struct AffineIfOperation<'c> { /* private fields */ }
Expand description

An if operation. If-then-else operation.

Syntax:

operation  ::= `affine.if` if-op-cond `{` op* `}` (`else` `{` op* `}`)?
if-op-cond ::= integer-set-attr dim-and-symbol-use-list

The affine.if operation restricts execution to a subset of the loop iteration space defined by an integer set (a conjunction of affine constraints). A single affine.if may end with an optional else clause.

The condition of the affine.if is represented by an integer set (a conjunction of affine constraints), and the SSA values bound to the dimensions and symbols in the integer set. The same restrictions hold for these SSA values as for all bindings of SSA values to dimensions and symbols.

The affine.if operation contains two regions for the “then” and “else” clauses. affine.if may return results that are defined in its regions. The values defined are determined by which execution path is taken. Each region of the affine.if must contain a single block with no arguments, and be terminated by affine.yield. If affine.if defines no values, the affine.yield can be left out, and will be inserted implicitly. Otherwise, it must be explicit. If no values are defined, the else block may be empty (i.e. contain no blocks).

Example:

#set = affine_set<(d0, d1)[s0]: (d0 - 10 >= 0, s0 - d0 - 9 >= 0,
                                 d1 - 10 >= 0, s0 - d1 - 9 >= 0)>
func.func @reduced_domain_example(%A, %X, %N) : (memref<10xi32>, i32, i32) {
  affine.for %i = 0 to %N {
     affine.for %j = 0 to %N {
       %0 = affine.apply #map42(%j)
       %tmp = call @S1(%X, %i, %0)
       affine.if #set(%i, %j)[%N] {
          %1 = affine.apply #map43(%i, %j)
          call @S2(%tmp, %A, %i, %1)
       }
    }
  }
  return
}

Example with an explicit yield (initialization with edge padding):

#interior = affine_set<(i, j) : (i - 1 >= 0, j - 1 >= 0,  10 - i >= 0, 10 - j >= 0)> (%i, %j)
func.func @pad_edges(%I : memref<10x10xf32>) -> (memref<12x12xf32) {
  %O = alloc memref<12x12xf32>
  affine.parallel (%i, %j) = (0, 0) to (12, 12) {
    %1 = affine.if #interior (%i, %j) {
      %2 = load %I[%i - 1, %j - 1] : memref<10x10xf32>
      affine.yield %2
    } else {
      %2 = arith.constant 0.0 : f32
      affine.yield %2 : f32
    }
    affine.store %1, %O[%i, %j] : memref<12x12xf32>
  }
  return %O
}

Implementations§

source§

impl<'c> AffineIfOperation<'c>

source

pub fn name() -> &'static str

Returns a name.

source

pub fn as_operation(&self) -> &Operation<'c>

Returns a generic operation.

source

pub fn builder( context: &'c Context, location: Location<'c> ) -> AffineIfOperationBuilder<'c, Unset, Unset, Unset>

Creates a builder.

source

pub fn results(&self) -> impl Iterator<Item = OperationResult<'c, '_>>

source

pub fn then_region(&self) -> Result<RegionRef<'c, '_>, Error>

source

pub fn else_region(&self) -> Result<RegionRef<'c, '_>, Error>

Trait Implementations§

source§

impl<'c> From<AffineIfOperation<'c>> for Operation<'c>

source§

fn from(operation: AffineIfOperation<'c>) -> Self

Converts to this type from the input type.
source§

impl<'c> TryFrom<Operation<'c>> for AffineIfOperation<'c>

§

type Error = Error

The type returned in the event of a conversion error.
source§

fn try_from(operation: Operation<'c>) -> Result<Self, Self::Error>

Performs the conversion.

Auto Trait Implementations§

§

impl<'c> RefUnwindSafe for AffineIfOperation<'c>

§

impl<'c> !Send for AffineIfOperation<'c>

§

impl<'c> !Sync for AffineIfOperation<'c>

§

impl<'c> Unpin for AffineIfOperation<'c>

§

impl<'c> UnwindSafe for AffineIfOperation<'c>

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.