[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:
Uday Bondhugula 2020-05-06 12:32:06 +05:30
parent 237d0e3c04
commit 57d361bd2f
12 changed files with 57 additions and 60 deletions

View File

@ -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.

View File

@ -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>` :

View File

@ -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.,

View File

@ -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

View File

@ -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;

View File

@ -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> {

View File

@ -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.

View File

@ -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>(),

View File

@ -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.

View File

@ -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"() ({

View File

@ -201,18 +201,18 @@ static void print(OpAsmPrinter &p, IsolatedRegionOp op) {
}
//===----------------------------------------------------------------------===//
// 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);
}

View File

@ -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);