[mlir] Adds getUpperBound() to LoopLikeInterface.

getUpperBound is analogous to getLowerBound(), except for the upper
bound, and is used in range analysis.

Reviewed By: Mogball

Differential Revision: https://reviews.llvm.org/D124020
This commit is contained in:
Krzysztof Drewniak 2022-03-08 18:39:52 +00:00
parent 0eb403ad1b
commit ddc2eb0ada
5 changed files with 29 additions and 4 deletions

View File

@ -109,7 +109,8 @@ def AffineApplyOp : Affine_Op<"apply", [NoSideEffect]> {
def AffineForOp : Affine_Op<"for",
[AutomaticAllocationScope, ImplicitAffineTerminator, RecursiveSideEffects,
DeclareOpInterfaceMethods<LoopLikeOpInterface,
["getSingleInductionVar", "getSingleLowerBound", "getSingleStep"]>]> {
["getSingleInductionVar", "getSingleLowerBound", "getSingleStep",
"getSingleUpperBound"]>]> {
let summary = "for operation";
let description = [{
Syntax:

View File

@ -111,7 +111,8 @@ def ExecuteRegionOp : SCF_Op<"execute_region", [
def ForOp : SCF_Op<"for",
[AutomaticAllocationScope, DeclareOpInterfaceMethods<LoopLikeOpInterface,
["getSingleInductionVar", "getSingleLowerBound", "getSingleStep"]>,
["getSingleInductionVar", "getSingleLowerBound", "getSingleStep",
"getSingleUpperBound"]>,
DeclareOpInterfaceMethods<RegionBranchOpInterface>,
SingleBlockImplicitTerminator<"scf::YieldOp">,
RecursiveSideEffects]> {

View File

@ -61,7 +61,7 @@ def LoopLikeOpInterface : OpInterface<"LoopLikeOpInterface"> {
}]
>,
InterfaceMethod<[{
Return the single lower bound value or attribute if it exist, otherwise
Return the single lower bound value or attribute if it exists, otherwise
return llvm::None.
}],
/*retTy=*/"::mlir::Optional<::mlir::OpFoldResult>",
@ -73,7 +73,7 @@ def LoopLikeOpInterface : OpInterface<"LoopLikeOpInterface"> {
}]
>,
InterfaceMethod<[{
Return the single step value or attribute if it exist, otherwise
Return the single step value or attribute if it exists, otherwise
return llvm::None.
}],
/*retTy=*/"::mlir::Optional<::mlir::OpFoldResult>",
@ -84,6 +84,18 @@ def LoopLikeOpInterface : OpInterface<"LoopLikeOpInterface"> {
return llvm::None;
}]
>,
InterfaceMethod<[{
Return the single upper bound value or attribute if it exists, otherwise
return llvm::None.
}],
/*retTy=*/"::mlir::Optional<::mlir::OpFoldResult>",
/*methodName=*/"getSingleUpperBound",
/*args=*/(ins),
/*methodBody=*/"",
/*defaultImplementation=*/[{
return llvm::None;
}]
>,
];
}

View File

@ -1873,6 +1873,13 @@ Optional<OpFoldResult> AffineForOp::getSingleStep() {
return OpFoldResult(b.getI64IntegerAttr(getStep()));
}
Optional<OpFoldResult> AffineForOp::getSingleUpperBound() {
if (!hasConstantUpperBound())
return llvm::None;
OpBuilder b(getContext());
return OpFoldResult(b.getI64IntegerAttr(getConstantUpperBound()));
}
/// Returns true if the provided value is the induction variable of a
/// AffineForOp.
bool mlir::isForInductionVar(Value val) {

View File

@ -356,6 +356,10 @@ Optional<OpFoldResult> ForOp::getSingleStep() {
return OpFoldResult(getStep());
}
Optional<OpFoldResult> ForOp::getSingleUpperBound() {
return OpFoldResult(getUpperBound());
}
/// Prints the initialization list in the form of
/// <prefix>(%inner = %outer, %inner2 = %outer2, <...>)
/// where 'inner' values are assumed to be region arguments and 'outer' values