Skip to content

Commit 1af0424

Browse files
authored
[flang][OpenACC] simplify copy and combiner recipe generation (#164988)
OpenACC copy and combiner recipe generation had non-trivial ad-hoc handling of the FIR types, and ended-up generating hlfir.assign that become runtime calls for arrays because of the lack of aliasing guarantees given to FIR for the region arguments. This code was started before HFLIR, and with HLFIR tools, most of the type specific handling can just be removed to use hlfir generic helper and assign (-230 lines in OpenACC.cpp). To avoid ending up with runtime calls in recipes: - use hlfir.assign temporary_lhs in copies to indicate that the copy cannot alias with the rhs. - add a new genNoAliasAssignment hlfir helper that takes its logic from the HLFIRInlineIntrinsic pass and allows applying a scalar combiner before generating the scalar assignments. This allows generating loops directly for the reduction and avoid having to find a clever way to signal HLFIR that the arguments do not alias (an other option would have been to introduce a dummy_scope and declares, but that would not be enough for POINTERs, and I am not sure we should start using this as a noalias operation).
1 parent fa050ea commit 1af0424

File tree

6 files changed

+1474
-1161
lines changed

6 files changed

+1474
-1161
lines changed

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

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,41 @@ mlir::Value inlineElementalOp(
450450
mlir::IRMapping &mapper,
451451
const std::function<bool(hlfir::ElementalOp)> &mustRecursivelyInline);
452452

453+
/// Generate an element-by-element assignment from \p rhs to \p lhs for arrays
454+
/// that are known not to alias. The assignment is performed using a loop nest
455+
/// over the optimal extents deduced from both shapes. If \p emitWorkshareLoop
456+
/// is true, a workshare loop construct may be emitted when available.
457+
/// Allocatable LHS must be allocated with the right shape and parameters.
458+
void genNoAliasArrayAssignment(
459+
mlir::Location loc, fir::FirOpBuilder &builder, hlfir::Entity rhs,
460+
hlfir::Entity lhs, bool emitWorkshareLoop = false,
461+
bool temporaryLHS = false,
462+
std::function<hlfir::Entity(mlir::Location, fir::FirOpBuilder &,
463+
hlfir::Entity, hlfir::Entity)> *combiner =
464+
nullptr);
465+
466+
/// Generate an assignment from \p rhs to \p lhs when they are known not to
467+
/// alias. Handles both arrays and scalars: for arrays, delegates to
468+
/// genNoAliasArrayAssignment; for scalars, performs load/store for trivial
469+
/// scalar types and falls back to hlfir.assign otherwise.
470+
/// Allocatable LHS must be allocated with the right shape and parameters.
471+
void genNoAliasAssignment(
472+
mlir::Location loc, fir::FirOpBuilder &builder, hlfir::Entity rhs,
473+
hlfir::Entity lhs, bool emitWorkshareLoop = false,
474+
bool temporaryLHS = false,
475+
std::function<hlfir::Entity(mlir::Location, fir::FirOpBuilder &,
476+
hlfir::Entity, hlfir::Entity)> *combiner =
477+
nullptr);
478+
inline void genNoAliasAssignment(
479+
mlir::Location loc, fir::FirOpBuilder &builder, hlfir::Entity rhs,
480+
hlfir::Entity lhs, bool emitWorkshareLoop, bool temporaryLHS,
481+
std::function<hlfir::Entity(mlir::Location, fir::FirOpBuilder &,
482+
hlfir::Entity, hlfir::Entity)>
483+
combiner) {
484+
genNoAliasAssignment(loc, builder, rhs, lhs, emitWorkshareLoop, temporaryLHS,
485+
&combiner);
486+
}
487+
453488
/// Create a new temporary with the shape and parameters of the provided
454489
/// hlfir.eval_in_mem operation and clone the body of the hlfir.eval_in_mem
455490
/// operating on this new temporary. returns the temporary and whether the

0 commit comments

Comments
 (0)