forked from OSchip/llvm-project
[MLIR] Add support for empty IVs to affine.parallel
Allow support for specifying empty IVs in an `affine.parallel`. For example: ``` affine.parallel () = () to () { affine.yield } ``` Reviewed By: bondhugula, jbruestle Differential Revision: https://reviews.llvm.org/D102895
This commit is contained in:
parent
002f5e158d
commit
b5c3f17e70
|
@ -601,14 +601,14 @@ def AffineParallelOp : Affine_Op<"parallel",
|
|||
let summary = "multi-index parallel band operation";
|
||||
let description = [{
|
||||
The "affine.parallel" operation represents a hyper-rectangular affine
|
||||
parallel band, defining multiple SSA values for its induction variables. It
|
||||
has one region capturing the parallel band body. The induction variables are
|
||||
represented as arguments of this region. These SSA values always have type
|
||||
index, which is the size of the machine word. The strides, represented by
|
||||
steps, are positive constant integers which defaults to "1" if not present.
|
||||
The lower and upper bounds specify a half-open range: the range includes the
|
||||
lower bound but does not include the upper bound. The body region must
|
||||
contain exactly one block that terminates with "affine.yield".
|
||||
parallel band, defining zero or more SSA values for its induction variables.
|
||||
It has one region capturing the parallel band body. The induction variables
|
||||
are represented as arguments of this region. These SSA values always have
|
||||
type index, which is the size of the machine word. The strides, represented
|
||||
by steps, are positive constant integers which defaults to "1" if not
|
||||
present. The lower and upper bounds specify a half-open range: the range
|
||||
includes the lower bound but does not include the upper bound. The body
|
||||
region must contain exactly one block that terminates with "affine.yield".
|
||||
|
||||
The lower and upper bounds of a parallel operation are represented as an
|
||||
application of an affine mapping to a list of SSA values passed to the map.
|
||||
|
|
|
@ -2641,8 +2641,6 @@ void AffineParallelOp::build(OpBuilder &builder, OperationState &result,
|
|||
ArrayRef<AffineMap> lbMaps, ValueRange lbArgs,
|
||||
ArrayRef<AffineMap> ubMaps, ValueRange ubArgs,
|
||||
ArrayRef<int64_t> steps) {
|
||||
assert(!lbMaps.empty() && "expected the lower bound map to be non-empty");
|
||||
assert(!ubMaps.empty() && "expected the upper bound map to be non-empty");
|
||||
assert(llvm::all_of(lbMaps,
|
||||
[lbMaps](AffineMap m) {
|
||||
return m.getNumDims() == lbMaps[0].getNumDims() &&
|
||||
|
@ -2657,12 +2655,14 @@ void AffineParallelOp::build(OpBuilder &builder, OperationState &result,
|
|||
}) &&
|
||||
"expected all upper bounds maps to have the same number of dimensions "
|
||||
"and symbols");
|
||||
assert(lbMaps[0].getNumInputs() == lbArgs.size() &&
|
||||
"expected lower bound maps to have as many inputs as lower bound "
|
||||
"operands");
|
||||
assert(ubMaps[0].getNumInputs() == ubArgs.size() &&
|
||||
"expected upper bound maps to have as many inputs as upper bound "
|
||||
"operands");
|
||||
assert(lbMaps.empty() ||
|
||||
lbMaps[0].getNumInputs() == lbArgs.size() &&
|
||||
"expected lower bound maps to have as many inputs as lower bound "
|
||||
"operands");
|
||||
assert(ubMaps.empty() ||
|
||||
ubMaps[0].getNumInputs() == ubArgs.size() &&
|
||||
"expected upper bound maps to have as many inputs as upper bound "
|
||||
"operands");
|
||||
|
||||
result.addTypes(resultTypes);
|
||||
|
||||
|
@ -2676,8 +2676,10 @@ void AffineParallelOp::build(OpBuilder &builder, OperationState &result,
|
|||
|
||||
// Concatenates maps defined in the same input space (same dimensions and
|
||||
// symbols), assumes there is at least one map.
|
||||
auto concatMapsSameInput = [](ArrayRef<AffineMap> maps,
|
||||
SmallVectorImpl<int32_t> &groups) {
|
||||
auto concatMapsSameInput = [&builder](ArrayRef<AffineMap> maps,
|
||||
SmallVectorImpl<int32_t> &groups) {
|
||||
if (maps.empty())
|
||||
return AffineMap::get(builder.getContext());
|
||||
SmallVector<AffineExpr> exprs;
|
||||
groups.reserve(groups.size() + maps.size());
|
||||
exprs.reserve(maps.size());
|
||||
|
@ -2685,7 +2687,6 @@ void AffineParallelOp::build(OpBuilder &builder, OperationState &result,
|
|||
llvm::append_range(exprs, m.getResults());
|
||||
groups.push_back(m.getNumResults());
|
||||
}
|
||||
assert(!maps.empty() && "expected a non-empty list of maps");
|
||||
return AffineMap::get(maps[0].getNumDims(), maps[0].getNumSymbols(), exprs,
|
||||
maps[0].getContext());
|
||||
};
|
||||
|
@ -2696,10 +2697,10 @@ void AffineParallelOp::build(OpBuilder &builder, OperationState &result,
|
|||
AffineMap ubMap = concatMapsSameInput(ubMaps, ubGroups);
|
||||
result.addAttribute(getLowerBoundsMapAttrName(), AffineMapAttr::get(lbMap));
|
||||
result.addAttribute(getLowerBoundsGroupsAttrName(),
|
||||
builder.getI32VectorAttr(lbGroups));
|
||||
builder.getI32TensorAttr(lbGroups));
|
||||
result.addAttribute(getUpperBoundsMapAttrName(), AffineMapAttr::get(ubMap));
|
||||
result.addAttribute(getUpperBoundsGroupsAttrName(),
|
||||
builder.getI32VectorAttr(ubGroups));
|
||||
builder.getI32TensorAttr(ubGroups));
|
||||
result.addAttribute(getStepsAttrName(), builder.getI64ArrayAttr(steps));
|
||||
result.addOperands(lbArgs);
|
||||
result.addOperands(ubArgs);
|
||||
|
@ -2790,7 +2791,6 @@ OpBuilder AffineParallelOp::getBodyBuilder() {
|
|||
void AffineParallelOp::setLowerBounds(ValueRange lbOperands, AffineMap map) {
|
||||
assert(lbOperands.size() == map.getNumInputs() &&
|
||||
"operands to map must match number of inputs");
|
||||
assert(map.getNumResults() >= 1 && "bounds map has at least one result");
|
||||
|
||||
auto ubOperands = getUpperBoundsOperands();
|
||||
|
||||
|
@ -2804,7 +2804,6 @@ void AffineParallelOp::setLowerBounds(ValueRange lbOperands, AffineMap map) {
|
|||
void AffineParallelOp::setUpperBounds(ValueRange ubOperands, AffineMap map) {
|
||||
assert(ubOperands.size() == map.getNumInputs() &&
|
||||
"operands to map must match number of inputs");
|
||||
assert(map.getNumResults() >= 1 && "bounds map has at least one result");
|
||||
|
||||
SmallVector<Value, 4> newOperands(getLowerBoundsOperands());
|
||||
newOperands.append(ubOperands.begin(), ubOperands.end());
|
||||
|
@ -3062,7 +3061,7 @@ static ParseResult parseAffineMapWithMinMax(OpAsmParser &parser,
|
|||
if (succeeded(parser.parseOptionalRParen())) {
|
||||
result.addAttribute(
|
||||
mapName, AffineMapAttr::get(parser.getBuilder().getEmptyAffineMap()));
|
||||
result.addAttribute(groupsName, parser.getBuilder().getI32VectorAttr({}));
|
||||
result.addAttribute(groupsName, parser.getBuilder().getI32TensorAttr({}));
|
||||
return success();
|
||||
}
|
||||
|
||||
|
@ -3134,7 +3133,7 @@ static ParseResult parseAffineMapWithMinMax(OpAsmParser &parser,
|
|||
dimRplacements, symRepacements, dimOperands.size(), symOperands.size());
|
||||
|
||||
result.addAttribute(mapName, AffineMapAttr::get(flatMap));
|
||||
result.addAttribute(groupsName, builder.getI32VectorAttr(numMapsPerGroup));
|
||||
result.addAttribute(groupsName, builder.getI32TensorAttr(numMapsPerGroup));
|
||||
return success();
|
||||
}
|
||||
|
||||
|
|
|
@ -184,6 +184,17 @@ func @parallel_min_max(%a: index, %b: index, %c: index, %d: index) {
|
|||
|
||||
// -----
|
||||
|
||||
// CHECK-LABEL: @parallel_no_ivs
|
||||
func @parallel_no_ivs() {
|
||||
// CHECK: affine.parallel () = () to ()
|
||||
affine.parallel () = () to () {
|
||||
affine.yield
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// -----
|
||||
|
||||
// CHECK-LABEL: func @affine_if
|
||||
func @affine_if() -> f32 {
|
||||
// CHECK: %[[ZERO:.*]] = constant {{.*}} : f32
|
||||
|
|
Loading…
Reference in New Issue