Rename op trait PolyhedralScope -> AffineScope for consistency.
Differential Revision: https://reviews.llvm.org/D79503
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.
* `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`
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>` :
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
};
/// 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`,
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.,
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
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
: 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;
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> {
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.
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.
/// 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>(),
}
/// 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>())
}
/// 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;
}
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);
}
// 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.
// -----
-// 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>
// -----
-// 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"() ({
}
//===----------------------------------------------------------------------===//
-// 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);
}
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);