[PATCH] D111337: [fir] Add array value copy pass
Mehdi AMINI via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Tue Nov 23 21:59:14 PST 2021
mehdi_amini added a comment.
Looks fine overall, thanks!
There are still a few minor issues: dead code in particular, but also the code documentation is a bit on the light side for something that really does not seem trivial to me.
(+ some inline comments)
================
Comment at: flang/include/flang/Optimizer/Builder/FIRBuilder.h:66
+ /// value to have the proper semantics and be strongly typed.
+ mlir::Value convertWithSemantics(mlir::Location loc, mlir::Type toTy,
+ mlir::Value val);
----------------
Seems unused in this patch?
================
Comment at: flang/include/flang/Optimizer/Builder/FIRBuilder.h:350
+ mlir::Type type);
+
private:
----------------
Unused in this patch?
================
Comment at: flang/include/flang/Optimizer/Builder/FIRBuilder.h:423
+ mlir::Location loc,
+ mlir::Value component);
+
----------------
This is unused in this patch?
================
Comment at: flang/include/flang/Optimizer/Builder/FIRBuilder.h:434
+ const fir::ExtendedValue &array,
+ mlir::Value element);
+
----------------
Same
================
Comment at: flang/include/flang/Optimizer/Builder/FIRBuilder.h:443
+
+mlir::TupleType getRaggedArrayHeaderType(fir::FirOpBuilder &builder);
+
----------------
Unused as well (and undocumented)
================
Comment at: flang/include/flang/Optimizer/Builder/Runtime/RTBuilder.h:359
+ AsSequence(X)>
+#define mkRTKey(X) mkKey(RTNAME(X))
+
----------------
Can you document all this macro system?
Does it need to in header? In general macros defined in header is "dangerous", should these be prefixed with Fir or something?
================
Comment at: flang/include/flang/Optimizer/Builder/Runtime/RTBuilder.h:363
+/// argument is intended to be of the form: <mkRTKey(runtime function name)>
+/// Clients should add "using namespace Fortran::runtime"
+/// in order to use this function.
----------------
You could add this in the function body if this is really needed, or what do I misse?
================
Comment at: flang/include/flang/Optimizer/Transforms/Factory.h:44
+void genCharacterCopy(mlir::Value src, mlir::Value srcLen, mlir::Value dst,
+ mlir::Value dstLen, B &builder, mlir::Location loc) {
+ auto srcTy =
----------------
This method isn't used anywhere either
================
Comment at: flang/include/flang/Optimizer/Transforms/Factory.h:147
+/// `std::vector<mlir::Value>` to avoid copies.
+inline std::vector<mlir::Value> getExtents(mlir::Value shapeVal) {
+ if (shapeVal)
----------------
I don't see a call-site for this either
================
Comment at: flang/include/flang/Optimizer/Transforms/Factory.h:190-192
+ assert(dimension == mlir::cast<fir::ShapeOp>(shapeVal.getDefiningOp())
+ .getType()
+ .getRank());
----------------
Move this assert with the one a few lines above? They seem related.
Using the `assert(!shapeVal ||` form like above you can avoid the `if` and the nesting
================
Comment at: flang/include/flang/Optimizer/Transforms/Factory.h:253
+ llvm::make_range(steps.begin(), steps.end()), threadedVals, unordered);
+}
+
----------------
The createLoopNest functions seem unused as well
================
Comment at: flang/lib/Optimizer/Builder/FIRBuilder.cpp:347
+ const fir::ExtendedValue &exv) {
+ auto itemAddr = fir::getBase(exv);
+ if (itemAddr.getType().isa<fir::BoxType>())
----------------
================
Comment at: flang/lib/Optimizer/Builder/FIRBuilder.cpp:353
+ mlir::emitError(loc, "internal: expected a memory reference type ")
+ << itemAddr.getType();
+ auto boxTy = fir::BoxType::get(elementType);
----------------
Seems like there should be a llvm_unreachable after this error is emitted
================
Comment at: flang/lib/Optimizer/Builder/FIRBuilder.cpp:355
+ auto boxTy = fir::BoxType::get(elementType);
+ return exv.match(
+ [&](const fir::ArrayBoxValue &box) -> mlir::Value {
----------------
I don't quite find what the `.match(` call resolves to on the `fir::ExtendedValue` class? Any tip?
================
Comment at: flang/lib/Optimizer/Builder/FIRBuilder.cpp:357
+ [&](const fir::ArrayBoxValue &box) -> mlir::Value {
+ auto s = createShape(loc, exv);
+ return create<fir::EmboxOp>(loc, boxTy, itemAddr, s);
----------------
(same below)
================
Comment at: flang/lib/Optimizer/Builder/FIRBuilder.cpp:382
+ },
+ [&](const auto &) -> mlir::Value {
+ return create<fir::EmboxOp>(loc, boxTy, itemAddr);
----------------
Can you comment on what this is supposed to match?
================
Comment at: flang/lib/Optimizer/Transforms/ArrayValueCopy.cpp:355
+ mlir::Value load;
+ auto addr = st.memref();
+ auto stEleTy = fir::dyn_cast_ptrOrBoxEleTy(addr.getType());
----------------
not sure if it is a Value here?
================
Comment at: flang/lib/Optimizer/Transforms/ArrayValueCopy.cpp:453-462
+ if (useMap.count(acc)) {
+ mlir::emitError(
+ load.getLoc(),
+ "The parallel semantics of multiple array_merge_stores per "
+ "array_load are not supported.");
+ return;
+ }
----------------
I commented on this before I believe: you have two map lookup when one would be enough I think:
================
Comment at: flang/lib/Optimizer/Transforms/ArrayValueCopy.cpp:644
+ ArrayOp update,
+ const std::function<void(mlir::Value)> &assignElement,
+ mlir::Type lhsEltRefType) const {
----------------
================
Comment at: flang/lib/Optimizer/Transforms/ArrayValueCopy.cpp:671
+ assignElement(coor);
+ auto *storeOp = useMap.lookup(loadOp);
+ auto store = mlir::cast<ArrayMergeStoreOp>(storeOp);
----------------
(previous use of `useMap.lookup()` in this function spelled out the type)
================
Comment at: flang/lib/Optimizer/Transforms/ArrayValueCopy.cpp:716
+ fir::getKindMapping(update->getParentOfType<mlir::ModuleOp>()));
+ if (!update.typeparams().empty()) {
+ auto boxTy = fir::BoxType::get(inEleTy);
----------------
This branch may be worth a comment.
In general the entire pattern is a bit light on documentation.
================
Comment at: flang/lib/Optimizer/Transforms/ArrayValueCopy.cpp:730
+ llvm::report_fatal_error("not a legal reference type");
+ }
+ } else {
----------------
You can reduce the indentation in the code by inverting the else and the then branch:
```
if (!inEleTy.isa<fir::RecordType>())
llvm::report_fatal_error("not a legal reference type");
```
Also, I'm not sure why it isn't an assertion here? If this can't be then shouldn't we degrade more gracefully?
```
assert(inEleTy.isa<fir::RecordType>());
```
================
Comment at: flang/lib/Optimizer/Transforms/ArrayValueCopy.cpp:468
+ LLVM_DEBUG(llvm::dbgs() << " access: " << *acc << '\n');
+ if (mlir::isa<ArrayFetchOp, ArrayUpdateOp, ArrayModifyOp>(acc)) {
+ if (useMap.count(acc)) {
----------------
mehdi_amini wrote:
> Can this check fail? Right now the contract of `arrayAccesses()` is to only return these three operations, and `conflictOnMerge` would fail if there were any other op.
> Can this be replace with an assert here?
You marked it done, but I don't see it done in the code.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D111337/new/
https://reviews.llvm.org/D111337
More information about the llvm-commits
mailing list