Skip to content

Commit 63f66ae

Browse files
committed
Support arrays behind a pointer, add metadata to disable vectorizing
1 parent 6a9d0fd commit 63f66ae

File tree

4 files changed

+55
-38
lines changed

4 files changed

+55
-38
lines changed

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -374,12 +374,14 @@ struct LoopNest {
374374
/// loop constructs currently.
375375
LoopNest genLoopNest(mlir::Location loc, fir::FirOpBuilder &builder,
376376
mlir::ValueRange extents, bool isUnordered = false,
377-
bool emitWorkshareLoop = false);
377+
bool emitWorkshareLoop = false,
378+
bool couldVectorize = true);
378379
inline LoopNest genLoopNest(mlir::Location loc, fir::FirOpBuilder &builder,
379380
mlir::Value shape, bool isUnordered = false,
380-
bool emitWorkshareLoop = false) {
381+
bool emitWorkshareLoop = false,
382+
bool couldVectorize = true) {
381383
return genLoopNest(loc, builder, getIndexExtents(loc, builder, shape),
382-
isUnordered, emitWorkshareLoop);
384+
isUnordered, emitWorkshareLoop, couldVectorize);
383385
}
384386

385387
/// The type of a callback that generates the body of a reduction

flang/lib/Optimizer/Builder/HLFIRTools.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "mlir/IR/IRMapping.h"
2222
#include "mlir/Support/LLVM.h"
2323
#include "llvm/ADT/TypeSwitch.h"
24+
#include <mlir/Dialect/LLVMIR/LLVMAttrs.h>
2425
#include <mlir/Dialect/OpenMP/OpenMPDialect.h>
2526
#include <optional>
2627

