forked from OSchip/llvm-project
				
			[MLIR][NFC] Rename op trait PolyhedralScope -> AffineScope
Rename op trait PolyhedralScope -> AffineScope for consistency. Differential Revision: https://reviews.llvm.org/D79503
This commit is contained in:
		
							parent
							
								
									237d0e3c04
								
							
						
					
					
						commit
						57d361bd2f
					
				| 
						 | 
				
			
			@ -62,16 +62,16 @@ Example:
 | 
			
		|||
The affine dialect imposes certain restrictions on dimension and symbolic
 | 
			
		||||
identifiers to enable powerful analysis and transformation. An SSA value's use
 | 
			
		||||
can be bound to a symbolic identifier if that SSA value is either
 | 
			
		||||
1. a region argument for an op with trait `PolyhedralScope` (eg. `FuncOp`),
 | 
			
		||||
2. a value defined at the top level of a `PolyhedralScope` op (i.e., immediately
 | 
			
		||||
1. a region argument for an op with trait `AffineScope` (eg. `FuncOp`),
 | 
			
		||||
2. a value defined at the top level of a `AffineScope` op (i.e., immediately
 | 
			
		||||
enclosed by the latter),
 | 
			
		||||
3. a value that dominates the `PolyhedralScope` op enclosing the value's use,
 | 
			
		||||
3. a value that dominates the `AffineScope` op enclosing the value's use,
 | 
			
		||||
4. the result of a [`constant` operation](Standard.md#constant-operation),
 | 
			
		||||
5. the result of an [`affine.apply`
 | 
			
		||||
operation](#affineapply-operation) that recursively takes as arguments any valid
 | 
			
		||||
symbolic identifiers, or
 | 
			
		||||
6. the result of a [`dim` operation](Standard.md#dim-operation) on either a
 | 
			
		||||
memref that is an argument to a `PolyhedralScope` op or a memref where the
 | 
			
		||||
memref that is an argument to a `AffineScope` op or a memref where the
 | 
			
		||||
corresponding dimension is either static or a dynamic one in turn bound to a
 | 
			
		||||
valid symbol.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -135,6 +135,21 @@ section goes as follows:
 | 
			
		|||
*   `Header`
 | 
			
		||||
    -   (`C++ class` -- `ODS class`(if applicable))
 | 
			
		||||
 | 
			
		||||
### AffineScope
 | 
			
		||||
 | 
			
		||||
*   `OpTrait::AffineScope` -- `AffineScope`
 | 
			
		||||
 | 
			
		||||
This trait is carried by region holding operations that define a new scope for
 | 
			
		||||
the purposes of polyhedral optimization and the affine dialect in particular.
 | 
			
		||||
Any SSA values of 'index' type that either dominate such operations, or are
 | 
			
		||||
defined at the top-level of such operations, or appear as region arguments for
 | 
			
		||||
such operations automatically become valid symbols for the polyhedral scope
 | 
			
		||||
defined by that operation. As a result, such SSA values could be used as the
 | 
			
		||||
operands or index operands of various affine dialect operations like affine.for,
 | 
			
		||||
affine.load, and affine.store.  The polyhedral scope defined by an operation
 | 
			
		||||
with this trait includes all operations in its region excluding operations that
 | 
			
		||||
are nested inside of other operations that themselves have this trait.
 | 
			
		||||
 | 
			
		||||
### AutomaticAllocationScope
 | 
			
		||||
 | 
			
		||||
*   `OpTrait::AutomaticAllocationScope` -- `AutomaticAllocationScope`
 | 
			
		||||
| 
						 | 
				
			
			@ -219,22 +234,6 @@ foo.region_op {
 | 
			
		|||
This trait is an important structural property of the IR, and enables operations
 | 
			
		||||
to have [passes](PassManagement.md) scheduled under them.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### PolyhedralScope
 | 
			
		||||
 | 
			
		||||
*   `OpTrait::PolyhedralScope` -- `PolyhedralScope`
 | 
			
		||||
 | 
			
		||||
This trait is carried by region holding operations that define a new scope for
 | 
			
		||||
the purposes of polyhedral optimization and the affine dialect in particular.
 | 
			
		||||
Any SSA values of 'index' type that either dominate such operations, or are
 | 
			
		||||
defined at the top-level of such operations, or appear as region arguments for
 | 
			
		||||
such operations automatically become valid symbols for the polyhedral scope
 | 
			
		||||
defined by that operation. As a result, such SSA values could be used as the
 | 
			
		||||
operands or index operands of various affine dialect operations like affine.for,
 | 
			
		||||
affine.load, and affine.store.  The polyhedral scope defined by an operation
 | 
			
		||||
with this trait includes all operations in its region excluding operations that
 | 
			
		||||
are nested inside of other operations that themselves have this trait.
 | 
			
		||||
 | 
			
		||||
### Single Block with Implicit Terminator
 | 
			
		||||
 | 
			
		||||
*   `OpTrait::SingleBlockImplicitTerminator<typename TerminatorOpType>` :
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,9 +32,9 @@ class FlatAffineConstraints;
 | 
			
		|||
class OpBuilder;
 | 
			
		||||
 | 
			
		||||
/// A utility function to check if a value is defined at the top level of an
 | 
			
		||||
/// op with trait `PolyhedralScope` or is a region argument for such an op. A
 | 
			
		||||
/// value of index type defined at the top level is always a valid symbol for
 | 
			
		||||
/// all its uses.
 | 
			
		||||
/// op with trait `AffineScope` or is a region argument for such an op. A value
 | 
			
		||||
/// of index type defined at the top level is always a valid symbol for all its
 | 
			
		||||
/// uses.
 | 
			
		||||
bool isTopLevelValue(Value value);
 | 
			
		||||
 | 
			
		||||
/// AffineDmaStartOp starts a non-blocking DMA operation that transfers data
 | 
			
		||||
| 
						 | 
				
			
			@ -318,7 +318,7 @@ public:
 | 
			
		|||
};
 | 
			
		||||
 | 
			
		||||
/// Returns true if the given Value can be used as a dimension id in the region
 | 
			
		||||
/// of the closest surrounding op that has the trait `PolyhedralScope`.
 | 
			
		||||
/// of the closest surrounding op that has the trait `AffineScope`.
 | 
			
		||||
bool isValidDim(Value value);
 | 
			
		||||
 | 
			
		||||
/// Returns true if the given Value can be used as a dimension id in `region`,
 | 
			
		||||
| 
						 | 
				
			
			@ -326,7 +326,7 @@ bool isValidDim(Value value);
 | 
			
		|||
bool isValidDim(Value value, Region *region);
 | 
			
		||||
 | 
			
		||||
/// Returns true if the given value can be used as a symbol in the region of the
 | 
			
		||||
/// closest surrounding op that has the trait `PolyhedralScope`.
 | 
			
		||||
/// closest surrounding op that has the trait `AffineScope`.
 | 
			
		||||
bool isValidSymbol(Value value);
 | 
			
		||||
 | 
			
		||||
/// Returns true if the given Value can be used as a symbol for `region`, i.e.,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -84,7 +84,7 @@ def AffineApplyOp : Affine_Op<"apply", [NoSideEffect]> {
 | 
			
		|||
    AffineValueMap getAffineValueMap();
 | 
			
		||||
 | 
			
		||||
    /// Returns true if the result of this operation can be used as dimension id
 | 
			
		||||
    /// in the region of the closest surrounding op with trait PolyhedralScope.
 | 
			
		||||
    /// in the region of the closest surrounding op with trait AffineScope.
 | 
			
		||||
    bool isValidDim();
 | 
			
		||||
 | 
			
		||||
    /// Returns true if the result of this operation can be used as dimension id
 | 
			
		||||
| 
						 | 
				
			
			@ -92,7 +92,7 @@ def AffineApplyOp : Affine_Op<"apply", [NoSideEffect]> {
 | 
			
		|||
    bool isValidDim(Region *region);
 | 
			
		||||
 | 
			
		||||
    /// Returns true if the result of this operation is a symbol in the region
 | 
			
		||||
    /// of the closest surrounding op that has the trait PolyhedralScope.
 | 
			
		||||
    /// of the closest surrounding op that has the trait AffineScope.
 | 
			
		||||
    bool isValidSymbol();
 | 
			
		||||
 | 
			
		||||
    /// Returns true if the result of this operation is a symbol for all its
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -34,7 +34,7 @@ class FuncOp
 | 
			
		|||
    : public Op<FuncOp, OpTrait::ZeroOperands, OpTrait::ZeroResult,
 | 
			
		||||
                OpTrait::OneRegion, OpTrait::IsIsolatedFromAbove,
 | 
			
		||||
                OpTrait::FunctionLike, OpTrait::AutomaticAllocationScope,
 | 
			
		||||
                OpTrait::PolyhedralScope, CallableOpInterface::Trait,
 | 
			
		||||
                OpTrait::AffineScope, CallableOpInterface::Trait,
 | 
			
		||||
                SymbolOpInterface::Trait> {
 | 
			
		||||
public:
 | 
			
		||||
  using Op::Op;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,7 +30,7 @@ class ModuleTerminatorOp;
 | 
			
		|||
class ModuleOp
 | 
			
		||||
    : public Op<
 | 
			
		||||
          ModuleOp, OpTrait::ZeroOperands, OpTrait::ZeroResult,
 | 
			
		||||
          OpTrait::IsIsolatedFromAbove, OpTrait::PolyhedralScope,
 | 
			
		||||
          OpTrait::IsIsolatedFromAbove, OpTrait::AffineScope,
 | 
			
		||||
          OpTrait::SymbolTable,
 | 
			
		||||
          OpTrait::SingleBlockImplicitTerminator<ModuleTerminatorOp>::Impl,
 | 
			
		||||
          SymbolOpInterface::Trait> {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1633,6 +1633,8 @@ class PredOpTrait<string descr, Pred pred> : OpTrait {
 | 
			
		|||
  Pred predicate = pred;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Op defines an affine scope.
 | 
			
		||||
def AffineScope : NativeOpTrait<"AffineScope">;
 | 
			
		||||
// Op defines an automatic allocation scope.
 | 
			
		||||
def AutomaticAllocationScope : NativeOpTrait<"AutomaticAllocationScope">;
 | 
			
		||||
// Op supports operand broadcast behavior.
 | 
			
		||||
| 
						 | 
				
			
			@ -1648,8 +1650,6 @@ def ConstantLike : NativeOpTrait<"ConstantLike">;
 | 
			
		|||
def FunctionLike : NativeOpTrait<"FunctionLike">;
 | 
			
		||||
// Op is isolated from above.
 | 
			
		||||
def IsolatedFromAbove : NativeOpTrait<"IsIsolatedFromAbove">;
 | 
			
		||||
// Op defines a polyhedral scope.
 | 
			
		||||
def PolyhedralScope : NativeOpTrait<"PolyhedralScope">;
 | 
			
		||||
// Op results are float or vectors/tensors thereof.
 | 
			
		||||
def ResultsAreFloatLike : NativeOpTrait<"ResultsAreFloatLike">;
 | 
			
		||||
// Op has the same operand type.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1045,9 +1045,9 @@ public:
 | 
			
		|||
/// optimization purposes. Any SSA values of 'index' type that either dominate
 | 
			
		||||
/// such an operation or are used at the top-level of such an operation
 | 
			
		||||
/// automatically become valid symbols for the polyhedral scope defined by that
 | 
			
		||||
/// operation. For more details, see `Traits.md#PolyhedralScope`.
 | 
			
		||||
/// operation. For more details, see `Traits.md#AffineScope`.
 | 
			
		||||
template <typename ConcreteType>
 | 
			
		||||
class PolyhedralScope : public TraitBase<ConcreteType, PolyhedralScope> {
 | 
			
		||||
class AffineScope : public TraitBase<ConcreteType, AffineScope> {
 | 
			
		||||
public:
 | 
			
		||||
  static LogicalResult verifyTrait(Operation *op) {
 | 
			
		||||
    static_assert(!ConcreteType::template hasTrait<ZeroRegion>(),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -85,19 +85,17 @@ Operation *AffineDialect::materializeConstant(OpBuilder &builder,
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
/// A utility function to check if a value is defined at the top level of an
 | 
			
		||||
/// op with trait `PolyhedralScope`. A value of index type defined at the top
 | 
			
		||||
/// op with trait `AffineScope`. A value of index type defined at the top
 | 
			
		||||
/// level is always a valid symbol.
 | 
			
		||||
bool mlir::isTopLevelValue(Value value) {
 | 
			
		||||
  if (auto arg = value.dyn_cast<BlockArgument>())
 | 
			
		||||
    return arg.getOwner()->getParentOp()->hasTrait<OpTrait::PolyhedralScope>();
 | 
			
		||||
  return value.getDefiningOp()
 | 
			
		||||
      ->getParentOp()
 | 
			
		||||
      ->hasTrait<OpTrait::PolyhedralScope>();
 | 
			
		||||
    return arg.getOwner()->getParentOp()->hasTrait<OpTrait::AffineScope>();
 | 
			
		||||
  return value.getDefiningOp()->getParentOp()->hasTrait<OpTrait::AffineScope>();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// A utility function to check if a value is defined at the top level of
 | 
			
		||||
/// `region` or is an argument of `region`. A value of index type defined at the
 | 
			
		||||
/// top level of a `PolyhedralScope` region is always a valid symbol for all
 | 
			
		||||
/// top level of a `AffineScope` region is always a valid symbol for all
 | 
			
		||||
/// uses in that region.
 | 
			
		||||
static bool isTopLevelValue(Value value, Region *region) {
 | 
			
		||||
  if (auto arg = value.dyn_cast<BlockArgument>())
 | 
			
		||||
| 
						 | 
				
			
			@ -106,12 +104,12 @@ static bool isTopLevelValue(Value value, Region *region) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
/// Returns the closest region enclosing `op` that is held by an operation with
 | 
			
		||||
/// trait `PolyhedralScope`.
 | 
			
		||||
/// trait `AffineScope`.
 | 
			
		||||
//  TODO: getAffineScope should be publicly exposed for affine passes/utilities.
 | 
			
		||||
static Region *getAffineScope(Operation *op) {
 | 
			
		||||
  auto *curOp = op;
 | 
			
		||||
  while (auto *parentOp = curOp->getParentOp()) {
 | 
			
		||||
    if (parentOp->hasTrait<OpTrait::PolyhedralScope>())
 | 
			
		||||
    if (parentOp->hasTrait<OpTrait::AffineScope>())
 | 
			
		||||
      return curOp->getParentRegion();
 | 
			
		||||
    curOp = parentOp;
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -132,9 +130,9 @@ bool mlir::isValidDim(Value value) {
 | 
			
		|||
    return isValidDim(value, getAffineScope(defOp));
 | 
			
		||||
 | 
			
		||||
  // This value has to be a block argument for an op that has the
 | 
			
		||||
  // `PolyhedralScope` trait or for an affine.for or affine.parallel.
 | 
			
		||||
  // `AffineScope` trait or for an affine.for or affine.parallel.
 | 
			
		||||
  auto *parentOp = value.cast<BlockArgument>().getOwner()->getParentOp();
 | 
			
		||||
  return parentOp->hasTrait<OpTrait::PolyhedralScope>() ||
 | 
			
		||||
  return parentOp->hasTrait<OpTrait::AffineScope>() ||
 | 
			
		||||
         isa<AffineForOp>(parentOp) || isa<AffineParallelOp>(parentOp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -209,7 +207,7 @@ static bool isDimOpValidSymbol(DimOp dimOp, Region *region) {
 | 
			
		|||
// the following conditions:
 | 
			
		||||
// *) It is a constant.
 | 
			
		||||
// *) Its defining op or block arg appearance is immediately enclosed by an op
 | 
			
		||||
//    with `PolyhedralScope` trait.
 | 
			
		||||
//    with `AffineScope` trait.
 | 
			
		||||
// *) It is the result of an affine.apply operation with symbol operands.
 | 
			
		||||
// *) It is a result of the dim op on a memref whose corresponding size is a
 | 
			
		||||
//    valid symbol.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -115,18 +115,18 @@ func @valid_symbols(%arg0: index, %arg1: index, %arg2: index) {
 | 
			
		|||
 | 
			
		||||
// -----
 | 
			
		||||
 | 
			
		||||
// Test symbol constraints for ops with PolyhedralScope trait.
 | 
			
		||||
// Test symbol constraints for ops with AffineScope trait.
 | 
			
		||||
 | 
			
		||||
// CHECK-LABEL: func @valid_symbol_polyhedral_scope
 | 
			
		||||
func @valid_symbol_polyhedral_scope(%n : index, %A : memref<?xf32>) {
 | 
			
		||||
  test.polyhedral_scope {
 | 
			
		||||
// CHECK-LABEL: func @valid_symbol_affine_scope
 | 
			
		||||
func @valid_symbol_affine_scope(%n : index, %A : memref<?xf32>) {
 | 
			
		||||
  test.affine_scope {
 | 
			
		||||
    %c1 = constant 1 : index
 | 
			
		||||
    %l = subi %n, %c1 : index
 | 
			
		||||
    // %l, %n are valid symbols since test.polyhedral_scope defines a new
 | 
			
		||||
    // polyhedral scope.
 | 
			
		||||
    // %l, %n are valid symbols since test.affine_scope defines a new affine
 | 
			
		||||
    // scope.
 | 
			
		||||
    affine.for %i = %l to %n {
 | 
			
		||||
      %m = subi %l, %i : index
 | 
			
		||||
      test.polyhedral_scope {
 | 
			
		||||
      test.affine_scope {
 | 
			
		||||
        // %m and %n are valid symbols.
 | 
			
		||||
        affine.for %j = %m to %n {
 | 
			
		||||
          %v = affine.load %A[%n - 1] : memref<?xf32>
 | 
			
		||||
| 
						 | 
				
			
			@ -142,7 +142,7 @@ func @valid_symbol_polyhedral_scope(%n : index, %A : memref<?xf32>) {
 | 
			
		|||
 | 
			
		||||
// -----
 | 
			
		||||
 | 
			
		||||
// Test the fact that module op always provides a polyhedral scope.
 | 
			
		||||
// Test the fact that module op always provides an affine scope.
 | 
			
		||||
 | 
			
		||||
%idx = "test.foo"() : () -> (index)
 | 
			
		||||
"test.func"() ({
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -201,18 +201,18 @@ static void print(OpAsmPrinter &p, IsolatedRegionOp op) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
//===----------------------------------------------------------------------===//
 | 
			
		||||
// Test PolyhedralScopeOp
 | 
			
		||||
// Test AffineScopeOp
 | 
			
		||||
//===----------------------------------------------------------------------===//
 | 
			
		||||
 | 
			
		||||
static ParseResult parsePolyhedralScopeOp(OpAsmParser &parser,
 | 
			
		||||
static ParseResult parseAffineScopeOp(OpAsmParser &parser,
 | 
			
		||||
                                      OperationState &result) {
 | 
			
		||||
  // Parse the body region, and reuse the operand info as the argument info.
 | 
			
		||||
  Region *body = result.addRegion();
 | 
			
		||||
  return parser.parseRegion(*body, /*arguments=*/{}, /*argTypes=*/{});
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void print(OpAsmPrinter &p, PolyhedralScopeOp op) {
 | 
			
		||||
  p << "test.polyhedral_scope ";
 | 
			
		||||
static void print(OpAsmPrinter &p, AffineScopeOp op) {
 | 
			
		||||
  p << "test.affine_scope ";
 | 
			
		||||
  p.printRegion(op.region(), /*printEntryBlockArgs=*/false);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1150,10 +1150,10 @@ def IsolatedRegionOp : TEST_Op<"isolated_region", [IsolatedFromAbove]> {
 | 
			
		|||
  let printer = [{ return ::print(p, *this); }];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
def PolyhedralScopeOp : TEST_Op<"polyhedral_scope", [PolyhedralScope]> {
 | 
			
		||||
  let summary =  "polyhedral scope operation";
 | 
			
		||||
def AffineScopeOp : TEST_Op<"affine_scope", [AffineScope]> {
 | 
			
		||||
  let summary =  "affine scope operation";
 | 
			
		||||
  let description = [{
 | 
			
		||||
    Test op that defines a new polyhedral scope.
 | 
			
		||||
    Test op that defines a new affine scope.
 | 
			
		||||
  }];
 | 
			
		||||
 | 
			
		||||
  let regions = (region SizedRegion<1>:$region);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue