aboutsummaryrefslogtreecommitdiff
path: root/flang/lib/Optimizer/Builder/HLFIRTools.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'flang/lib/Optimizer/Builder/HLFIRTools.cpp')
-rw-r--r--flang/lib/Optimizer/Builder/HLFIRTools.cpp60
1 files changed, 60 insertions, 0 deletions
diff --git a/flang/lib/Optimizer/Builder/HLFIRTools.cpp b/flang/lib/Optimizer/Builder/HLFIRTools.cpp
index 93dfc57..793be32 100644
--- a/flang/lib/Optimizer/Builder/HLFIRTools.cpp
+++ b/flang/lib/Optimizer/Builder/HLFIRTools.cpp
@@ -1392,6 +1392,66 @@ bool hlfir::elementalOpMustProduceTemp(hlfir::ElementalOp elemental) {
return false;
}
+static void combineAndStoreElement(
+ mlir::Location loc, fir::FirOpBuilder &builder, hlfir::Entity lhs,
+ hlfir::Entity rhs, bool temporaryLHS,
+ std::function<hlfir::Entity(mlir::Location, fir::FirOpBuilder &,
+ hlfir::Entity, hlfir::Entity)> *combiner) {
+ hlfir::Entity valueToAssign = hlfir::loadTrivialScalar(loc, builder, rhs);
+ if (combiner) {
+ hlfir::Entity lhsValue = hlfir::loadTrivialScalar(loc, builder, lhs);
+ valueToAssign = (*combiner)(loc, builder, lhsValue, valueToAssign);
+ }
+ hlfir::AssignOp::create(builder, loc, valueToAssign, lhs,
+ /*realloc=*/false,
+ /*keep_lhs_length_if_realloc=*/false,
+ /*temporary_lhs=*/temporaryLHS);
+}
+
+void hlfir::genNoAliasArrayAssignment(
+ mlir::Location loc, fir::FirOpBuilder &builder, hlfir::Entity rhs,
+ hlfir::Entity lhs, bool emitWorkshareLoop, bool temporaryLHS,
+ std::function<hlfir::Entity(mlir::Location, fir::FirOpBuilder &,
+ hlfir::Entity, hlfir::Entity)> *combiner) {
+ mlir::OpBuilder::InsertionGuard guard(builder);
+ rhs = hlfir::derefPointersAndAllocatables(loc, builder, rhs);
+ lhs = hlfir::derefPointersAndAllocatables(loc, builder, lhs);
+ mlir::Value lhsShape = hlfir::genShape(loc, builder, lhs);
+ llvm::SmallVector<mlir::Value> lhsExtents =
+ hlfir::getIndexExtents(loc, builder, lhsShape);
+ mlir::Value rhsShape = hlfir::genShape(loc, builder, rhs);
+ llvm::SmallVector<mlir::Value> rhsExtents =
+ hlfir::getIndexExtents(loc, builder, rhsShape);
+ llvm::SmallVector<mlir::Value> extents =
+ fir::factory::deduceOptimalExtents(lhsExtents, rhsExtents);
+ hlfir::LoopNest loopNest =
+ hlfir::genLoopNest(loc, builder, extents,
+ /*isUnordered=*/true, emitWorkshareLoop);
+ builder.setInsertionPointToStart(loopNest.body);
+ auto rhsArrayElement =
+ hlfir::getElementAt(loc, builder, rhs, loopNest.oneBasedIndices);
+ rhsArrayElement = hlfir::loadTrivialScalar(loc, builder, rhsArrayElement);
+ auto lhsArrayElement =
+ hlfir::getElementAt(loc, builder, lhs, loopNest.oneBasedIndices);
+ combineAndStoreElement(loc, builder, lhsArrayElement, rhsArrayElement,
+ temporaryLHS, combiner);
+}
+
+void hlfir::genNoAliasAssignment(
+ mlir::Location loc, fir::FirOpBuilder &builder, hlfir::Entity rhs,
+ hlfir::Entity lhs, bool emitWorkshareLoop, bool temporaryLHS,
+ std::function<hlfir::Entity(mlir::Location, fir::FirOpBuilder &,
+ hlfir::Entity, hlfir::Entity)> *combiner) {
+ if (lhs.isArray()) {
+ genNoAliasArrayAssignment(loc, builder, rhs, lhs, emitWorkshareLoop,
+ temporaryLHS, combiner);
+ return;
+ }
+ rhs = hlfir::derefPointersAndAllocatables(loc, builder, rhs);
+ lhs = hlfir::derefPointersAndAllocatables(loc, builder, lhs);
+ combineAndStoreElement(loc, builder, lhs, rhs, temporaryLHS, combiner);
+}
+
std::pair<hlfir::Entity, bool>
hlfir::createTempFromMold(mlir::Location loc, fir::FirOpBuilder &builder,
hlfir::Entity mold) {