mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-09 09:32:20 +00:00
[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,
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -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
Block a user