@@ -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,63 @@ 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+
13661423static LogicalResult
13671424convertOmpSections (Operation &opInst, llvm::IRBuilderBase &builder,
13681425 LLVM::ModuleTranslation &moduleTranslation) {
@@ -1622,50 +1679,10 @@ convertOmpTaskOp(omp::TaskOp taskOp, llvm::IRBuilderBase &builder,
16221679 if (handleError (afterAllocas, *taskOp).failed ())
16231680 return llvm::make_error<PreviouslyReportedError>();
16241681
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- }
1682+ if (failed (initFirstPrivateVars (builder, moduleTranslation, mlirPrivateVars,
1683+ llvmPrivateVars, privateDecls,
1684+ afterAllocas.get ())))
1685+ return llvm::make_error<PreviouslyReportedError>();
16691686
16701687 // translate the body of the task:
16711688 builder.restoreIP (codegenIP);
@@ -1777,22 +1794,56 @@ convertOmpWsloop(Operation &opInst, llvm::IRBuilderBase &builder,
17771794 chunk = builder.CreateSExtOrTrunc (chunkVar, ivType);
17781795 }
17791796
1797+ MutableArrayRef<BlockArgument> privateBlockArgs =
1798+ cast<omp::BlockArgOpenMPOpInterface>(*wsloopOp).getPrivateBlockArgs ();
1799+ SmallVector<mlir::Value> mlirPrivateVars;
1800+ SmallVector<llvm::Value *> llvmPrivateVars;
1801+ SmallVector<omp::PrivateClauseOp> privateDecls;
1802+ mlirPrivateVars.reserve (privateBlockArgs.size ());
1803+ llvmPrivateVars.reserve (privateBlockArgs.size ());
1804+ collectPrivatizationDecls (wsloopOp, privateDecls);
1805+
1806+ for (mlir::Value privateVar : wsloopOp.getPrivateVars ())
1807+ mlirPrivateVars.push_back (privateVar);
1808+
17801809 SmallVector<omp::DeclareReductionOp> reductionDecls;
17811810 collectReductionDecls (wsloopOp, reductionDecls);
17821811 llvm::OpenMPIRBuilder::InsertPointTy allocaIP =
17831812 findAllocaInsertPoint (builder, moduleTranslation);
17841813
17851814 SmallVector<llvm::Value *> privateReductionVariables (
17861815 wsloopOp.getNumReductionVars ());
1816+
1817+ llvm::Expected<llvm::BasicBlock *> afterAllocas = allocatePrivateVars (
1818+ builder, moduleTranslation, privateBlockArgs, privateDecls,
1819+ mlirPrivateVars, llvmPrivateVars, allocaIP);
1820+ if (handleError (afterAllocas, opInst).failed ())
1821+ return failure ();
1822+
17871823 DenseMap<Value, llvm::Value *> reductionVariableMap;
17881824
17891825 MutableArrayRef<BlockArgument> reductionArgs =
17901826 cast<omp::BlockArgOpenMPOpInterface>(opInst).getReductionBlockArgs ();
17911827
1792- if (failed (allocAndInitializeReductionVars (
1793- wsloopOp, reductionArgs, builder, moduleTranslation, allocaIP,
1794- reductionDecls, privateReductionVariables, reductionVariableMap,
1795- isByRef)))
1828+ SmallVector<DeferredStore> deferredStores;
1829+
1830+ if (failed (allocReductionVars (wsloopOp, reductionArgs, builder,
1831+ moduleTranslation, allocaIP, reductionDecls,
1832+ privateReductionVariables, reductionVariableMap,
1833+ deferredStores, isByRef)))
1834+ return failure ();
1835+
1836+ if (failed (initFirstPrivateVars (builder, moduleTranslation, mlirPrivateVars,
1837+ llvmPrivateVars, privateDecls,
1838+ afterAllocas.get ())))
1839+ return failure ();
1840+
1841+ assert (afterAllocas.get ()->getSinglePredecessor ());
1842+ if (failed (initReductionVars (wsloopOp, reductionArgs, builder,
1843+ moduleTranslation,
1844+ afterAllocas.get ()->getSinglePredecessor (),
1845+ reductionDecls, privateReductionVariables,
1846+ reductionVariableMap, isByRef, deferredStores)))
17961847 return failure ();
17971848
17981849 // TODO: Replace this with proper composite translation support.
@@ -1959,53 +2010,12 @@ convertOmpParallel(omp::ParallelOp opInst, llvm::IRBuilderBase &builder,
19592010 deferredStores, isByRef)))
19602011 return llvm::make_error<PreviouslyReportedError>();
19612012
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- }
2013+ if (failed (initFirstPrivateVars (builder, moduleTranslation, mlirPrivateVars,
2014+ llvmPrivateVars, privateDecls,
2015+ afterAllocas.get ())))
2016+ return llvm::make_error<PreviouslyReportedError>();
20082017
2018+ assert (afterAllocas.get ()->getSinglePredecessor ());
20092019 if (failed (
20102020 initReductionVars (opInst, reductionArgs, builder, moduleTranslation,
20112021 afterAllocas.get ()->getSinglePredecessor (),
0 commit comments