summaryrefslogtreecommitdiff
path: root/flang/lib/Lower/OpenACC.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'flang/lib/Lower/OpenACC.cpp')
-rw-r--r--flang/lib/Lower/OpenACC.cpp49
1 files changed, 34 insertions, 15 deletions
diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp
index 6266a5056ace..be184aeead6e 100644
--- a/flang/lib/Lower/OpenACC.cpp
+++ b/flang/lib/Lower/OpenACC.cpp
@@ -32,6 +32,9 @@
#include "flang/Semantics/tools.h"
#include "mlir/Dialect/ControlFlow/IR/ControlFlowOps.h"
#include "llvm/Frontend/OpenACC/ACC.h.inc"
+#include "llvm/Support/Debug.h"
+
+#define DEBUG_TYPE "flang-lower-openacc"
// Special value for * passed in device_type or gang clauses.
static constexpr std::int64_t starCst = -1;
@@ -85,11 +88,17 @@ createDataEntryOp(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::Type retTy, llvm::ArrayRef<mlir::Value> async,
llvm::ArrayRef<mlir::Attribute> asyncDeviceTypes,
llvm::ArrayRef<mlir::Attribute> asyncOnlyDeviceTypes,
- mlir::Value isPresent = {}) {
+ bool unwrapBoxAddr = false, mlir::Value isPresent = {}) {
mlir::Value varPtrPtr;
- if (auto boxTy = mlir::dyn_cast<fir::BaseBoxType>(baseAddr.getType())) {
+ // The data clause may apply to either the box reference itself or the
+ // pointer to the data it holds. So use `unwrapBoxAddr` to decide.
+ // When we have a box value - assume it refers to the data inside box.
+ if ((fir::isBoxAddress(baseAddr.getType()) && unwrapBoxAddr) ||
+ fir::isa_box_type(baseAddr.getType())) {
if (isPresent) {
- mlir::Type ifRetTy = boxTy.getEleTy();
+ mlir::Type ifRetTy =
+ mlir::cast<fir::BaseBoxType>(fir::unwrapRefType(baseAddr.getType()))
+ .getEleTy();
if (!fir::isa_ref_type(ifRetTy))
ifRetTy = fir::ReferenceType::get(ifRetTy);
baseAddr =
@@ -97,6 +106,8 @@ createDataEntryOp(fir::FirOpBuilder &builder, mlir::Location loc,
.genIfOp(loc, {ifRetTy}, isPresent,
/*withElseRegion=*/true)
.genThen([&]() {
+ if (fir::isBoxAddress(baseAddr.getType()))
+ baseAddr = builder.create<fir::LoadOp>(loc, baseAddr);
mlir::Value boxAddr =
builder.create<fir::BoxAddrOp>(loc, baseAddr);
builder.create<fir::ResultOp>(loc, mlir::ValueRange{boxAddr});
@@ -108,6 +119,8 @@ createDataEntryOp(fir::FirOpBuilder &builder, mlir::Location loc,
})
.getResults()[0];
} else {
+ if (fir::isBoxAddress(baseAddr.getType()))
+ baseAddr = builder.create<fir::LoadOp>(loc, baseAddr);
baseAddr = builder.create<fir::BoxAddrOp>(loc, baseAddr);
}
retTy = baseAddr.getType();
@@ -342,18 +355,19 @@ genDataOperandOperations(const Fortran::parser::AccObjectList &objectList,
converter, builder, semanticsContext, stmtCtx, symbol, designator,
operandLocation, asFortran, bounds,
/*treatIndexAsSection=*/true);
+ LLVM_DEBUG(llvm::dbgs() << __func__ << "\n"; info.dump(llvm::dbgs()));
// If the input value is optional and is not a descriptor, we use the
// rawInput directly.
- mlir::Value baseAddr =
- ((info.addr.getType() != fir::unwrapRefType(info.rawInput.getType())) &&
- info.isPresent)
- ? info.rawInput
- : info.addr;
- Op op = createDataEntryOp<Op>(builder, operandLocation, baseAddr, asFortran,
- bounds, structured, implicit, dataClause,
- baseAddr.getType(), async, asyncDeviceTypes,
- asyncOnlyDeviceTypes, info.isPresent);
+ mlir::Value baseAddr = ((fir::unwrapRefType(info.addr.getType()) !=
+ fir::unwrapRefType(info.rawInput.getType())) &&
+ info.isPresent)
+ ? info.rawInput
+ : info.addr;
+ Op op = createDataEntryOp<Op>(
+ builder, operandLocation, baseAddr, asFortran, bounds, structured,
+ implicit, dataClause, baseAddr.getType(), async, asyncDeviceTypes,
+ asyncOnlyDeviceTypes, /*unwrapBoxAddr=*/true, info.isPresent);
dataOperands.push_back(op.getAccPtr());
}
}
@@ -380,6 +394,7 @@ static void genDeclareDataOperandOperations(
mlir::acc::DataBoundsOp, mlir::acc::DataBoundsType>(
converter, builder, semanticsContext, stmtCtx, symbol, designator,
operandLocation, asFortran, bounds);
+ LLVM_DEBUG(llvm::dbgs() << __func__ << "\n"; info.dump(llvm::dbgs()));
EntryOp op = createDataEntryOp<EntryOp>(
builder, operandLocation, info.addr, asFortran, bounds, structured,
implicit, dataClause, info.addr.getType(),
@@ -842,6 +857,8 @@ genPrivatizations(const Fortran::parser::AccObjectList &objectList,
mlir::acc::DataBoundsOp, mlir::acc::DataBoundsType>(
converter, builder, semanticsContext, stmtCtx, symbol, designator,
operandLocation, asFortran, bounds);
+ LLVM_DEBUG(llvm::dbgs() << __func__ << "\n"; info.dump(llvm::dbgs()));
+
RecipeOp recipe;
mlir::Type retTy = getTypeFromBounds(bounds, info.addr.getType());
if constexpr (std::is_same_v<RecipeOp, mlir::acc::PrivateRecipeOp>) {
@@ -853,7 +870,7 @@ genPrivatizations(const Fortran::parser::AccObjectList &objectList,
auto op = createDataEntryOp<mlir::acc::PrivateOp>(
builder, operandLocation, info.addr, asFortran, bounds, true,
/*implicit=*/false, mlir::acc::DataClause::acc_private, retTy, async,
- asyncDeviceTypes, asyncOnlyDeviceTypes);
+ asyncDeviceTypes, asyncOnlyDeviceTypes, /*unwrapBoxAddr=*/true);
dataOperands.push_back(op.getAccPtr());
} else {
std::string suffix =
@@ -865,7 +882,8 @@ genPrivatizations(const Fortran::parser::AccObjectList &objectList,
auto op = createDataEntryOp<mlir::acc::FirstprivateOp>(
builder, operandLocation, info.addr, asFortran, bounds, true,
/*implicit=*/false, mlir::acc::DataClause::acc_firstprivate, retTy,
- async, asyncDeviceTypes, asyncOnlyDeviceTypes);
+ async, asyncDeviceTypes, asyncOnlyDeviceTypes,
+ /*unwrapBoxAddr=*/true);
dataOperands.push_back(op.getAccPtr());
}
privatizations.push_back(mlir::SymbolRefAttr::get(
@@ -1421,6 +1439,7 @@ genReductions(const Fortran::parser::AccObjectListWithReduction &objectList,
mlir::acc::DataBoundsOp, mlir::acc::DataBoundsType>(
converter, builder, semanticsContext, stmtCtx, symbol, designator,
operandLocation, asFortran, bounds);
+ LLVM_DEBUG(llvm::dbgs() << __func__ << "\n"; info.dump(llvm::dbgs()));
mlir::Type reductionTy = fir::unwrapRefType(info.addr.getType());
if (auto seqTy = mlir::dyn_cast<fir::SequenceType>(reductionTy))
@@ -1433,7 +1452,7 @@ genReductions(const Fortran::parser::AccObjectListWithReduction &objectList,
builder, operandLocation, info.addr, asFortran, bounds,
/*structured=*/true, /*implicit=*/false,
mlir::acc::DataClause::acc_reduction, info.addr.getType(), async,
- asyncDeviceTypes, asyncOnlyDeviceTypes);
+ asyncDeviceTypes, asyncOnlyDeviceTypes, /*unwrapBoxAddr=*/true);
mlir::Type ty = op.getAccPtr().getType();
if (!areAllBoundConstant(bounds) ||
fir::isAssumedShape(info.addr.getType()) ||