Skip to content

Commit 8fe11a2

Browse files
authored
[Flang][OpenMP] Lowering of host-evaluated clauses (#116219)
This patch adds support for lowering OpenMP clauses and expressions attached to constructs nested inside of a target region that need to be evaluated in the host device. This is done through the use of the `OpenMP_HostEvalClause` `omp.target` set of operands and entry block arguments. When lowering clauses for a target construct, a more involved `processHostEvalClauses()` function is called, which looks at the current and potentially other nested constructs in order to find and lower clauses that need to be processed outside of the `omp.target` operation under construction. This populates an instance of a global structure with the resulting MLIR values. The resulting list of host-evaluated values is used to initialize the `host_eval` operands when constructing the `omp.target` operation, and then replaced with the corresponding block arguments after creating that operation's region. Afterwards, while lowering nested operations, those that might potentially be evaluated on the host (i.e. `num_teams`, `thread_limit`, `num_threads` and `collapse`) check first whether there is an active global host-evaluated information structure and whether it holds values referring to these clauses. If that is the case, the stored values (`omp.target` entry block arguments at that stage) are used instead of lowering these clauses again.
1 parent d8d30a9 commit 8fe11a2

File tree

6 files changed

+805
-26
lines changed

6 files changed

+805
-26
lines changed

flang/include/flang/Common/OpenMP-utils.h

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ struct EntryBlockArgsEntry {
3434
/// Structure holding the information needed to create and bind entry block
3535
/// arguments associated to all clauses that can define them.
3636
struct EntryBlockArgs {
37+
llvm::ArrayRef<mlir::Value> hostEvalVars;
3738
EntryBlockArgsEntry inReduction;
3839
EntryBlockArgsEntry map;
3940
EntryBlockArgsEntry priv;
@@ -49,18 +50,25 @@ struct EntryBlockArgs {
4950
}
5051

5152
auto getSyms() const {
52-
return llvm::concat<const Fortran::semantics::Symbol *const>(
53-
inReduction.syms, map.syms, priv.syms, reduction.syms,
54-
taskReduction.syms, useDeviceAddr.syms, useDevicePtr.syms);
53+
return llvm::concat<const semantics::Symbol *const>(inReduction.syms,
54+
map.syms, priv.syms, reduction.syms, taskReduction.syms,
55+
useDeviceAddr.syms, useDevicePtr.syms);
5556
}
5657

5758
auto getVars() const {
58-
return llvm::concat<const mlir::Value>(inReduction.vars, map.vars,
59-
priv.vars, reduction.vars, taskReduction.vars, useDeviceAddr.vars,
60-
useDevicePtr.vars);
59+
return llvm::concat<const mlir::Value>(hostEvalVars, inReduction.vars,
60+
map.vars, priv.vars, reduction.vars, taskReduction.vars,
61+
useDeviceAddr.vars, useDevicePtr.vars);
6162
}
6263
};
6364

65+
/// Create an entry block for the given region, including the clause-defined
66+
/// arguments specified.
67+
///
68+
/// \param [in] builder - MLIR operation builder.
69+
/// \param [in] args - entry block arguments information for the given
70+
/// operation.
71+
/// \param [in] region - Empty region in which to create the entry block.
6472
mlir::Block *genEntryBlock(
6573
mlir::OpBuilder &builder, const EntryBlockArgs &args, mlir::Region &region);
6674
} // namespace Fortran::common::openmp

flang/lib/Common/OpenMP-utils.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@ mlir::Block *genEntryBlock(mlir::OpBuilder &builder, const EntryBlockArgs &args,
1818

1919
llvm::SmallVector<mlir::Type> types;
2020
llvm::SmallVector<mlir::Location> locs;
21-
unsigned numVars = args.inReduction.vars.size() + args.map.vars.size() +
22-
args.priv.vars.size() + args.reduction.vars.size() +
23-
args.taskReduction.vars.size() + args.useDeviceAddr.vars.size() +
24-
args.useDevicePtr.vars.size();
21+
unsigned numVars = args.hostEvalVars.size() + args.inReduction.vars.size() +
22+
args.map.vars.size() + args.priv.vars.size() +
23+
args.reduction.vars.size() + args.taskReduction.vars.size() +
24+
args.useDeviceAddr.vars.size() + args.useDevicePtr.vars.size();
2525
types.reserve(numVars);
2626
locs.reserve(numVars);
2727

@@ -34,6 +34,7 @@ mlir::Block *genEntryBlock(mlir::OpBuilder &builder, const EntryBlockArgs &args,
3434

3535
// Populate block arguments in clause name alphabetical order to match
3636
// expected order by the BlockArgOpenMPOpInterface.
37+
extractTypeLoc(args.hostEvalVars);
3738
extractTypeLoc(args.inReduction.vars);
3839
extractTypeLoc(args.map.vars);
3940
extractTypeLoc(args.priv.vars);

0 commit comments

Comments
 (0)