Skip to content

Commit b656553

Browse files
committed
[Flang][OpenMP] Properly bind arguments of composite operations
When composite constructs are lowered, clauses for each leaf construct are lowered before creating the set of loop wrapper operations, using these outside values to populate their operand lists. Then, when the loop nest associated to that composite construct is lowered, the binding of Fortran symbols to the entry block arguments defined by these loop wrappers is performed, resulting in the creation of `hlfir.declare` operations in the entry block of the `omp.loop_nest`. This approach prevents `hlfir.declare` operations related to the binding and other operations resulting from the evaluation of the clauses from being inserted between loop wrapper operations, which would be an illegal MLIR representation. However, this introduces the problem of entry block arguments defined by a wrapper that then should be used by one of its nested wrappers, because the corresponding Fortran symbol would still be mapped to an outside value at the time of gathering the list of operands for the nested wrapper. This patch adds operand re-mapping logic to update wrappers without changing when clauses are evaluated or where the `hlfir.declare` creation is performed.
1 parent 1e73f93 commit b656553

File tree

1 file changed

+19
-2
lines changed

1 file changed

+19
-2
lines changed

flang/lib/Lower/OpenMP/OpenMP.cpp

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -589,10 +589,27 @@ static void genLoopVars(
589589
llvm::SmallVector<mlir::Location> locs(args.size(), loc);
590590
firOpBuilder.createBlock(&region, {}, tiv, locs);
591591

592+
// Update nested wrapper operands if parent wrappers have mapped these values
593+
// to block arguments.
594+
//
595+
// Binding these values earlier would take care of this, but we cannot rely on
596+
// that approach because binding in between the creation of a wrapper and the
597+
// next one would result in 'hlfir.declare' operations being introduced inside
598+
// of a wrapper, which is illegal.
599+
mlir::IRMapping mapper;
600+
for (auto [argGeneratingOp, blockArgs] : wrapperArgs) {
601+
for (mlir::OpOperand &operand : argGeneratingOp->getOpOperands())
602+
operand.set(mapper.lookupOrDefault(operand.get()));
603+
604+
for (const auto [arg, var] : llvm::zip_equal(
605+
argGeneratingOp->getRegion(0).getArguments(), blockArgs.getVars()))
606+
mapper.map(var, arg);
607+
}
608+
592609
// Bind the entry block arguments of parent wrappers to the corresponding
593610
// symbols.
594-
for (auto [argGeneratingOp, args] : wrapperArgs)
595-
bindEntryBlockArgs(converter, argGeneratingOp, args);
611+
for (auto [argGeneratingOp, blockArgs] : wrapperArgs)
612+
bindEntryBlockArgs(converter, argGeneratingOp, blockArgs);
596613

597614
// The argument is not currently in memory, so make a temporary for the
598615
// argument, and store it there, then bind that location to the argument.

0 commit comments

Comments
 (0)