@@ -268,7 +268,6 @@ static LogicalResult checkImplementationStatus(Operation &op) {
268
268
checkAllocate (op, result);
269
269
checkLinear (op, result);
270
270
checkOrder (op, result);
271
- checkPrivate (op, result);
272
271
})
273
272
.Case ([&](omp::ParallelOp op) { checkAllocate (op, result); })
274
273
.Case ([&](omp::SimdOp op) {
@@ -1302,6 +1301,7 @@ allocatePrivateVars(llvm::IRBuilderBase &builder,
1302
1301
MutableArrayRef<mlir::Value> mlirPrivateVars,
1303
1302
llvm::SmallVectorImpl<llvm::Value *> &llvmPrivateVars,
1304
1303
const llvm::OpenMPIRBuilder::InsertPointTy &allocaIP) {
1304
+ llvm::IRBuilderBase::InsertPointGuard guard (builder);
1305
1305
// Allocate private vars
1306
1306
llvm::BranchInst *allocaTerminator =
1307
1307
llvm::cast<llvm::BranchInst>(allocaIP.getBlock ()->getTerminator ());
@@ -1363,6 +1363,86 @@ allocatePrivateVars(llvm::IRBuilderBase &builder,
1363
1363
return afterAllocas;
1364
1364
}
1365
1365
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
+
1366
1446
static LogicalResult
1367
1447
convertOmpSections (Operation &opInst, llvm::IRBuilderBase &builder,
1368
1448
LLVM::ModuleTranslation &moduleTranslation) {
@@ -1622,50 +1702,10 @@ convertOmpTaskOp(omp::TaskOp taskOp, llvm::IRBuilderBase &builder,
1622
1702
if (handleError (afterAllocas, *taskOp).failed ())
1623
1703
return llvm::make_error<PreviouslyReportedError>();
1624
1704
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>();
1669
1709
1670
1710
// translate the body of the task:
1671
1711
builder.restoreIP (codegenIP);
@@ -1674,19 +1714,11 @@ convertOmpTaskOp(omp::TaskOp taskOp, llvm::IRBuilderBase &builder,
1674
1714
if (failed (handleError (continuationBlockOrError, *taskOp)))
1675
1715
return llvm::make_error<PreviouslyReportedError>();
1676
1716
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
-
1684
1717
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>();
1690
1722
1691
1723
return llvm::Error::success ();
1692
1724
};
@@ -1777,22 +1809,56 @@ convertOmpWsloop(Operation &opInst, llvm::IRBuilderBase &builder,
1777
1809
chunk = builder.CreateSExtOrTrunc (chunkVar, ivType);
1778
1810
}
1779
1811
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
+
1780
1824
SmallVector<omp::DeclareReductionOp> reductionDecls;
1781
1825
collectReductionDecls (wsloopOp, reductionDecls);
1782
1826
llvm::OpenMPIRBuilder::InsertPointTy allocaIP =
1783
1827
findAllocaInsertPoint (builder, moduleTranslation);
1784
1828
1785
1829
SmallVector<llvm::Value *> privateReductionVariables (
1786
1830
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
+
1787
1838
DenseMap<Value, llvm::Value *> reductionVariableMap;
1788
1839
1789
1840
MutableArrayRef<BlockArgument> reductionArgs =
1790
1841
cast<omp::BlockArgOpenMPOpInterface>(opInst).getReductionBlockArgs ();
1791
1842
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)))
1796
1862
return failure ();
1797
1863
1798
1864
// TODO: Replace this with proper composite translation support.
@@ -1899,9 +1965,13 @@ convertOmpWsloop(Operation &opInst, llvm::IRBuilderBase &builder,
1899
1965
builder.restoreIP (afterIP);
1900
1966
1901
1967
// 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);
1905
1975
}
1906
1976
1907
1977
// / Converts the OpenMP parallel operation to LLVM IR.
@@ -1959,52 +2029,12 @@ convertOmpParallel(omp::ParallelOp opInst, llvm::IRBuilderBase &builder,
1959
2029
deferredStores, isByRef)))
1960
2030
return llvm::make_error<PreviouslyReportedError>();
1961
2031
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>();
2007
2036
2037
+ assert (afterAllocas.get ()->getSinglePredecessor ());
2008
2038
if (failed (
2009
2039
initReductionVars (opInst, reductionArgs, builder, moduleTranslation,
2010
2040
afterAllocas.get ()->getSinglePredecessor (),
@@ -2089,17 +2119,9 @@ convertOmpParallel(omp::ParallelOp opInst, llvm::IRBuilderBase &builder,
2089
2119
return llvm::createStringError (
2090
2120
" failed to inline `cleanup` region of `omp.declare_reduction`" );
2091
2121
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>();
2103
2125
2104
2126
builder.restoreIP (oldIP);
2105
2127
return llvm::Error::success ();
0 commit comments