Skip to content

Commit 7b4aa95

Browse files
committed
[flang][hlfir] Set/propagate 'unordered' attribute for elementals.
This patch adds 'unordered' attribute handling the HLFIR elementals' builders and fixes the attribute handling in lowering and transformations. Depends on D154031, D154032 Reviewed By: jeanPerier, tblah Differential Revision: https://reviews.llvm.org/D154035
1 parent 65379d4 commit 7b4aa95

25 files changed

+101
-84
lines changed

flang/include/flang/Optimizer/Builder/HLFIRTools.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,7 @@ hlfir::ElementalOp genElementalOp(mlir::Location loc,
375375
mlir::Type elementType, mlir::Value shape,
376376
mlir::ValueRange typeParams,
377377
const ElementalKernelGenerator &genKernel,
378+
bool isUnordered = false,
378379
mlir::Type exprType = mlir::Type{});
379380

380381
/// Structure to describe a loop nest.

flang/include/flang/Optimizer/HLFIR/HLFIROps.td

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -786,7 +786,9 @@ def hlfir_ElementalOp : hlfir_Op<"elemental", [RecursiveMemoryEffects, hlfir_Ele
786786
let skipDefaultBuilders = 1;
787787
let builders = [
788788
OpBuilder<(ins "mlir::Type":$result_type, "mlir::Value":$shape,
789-
CArg<"mlir::ValueRange", "{}">:$typeparams)>];
789+
CArg<"mlir::ValueRange", "{}">:$typeparams,
790+
CArg<"bool", "false">:$isUnordered)>
791+
];
790792

791793
}
792794

@@ -1216,7 +1218,7 @@ def hlfir_ElementalAddrOp : hlfir_Op<"elemental_addr", [Terminator, HasParent<"R
12161218
MaxSizedRegion<1>:$cleanup);
12171219

12181220
let builders = [
1219-
OpBuilder<(ins "mlir::Value":$shape)>
1221+
OpBuilder<(ins "mlir::Value":$shape, CArg<"bool", "false">:$isUnordered)>
12201222
];
12211223