@@ -932,7 +933,8 @@ mlir::Value hlfir::inlineElementalOp(
932933
hlfir::LoopNest hlfir::genLoopNest(mlir::Location loc,
933934
fir::FirOpBuilder &builder,
934935
mlir::ValueRange extents, bool isUnordered,
935-
bool emitWorkshareLoop) {
936+
bool emitWorkshareLoop,
937+
bool couldVectorize) {
936938
emitWorkshareLoop = emitWorkshareLoop && isUnordered;
937939
hlfir::LoopNest loopNest;
938940
assert(!extents.empty() && "must have at least one extent");
@@ -967,6 +969,15 @@ hlfir::LoopNest hlfir::genLoopNest(mlir::Location loc,
967969
auto ub = builder.createConvert(loc, indexType, extent);
968970
auto doLoop =
969971
builder.create<fir::DoLoopOp>(loc, one, ub, one, isUnordered);
972+
if (!couldVectorize) {
973+
mlir::LLVM::LoopVectorizeAttr va{mlir::LLVM::LoopVectorizeAttr::get(
974+
builder.getContext(),
975+
/*disable=*/builder.getBoolAttr(true), {}, {}, {}, {}, {}, {})};
976+
mlir::LLVM::LoopAnnotationAttr la = mlir::LLVM::LoopAnnotationAttr::get(
977+
builder.getContext(), {}, /*vectorize=*/va, {}, /*unroll*/ {},
978+
/*unroll_and_jam*/ {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {});
979+
doLoop.setLoopAnnotationAttr(la);
980+
}
970981
loopNest.body = doLoop.getBody();
971982
builder.setInsertionPointToStart(loopNest.body);
972983
// Reverse the indices so they are in column-major order.

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

Lines changed: 35 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -52,19 +52,15 @@ InlineCopyInConversion::matchAndRewrite(hlfir::CopyInOp copyIn,
5252
return rewriter.notifyMatchFailure(copyIn,
5353
"CopyInOp's data type is not trivial");
5454

55-
if (fir::isPointerType(inputVariable.getType()))
56-
return rewriter.notifyMatchFailure(
57-
copyIn, "CopyInOp's input variable is a pointer");
58-
5955
// There should be exactly one user of WasCopied - the corresponding
6056
// CopyOutOp.
61-
if (copyIn.getWasCopied().getUses().empty())
62-
return rewriter.notifyMatchFailure(copyIn,
63-
"CopyInOp's WasCopied has no uses");
57+
if (!copyIn.getWasCopied().hasOneUse())
58+
return rewriter.notifyMatchFailure(
59+
copyIn, "CopyInOp's WasCopied has no single user");
6460
// The copy out should always be present, either to actually copy or just
6561
// deallocate memory.
6662
auto copyOut = mlir::dyn_cast<hlfir::CopyOutOp>(
67-
copyIn.getWasCopied().getUsers().begin().getCurrent().getUser());
63+
copyIn.getWasCopied().user_begin().getCurrent().getUser());
6864

6965
if (!copyOut)
7066
return rewriter.notifyMatchFailure(copyIn,
@@ -77,28 +73,45 @@ InlineCopyInConversion::matchAndRewrite(hlfir::CopyInOp copyIn,
7773

7874
inputVariable =
7975
hlfir::derefPointersAndAllocatables(loc, builder, inputVariable);
80-
mlir::Type resultAddrType = copyIn.getCopiedIn().getType();
76+
mlir::Type sequenceType =
77+
hlfir::getFortranElementOrSequenceType(inputVariable.getType());
78+
fir::BoxType resultBoxType = fir::BoxType::get(sequenceType);
8179
mlir::Value isContiguous =
8280
builder.create<fir::IsContiguousBoxOp>(loc, inputVariable);
8381
mlir::Operation::result_range results =
8482
builder
85-
.genIfOp(loc, {resultAddrType, builder.getI1Type()}, isContiguous,
83+
.genIfOp(loc, {resultBoxType, builder.getI1Type()}, isContiguous,
8684
/*withElseRegion=*/true)
8785
.genThen([&]() {
88-
mlir::Value falseVal = builder.create<mlir::arith::ConstantOp>(
89-
loc, builder.getI1Type(), builder.getBoolAttr(false));
86+
mlir::Value result = inputVariable;
87+
if (fir::isPointerType(inputVariable.getType())) {
88+
auto boxAddr = builder.create<fir::BoxAddrOp>(loc, inputVariable);
89+
fir::ReferenceType refTy = fir::ReferenceType::get(sequenceType);
90+
mlir::Value refVal = builder.createConvert(loc, refTy, boxAddr);
91+
mlir::Value shape = hlfir::genShape(loc, builder, inputVariable);
92+
result = builder.create<fir::EmboxOp>(loc, resultBoxType, refVal,
93+
shape);
94+
}
9095
builder.create<fir::ResultOp>(
91-
loc, mlir::ValueRange{inputVariable, falseVal});
96+
loc, mlir::ValueRange{result, builder.createBool(loc, false)});
9297
})
9398
.genElse([&] {
94-
auto [temp, cleanup] =
95-
hlfir::createTempFromMold(loc, builder, inputVariable);
9699
mlir::Value shape = hlfir::genShape(loc, builder, inputVariable);
97100
llvm::SmallVector<mlir::Value> extents =
98101
hlfir::getIndexExtents(loc, builder, shape);
99-
hlfir::LoopNest loopNest = hlfir::genLoopNest(
100-
loc, builder, extents, /*isUnordered=*/true,
101-
flangomp::shouldUseWorkshareLowering(copyIn));
102+
llvm::StringRef tmpName{".tmp.copy_in"};
103+
llvm::SmallVector<mlir::Value> lenParams;
104+
mlir::Value alloc = builder.createHeapTemporary(
105+
loc, sequenceType, tmpName, extents, lenParams);
106+
107+
auto declareOp = builder.create<hlfir::DeclareOp>(
108+
loc, alloc, tmpName, shape, lenParams,
109+
/*dummy_scope=*/nullptr);
110+
hlfir::Entity temp{declareOp.getBase()};
111+
hlfir::LoopNest loopNest =
112+
hlfir::genLoopNest(loc, builder, extents, /*isUnordered=*/true,
113+
flangomp::shouldUseWorkshareLowering(copyIn),
114+
/*couldVectorize=*/false);
102115
builder.setInsertionPointToStart(loopNest.body);
103116
hlfir::Entity elem = hlfir::getElementAt(
104117
loc, builder, inputVariable, loopNest.oneBasedIndices);
@@ -117,12 +130,12 @@ InlineCopyInConversion::matchAndRewrite(hlfir::CopyInOp copyIn,
117130
fir::ReferenceType refTy =
118131
fir::ReferenceType::get(temp.getElementOrSequenceType());
119132
mlir::Value refVal = builder.createConvert(loc, refTy, temp);
120-
result =
121-
builder.create<fir::EmboxOp>(loc, resultAddrType, refVal);
133+
result = builder.create<fir::EmboxOp>(loc, resultBoxType, refVal,
134+
shape);
122135
}
123136

124-
builder.create<fir::ResultOp>(loc,
125-
mlir::ValueRange{result, cleanup});
137+
builder.create<fir::ResultOp>(
138+
loc, mlir::ValueRange{result, builder.createBool(loc, true)});
126139
})
127140
.getResults();
128141

@@ -140,16 +153,7 @@ InlineCopyInConversion::matchAndRewrite(hlfir::CopyInOp copyIn,
140153
});
141154
rewriter.eraseOp(copyOut);
142155

143-
mlir::Value tempBox = copyIn.getTempBox();
144-
145156
rewriter.replaceOp(copyIn, {addr, builder.genNot(loc, isContiguous)});
146-
147-
// The TempBox is only needed for flang-rt calls which we're no longer
148-
// generating. It should have no uses left at this stage.
149-
if (!tempBox.getUses().empty())
150-
return mlir::failure();
151-
rewriter.eraseOp(tempBox.getDefiningOp());
152-
153157
return mlir::success();
154158
}
155159

flang/test/HLFIR/inline-hlfir-copy-in.fir

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,9 @@ func.func private @_test_inline_copy_in(%arg0: !fir.box<!fir.array<?x?x?xf64>> {
6060
// CHECK: %[[VAL_21:.*]]:2 = fir.if %[[VAL_20:.*]] -> (!fir.box<!fir.array<?xf64>>, i1) {
6161
// CHECK: fir.result %[[VAL_19:.*]], %[[VAL_4:.*]] : !fir.box<!fir.array<?xf64>>, i1
6262
// CHECK: } else {
63-
// CHECK: %[[VAL_24:.*]] = fir.allocmem !fir.array<?xf64>, %[[VAL_15:.*]] {bindc_name = ".tmp", uniq_name = ""}
64-
// CHECK: %[[VAL_25:.*]]:2 = hlfir.declare %[[VAL_24:.*]](%[[VAL_18:.*]]) {uniq_name = ".tmp"} : (!fir.heap<!fir.array<?xf64>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xf64>>, !fir.heap<!fir.array<?xf64>>)
65-
// CHECK: fir.do_loop %arg3 = %[[VAL_7:.*]] to %[[VAL_15:.*]] step %[[VAL_7:.*]] unordered {
63+
// CHECK: %[[VAL_24:.*]] = fir.allocmem !fir.array<?xf64>, %[[VAL_15:.*]] {bindc_name = ".tmp.copy_in", uniq_name = ""}
64+
// CHECK: %[[VAL_25:.*]]:2 = hlfir.declare %[[VAL_24:.*]](%[[VAL_18:.*]]) {uniq_name = ".tmp.copy_in"} : (!fir.heap<!fir.array<?xf64>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xf64>>, !fir.heap<!fir.array<?xf64>>)
65+
// CHECK: fir.do_loop %arg3 = %[[VAL_7:.*]] to %[[VAL_15:.*]] step %[[VAL_7:.*]] unordered attributes {loopAnnotation = #loop_annotation} {
6666
// CHECK: %[[VAL_26:.*]] = hlfir.designate %[[VAL_19:.*]] (%arg3) : (!fir.box<!fir.array<?xf64>>, index) -> !fir.ref<f64>
6767
// CHECK: %[[VAL_27:.*]] = fir.load %[[VAL_26:.*]] : !fir.ref<f64>
6868
// CHECK: %[[VAL_28:.*]] = hlfir.designate %[[VAL_25:.*]]#0 (%arg3) : (!fir.box<!fir.array<?xf64>>, index) -> !fir.ref<f64>

0 commit comments

Comments
 (0)