@@ -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,86 @@ 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+ return success ();
1383+
1384+ assert (afterAllocas->getSinglePredecessor ());
1385+
1386+ // Find the end of the allocation blocks
1387+ builder.SetInsertPoint (afterAllocas->getSinglePredecessor ()->getTerminator ());
1388+ llvm::BasicBlock *copyBlock =
1389+ splitBB (builder, /* CreateBranch=*/ true , " omp.private.copy" );
1390+ builder.SetInsertPoint (copyBlock->getFirstNonPHIOrDbgOrAlloca ());
1391+
1392+ for (auto [decl, mlirVar, llvmVar] :
1393+ llvm::zip_equal (privateDecls, mlirPrivateVars, llvmPrivateVars)) {
1394+ if (decl.getDataSharingType () != omp::DataSharingClauseType::FirstPrivate)
1395+ continue ;
1396+
1397+ // copyRegion implements `lhs = rhs`
1398+ Region ©Region = decl.getCopyRegion ();
1399+
1400+ // map copyRegion rhs arg
1401+ llvm::Value *nonPrivateVar = moduleTranslation.lookupValue (mlirVar);
1402+ assert (nonPrivateVar);
1403+ moduleTranslation.mapValue (decl.getCopyMoldArg (), nonPrivateVar);
1404+
1405+ // map copyRegion lhs arg
1406+ moduleTranslation.mapValue (decl.getCopyPrivateArg (), llvmVar);
1407+
1408+ // in-place convert copy region
1409+ builder.SetInsertPoint (builder.GetInsertBlock ()->getTerminator ());
1410+ if (failed (inlineConvertOmpRegions (copyRegion, " omp.private.copy" , builder,
1411+ moduleTranslation)))
1412+ return decl.emitError (" failed to inline `copy` region of `omp.private`" );
1413+
1414+ // ignore unused value yielded from copy region
1415+
1416+ // clear copy region block argument mapping in case it needs to be
1417+ // re-created with different sources for reuse of the same reduction
1418+ // decl
1419+ moduleTranslation.forgetMapping (copyRegion);
1420+ }
1421+
1422+ return success ();
1423+ }
1424+
1425+ static LogicalResult
1426+ cleanupPrivateVars (llvm::IRBuilderBase &builder,
1427+ LLVM::ModuleTranslation &moduleTranslation, Location loc,
1428+ SmallVectorImpl<llvm::Value *> &llvmPrivateVars,
1429+ SmallVectorImpl<omp::PrivateClauseOp> &privateDecls) {
1430+ // private variable deallocation
1431+ SmallVector<Region *> privateCleanupRegions;
1432+ llvm::transform (privateDecls, std::back_inserter (privateCleanupRegions),
1433+ [](omp::PrivateClauseOp privatizer) {
1434+ return &privatizer.getDeallocRegion ();
1435+ });
1436+
1437+ if (failed (inlineOmpRegionCleanup (
1438+ privateCleanupRegions, llvmPrivateVars, moduleTranslation, builder,
1439+ " omp.private.dealloc" , /* shouldLoadCleanupRegionArg=*/ false )))
1440+ return mlir::emitError (loc, " failed to inline `dealloc` region of an "
1441+ " `omp.private` op in" );
1442+
1443+ return success ();
1444+ }
1445+
13661446static LogicalResult
13671447convertOmpSections (Operation &opInst, llvm::IRBuilderBase &builder,
13681448 LLVM::ModuleTranslation &moduleTranslation) {
@@ -1622,50 +1702,10 @@ convertOmpTaskOp(omp::TaskOp taskOp, llvm::IRBuilderBase &builder,
16221702 if (handleError (afterAllocas, *taskOp).failed ())
16231703 return llvm::make_error<PreviouslyReportedError>();
16241704
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- }
1705+ if (failed (initFirstPrivateVars (builder, moduleTranslation, mlirPrivateVars,
1706+ llvmPrivateVars, privateDecls,
1707+ afterAllocas.get ())))
1708+ return llvm::make_error<PreviouslyReportedError>();
16691709
16701710 // translate the body of the task:
16711711 builder.restoreIP (codegenIP);
@@ -1674,19 +1714,11 @@ convertOmpTaskOp(omp::TaskOp taskOp, llvm::IRBuilderBase &builder,
16741714 if (failed (handleError (continuationBlockOrError, *taskOp)))
16751715 return llvm::make_error<PreviouslyReportedError>();
16761716
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-
16841717 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" );
1718+
1719+ if (failed (cleanupPrivateVars (builder, moduleTranslation, taskOp.getLoc (),
1720+ llvmPrivateVars, privateDecls)))
1721+ return llvm::make_error<PreviouslyReportedError>();
16901722
16911723 return llvm::Error::success ();
16921724 };
@@ -1777,22 +1809,56 @@ convertOmpWsloop(Operation &opInst, llvm::IRBuilderBase &builder,
17771809 chunk = builder.CreateSExtOrTrunc (chunkVar, ivType);
17781810 }
17791811
1812+ MutableArrayRef<BlockArgument> privateBlockArgs =
1813+ cast<omp::BlockArgOpenMPOpInterface>(*wsloopOp).getPrivateBlockArgs ();
1814+ SmallVector<mlir::Value> mlirPrivateVars;
1815+ SmallVector<llvm::Value *> llvmPrivateVars;
1816+ SmallVector<omp::PrivateClauseOp> privateDecls;
1817+ mlirPrivateVars.reserve (privateBlockArgs.size ());
1818+ llvmPrivateVars.reserve (privateBlockArgs.size ());
1819+ collectPrivatizationDecls (wsloopOp, privateDecls);
1820+
1821+ for (mlir::Value privateVar : wsloopOp.getPrivateVars ())
1822+ mlirPrivateVars.push_back (privateVar);
1823+
17801824 SmallVector<omp::DeclareReductionOp> reductionDecls;
17811825 collectReductionDecls (wsloopOp, reductionDecls);
17821826 llvm::OpenMPIRBuilder::InsertPointTy allocaIP =
17831827 findAllocaInsertPoint (builder, moduleTranslation);
17841828
17851829 SmallVector<llvm::Value *> privateReductionVariables (
17861830 wsloopOp.getNumReductionVars ());
1831+
1832+ llvm::Expected<llvm::BasicBlock *> afterAllocas = allocatePrivateVars (
1833+ builder, moduleTranslation, privateBlockArgs, privateDecls,
1834+ mlirPrivateVars, llvmPrivateVars, allocaIP);
1835+ if (handleError (afterAllocas, opInst).failed ())
1836+ return failure ();
1837+
17871838 DenseMap<Value, llvm::Value *> reductionVariableMap;
17881839
17891840 MutableArrayRef<BlockArgument> reductionArgs =
17901841 cast<omp::BlockArgOpenMPOpInterface>(opInst).getReductionBlockArgs ();
17911842
1792- if (failed (allocAndInitializeReductionVars (
1793- wsloopOp, reductionArgs, builder, moduleTranslation, allocaIP,
1794- reductionDecls, privateReductionVariables, reductionVariableMap,
1795- isByRef)))
1843+ SmallVector<DeferredStore> deferredStores;
1844+
1845+ if (failed (allocReductionVars (wsloopOp, reductionArgs, builder,
1846+ moduleTranslation, allocaIP, reductionDecls,
1847+ privateReductionVariables, reductionVariableMap,
1848+ deferredStores, isByRef)))
1849+ return failure ();
1850+
1851+ if (failed (initFirstPrivateVars (builder, moduleTranslation, mlirPrivateVars,
1852+ llvmPrivateVars, privateDecls,
1853+ afterAllocas.get ())))
1854+ return failure ();
1855+
1856+ assert (afterAllocas.get ()->getSinglePredecessor ());
1857+ if (failed (initReductionVars (wsloopOp, reductionArgs, builder,
1858+ moduleTranslation,
1859+ afterAllocas.get ()->getSinglePredecessor (),
1860+ reductionDecls, privateReductionVariables,
1861+ reductionVariableMap, isByRef, deferredStores)))
17961862 return failure ();
17971863
17981864 // TODO: Replace this with proper composite translation support.
@@ -1899,9 +1965,13 @@ convertOmpWsloop(Operation &opInst, llvm::IRBuilderBase &builder,
18991965 builder.restoreIP (afterIP);
19001966
19011967 // Process the reductions if required.
1902- return createReductionsAndCleanup (wsloopOp, builder, moduleTranslation,
1903- allocaIP, reductionDecls,
1904- privateReductionVariables, isByRef);
1968+ if (failed (createReductionsAndCleanup (wsloopOp, builder, moduleTranslation,
1969+ allocaIP, reductionDecls,
1970+ privateReductionVariables, isByRef)))
1971+ return failure ();
1972+
1973+ return cleanupPrivateVars (builder, moduleTranslation, wsloopOp.getLoc (),
1974+ llvmPrivateVars, privateDecls);
19051975}
19061976
19071977// / Converts the OpenMP parallel operation to LLVM IR.
@@ -1959,52 +2029,12 @@ convertOmpParallel(omp::ParallelOp opInst, llvm::IRBuilderBase &builder,
19592029 deferredStores, isByRef)))
19602030 return llvm::make_error<PreviouslyReportedError>();
19612031
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- for (auto [decl, mlirVar, llvmVar] :
1978- llvm::zip_equal (privateDecls, mlirPrivateVars, llvmPrivateVars)) {
1979- if (decl.getDataSharingType () != omp::DataSharingClauseType::FirstPrivate)
1980- continue ;
1981-
1982- // copyRegion implements `lhs = rhs`
1983- Region ©Region = decl.getCopyRegion ();
1984-
1985- // map copyRegion rhs arg
1986- llvm::Value *nonPrivateVar = moduleTranslation.lookupValue (mlirVar);
1987- assert (nonPrivateVar);
1988- moduleTranslation.mapValue (decl.getCopyMoldArg (), nonPrivateVar);
1989-
1990- // map copyRegion lhs arg
1991- moduleTranslation.mapValue (decl.getCopyPrivateArg (), llvmVar);
1992-
1993- // in-place convert copy region
1994- builder.SetInsertPoint (builder.GetInsertBlock ()->getTerminator ());
1995- if (failed (inlineConvertOmpRegions (copyRegion, " omp.private.copy" ,
1996- builder, moduleTranslation)))
1997- return llvm::createStringError (
1998- " failed to inline `copy` region of `omp.private`" );
1999-
2000- // ignore unused value yielded from copy region
2001-
2002- // clear copy region block argument mapping in case it needs to be
2003- // re-created with different sources for reuse of the same reduction
2004- // decl
2005- moduleTranslation.forgetMapping (copyRegion);
2006- }
2032+ if (failed (initFirstPrivateVars (builder, moduleTranslation, mlirPrivateVars,
2033+ llvmPrivateVars, privateDecls,
2034+ afterAllocas.get ())))
2035+ return llvm::make_error<PreviouslyReportedError>();
20072036
2037+ assert (afterAllocas.get ()->getSinglePredecessor ());
20082038 if (failed (
20092039 initReductionVars (opInst, reductionArgs, builder, moduleTranslation,
20102040 afterAllocas.get ()->getSinglePredecessor (),
@@ -2089,17 +2119,9 @@ convertOmpParallel(omp::ParallelOp opInst, llvm::IRBuilderBase &builder,
20892119 return llvm::createStringError (
20902120 " failed to inline `cleanup` region of `omp.declare_reduction`" );
20912121
2092- SmallVector<Region *> privateCleanupRegions;
2093- llvm::transform (privateDecls, std::back_inserter (privateCleanupRegions),
2094- [](omp::PrivateClauseOp privatizer) {
2095- return &privatizer.getDeallocRegion ();
2096- });
2097-
2098- if (failed (inlineOmpRegionCleanup (
2099- privateCleanupRegions, llvmPrivateVars, moduleTranslation, builder,
2100- " omp.private.dealloc" , /* shouldLoadCleanupRegionArg=*/ false )))
2101- return llvm::createStringError (
2102- " failed to inline `dealloc` region of `omp.private`" );
2122+ if (failed (cleanupPrivateVars (builder, moduleTranslation, opInst.getLoc (),
2123+ llvmPrivateVars, privateDecls)))
2124+ return llvm::make_error<PreviouslyReportedError>();
21032125
21042126 builder.restoreIP (oldIP);
21052127 return llvm::Error::success ();
0 commit comments