diff --git a/mlir/docs/Dialects/Affine.md b/mlir/docs/Dialects/Affine.md --- a/mlir/docs/Dialects/Affine.md +++ b/mlir/docs/Dialects/Affine.md @@ -62,16 +62,16 @@ 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. diff --git a/mlir/docs/Traits.md b/mlir/docs/Traits.md --- a/mlir/docs/Traits.md +++ b/mlir/docs/Traits.md @@ -135,6 +135,21 @@ * `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 @@ 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` : diff --git a/mlir/include/mlir/Dialect/Affine/IR/AffineOps.h b/mlir/include/mlir/Dialect/Affine/IR/AffineOps.h --- a/mlir/include/mlir/Dialect/Affine/IR/AffineOps.h +++ b/mlir/include/mlir/Dialect/Affine/IR/AffineOps.h @@ -32,9 +32,9 @@ 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 @@ }; /// 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, 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., diff --git a/mlir/include/mlir/Dialect/Affine/IR/AffineOps.td b/mlir/include/mlir/Dialect/Affine/IR/AffineOps.td --- a/mlir/include/mlir/Dialect/Affine/IR/AffineOps.td +++ b/mlir/include/mlir/Dialect/Affine/IR/AffineOps.td @@ -84,7 +84,7 @@ 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 @@ 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 diff --git a/mlir/include/mlir/IR/Function.h b/mlir/include/mlir/IR/Function.h --- a/mlir/include/mlir/IR/Function.h +++ b/mlir/include/mlir/IR/Function.h @@ -34,7 +34,7 @@ : public Op { public: using Op::Op; diff --git a/mlir/include/mlir/IR/Module.h b/mlir/include/mlir/IR/Module.h --- a/mlir/include/mlir/IR/Module.h +++ b/mlir/include/mlir/IR/Module.h @@ -30,7 +30,7 @@ class ModuleOp : public Op< ModuleOp, OpTrait::ZeroOperands, OpTrait::ZeroResult, - OpTrait::IsIsolatedFromAbove, OpTrait::PolyhedralScope, + OpTrait::IsIsolatedFromAbove, OpTrait::AffineScope, OpTrait::SymbolTable, OpTrait::SingleBlockImplicitTerminator::Impl, SymbolOpInterface::Trait> { diff --git a/mlir/include/mlir/IR/OpBase.td b/mlir/include/mlir/IR/OpBase.td --- a/mlir/include/mlir/IR/OpBase.td +++ b/mlir/include/mlir/IR/OpBase.td @@ -1633,6 +1633,8 @@ 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 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. diff --git a/mlir/include/mlir/IR/OpDefinition.h b/mlir/include/mlir/IR/OpDefinition.h --- a/mlir/include/mlir/IR/OpDefinition.h +++ b/mlir/include/mlir/IR/OpDefinition.h @@ -1045,9 +1045,9 @@ /// 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 -class PolyhedralScope : public TraitBase { +class AffineScope : public TraitBase { public: static LogicalResult verifyTrait(Operation *op) { static_assert(!ConcreteType::template hasTrait(), diff --git a/mlir/lib/Dialect/Affine/IR/AffineOps.cpp b/mlir/lib/Dialect/Affine/IR/AffineOps.cpp --- a/mlir/lib/Dialect/Affine/IR/AffineOps.cpp +++ b/mlir/lib/Dialect/Affine/IR/AffineOps.cpp @@ -85,19 +85,17 @@ } /// 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()) - return arg.getOwner()->getParentOp()->hasTrait(); - return value.getDefiningOp() - ->getParentOp() - ->hasTrait(); + return arg.getOwner()->getParentOp()->hasTrait(); + return value.getDefiningOp()->getParentOp()->hasTrait(); } /// 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()) @@ -106,12 +104,12 @@ } /// 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()) + if (parentOp->hasTrait()) return curOp->getParentRegion(); curOp = parentOp; } @@ -132,9 +130,9 @@ 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().getOwner()->getParentOp(); - return parentOp->hasTrait() || + return parentOp->hasTrait() || isa(parentOp) || isa(parentOp); } @@ -209,7 +207,7 @@ // 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. diff --git a/mlir/test/Dialect/Affine/ops.mlir b/mlir/test/Dialect/Affine/ops.mlir --- a/mlir/test/Dialect/Affine/ops.mlir +++ b/mlir/test/Dialect/Affine/ops.mlir @@ -115,18 +115,18 @@ // ----- -// 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) { - test.polyhedral_scope { +// CHECK-LABEL: func @valid_symbol_affine_scope +func @valid_symbol_affine_scope(%n : index, %A : memref) { + 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 @@ -142,7 +142,7 @@ // ----- -// 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"() ({ diff --git a/mlir/test/lib/Dialect/Test/TestDialect.cpp b/mlir/test/lib/Dialect/Test/TestDialect.cpp --- a/mlir/test/lib/Dialect/Test/TestDialect.cpp +++ b/mlir/test/lib/Dialect/Test/TestDialect.cpp @@ -201,18 +201,18 @@ } //===----------------------------------------------------------------------===// -// Test PolyhedralScopeOp +// Test AffineScopeOp //===----------------------------------------------------------------------===// -static ParseResult parsePolyhedralScopeOp(OpAsmParser &parser, - OperationState &result) { +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); } diff --git a/mlir/test/lib/Dialect/Test/TestOps.td b/mlir/test/lib/Dialect/Test/TestOps.td --- a/mlir/test/lib/Dialect/Test/TestOps.td +++ b/mlir/test/lib/Dialect/Test/TestOps.td @@ -1150,10 +1150,10 @@ 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);