@@ -268,7 +268,6 @@ static LogicalResult checkImplementationStatus(Operation &op) {
268268 checkAllocate (op, result);
269269 checkLinear (op, result);
270270 checkOrder (op, result);
271- checkPrivate (op, result);
272271 })
273272 .Case ([&](omp::ParallelOp op) { checkAllocate (op, result); })
274273 .Case ([&](omp::SimdOp op) {
@@ -1302,6 +1301,7 @@ allocatePrivateVars(llvm::IRBuilderBase &builder,
13021301 MutableArrayRef<mlir::Value> mlirPrivateVars,
13031302 llvm::SmallVectorImpl<llvm::Value *> &llvmPrivateVars,
13041303 const llvm::OpenMPIRBuilder::InsertPointTy &allocaIP) {
1304+ llvm::IRBuilderBase::InsertPointGuard guard (builder);
13051305 // Allocate private vars
13061306 llvm::BranchInst *allocaTerminator =
13071307 llvm::cast<llvm::BranchInst>(allocaIP.getBlock ()->getTerminator ());
@@ -1363,6 +1363,84 @@ allocatePrivateVars(llvm::IRBuilderBase &builder,
13631363 return afterAllocas;
13641364}
13651365
1366+ static LogicalResult
1367+ initFirstPrivateVars (llvm::IRBuilderBase &builder,
1368+ LLVM::ModuleTranslation &moduleTranslation,
1369+ SmallVectorImpl<mlir::Value> &mlirPrivateVars,
1370+ SmallVectorImpl<llvm::Value *> &llvmPrivateVars,
1371+ SmallVectorImpl<omp::PrivateClauseOp> &privateDecls,
1372+ llvm::BasicBlock *afterAllocas) {
1373+ llvm::IRBuilderBase::InsertPointGuard guard (builder);
1374+ // Apply copy region for firstprivate.
1375+ bool needsFirstprivate =
1376+ llvm::any_of (privateDecls, [](omp::PrivateClauseOp &privOp) {
1377+ return privOp.getDataSharingType () ==
1378+ omp::DataSharingClauseType::FirstPrivate;
1379+ });
1380+
1381+ if (needsFirstprivate) {
1382+ // Find the end of the allocation blocks
1383+ builder.SetInsertPoint (
1384+ afterAllocas->getSinglePredecessor ()->getTerminator ());
1385+ llvm::BasicBlock *copyBlock =
1386+ splitBB (builder, /* CreateBranch=*/ true , " omp.private.copy" );
1387+ builder.SetInsertPoint (copyBlock->getFirstNonPHIOrDbgOrAlloca ());
1388+ }
1389+
1390+ for (auto [decl, mlirVar, llvmVar] :
1391+ llvm::zip_equal (privateDecls, mlirPrivateVars, llvmPrivateVars)) {
1392+ if (decl.getDataSharingType () != omp::DataSharingClauseType::FirstPrivate)
1393+ continue ;
1394+
1395+ // copyRegion implements `lhs = rhs`
1396+ Region ©Region = decl.getCopyRegion ();
1397+
1398+ // map copyRegion rhs arg
1399+ llvm::Value *nonPrivateVar = moduleTranslation.lookupValue (mlirVar);
1400+ assert (nonPrivateVar);
1401+ moduleTranslation.mapValue (decl.getCopyMoldArg (), nonPrivateVar);
1402+
1403+ // map copyRegion lhs arg
1404+ moduleTranslation.mapValue (decl.getCopyPrivateArg (), llvmVar);
1405+
1406+ // in-place convert copy region
1407+ builder.SetInsertPoint (builder.GetInsertBlock ()->getTerminator ());
1408+ if (failed (inlineConvertOmpRegions (copyRegion, " omp.private.copy" , builder,
1409+ moduleTranslation)))
1410+ return decl.emitError (" failed to inline `copy` region of `omp.private`" );
1411+
1412+ // ignore unused value yielded from copy region
1413+
1414+ // clear copy region block argument mapping in case it needs to be
1415+ // re-created with different sources for reuse of the same reduction
1416+ // decl
1417+ moduleTranslation.forgetMapping (copyRegion);
1418+ }
1419+
1420+ return success ();
1421+ }
1422+
1423+ static LogicalResult
1424+ cleanupPrivateVars (llvm::IRBuilderBase &builder,
1425+ LLVM::ModuleTranslation &moduleTranslation, Location loc,
1426+ SmallVectorImpl<llvm::Value *> &llvmPrivateVars,
1427+ SmallVectorImpl<omp::PrivateClauseOp> &privateDecls) {
1428+ // private variable deallocation
1429+ SmallVector<Region *> privateCleanupRegions;
1430+ llvm::transform (privateDecls, std::back_inserter (privateCleanupRegions),
1431+ [](omp::PrivateClauseOp privatizer) {
1432+ return &privatizer.getDeallocRegion ();
1433+ });
1434+
1435+ if (failed (inlineOmpRegionCleanup (
1436+ privateCleanupRegions, llvmPrivateVars, moduleTranslation, builder,
1437+ " omp.private.dealloc" , /* shouldLoadCleanupRegionArg=*/ false )))
1438+ return mlir::emitError (loc, " failed to inline `dealloc` region of an "
1439+ " `omp.private` op in an omp.task" );
1440+
1441+ return success ();
1442+ }
1443+
13661444static LogicalResult
13671445convertOmpSections (Operation &opInst, llvm::IRBuilderBase &builder,
13681446 LLVM::ModuleTranslation &moduleTranslation) {
@@ -1622,50 +1700,10 @@ convertOmpTaskOp(omp::TaskOp taskOp, llvm::IRBuilderBase &builder,
16221700 if (handleError (afterAllocas, *taskOp).failed ())
16231701 return llvm::make_error<PreviouslyReportedError>();
16241702
1625- // Apply copy region for firstprivate
1626- bool needsFirstPrivate =
1627- llvm::any_of (privateDecls, [](omp::PrivateClauseOp &privOp) {
1628- return privOp.getDataSharingType () ==
1629- omp::DataSharingClauseType::FirstPrivate;
1630- });
1631- if (needsFirstPrivate) {
1632- // Find the end of the allocation blocks
1633- assert (afterAllocas.get ()->getSinglePredecessor ());
1634- builder.SetInsertPoint (
1635- afterAllocas.get ()->getSinglePredecessor ()->getTerminator ());
1636- llvm::BasicBlock *copyBlock =
1637- splitBB (builder, /* CreateBranch=*/ true , " omp.private.copy" );
1638- builder.SetInsertPoint (copyBlock->getFirstNonPHIOrDbgOrAlloca ());
1639- }
1640- for (auto [decl, mlirVar, llvmVar] :
1641- llvm::zip_equal (privateDecls, mlirPrivateVars, llvmPrivateVars)) {
1642- if (decl.getDataSharingType () != omp::DataSharingClauseType::FirstPrivate)
1643- continue ;
1644-
1645- // copyRegion implements `lhs = rhs`
1646- Region ©Region = decl.getCopyRegion ();
1647-
1648- // map copyRegion rhs arg
1649- llvm::Value *nonPrivateVar = moduleTranslation.lookupValue (mlirVar);
1650- assert (nonPrivateVar);
1651- moduleTranslation.mapValue (decl.getCopyMoldArg (), nonPrivateVar);
1652-
1653- // map copyRegion lhs arg
1654- moduleTranslation.mapValue (decl.getCopyPrivateArg (), llvmVar);
1655-
1656- // in-place convert copy region
1657- builder.SetInsertPoint (builder.GetInsertBlock ()->getTerminator ());
1658- if (failed (inlineConvertOmpRegions (copyRegion, " omp.private.copy" ,
1659- builder, moduleTranslation)))
1660- return llvm::createStringError (
1661- " failed to inline `copy` region of an `omp.private` op in taskOp" );
1662-
1663- // ignore unused value yielded from copy region
1664-
1665- // clear copy region block argument mapping in case it needs to be
1666- // re-created with different source for reuse of the same reduction decl
1667- moduleTranslation.forgetMapping (copyRegion);
1668- }
1703+ if (failed (initFirstPrivateVars (builder, moduleTranslation, mlirPrivateVars,
1704+ llvmPrivateVars, privateDecls,
1705+ afterAllocas.get ())))
1706+ return llvm::make_error<PreviouslyReportedError>();
16691707
16701708 // translate the body of the task:
16711709 builder.restoreIP (codegenIP);
@@ -1674,19 +1712,11 @@ convertOmpTaskOp(omp::TaskOp taskOp, llvm::IRBuilderBase &builder,
16741712 if (failed (handleError (continuationBlockOrError, *taskOp)))
16751713 return llvm::make_error<PreviouslyReportedError>();
16761714
1677- // private variable deallocation
1678- SmallVector<Region *> privateCleanupRegions;
1679- llvm::transform (privateDecls, std::back_inserter (privateCleanupRegions),
1680- [](omp::PrivateClauseOp privatizer) {
1681- return &privatizer.getDeallocRegion ();
1682- });
1683-
16841715 builder.SetInsertPoint (continuationBlockOrError.get ()->getTerminator ());
1685- if (failed (inlineOmpRegionCleanup (
1686- privateCleanupRegions, llvmPrivateVars, moduleTranslation, builder,
1687- " omp.private.dealloc" , /* shouldLoadCleanupRegionArg=*/ false )))
1688- return llvm::createStringError (" failed to inline `dealloc` region of an "
1689- " `omp.private` op in an omp.task" );
1716+
1717+ if (failed (cleanupPrivateVars (builder, moduleTranslation, taskOp.getLoc (),
1718+ llvmPrivateVars, privateDecls)))
1719+ return llvm::make_error<PreviouslyReportedError>();
16901720
16911721 return llvm::Error::success ();
16921722 };
@@ -1777,22 +1807,56 @@ convertOmpWsloop(Operation &opInst, llvm::IRBuilderBase &builder,
17771807 chunk = builder.CreateSExtOrTrunc (chunkVar, ivType);
17781808 }
17791809
1810+ MutableArrayRef<BlockArgument> privateBlockArgs =
1811+ cast<omp::BlockArgOpenMPOpInterface>(*wsloopOp).getPrivateBlockArgs ();
1812+ SmallVector<mlir::Value> mlirPrivateVars;
1813+ SmallVector<llvm::Value *> llvmPrivateVars;
1814+ SmallVector<omp::PrivateClauseOp> privateDecls;
1815+ mlirPrivateVars.reserve (privateBlockArgs.size ());
1816+ llvmPrivateVars.reserve (privateBlockArgs.size ());
1817+ collectPrivatizationDecls (wsloopOp, privateDecls);
1818+
1819+ for (mlir::Value privateVar : wsloopOp.getPrivateVars ())
1820+ mlirPrivateVars.push_back (privateVar);
1821+
17801822 SmallVector<omp::DeclareReductionOp> reductionDecls;
17811823 collectReductionDecls (wsloopOp, reductionDecls);
17821824 llvm::OpenMPIRBuilder::InsertPointTy allocaIP =
17831825 findAllocaInsertPoint (builder, moduleTranslation);
17841826
17851827 SmallVector<llvm::Value *> privateReductionVariables (
17861828 wsloopOp.getNumReductionVars ());
1829+
1830+ llvm::Expected<llvm::BasicBlock *> afterAllocas = allocatePrivateVars (
1831+ builder, moduleTranslation, privateBlockArgs, privateDecls,
1832+ mlirPrivateVars, llvmPrivateVars, allocaIP);
1833+ if (handleError (afterAllocas, opInst).failed ())
1834+ return failure ();
1835+
17871836 DenseMap<Value, llvm::Value *> reductionVariableMap;
17881837
17891838 MutableArrayRef<BlockArgument> reductionArgs =
17901839 cast<omp::BlockArgOpenMPOpInterface>(opInst).getReductionBlockArgs ();
17911840
1792- if (failed (allocAndInitializeReductionVars (
1793- wsloopOp, reductionArgs, builder, moduleTranslation, allocaIP,
1794- reductionDecls, privateReductionVariables, reductionVariableMap,
1795- isByRef)))
1841+ SmallVector<DeferredStore> deferredStores;
1842+
1843+ if (failed (allocReductionVars (wsloopOp, reductionArgs, builder,
1844+ moduleTranslation, allocaIP, reductionDecls,
1845+ privateReductionVariables, reductionVariableMap,
1846+ deferredStores, isByRef)))
1847+ return failure ();
1848+
1849+ if (failed (initFirstPrivateVars (builder, moduleTranslation, mlirPrivateVars,
1850+ llvmPrivateVars, privateDecls,
1851+ afterAllocas.get ())))
1852+ return failure ();
1853+
1854+ assert (afterAllocas.get ()->getSinglePredecessor ());
1855+ if (failed (initReductionVars (wsloopOp, reductionArgs, builder,
1856+ moduleTranslation,
1857+ afterAllocas.get ()->getSinglePredecessor (),
1858+ reductionDecls, privateReductionVariables,
1859+ reductionVariableMap, isByRef, deferredStores)))
17961860 return failure ();
17971861
17981862 // TODO: Replace this with proper composite translation support.
@@ -1899,9 +1963,13 @@ convertOmpWsloop(Operation &opInst, llvm::IRBuilderBase &builder,
18991963 builder.restoreIP (afterIP);
19001964
19011965 // Process the reductions if required.
1902- return createReductionsAndCleanup (wsloopOp, builder, moduleTranslation,
1903- allocaIP, reductionDecls,
1904- privateReductionVariables, isByRef);
1966+ if (failed (createReductionsAndCleanup (wsloopOp, builder, moduleTranslation,
1967+ allocaIP, reductionDecls,
1968+ privateReductionVariables, isByRef)))
1969+ return failure ();
1970+
1971+ return cleanupPrivateVars (builder, moduleTranslation, wsloopOp.getLoc (),
1972+ llvmPrivateVars, privateDecls);
19051973}
19061974
19071975// / Converts the OpenMP parallel operation to LLVM IR.
@@ -1959,53 +2027,12 @@ convertOmpParallel(omp::ParallelOp opInst, llvm::IRBuilderBase &builder,
19592027 deferredStores, isByRef)))
19602028 return llvm::make_error<PreviouslyReportedError>();
19612029
1962- // Apply copy region for firstprivate.
1963- bool needsFirstprivate =
1964- llvm::any_of (privateDecls, [](omp::PrivateClauseOp &privOp) {
1965- return privOp.getDataSharingType () ==
1966- omp::DataSharingClauseType::FirstPrivate;
1967- });
1968- if (needsFirstprivate) {
1969- // Find the end of the allocation blocks
1970- assert (afterAllocas.get ()->getSinglePredecessor ());
1971- builder.SetInsertPoint (
1972- afterAllocas.get ()->getSinglePredecessor ()->getTerminator ());
1973- llvm::BasicBlock *copyBlock =
1974- splitBB (builder, /* CreateBranch=*/ true , " omp.private.copy" );
1975- builder.SetInsertPoint (copyBlock->getFirstNonPHIOrDbgOrAlloca ());
1976- }
1977-
1978- for (auto [decl, mlirVar, llvmVar] :
1979- llvm::zip_equal (privateDecls, mlirPrivateVars, llvmPrivateVars)) {
1980- if (decl.getDataSharingType () != omp::DataSharingClauseType::FirstPrivate)
1981- continue ;
1982-
1983- // copyRegion implements `lhs = rhs`
1984- Region ©Region = decl.getCopyRegion ();
1985-
1986- // map copyRegion rhs arg
1987- llvm::Value *nonPrivateVar = moduleTranslation.lookupValue (mlirVar);
1988- assert (nonPrivateVar);
1989- moduleTranslation.mapValue (decl.getCopyMoldArg (), nonPrivateVar);
1990-
1991- // map copyRegion lhs arg
1992- moduleTranslation.mapValue (decl.getCopyPrivateArg (), llvmVar);
1993-
1994- // in-place convert copy region
1995- builder.SetInsertPoint (builder.GetInsertBlock ()->getTerminator ());
1996- if (failed (inlineConvertOmpRegions (copyRegion, " omp.private.copy" ,
1997- builder, moduleTranslation)))
1998- return llvm::createStringError (
1999- " failed to inline `copy` region of `omp.private`" );
2000-
2001- // ignore unused value yielded from copy region
2002-
2003- // clear copy region block argument mapping in case it needs to be
2004- // re-created with different sources for reuse of the same reduction
2005- // decl
2006- moduleTranslation.forgetMapping (copyRegion);
2007- }
2030+ if (failed (initFirstPrivateVars (builder, moduleTranslation, mlirPrivateVars,
2031+ llvmPrivateVars, privateDecls,
2032+ afterAllocas.get ())))
2033+ return llvm::make_error<PreviouslyReportedError>();
20082034
2035+ assert (afterAllocas.get ()->getSinglePredecessor ());
20092036 if (failed (
20102037 initReductionVars (opInst, reductionArgs, builder, moduleTranslation,
20112038 afterAllocas.get ()->getSinglePredecessor (),
@@ -2090,17 +2117,9 @@ convertOmpParallel(omp::ParallelOp opInst, llvm::IRBuilderBase &builder,
20902117 return llvm::createStringError (
20912118 " failed to inline `cleanup` region of `omp.declare_reduction`" );
20922119
2093- SmallVector<Region *> privateCleanupRegions;
2094- llvm::transform (privateDecls, std::back_inserter (privateCleanupRegions),
2095- [](omp::PrivateClauseOp privatizer) {
2096- return &privatizer.getDeallocRegion ();
2097- });
2098-
2099- if (failed (inlineOmpRegionCleanup (
2100- privateCleanupRegions, llvmPrivateVars, moduleTranslation, builder,
2101- " omp.private.dealloc" , /* shouldLoadCleanupRegionArg=*/ false )))
2102- return llvm::createStringError (
2103- " failed to inline `dealloc` region of `omp.private`" );
2120+ if (failed (cleanupPrivateVars (builder, moduleTranslation, opInst.getLoc (),
2121+ llvmPrivateVars, privateDecls)))
2122+ return llvm::make_error<PreviouslyReportedError>();
21042123
21052124 builder.restoreIP (oldIP);
21062125 return llvm::Error::success ();
0 commit comments