[flang-commits] [flang] [Flang][OpenMP] Prepare lowering for composite construct support (PR #97430)
via flang-commits
flang-commits at lists.llvm.org
Tue Jul 2 09:00:33 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-fir-hlfir
Author: Sergio Afonso (skatrak)
<details>
<summary>Changes</summary>
This patch performs various changes in preparation for adding lowering support for composite constructs. In particular, the following changes are done:
- Splitting lowering for `omp.loop_nest` into its own function and update lowering for all supported loop wrappers to not create this operation themselves.
- Creating "wrapper" lowering functions called by their associated "standalone" lowering functions, which also are responsible for calling the new codegen function for `omp.loop_nest`. "Wrapper" lowering functions will later be reused by "composite" lowering functions as well.
- Implementing the creation of a single `DataSharingProcessor` inside of `genOMPDispatch` to be used while lowering standalone and composite loop-associated constructs. This avoids code duplication and ensures that no privatization-related allocations are created inside of loop wrapper regions.
- Preventing the `FirOpBuilder::getAllocaBlock` method from returning blocks of a loop wrapper, as inserting allocations there would violate existing requirements on the contents of a loop wrapper region.
- Removing the introduction of `fir.undef` operations as a way to keep track of insertion points inside of the `DataSharingProcessor` to avoid leaving such operations inside of loop wrappers.
- Updating tests broken by reordering of privatization with respect to clause processing.
---
Patch is 50.14 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/97430.diff
10 Files Affected:
- (modified) flang/lib/Lower/OpenMP/DataSharingProcessor.cpp (+1-4)
- (modified) flang/lib/Lower/OpenMP/OpenMP.cpp (+259-207)
- (modified) flang/lib/Optimizer/Builder/FIRBuilder.cpp (+23)
- (modified) flang/test/Lower/OpenMP/parallel-reduction3.f90 (+7-7)
- (modified) flang/test/Lower/OpenMP/simd.f90 (+1-1)
- (modified) flang/test/Lower/OpenMP/wsloop-chunks.f90 (+18-18)
- (modified) flang/test/Lower/OpenMP/wsloop-reduction-array-assumed-shape.f90 (+7-7)
- (modified) flang/test/Lower/OpenMP/wsloop-reduction-array.f90 (+8-8)
- (modified) flang/test/Lower/OpenMP/wsloop-reduction-array2.f90 (+8-8)
- (modified) flang/test/Lower/OpenMP/wsloop-reduction-multiple-clauses.f90 (+7-7)
``````````diff
diff --git a/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp b/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp
index e2b55fcc64062..7df3905c29990 100644
--- a/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp
+++ b/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp
@@ -72,11 +72,8 @@ void DataSharingProcessor::processStep2(mlir::Operation *op, bool isLoop) {
firOpBuilder.setInsertionPointAfter(op);
insertDeallocs();
} else {
- // insert dummy instruction to mark the insertion position
- mlir::Value undefMarker = firOpBuilder.create<fir::UndefOp>(
- op->getLoc(), firOpBuilder.getIndexType());
+ mlir::OpBuilder::InsertionGuard guard(firOpBuilder);
insertDeallocs();
- firOpBuilder.setInsertionPointAfter(undefMarker.getDefiningOp());
}
}
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index d8679fb693659..1830e31349cfb 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -518,8 +518,8 @@ struct OpWithBodyGenInfo {
}
OpWithBodyGenInfo &
- setReductions(llvm::SmallVectorImpl<const semantics::Symbol *> *value1,
- llvm::SmallVectorImpl<mlir::Type> *value2) {
+ setReductions(llvm::ArrayRef<const semantics::Symbol *> *value1,
+ llvm::ArrayRef<mlir::Type> *value2) {
reductionSymbols = value1;
reductionTypes = value2;
return *this;
@@ -549,9 +549,9 @@ struct OpWithBodyGenInfo {
/// [in] if provided, processes the construct's data-sharing attributes.
DataSharingProcessor *dsp = nullptr;
/// [in] if provided, list of reduction symbols
- llvm::SmallVectorImpl<const semantics::Symbol *> *reductionSymbols = nullptr;
+ llvm::ArrayRef<const semantics::Symbol *> *reductionSymbols = nullptr;
/// [in] if provided, list of reduction types
- llvm::SmallVectorImpl<mlir::Type> *reductionTypes = nullptr;
+ llvm::ArrayRef<mlir::Type> *reductionTypes = nullptr;
/// [in] if provided, emits the op's region entry. Otherwise, an emtpy block
/// is created in the region.
GenOMPRegionEntryCBFn genRegionEntryCB = nullptr;
@@ -1134,7 +1134,7 @@ static void genSingleClauses(lower::AbstractConverter &converter,
static void genTargetClauses(
lower::AbstractConverter &converter, semantics::SemanticsContext &semaCtx,
lower::StatementContext &stmtCtx, const List<Clause> &clauses,
- mlir::Location loc, bool processHostOnlyClauses, bool processReduction,
+ mlir::Location loc, bool processHostOnlyClauses,
mlir::omp::TargetClauseOps &clauseOps,
llvm::SmallVectorImpl<const semantics::Symbol *> &mapSyms,
llvm::SmallVectorImpl<mlir::Location> &mapLocs,
@@ -1336,57 +1336,6 @@ genCriticalOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
queue, item, nameAttr);
}
-static mlir::omp::DistributeOp
-genDistributeOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
- semantics::SemanticsContext &semaCtx,
- lower::pft::Evaluation &eval, mlir::Location loc,
- const ConstructQueue &queue, ConstructQueue::iterator item) {
- fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
- symTable.pushScope();
- DataSharingProcessor dsp(converter, semaCtx, item->clauses, eval,
- lower::omp::isLastItemInQueue(item, queue));
- dsp.processStep1();
-
- lower::StatementContext stmtCtx;
- mlir::omp::LoopNestClauseOps loopClauseOps;
- mlir::omp::DistributeClauseOps distributeClauseOps;
- llvm::SmallVector<const semantics::Symbol *> iv;
- genLoopNestClauses(converter, semaCtx, eval, item->clauses, loc,
- loopClauseOps, iv);
- genDistributeClauses(converter, semaCtx, stmtCtx, item->clauses, loc,
- distributeClauseOps);
-
- // Create omp.distribute wrapper.
- auto distributeOp =
- firOpBuilder.create<mlir::omp::DistributeOp>(loc, distributeClauseOps);
-
- firOpBuilder.createBlock(&distributeOp.getRegion());
- firOpBuilder.setInsertionPoint(
- lower::genOpenMPTerminator(firOpBuilder, distributeOp, loc));
-
- // Create nested omp.loop_nest and fill body with loop contents.
- auto loopOp = firOpBuilder.create<mlir::omp::LoopNestOp>(loc, loopClauseOps);
-
- auto *nestedEval =
- getCollapsedLoopEval(eval, getCollapseValue(item->clauses));
-
- auto ivCallback = [&](mlir::Operation *op) {
- genLoopVars(op, converter, loc, iv);
- return iv;
- };
-
- createBodyOfOp(*loopOp,
- OpWithBodyGenInfo(converter, symTable, semaCtx, loc,
- *nestedEval, llvm::omp::Directive::OMPD_simd)
- .setClauses(&item->clauses)
- .setDataSharingProcessor(&dsp)
- .setGenRegionEntryCb(ivCallback),
- queue, item);
-
- symTable.popScope();
- return distributeOp;
-}
-
static mlir::omp::FlushOp
genFlushOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval,
@@ -1400,6 +1349,33 @@ genFlushOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
converter.getCurrentLocation(), operandRange);
}
+static mlir::omp::LoopNestOp
+genLoopNestOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
+ semantics::SemanticsContext &semaCtx,
+ lower::pft::Evaluation &eval, mlir::Location loc,
+ const ConstructQueue &queue, ConstructQueue::iterator item,
+ mlir::omp::LoopNestClauseOps &clauseOps,
+ llvm::ArrayRef<const semantics::Symbol *> iv,
+ llvm::ArrayRef<const semantics::Symbol *> wrapperSyms,
+ llvm::ArrayRef<mlir::BlockArgument> wrapperArgs,
+ llvm::omp::Directive directive, DataSharingProcessor &dsp) {
+ auto ivCallback = [&](mlir::Operation *op) {
+ genLoopVars(op, converter, loc, iv, wrapperSyms, wrapperArgs);
+ return llvm::SmallVector<const semantics::Symbol *>(iv);
+ };
+
+ auto *nestedEval =
+ getCollapsedLoopEval(eval, getCollapseValue(item->clauses));
+
+ return genOpWithBody<mlir::omp::LoopNestOp>(
+ OpWithBodyGenInfo(converter, symTable, semaCtx, loc, *nestedEval,
+ directive)
+ .setClauses(&item->clauses)
+ .setDataSharingProcessor(&dsp)
+ .setGenRegionEntryCb(ivCallback),
+ queue, item, clauseOps);
+}
+
static mlir::omp::MasterOp
genMasterOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval,
@@ -1434,24 +1410,18 @@ genOrderedRegionOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
queue, item, clauseOps);
}
-static mlir::omp::ParallelOp
-genParallelOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
- semantics::SemanticsContext &semaCtx,
- lower::pft::Evaluation &eval, mlir::Location loc,
- const ConstructQueue &queue, ConstructQueue::iterator item,
- bool outerCombined = false) {
+static mlir::omp::ParallelOp genParallelOp(
+ lower::AbstractConverter &converter, lower::SymMap &symTable,
+ semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval,
+ mlir::Location loc, const ConstructQueue &queue,
+ ConstructQueue::iterator item, mlir::omp::ParallelClauseOps &clauseOps,
+ llvm::ArrayRef<const semantics::Symbol *> reductionSyms,
+ llvm::ArrayRef<mlir::Type> reductionTypes, bool outerCombined = false) {
fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
- lower::StatementContext stmtCtx;
- mlir::omp::ParallelClauseOps clauseOps;
- llvm::SmallVector<mlir::Type> reductionTypes;
- llvm::SmallVector<const semantics::Symbol *> reductionSyms;
- genParallelClauses(converter, semaCtx, stmtCtx, item->clauses, loc,
- /*processReduction=*/!outerCombined, clauseOps,
- reductionTypes, reductionSyms);
auto reductionCallback = [&](mlir::Operation *op) {
genReductionVars(op, converter, loc, reductionSyms, reductionTypes);
- return reductionSyms;
+ return llvm::SmallVector<const semantics::Symbol *>(reductionSyms);
};
OpWithBodyGenInfo genInfo =
@@ -1481,7 +1451,7 @@ genParallelOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
clauseOps.reductionVars.size(), loc);
llvm::SmallVector<mlir::Type> allRegionArgTypes;
- mergePrivateVarsInfo(parallelOp, llvm::ArrayRef(reductionTypes),
+ mergePrivateVarsInfo(parallelOp, reductionTypes,
llvm::function_ref<mlir::Type(mlir::Value)>{
[](mlir::Value v) { return v.getType(); }},
allRegionArgTypes);
@@ -1496,7 +1466,7 @@ genParallelOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
firOpBuilder.createBlock(®ion, /*insertPt=*/{}, allRegionArgTypes,
allRegionArgLocs);
- llvm::SmallVector<const semantics::Symbol *> allSymbols = reductionSyms;
+ llvm::SmallVector<const semantics::Symbol *> allSymbols(reductionSyms);
allSymbols.append(dsp.getAllSymbolsToPrivatize().begin(),
dsp.getAllSymbolsToPrivatize().end());
@@ -1607,56 +1577,6 @@ genSectionsOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
return sectionsOp;
}
-static mlir::omp::SimdOp
-genSimdOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
- semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval,
- mlir::Location loc, const ConstructQueue &queue,
- ConstructQueue::iterator item) {
- fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
- symTable.pushScope();
- DataSharingProcessor dsp(converter, semaCtx, item->clauses, eval,
- lower::omp::isLastItemInQueue(item, queue));
- dsp.processStep1();
-
- lower::StatementContext stmtCtx;
- mlir::omp::LoopNestClauseOps loopClauseOps;
- mlir::omp::SimdClauseOps simdClauseOps;
- llvm::SmallVector<const semantics::Symbol *> iv;
- genLoopNestClauses(converter, semaCtx, eval, item->clauses, loc,
- loopClauseOps, iv);
- genSimdClauses(converter, semaCtx, item->clauses, loc, simdClauseOps);
-
- // Create omp.simd wrapper.
- auto simdOp = firOpBuilder.create<mlir::omp::SimdOp>(loc, simdClauseOps);
-
- // TODO: Add reduction-related arguments to the wrapper's entry block.
- firOpBuilder.createBlock(&simdOp.getRegion());
- firOpBuilder.setInsertionPoint(
- lower::genOpenMPTerminator(firOpBuilder, simdOp, loc));
-
- // Create nested omp.loop_nest and fill body with loop contents.
- auto loopOp = firOpBuilder.create<mlir::omp::LoopNestOp>(loc, loopClauseOps);
-
- auto *nestedEval =
- getCollapsedLoopEval(eval, getCollapseValue(item->clauses));
-
- auto ivCallback = [&](mlir::Operation *op) {
- genLoopVars(op, converter, loc, iv);
- return iv;
- };
-
- createBodyOfOp(*loopOp,
- OpWithBodyGenInfo(converter, symTable, semaCtx, loc,
- *nestedEval, llvm::omp::Directive::OMPD_simd)
- .setClauses(&item->clauses)
- .setDataSharingProcessor(&dsp)
- .setGenRegionEntryCb(ivCallback),
- queue, item);
-
- symTable.popScope();
- return simdOp;
-}
-
static mlir::omp::SingleOp
genSingleOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval,
@@ -1676,7 +1596,7 @@ static mlir::omp::TargetOp
genTargetOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval,
mlir::Location loc, const ConstructQueue &queue,
- ConstructQueue::iterator item, bool outerCombined = false) {
+ ConstructQueue::iterator item) {
fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
lower::StatementContext stmtCtx;
@@ -1690,10 +1610,9 @@ genTargetOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
llvm::SmallVector<mlir::Location> mapLocs, devicePtrLocs, deviceAddrLocs;
llvm::SmallVector<mlir::Type> mapTypes, devicePtrTypes, deviceAddrTypes;
genTargetClauses(converter, semaCtx, stmtCtx, item->clauses, loc,
- processHostOnlyClauses, /*processReduction=*/outerCombined,
- clauseOps, mapSyms, mapLocs, mapTypes, deviceAddrSyms,
- deviceAddrLocs, deviceAddrTypes, devicePtrSyms,
- devicePtrLocs, devicePtrTypes);
+ processHostOnlyClauses, clauseOps, mapSyms, mapLocs,
+ mapTypes, deviceAddrSyms, deviceAddrLocs, deviceAddrTypes,
+ devicePtrSyms, devicePtrLocs, devicePtrTypes);
llvm::SmallVector<const semantics::Symbol *> privateSyms;
DataSharingProcessor dsp(converter, semaCtx, item->clauses, eval,
@@ -1889,14 +1808,6 @@ genTaskgroupOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
queue, item, clauseOps);
}
-static mlir::omp::TaskloopOp
-genTaskloopOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
- semantics::SemanticsContext &semaCtx,
- lower::pft::Evaluation &eval, mlir::Location loc,
- const ConstructQueue &queue, ConstructQueue::iterator item) {
- TODO(loc, "Taskloop construct");
-}
-
static mlir::omp::TaskwaitOp
genTaskwaitOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
semantics::SemanticsContext &semaCtx,
@@ -1933,59 +1844,185 @@ genTeamsOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
queue, item, clauseOps);
}
+//===----------------------------------------------------------------------===//
+// Code generation functions for loop wrappers
+//===----------------------------------------------------------------------===//
+
+static mlir::omp::DistributeOp
+genDistributeWrapperOp(lower::AbstractConverter &converter,
+ semantics::SemanticsContext &semaCtx,
+ lower::pft::Evaluation &eval, mlir::Location loc,
+ const mlir::omp::DistributeClauseOps &clauseOps) {
+ fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
+
+ // Create omp.distribute wrapper.
+ auto distributeOp =
+ firOpBuilder.create<mlir::omp::DistributeOp>(loc, clauseOps);
+
+ // TODO: Populate entry block arguments with private variables.
+ firOpBuilder.createBlock(&distributeOp.getRegion());
+ firOpBuilder.setInsertionPoint(
+ lower::genOpenMPTerminator(firOpBuilder, distributeOp, loc));
+
+ return distributeOp;
+}
+
+static mlir::omp::SimdOp
+genSimdWrapperOp(lower::AbstractConverter &converter,
+ semantics::SemanticsContext &semaCtx,
+ lower::pft::Evaluation &eval, mlir::Location loc,
+ const mlir::omp::SimdClauseOps &clauseOps) {
+ fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
+
+ // Create omp.simd wrapper.
+ auto simdOp = firOpBuilder.create<mlir::omp::SimdOp>(loc, clauseOps);
+
+ // TODO: Populate entry block arguments with reduction and private variables.
+ firOpBuilder.createBlock(&simdOp.getRegion());
+ firOpBuilder.setInsertionPoint(
+ lower::genOpenMPTerminator(firOpBuilder, simdOp, loc));
+
+ return simdOp;
+}
+
+static mlir::omp::TaskloopOp
+genTaskloopWrapperOp(lower::AbstractConverter &converter,
+ semantics::SemanticsContext &semaCtx,
+ lower::pft::Evaluation &eval, mlir::Location loc,
+ const mlir::omp::TaskloopClauseOps &clauseOps) {
+ TODO(loc, "Taskloop construct");
+}
+
static mlir::omp::WsloopOp
-genWsloopOp(lower::AbstractConverter &converter, lower::SymMap &symTable,
- semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval,
- mlir::Location loc, const ConstructQueue &queue,
- ConstructQueue::iterator item) {
+genWsloopWrapperOp(lower::AbstractConverter &converter,
+ semantics::SemanticsContext &semaCtx,
+ lower::pft::Evaluation &eval, mlir::Location loc,
+ const mlir::omp::WsloopClauseOps &clauseOps,
+ llvm::ArrayRef<const semantics::Symbol *> reductionSyms,
+ llvm::ArrayRef<mlir::Type> reductionTypes) {
fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
- symTable.pushScope();
- DataSharingProcessor dsp(converter, semaCtx, item->clauses, eval,
- lower::omp::isLastItemInQueue(item, queue));
- dsp.processStep1();
+ // Create omp.wsloop wrapper.
+ llvm::SmallVector<mlir::Location> reductionLocs(reductionSyms.size(), loc);
+ auto wsloopOp = firOpBuilder.create<mlir::omp::WsloopOp>(loc, clauseOps);
+
+ // Populate entry block arguments with reduction variables.
+ // TODO: Add private variables to entry block arguments.
+ firOpBuilder.createBlock(&wsloopOp.getRegion(), {}, reductionTypes,
+ reductionLocs);
+ firOpBuilder.setInsertionPoint(
+ lower::genOpenMPTerminator(firOpBuilder, wsloopOp, loc));
+
+ return wsloopOp;
+}
+
+//===----------------------------------------------------------------------===//
+// Code generation functions for the standalone version of constructs that can
+// also be a leaf of a composite construct
+//===----------------------------------------------------------------------===//
+
+static void genStandaloneDistribute(
+ lower::AbstractConverter &converter, lower::SymMap &symTable,
+ semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval,
+ mlir::Location loc, const ConstructQueue &queue,
+ ConstructQueue::iterator item, DataSharingProcessor &dsp) {
lower::StatementContext stmtCtx;
- mlir::omp::LoopNestClauseOps loopClauseOps;
- mlir::omp::WsloopClauseOps wsClauseOps;
+
+ mlir::omp::DistributeClauseOps distributeClauseOps;
+ genDistributeClauses(converter, semaCtx, stmtCtx, item->clauses, loc,
+ distributeClauseOps);
+
+ mlir::omp::LoopNestClauseOps loopNestClauseOps;
llvm::SmallVector<const semantics::Symbol *> iv;
- llvm::SmallVector<mlir::Type> reductionTypes;
+ genLoopNestClauses(converter, semaCtx, eval, item->clauses, loc,
+ loopNestClauseOps, iv);
+
+ auto distributeOp = genDistributeWrapperOp(converter, semaCtx, eval, loc,
+ distributeClauseOps);
+
+ genLoopNestOp(converter, symTable, semaCtx, eval, loc, queue, item,
+ loopNestClauseOps, iv,
+ /*wrapperSyms=*/{}, distributeOp.getRegion().getArguments(),
+ llvm::omp::Directive::OMPD_distribute, dsp);
+}
+
+static void genStandaloneDo(lower::AbstractConverter &converter,
+ lower::SymMap &symTable,
+ semantics::SemanticsContext &semaCtx,
+ lower::pft::Evaluation &eval, mlir::Location loc,
+ const ConstructQueue &queue,
+ ConstructQueue::iterator item,
+ DataSharingProcessor &dsp) {
+ lower::StatementContext stmtCtx;
+
+ mlir::omp::WsloopClauseOps wsloopClauseOps;
llvm::SmallVector<const semantics::Symbol *> reductionSyms;
+ llvm::SmallVector<mlir::Type> reductionTypes;
+ genWsloopClauses(converter, semaCtx, stmtCtx, item->clauses, loc,
+ wsloopClauseOps, reductionTypes, reductionSyms);
+
+ mlir::omp::LoopNestClauseOps loopNestClauseOps;
+ llvm::SmallVector<const semantics::Symbol *> iv;
genLoopNestClauses(converter, semaCtx, eval, item->clauses, loc,
- loopClauseOps, iv);
- genWsloopClauses(converter, semaCtx, stmtCtx, item->clauses, loc, wsClauseOps,
- reductionTypes, reductionSyms);
+ loopNestClauseOps, iv);
- // Create omp.wsloop wrapper and populate entry block arguments with reduction
- // variables.
- auto wsloopOp = firOpBuilder.create<mlir::omp::WsloopOp>(loc, wsClauseOps);
- llvm::SmallVector<mlir::Location> reductionLocs(reductionSyms.size(), loc);
- mlir::Block *wsloopEntryBlock = firOpBuilder.createBlock(
- &wsloopOp.getRegion(), {}, reductionTypes, reductionLocs);
- firOpB...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/97430
More information about the flang-commits
mailing list