12221224
let assemblyFormat = [{

flang/lib/Lower/Bridge.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3165,7 +3165,8 @@ class FirConverter : public Fortran::lower::AbstractConverter {
31653165
return hlfir::EntityWithAttributes{builder.createConvert(loc, toTy, val)};
31663166
};
31673167
mlir::Value convertedRhs = hlfir::genElementalOp(
3168-
loc, builder, toTy, shape, /*typeParams=*/{}, genKernel);
3168+
loc, builder, toTy, shape, /*typeParams=*/{}, genKernel,
3169+
/*isUnordered=*/true);
31693170
fir::FirOpBuilder *bldr = &builder;
31703171
stmtCtx.attachCleanup([loc, bldr, convertedRhs]() {
31713172
bldr->create<hlfir::DestroyOp>(loc, convertedRhs);

flang/lib/Lower/ConvertArrayConstructor.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,8 @@ class AsElementalStrategy : public StrategyBase {
215215
mlir::Value one =
216216
builder.createIntegerConstant(loc, builder.getIndexType(), 1);
217217
elementalOp =
218-
builder.create<hlfir::ElementalOp>(loc, exprType, shape, lengthParams);
218+
builder.create<hlfir::ElementalOp>(loc, exprType, shape, lengthParams,
219+
/*isUnordered=*/true);
219220
builder.setInsertionPointToStart(elementalOp.getBody());
220221
// implied-do-index = lower+((i-1)*stride)
221222
mlir::Value diff = builder.create<mlir::arith::SubIOp>(
@@ -686,9 +687,10 @@ static ArrayCtorLoweringStrategy selectArrayCtorLoweringStrategy(
686687
loc, builder, stmtCtx, symMap, declaredType,
687688
extent ? std::optional<mlir::Value>(extent) : std::nullopt, lengths,
688689
needToEvaluateOneExprToGetLengthParameters);
689-
// Note: array constructors containing impure ac-value expr are currently not
690-
// rewritten to hlfir.elemental because impure expressions should be evaluated
691-
// in order, and hlfir.elemental currently misses a way to indicate that.
690+
// Note: the generated hlfir.elemental is always unordered, thus,
691+
// AsElementalStrategy can only be used for array constructors without
692+
// impure ac-value expressions. If/when this changes, make sure
693+
// the 'unordered' attribute is set accordingly for the hlfir.elemental.
692694
if (analysis.isSingleImpliedDoWithOneScalarPureExpr())
693695
return AsElementalStrategy(loc, builder, stmtCtx, symMap, declaredType,
694696
extent, lengths);

flang/lib/Lower/ConvertCall.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1612,8 +1612,6 @@ class ElementalCallBuilder {
16121612
return std::nullopt;
16131613
}
16141614
// Function case: generate call inside hlfir.elemental
1615-
if (mustBeOrdered)
1616-
TODO(loc, "ordered elemental calls in HLFIR");
16171615
mlir::Type elementType =
16181616
hlfir::getFortranElementType(*callContext.resultType);
16191617
// Get result length parameters.
@@ -1645,8 +1643,9 @@ class ElementalCallBuilder {
16451643
// use.
16461644
return res;
16471645
};
1648-
mlir::Value elemental = hlfir::genElementalOp(loc, builder, elementType,
1649-
shape, typeParams, genKernel);
1646+
mlir::Value elemental =
1647+
hlfir::genElementalOp(loc, builder, elementType, shape, typeParams,
1648+
genKernel, !mustBeOrdered);
16501649
fir::FirOpBuilder *bldr = &builder;
16511650
callContext.stmtCtx.attachCleanup(
16521651
[=]() { bldr->create<hlfir::DestroyOp>(loc, elemental); });

flang/lib/Lower/ConvertExprToHLFIR.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -783,7 +783,9 @@ class HlfirDesignatorBuilder {
783783
// of the whole designator (not the ones of the vector subscripted part).
784784
// These are not yet known and will be added when finalizing the designator
785785
// lowering.
786-
auto elementalAddrOp = builder.create<hlfir::ElementalAddrOp>(loc, shape);
786+
auto elementalAddrOp =
787+
builder.create<hlfir::ElementalAddrOp>(loc, shape,
788+
/*isUnordered=*/true);
787789
setVectorSubscriptElementAddrOp(elementalAddrOp);
788790
builder.setInsertionPointToEnd(&elementalAddrOp.getBody().front());
789791
mlir::Region::BlockArgListType indices = elementalAddrOp.getIndices();
@@ -1512,7 +1514,8 @@ class HlfirBuilder {
15121514
return unaryOp.gen(l, b, op.derived(), leftVal);
15131515
};
15141516
mlir::Value elemental = hlfir::genElementalOp(loc, builder, elementType,
1515-
shape, typeParams, genKernel);
1517+
shape, typeParams, genKernel,
1518+
/*isUnordered=*/true);
15161519
fir::FirOpBuilder *bldr = &builder;
15171520
getStmtCtx().attachCleanup(
15181521
[=]() { bldr->create<hlfir::DestroyOp>(loc, elemental); });
@@ -1557,7 +1560,8 @@ class HlfirBuilder {
15571560
return binaryOp.gen(l, b, op.derived(), leftVal, rightVal);
15581561
};
15591562
mlir::Value elemental = hlfir::genElementalOp(loc, builder, elementType,
1560-
shape, typeParams, genKernel);
1563+
shape, typeParams, genKernel,
1564+
/*isUnordered=*/true);
15611565
fir::FirOpBuilder *bldr = &builder;
15621566
getStmtCtx().attachCleanup(
15631567
[=]() { bldr->create<hlfir::DestroyOp>(loc, elemental); });

flang/lib/Optimizer/Builder/HLFIRTools.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -732,14 +732,16 @@ static hlfir::ExprType getArrayExprType(mlir::Type elementType,
732732
isPolymorphic);
733733
}
734734

735-
hlfir::ElementalOp hlfir::genElementalOp(
736-
mlir::Location loc, fir::FirOpBuilder &builder, mlir::Type elementType,
737-
mlir::Value shape, mlir::ValueRange typeParams,
738-
const ElementalKernelGenerator &genKernel, mlir::Type exprType) {
735+
hlfir::ElementalOp
736+
hlfir::genElementalOp(mlir::Location loc, fir::FirOpBuilder &builder,
737+
mlir::Type elementType, mlir::Value shape,
738+
mlir::ValueRange typeParams,
739+
const ElementalKernelGenerator &genKernel,
740+
bool isUnordered, mlir::Type exprType) {
739741
if (!exprType)
740742
exprType = getArrayExprType(elementType, shape, false);
741-
auto elementalOp =
742-
builder.create<hlfir::ElementalOp>(loc, exprType, shape, typeParams);
743+
auto elementalOp = builder.create<hlfir::ElementalOp>(
744+
loc, exprType, shape, typeParams, isUnordered);
743745
auto insertPt = builder.saveInsertionPoint();
744746
builder.setInsertionPointToStart(elementalOp.getBody());
745747
mlir::Value elementResult = genKernel(loc, builder, elementalOp.getIndices());
@@ -1013,5 +1015,5 @@ hlfir::cloneToElementalOp(mlir::Location loc, fir::FirOpBuilder &builder,
10131015
mlir::Type elementType = scalarAddress.getFortranElementType();
10141016
return hlfir::genElementalOp(loc, builder, elementType,
10151017
elementalAddrOp.getShape(), typeParams,
1016-
genKernel);
1018+
genKernel, !elementalAddrOp.isOrdered());
10171019
}

flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1029,10 +1029,13 @@ void hlfir::AsExprOp::build(mlir::OpBuilder &builder,
10291029
void hlfir::ElementalOp::build(mlir::OpBuilder &builder,
10301030
mlir::OperationState &odsState,
10311031
mlir::Type resultType, mlir::Value shape,
1032-
mlir::ValueRange typeparams) {
1032+
mlir::ValueRange typeparams, bool isUnordered) {
10331033
odsState.addOperands(shape);
10341034
odsState.addOperands(typeparams);
10351035
odsState.addTypes(resultType);
1036+
if (isUnordered)
1037+
odsState.addAttribute(getUnorderedAttrName(odsState.name),
1038+
isUnordered ? builder.getUnitAttr() : nullptr);
10361039
mlir::Region *bodyRegion = odsState.addRegion();
10371040
bodyRegion->push_back(new mlir::Block{});
10381041
if (auto exprType = resultType.dyn_cast<hlfir::ExprType>()) {
@@ -1264,8 +1267,11 @@ static void printYieldOpCleanup(mlir::OpAsmPrinter &p, YieldOp yieldOp,
12641267

12651268
void hlfir::ElementalAddrOp::build(mlir::OpBuilder &builder,
12661269
mlir::OperationState &odsState,
1267-
mlir::Value shape) {
1270+
mlir::Value shape, bool isUnordered) {
12681271
odsState.addOperands(shape);
1272+
if (isUnordered)
1273+
odsState.addAttribute(getUnorderedAttrName(odsState.name),
1274+
isUnordered ? builder.getUnitAttr() : nullptr);
12691275
mlir::Region *bodyRegion = odsState.addRegion();
12701276
bodyRegion->push_back(new mlir::Block{});
12711277
if (auto shapeType = shape.getType().dyn_cast<fir::ShapeType>()) {

flang/lib/Optimizer/HLFIR/Transforms/SimplifyHLFIRIntrinsics.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ class TransposeAsElementalConversion
6060
};
6161
hlfir::ElementalOp elementalOp = hlfir::genElementalOp(
6262
loc, builder, elementType, resultShape, typeParams, genKernel,
63-
transpose.getResult().getType());
63+
/*isUnordered=*/true, transpose.getResult().getType());
6464

6565
// it wouldn't be safe to replace block arguments with a different
6666
// hlfir.expr type. Types can differ due to differing amounts of shape

flang/test/HLFIR/simplify-hlfir-intrinsics.fir

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ func.func @transpose0(%arg0: !fir.box<!fir.array<1x2xi32>>) {
1010
// CHECK: %[[C1:.*]] = arith.constant 1 : index
1111
// CHECK: %[[C2:.*]] = arith.constant 2 : index
1212
// CHECK: %[[SHAPE:.*]] = fir.shape %[[C2]], %[[C1]] : (index, index) -> !fir.shape<2>
13-
// CHECK: %[[EXPR:.*]] = hlfir.elemental %[[SHAPE]] : (!fir.shape<2>) -> !hlfir.expr<2x1xi32> {
13+
// CHECK: %[[EXPR:.*]] = hlfir.elemental %[[SHAPE]] unordered : (!fir.shape<2>) -> !hlfir.expr<2x1xi32> {
1414
// CHECK: ^bb0(%[[I:.*]]: index, %[[J:.*]]: index):
1515
// CHECK: %[[C0:.*]] = arith.constant 0 : index
1616
// CHECK: %[[DIMS0:.*]]:3 = fir.box_dims %[[ARG0]], %[[C0]] : (!fir.box<!fir.array<1x2xi32>>, index) -> (index, index, index)
@@ -38,7 +38,7 @@ func.func @transpose1(%arg0: !hlfir.expr<1x2xi32>) {
3838
// CHECK: %[[C1:.*]] = arith.constant 1 : index
3939
// CHECK: %[[C2:.*]] = arith.constant 2 : index
4040
// CHECK: %[[SHAPE:.*]] = fir.shape %[[C2]], %[[C1]] : (index, index) -> !fir.shape<2>
41-
// CHECK: %[[EXPR:.*]] = hlfir.elemental %[[SHAPE]] : (!fir.shape<2>) -> !hlfir.expr<2x1xi32> {
41+
// CHECK: %[[EXPR:.*]] = hlfir.elemental %[[SHAPE]] unordered : (!fir.shape<2>) -> !hlfir.expr<2x1xi32> {
4242
// CHECK: ^bb0(%[[I:.*]]: index, %[[J:.*]]: index):
4343
// CHECK: %[[ELEMENT:.*]] = hlfir.apply %[[ARG0]], %[[J]], %[[I]] : (!hlfir.expr<1x2xi32>, index, index) -> i32
4444
// CHECK: hlfir.yield_element %[[ELEMENT]] : i32
@@ -57,7 +57,7 @@ func.func @transpose2(%arg0: !fir.box<!fir.array<?x2xi32>>) {
5757
// CHECK: %[[DIMS0:.*]]:3 = fir.box_dims %[[ARG0]], %[[C0]] : (!fir.box<!fir.array<?x2xi32>>, index) -> (index, index, index)
5858
// CHECK: %[[C2:.*]] = arith.constant 2 : index
5959
// CHECK: %[[SHAPE:.*]] = fir.shape %[[C2]], %[[DIMS0]]#1 : (index, index) -> !fir.shape<2>
60-
// CHECK: %[[EXPR:.*]] = hlfir.elemental %[[SHAPE]] : (!fir.shape<2>) -> !hlfir.expr<2x?xi32> {
60+
// CHECK: %[[EXPR:.*]] = hlfir.elemental %[[SHAPE]] unordered : (!fir.shape<2>) -> !hlfir.expr<2x?xi32> {
6161
// CHECK: ^bb0(%[[I:.*]]: index, %[[J:.*]]: index):
6262
// CHECK: %[[C0_1:.*]] = arith.constant 0 : index
6363
// CHECK: %[[DIMS0:.*]]:3 = fir.box_dims %[[ARG0]], %[[C0_1]] : (!fir.box<!fir.array<?x2xi32>>, index) -> (index, index, index)
@@ -86,7 +86,7 @@ func.func @transpose3(%arg0: !hlfir.expr<?x2xi32>) {
8686
// CHECK: %[[EXTENT0:.*]] = hlfir.get_extent %[[IN_SHAPE]] {dim = 0 : index} : (!fir.shape<2>) -> index
8787
// CHECK: %[[C2:.*]] = arith.constant 2 : index
8888
// CHECK: %[[OUT_SHAPE:.*]] = fir.shape %[[C2]], %[[EXTENT0]] : (index, index) -> !fir.shape<2>
89-
// CHECK: %[[EXPR:.*]] = hlfir.elemental %[[OUT_SHAPE]] : (!fir.shape<2>) -> !hlfir.expr<2x?xi32> {
89+
// CHECK: %[[EXPR:.*]] = hlfir.elemental %[[OUT_SHAPE]] unordered : (!fir.shape<2>) -> !hlfir.expr<2x?xi32> {
9090
// CHECK: ^bb0(%[[I:.*]]: index, %[[J:.*]]: index):
9191
// CHECK: %[[ELEMENT:.*]] = hlfir.apply %[[ARG0]], %[[J]], %[[I]] : (!hlfir.expr<?x2xi32>, index, index) -> i32
9292
// CHECK: hlfir.yield_element %[[ELEMENT]] : i32
@@ -113,7 +113,7 @@ func.func @transpose4(%arg0: !hlfir.expr<2x2xf32>, %arg1: !fir.ref<!fir.box<!fir
113113
// CHECK-SAME: %[[ARG0:.*]]: !hlfir.expr<2x2xf32>
114114
// CHECK-SAME: %[[ARG1:.*]]:
115115
// CHECK: %[[SHAPE0:.*]] = fir.shape
116-
// CHECK: %[[TRANSPOSE:.*]] = hlfir.elemental %[[SHAPE0]] : (!fir.shape<2>) -> !hlfir.expr<2x2xf32> {
116+
// CHECK: %[[TRANSPOSE:.*]] = hlfir.elemental %[[SHAPE0]] unordered : (!fir.shape<2>) -> !hlfir.expr<2x2xf32> {
117117
// CHECK: ^bb0(%[[I:.*]]: index, %[[J:.*]]: index):
118118
// CHECK: %[[ELE:.*]] = hlfir.apply %[[ARG0]], %[[J]], %[[I]] : (!hlfir.expr<2x2xf32>, index, index) -> f32
119119
// CHECK: hlfir.yield_element %[[ELE]] : f32

0 commit comments

Comments
 (0)