diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp index ab90b4609e855..0968df4f88e28 100644 --- a/flang/lib/Lower/OpenMP/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP/OpenMP.cpp @@ -1763,7 +1763,6 @@ static void genTaskClauses(lower::AbstractConverter &converter, cp.processPriority(stmtCtx, clauseOps); cp.processUntied(clauseOps); cp.processDetach(clauseOps); - // TODO Support delayed privatization. cp.processTODO( loc, llvm::omp::Directive::OMPD_task); @@ -1914,12 +1913,11 @@ static mlir::omp::LoopNestOp genLoopNestOp( queue, item, clauseOps); } -static void genLoopOp(lower::AbstractConverter &converter, - lower::SymMap &symTable, - semantics::SemanticsContext &semaCtx, - lower::pft::Evaluation &eval, mlir::Location loc, - const ConstructQueue &queue, - ConstructQueue::const_iterator item) { +static mlir::omp::LoopOp +genLoopOp(lower::AbstractConverter &converter, lower::SymMap &symTable, + semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval, + mlir::Location loc, const ConstructQueue &queue, + ConstructQueue::const_iterator item) { mlir::omp::LoopOperands loopClauseOps; llvm::SmallVector loopReductionSyms; genLoopClauses(converter, semaCtx, item->clauses, loc, loopClauseOps, @@ -1946,14 +1944,15 @@ static void genLoopOp(lower::AbstractConverter &converter, genLoopNestOp(converter, symTable, semaCtx, eval, loc, queue, item, loopNestClauseOps, iv, {{loopOp, loopArgs}}, llvm::omp::Directive::OMPD_loop, dsp); + return loopOp; } static mlir::omp::MaskedOp genMaskedOp(lower::AbstractConverter &converter, lower::SymMap &symTable, + lower::StatementContext &stmtCtx, semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval, mlir::Location loc, const ConstructQueue &queue, ConstructQueue::const_iterator item) { - lower::StatementContext stmtCtx; mlir::omp::MaskedOperands clauseOps; genMaskedClauses(converter, semaCtx, stmtCtx, item->clauses, loc, clauseOps); @@ -2157,13 +2156,13 @@ genSectionsOp(lower::AbstractConverter &converter, lower::SymMap &symTable, return sectionsOp; } -static void genScopeOp(lower::AbstractConverter &converter, - lower::SymMap &symTable, - semantics::SemanticsContext &semaCtx, - lower::pft::Evaluation &eval, mlir::Location loc, - const ConstructQueue &queue, - ConstructQueue::const_iterator item) { +static mlir::Operation * +genScopeOp(lower::AbstractConverter &converter, lower::SymMap &symTable, + semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval, + mlir::Location loc, const ConstructQueue &queue, + ConstructQueue::const_iterator item) { TODO(loc, "Scope construct"); + return nullptr; } static mlir::omp::SingleOp @@ -2183,11 +2182,11 @@ genSingleOp(lower::AbstractConverter &converter, lower::SymMap &symTable, static mlir::omp::TargetOp genTargetOp(lower::AbstractConverter &converter, lower::SymMap &symTable, + lower::StatementContext &stmtCtx, semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval, mlir::Location loc, const ConstructQueue &queue, ConstructQueue::const_iterator item) { fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder(); - lower::StatementContext stmtCtx; bool isTargetDevice = llvm::cast(*converter.getModuleOp()) .getIsTargetDevice(); @@ -2366,13 +2365,11 @@ genTargetOp(lower::AbstractConverter &converter, lower::SymMap &symTable, return targetOp; } -static mlir::omp::TargetDataOp -genTargetDataOp(lower::AbstractConverter &converter, lower::SymMap &symTable, - semantics::SemanticsContext &semaCtx, - lower::pft::Evaluation &eval, mlir::Location loc, - const ConstructQueue &queue, - ConstructQueue::const_iterator item) { - lower::StatementContext stmtCtx; +static mlir::omp::TargetDataOp genTargetDataOp( + lower::AbstractConverter &converter, lower::SymMap &symTable, + lower::StatementContext &stmtCtx, semantics::SemanticsContext &semaCtx, + lower::pft::Evaluation &eval, mlir::Location loc, + const ConstructQueue &queue, ConstructQueue::const_iterator item) { mlir::omp::TargetDataOperands clauseOps; llvm::SmallVector useDeviceAddrSyms, useDevicePtrSyms; @@ -2402,10 +2399,10 @@ genTargetDataOp(lower::AbstractConverter &converter, lower::SymMap &symTable, template static OpTy genTargetEnterExitUpdateDataOp( lower::AbstractConverter &converter, lower::SymMap &symTable, - semantics::SemanticsContext &semaCtx, mlir::Location loc, - const ConstructQueue &queue, ConstructQueue::const_iterator item) { + lower::StatementContext &stmtCtx, semantics::SemanticsContext &semaCtx, + mlir::Location loc, const ConstructQueue &queue, + ConstructQueue::const_iterator item) { fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder(); - lower::StatementContext stmtCtx; // GCC 9.3.0 emits a (probably) bogus warning about an unused variable. [[maybe_unused]] llvm::omp::Directive directive; @@ -2428,10 +2425,10 @@ static OpTy genTargetEnterExitUpdateDataOp( static mlir::omp::TaskOp genTaskOp(lower::AbstractConverter &converter, lower::SymMap &symTable, + lower::StatementContext &stmtCtx, semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval, mlir::Location loc, const ConstructQueue &queue, ConstructQueue::const_iterator item) { - lower::StatementContext stmtCtx; mlir::omp::TaskOperands clauseOps; genTaskClauses(converter, semaCtx, symTable, stmtCtx, item->clauses, loc, clauseOps); @@ -2498,13 +2495,11 @@ genTaskyieldOp(lower::AbstractConverter &converter, lower::SymMap &symTable, return converter.getFirOpBuilder().create(loc); } -static mlir::omp::WorkshareOp -genWorkshareOp(lower::AbstractConverter &converter, lower::SymMap &symTable, - semantics::SemanticsContext &semaCtx, - lower::pft::Evaluation &eval, mlir::Location loc, - const ConstructQueue &queue, - ConstructQueue::const_iterator item) { - lower::StatementContext stmtCtx; +static mlir::omp::WorkshareOp genWorkshareOp( + lower::AbstractConverter &converter, lower::SymMap &symTable, + lower::StatementContext &stmtCtx, semantics::SemanticsContext &semaCtx, + lower::pft::Evaluation &eval, mlir::Location loc, + const ConstructQueue &queue, ConstructQueue::const_iterator item) { mlir::omp::WorkshareOperands clauseOps; genWorkshareClauses(converter, semaCtx, stmtCtx, item->clauses, loc, clauseOps); @@ -2518,11 +2513,10 @@ genWorkshareOp(lower::AbstractConverter &converter, lower::SymMap &symTable, static mlir::omp::TeamsOp genTeamsOp(lower::AbstractConverter &converter, lower::SymMap &symTable, + lower::StatementContext &stmtCtx, semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval, mlir::Location loc, const ConstructQueue &queue, ConstructQueue::const_iterator item) { - lower::StatementContext stmtCtx; - mlir::omp::TeamsOperands clauseOps; llvm::SmallVector reductionSyms; genTeamsClauses(converter, semaCtx, stmtCtx, item->clauses, loc, clauseOps, @@ -2546,15 +2540,11 @@ genTeamsOp(lower::AbstractConverter &converter, lower::SymMap &symTable, // 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::const_iterator item) { - lower::StatementContext stmtCtx; - +static mlir::omp::DistributeOp genStandaloneDistribute( + lower::AbstractConverter &converter, lower::SymMap &symTable, + lower::StatementContext &stmtCtx, semantics::SemanticsContext &semaCtx, + lower::pft::Evaluation &eval, mlir::Location loc, + const ConstructQueue &queue, ConstructQueue::const_iterator item) { mlir::omp::DistributeOperands distributeClauseOps; genDistributeClauses(converter, semaCtx, stmtCtx, item->clauses, loc, distributeClauseOps); @@ -2578,16 +2568,14 @@ static void genStandaloneDistribute(lower::AbstractConverter &converter, genLoopNestOp(converter, symTable, semaCtx, eval, loc, queue, item, loopNestClauseOps, iv, {{distributeOp, distributeArgs}}, llvm::omp::Directive::OMPD_distribute, dsp); + return distributeOp; } -static void genStandaloneDo(lower::AbstractConverter &converter, - lower::SymMap &symTable, - semantics::SemanticsContext &semaCtx, - lower::pft::Evaluation &eval, mlir::Location loc, - const ConstructQueue &queue, - ConstructQueue::const_iterator item) { - lower::StatementContext stmtCtx; - +static mlir::omp::WsloopOp genStandaloneDo( + lower::AbstractConverter &converter, lower::SymMap &symTable, + lower::StatementContext &stmtCtx, semantics::SemanticsContext &semaCtx, + lower::pft::Evaluation &eval, mlir::Location loc, + const ConstructQueue &queue, ConstructQueue::const_iterator item) { mlir::omp::WsloopOperands wsloopClauseOps; llvm::SmallVector wsloopReductionSyms; genWsloopClauses(converter, semaCtx, stmtCtx, item->clauses, loc, @@ -2614,17 +2602,14 @@ static void genStandaloneDo(lower::AbstractConverter &converter, genLoopNestOp(converter, symTable, semaCtx, eval, loc, queue, item, loopNestClauseOps, iv, {{wsloopOp, wsloopArgs}}, llvm::omp::Directive::OMPD_do, dsp); + return wsloopOp; } -static void genStandaloneParallel(lower::AbstractConverter &converter, - lower::SymMap &symTable, - semantics::SemanticsContext &semaCtx, - lower::pft::Evaluation &eval, - mlir::Location loc, - const ConstructQueue &queue, - ConstructQueue::const_iterator item) { - lower::StatementContext stmtCtx; - +static mlir::omp::ParallelOp genStandaloneParallel( + lower::AbstractConverter &converter, lower::SymMap &symTable, + lower::StatementContext &stmtCtx, semantics::SemanticsContext &semaCtx, + lower::pft::Evaluation &eval, mlir::Location loc, + const ConstructQueue &queue, ConstructQueue::const_iterator item) { mlir::omp::ParallelOperands parallelClauseOps; llvm::SmallVector parallelReductionSyms; genParallelClauses(converter, semaCtx, stmtCtx, item->clauses, loc, @@ -2644,17 +2629,17 @@ static void genStandaloneParallel(lower::AbstractConverter &converter, parallelArgs.priv.vars = parallelClauseOps.privateVars; parallelArgs.reduction.syms = parallelReductionSyms; parallelArgs.reduction.vars = parallelClauseOps.reductionVars; - genParallelOp(converter, symTable, semaCtx, eval, loc, queue, item, - parallelClauseOps, parallelArgs, - enableDelayedPrivatization ? &dsp.value() : nullptr); + return genParallelOp(converter, symTable, semaCtx, eval, loc, queue, item, + parallelClauseOps, parallelArgs, + enableDelayedPrivatization ? &dsp.value() : nullptr); } -static void genStandaloneSimd(lower::AbstractConverter &converter, - lower::SymMap &symTable, - semantics::SemanticsContext &semaCtx, - lower::pft::Evaluation &eval, mlir::Location loc, - const ConstructQueue &queue, - ConstructQueue::const_iterator item) { +static mlir::omp::SimdOp +genStandaloneSimd(lower::AbstractConverter &converter, lower::SymMap &symTable, + semantics::SemanticsContext &semaCtx, + lower::pft::Evaluation &eval, mlir::Location loc, + const ConstructQueue &queue, + ConstructQueue::const_iterator item) { mlir::omp::SimdOperands simdClauseOps; llvm::SmallVector simdReductionSyms; genSimdClauses(converter, semaCtx, item->clauses, loc, simdClauseOps, @@ -2681,29 +2666,27 @@ static void genStandaloneSimd(lower::AbstractConverter &converter, genLoopNestOp(converter, symTable, semaCtx, eval, loc, queue, item, loopNestClauseOps, iv, {{simdOp, simdArgs}}, llvm::omp::Directive::OMPD_simd, dsp); + return simdOp; } -static void genStandaloneTaskloop(lower::AbstractConverter &converter, - lower::SymMap &symTable, - semantics::SemanticsContext &semaCtx, - lower::pft::Evaluation &eval, - mlir::Location loc, - const ConstructQueue &queue, - ConstructQueue::const_iterator item) { +static mlir::omp::TaskloopOp genStandaloneTaskloop( + lower::AbstractConverter &converter, lower::SymMap &symTable, + semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval, + mlir::Location loc, const ConstructQueue &queue, + ConstructQueue::const_iterator item) { TODO(loc, "Taskloop construct"); + return nullptr; } //===----------------------------------------------------------------------===// // Code generation functions for composite constructs //===----------------------------------------------------------------------===// -static void genCompositeDistributeParallelDo( +static mlir::omp::DistributeOp genCompositeDistributeParallelDo( lower::AbstractConverter &converter, lower::SymMap &symTable, - semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval, - mlir::Location loc, const ConstructQueue &queue, - ConstructQueue::const_iterator item) { - lower::StatementContext stmtCtx; - + lower::StatementContext &stmtCtx, semantics::SemanticsContext &semaCtx, + lower::pft::Evaluation &eval, mlir::Location loc, + const ConstructQueue &queue, ConstructQueue::const_iterator item) { assert(std::distance(item, queue.end()) == 3 && "Invalid leaf constructs"); ConstructQueue::const_iterator distributeItem = item; ConstructQueue::const_iterator parallelItem = std::next(distributeItem); @@ -2762,15 +2745,14 @@ static void genCompositeDistributeParallelDo( loopNestClauseOps, iv, {{distributeOp, distributeArgs}, {wsloopOp, wsloopArgs}}, llvm::omp::Directive::OMPD_distribute_parallel_do, dsp); + return distributeOp; } -static void genCompositeDistributeParallelDoSimd( +static mlir::omp::DistributeOp genCompositeDistributeParallelDoSimd( lower::AbstractConverter &converter, lower::SymMap &symTable, - semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval, - mlir::Location loc, const ConstructQueue &queue, - ConstructQueue::const_iterator item) { - lower::StatementContext stmtCtx; - + lower::StatementContext &stmtCtx, semantics::SemanticsContext &semaCtx, + lower::pft::Evaluation &eval, mlir::Location loc, + const ConstructQueue &queue, ConstructQueue::const_iterator item) { assert(std::distance(item, queue.end()) == 4 && "Invalid leaf constructs"); ConstructQueue::const_iterator distributeItem = item; ConstructQueue::const_iterator parallelItem = std::next(distributeItem); @@ -2854,17 +2836,14 @@ static void genCompositeDistributeParallelDoSimd( {simdOp, simdArgs}}, llvm::omp::Directive::OMPD_distribute_parallel_do_simd, simdItemDSP); + return distributeOp; } -static void genCompositeDistributeSimd(lower::AbstractConverter &converter, - lower::SymMap &symTable, - semantics::SemanticsContext &semaCtx, - lower::pft::Evaluation &eval, - mlir::Location loc, - const ConstructQueue &queue, - ConstructQueue::const_iterator item) { - lower::StatementContext stmtCtx; - +static mlir::omp::DistributeOp genCompositeDistributeSimd( + lower::AbstractConverter &converter, lower::SymMap &symTable, + lower::StatementContext &stmtCtx, semantics::SemanticsContext &semaCtx, + lower::pft::Evaluation &eval, mlir::Location loc, + const ConstructQueue &queue, ConstructQueue::const_iterator item) { assert(std::distance(item, queue.end()) == 2 && "Invalid leaf constructs"); ConstructQueue::const_iterator distributeItem = item; ConstructQueue::const_iterator simdItem = std::next(distributeItem); @@ -2911,16 +2890,14 @@ static void genCompositeDistributeSimd(lower::AbstractConverter &converter, loopNestClauseOps, iv, {{distributeOp, distributeArgs}, {simdOp, simdArgs}}, llvm::omp::Directive::OMPD_distribute_simd, dsp); + return distributeOp; } -static void genCompositeDoSimd(lower::AbstractConverter &converter, - lower::SymMap &symTable, - semantics::SemanticsContext &semaCtx, - lower::pft::Evaluation &eval, mlir::Location loc, - const ConstructQueue &queue, - ConstructQueue::const_iterator item) { - lower::StatementContext stmtCtx; - +static mlir::omp::WsloopOp genCompositeDoSimd( + lower::AbstractConverter &converter, lower::SymMap &symTable, + lower::StatementContext &stmtCtx, semantics::SemanticsContext &semaCtx, + lower::pft::Evaluation &eval, mlir::Location loc, + const ConstructQueue &queue, ConstructQueue::const_iterator item) { assert(std::distance(item, queue.end()) == 2 && "Invalid leaf constructs"); ConstructQueue::const_iterator doItem = item; ConstructQueue::const_iterator simdItem = std::next(doItem); @@ -2970,30 +2947,29 @@ static void genCompositeDoSimd(lower::AbstractConverter &converter, loopNestClauseOps, iv, {{wsloopOp, wsloopArgs}, {simdOp, simdArgs}}, llvm::omp::Directive::OMPD_do_simd, dsp); + return wsloopOp; } -static void genCompositeTaskloopSimd(lower::AbstractConverter &converter, - lower::SymMap &symTable, - semantics::SemanticsContext &semaCtx, - lower::pft::Evaluation &eval, - mlir::Location loc, - const ConstructQueue &queue, - ConstructQueue::const_iterator item) { +static mlir::omp::TaskloopOp genCompositeTaskloopSimd( + lower::AbstractConverter &converter, lower::SymMap &symTable, + lower::StatementContext &stmtCtx, semantics::SemanticsContext &semaCtx, + lower::pft::Evaluation &eval, mlir::Location loc, + const ConstructQueue &queue, ConstructQueue::const_iterator item) { assert(std::distance(item, queue.end()) == 2 && "Invalid leaf constructs"); TODO(loc, "Composite TASKLOOP SIMD"); + return nullptr; } //===----------------------------------------------------------------------===// // Dispatch //===----------------------------------------------------------------------===// -static bool genOMPCompositeDispatch(lower::AbstractConverter &converter, - lower::SymMap &symTable, - semantics::SemanticsContext &semaCtx, - lower::pft::Evaluation &eval, - mlir::Location loc, - const ConstructQueue &queue, - ConstructQueue::const_iterator item) { +static bool genOMPCompositeDispatch( + lower::AbstractConverter &converter, lower::SymMap &symTable, + lower::StatementContext &stmtCtx, semantics::SemanticsContext &semaCtx, + lower::pft::Evaluation &eval, mlir::Location loc, + const ConstructQueue &queue, ConstructQueue::const_iterator item, + mlir::Operation *&newOp) { using llvm::omp::Directive; using lower::omp::matchLeafSequence; @@ -3002,20 +2978,21 @@ static bool genOMPCompositeDispatch(lower::AbstractConverter &converter, // correct. Consider per-leaf privatization of composite constructs once // delayed privatization is supported by all participating ops. if (matchLeafSequence(item, queue, Directive::OMPD_distribute_parallel_do)) - genCompositeDistributeParallelDo(converter, symTable, semaCtx, eval, loc, - queue, item); + newOp = genCompositeDistributeParallelDo(converter, symTable, stmtCtx, + semaCtx, eval, loc, queue, item); else if (matchLeafSequence(item, queue, Directive::OMPD_distribute_parallel_do_simd)) - genCompositeDistributeParallelDoSimd(converter, symTable, semaCtx, eval, - loc, queue, item); + newOp = genCompositeDistributeParallelDoSimd( + converter, symTable, stmtCtx, semaCtx, eval, loc, queue, item); else if (matchLeafSequence(item, queue, Directive::OMPD_distribute_simd)) - genCompositeDistributeSimd(converter, symTable, semaCtx, eval, loc, queue, - item); + newOp = genCompositeDistributeSimd(converter, symTable, stmtCtx, semaCtx, + eval, loc, queue, item); else if (matchLeafSequence(item, queue, Directive::OMPD_do_simd)) - genCompositeDoSimd(converter, symTable, semaCtx, eval, loc, queue, item); + newOp = genCompositeDoSimd(converter, symTable, stmtCtx, semaCtx, eval, loc, + queue, item); else if (matchLeafSequence(item, queue, Directive::OMPD_taskloop_simd)) - genCompositeTaskloopSimd(converter, symTable, semaCtx, eval, loc, queue, - item); + newOp = genCompositeTaskloopSimd(converter, symTable, stmtCtx, semaCtx, + eval, loc, queue, item); else return false; @@ -3030,46 +3007,64 @@ static void genOMPDispatch(lower::AbstractConverter &converter, ConstructQueue::const_iterator item) { assert(item != queue.end()); + lower::StatementContext stmtCtx; + mlir::Operation *newOp = nullptr; + + // Generate cleanup code for the stmtCtx after newOp + auto finalizeStmtCtx = [&]() { + if (newOp) { + fir::FirOpBuilder &builder = converter.getFirOpBuilder(); + fir::FirOpBuilder::InsertionGuard guard(builder); + builder.setInsertionPointAfter(newOp); + stmtCtx.finalizeAndPop(); + } + }; + bool loopLeaf = llvm::omp::getDirectiveAssociation(item->id) == llvm::omp::Association::Loop; if (loopLeaf) { symTable.pushScope(); - if (genOMPCompositeDispatch(converter, symTable, semaCtx, eval, loc, queue, - item)) { + if (genOMPCompositeDispatch(converter, symTable, stmtCtx, semaCtx, eval, + loc, queue, item, newOp)) { symTable.popScope(); + finalizeStmtCtx(); return; } } switch (llvm::omp::Directive dir = item->id) { case llvm::omp::Directive::OMPD_barrier: - genBarrierOp(converter, symTable, semaCtx, eval, loc, queue, item); + newOp = genBarrierOp(converter, symTable, semaCtx, eval, loc, queue, item); break; case llvm::omp::Directive::OMPD_distribute: - genStandaloneDistribute(converter, symTable, semaCtx, eval, loc, queue, - item); + newOp = genStandaloneDistribute(converter, symTable, stmtCtx, semaCtx, eval, + loc, queue, item); break; case llvm::omp::Directive::OMPD_do: - genStandaloneDo(converter, symTable, semaCtx, eval, loc, queue, item); + newOp = genStandaloneDo(converter, symTable, stmtCtx, semaCtx, eval, loc, + queue, item); break; case llvm::omp::Directive::OMPD_loop: - genLoopOp(converter, symTable, semaCtx, eval, loc, queue, item); + newOp = genLoopOp(converter, symTable, semaCtx, eval, loc, queue, item); break; case llvm::omp::Directive::OMPD_masked: - genMaskedOp(converter, symTable, semaCtx, eval, loc, queue, item); + newOp = genMaskedOp(converter, symTable, stmtCtx, semaCtx, eval, loc, queue, + item); break; case llvm::omp::Directive::OMPD_master: - genMasterOp(converter, symTable, semaCtx, eval, loc, queue, item); + newOp = genMasterOp(converter, symTable, semaCtx, eval, loc, queue, item); break; case llvm::omp::Directive::OMPD_ordered: // Block-associated "ordered" construct. - genOrderedRegionOp(converter, symTable, semaCtx, eval, loc, queue, item); + newOp = genOrderedRegionOp(converter, symTable, semaCtx, eval, loc, queue, + item); break; case llvm::omp::Directive::OMPD_parallel: - genStandaloneParallel(converter, symTable, semaCtx, eval, loc, queue, item); + newOp = genStandaloneParallel(converter, symTable, stmtCtx, semaCtx, eval, + loc, queue, item); break; case llvm::omp::Directive::OMPD_scan: - genScanOp(converter, symTable, semaCtx, loc, queue, item); + newOp = genScanOp(converter, symTable, semaCtx, loc, queue, item); break; case llvm::omp::Directive::OMPD_section: llvm_unreachable("genOMPDispatch: OMPD_section"); @@ -3082,49 +3077,57 @@ static void genOMPDispatch(lower::AbstractConverter &converter, // in genBodyOfOp break; case llvm::omp::Directive::OMPD_simd: - genStandaloneSimd(converter, symTable, semaCtx, eval, loc, queue, item); + newOp = + genStandaloneSimd(converter, symTable, semaCtx, eval, loc, queue, item); break; case llvm::omp::Directive::OMPD_scope: - genScopeOp(converter, symTable, semaCtx, eval, loc, queue, item); + newOp = genScopeOp(converter, symTable, semaCtx, eval, loc, queue, item); break; case llvm::omp::Directive::OMPD_single: - genSingleOp(converter, symTable, semaCtx, eval, loc, queue, item); + newOp = genSingleOp(converter, symTable, semaCtx, eval, loc, queue, item); break; case llvm::omp::Directive::OMPD_target: - genTargetOp(converter, symTable, semaCtx, eval, loc, queue, item); + newOp = genTargetOp(converter, symTable, stmtCtx, semaCtx, eval, loc, queue, + item); break; case llvm::omp::Directive::OMPD_target_data: - genTargetDataOp(converter, symTable, semaCtx, eval, loc, queue, item); + newOp = genTargetDataOp(converter, symTable, stmtCtx, semaCtx, eval, loc, + queue, item); break; case llvm::omp::Directive::OMPD_target_enter_data: - genTargetEnterExitUpdateDataOp( - converter, symTable, semaCtx, loc, queue, item); + newOp = genTargetEnterExitUpdateDataOp( + converter, symTable, stmtCtx, semaCtx, loc, queue, item); break; case llvm::omp::Directive::OMPD_target_exit_data: - genTargetEnterExitUpdateDataOp( - converter, symTable, semaCtx, loc, queue, item); + newOp = genTargetEnterExitUpdateDataOp( + converter, symTable, stmtCtx, semaCtx, loc, queue, item); break; case llvm::omp::Directive::OMPD_target_update: - genTargetEnterExitUpdateDataOp( - converter, symTable, semaCtx, loc, queue, item); + newOp = genTargetEnterExitUpdateDataOp( + converter, symTable, stmtCtx, semaCtx, loc, queue, item); break; case llvm::omp::Directive::OMPD_task: - genTaskOp(converter, symTable, semaCtx, eval, loc, queue, item); + newOp = genTaskOp(converter, symTable, stmtCtx, semaCtx, eval, loc, queue, + item); break; case llvm::omp::Directive::OMPD_taskgroup: - genTaskgroupOp(converter, symTable, semaCtx, eval, loc, queue, item); + newOp = + genTaskgroupOp(converter, symTable, semaCtx, eval, loc, queue, item); break; case llvm::omp::Directive::OMPD_taskloop: - genStandaloneTaskloop(converter, symTable, semaCtx, eval, loc, queue, item); + newOp = genStandaloneTaskloop(converter, symTable, semaCtx, eval, loc, + queue, item); break; case llvm::omp::Directive::OMPD_taskwait: - genTaskwaitOp(converter, symTable, semaCtx, eval, loc, queue, item); + newOp = genTaskwaitOp(converter, symTable, semaCtx, eval, loc, queue, item); break; case llvm::omp::Directive::OMPD_taskyield: - genTaskyieldOp(converter, symTable, semaCtx, eval, loc, queue, item); + newOp = + genTaskyieldOp(converter, symTable, semaCtx, eval, loc, queue, item); break; case llvm::omp::Directive::OMPD_teams: - genTeamsOp(converter, symTable, semaCtx, eval, loc, queue, item); + newOp = genTeamsOp(converter, symTable, stmtCtx, semaCtx, eval, loc, queue, + item); break; case llvm::omp::Directive::OMPD_tile: case llvm::omp::Directive::OMPD_unroll: @@ -3132,7 +3135,8 @@ static void genOMPDispatch(lower::AbstractConverter &converter, llvm::omp::getOpenMPDirectiveName(dir) + ")"); // case llvm::omp::Directive::OMPD_workdistribute: case llvm::omp::Directive::OMPD_workshare: - genWorkshareOp(converter, symTable, semaCtx, eval, loc, queue, item); + newOp = genWorkshareOp(converter, symTable, stmtCtx, semaCtx, eval, loc, + queue, item); break; default: // Combined and composite constructs should have been split into a sequence @@ -3142,6 +3146,7 @@ static void genOMPDispatch(lower::AbstractConverter &converter, break; } + finalizeStmtCtx(); if (loopLeaf) symTable.popScope(); } diff --git a/flang/test/Lower/OpenMP/clause-cleanup.f90 b/flang/test/Lower/OpenMP/clause-cleanup.f90 new file mode 100644 index 0000000000000..79de44cf42c72 --- /dev/null +++ b/flang/test/Lower/OpenMP/clause-cleanup.f90 @@ -0,0 +1,17 @@ +!RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s + +subroutine test1(a) +integer :: a(:) + +!$omp parallel num_threads(count(a .eq. 1)) +print *, "don't optimize me" +!$omp end parallel +end subroutine + +! CHECK: %[[EXPR:.*]] = hlfir.elemental {{.*}} -> !hlfir.expr> +! CHECK: %[[COUNT:.*]] = hlfir.count %[[EXPR]] +! CHECK: omp.parallel num_threads(%[[COUNT]] : i32) { +! CHECK-NOT: hlfir.destory %[[EXPR]] +! CHECK: omp.terminator +! CHECK: } +! CHECK: hlfir.destroy %[[EXPR]]