@@ -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
};
@@ -1760,7 +1792,6 @@ convertOmpWsloop(Operation &opInst, llvm::IRBuilderBase &builder,
1760
1792
return failure ();
1761
1793
1762
1794
auto loopOp = cast<omp::LoopNestOp>(wsloopOp.getWrappedLoop ());
1763
-
1764
1795
llvm::ArrayRef<bool > isByRef = getIsByRef (wsloopOp.getReductionByref ());
1765
1796
assert (isByRef.size () == wsloopOp.getNumReductionVars ());
1766
1797
@@ -1778,22 +1809,61 @@ convertOmpWsloop(Operation &opInst, llvm::IRBuilderBase &builder,
1778
1809
chunk = builder.CreateSExtOrTrunc (chunkVar, ivType);
1779
1810
}
1780
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
+
1781
1824
SmallVector<omp::DeclareReductionOp> reductionDecls;
1782
1825
collectReductionDecls (wsloopOp, reductionDecls);
1783
1826
llvm::OpenMPIRBuilder::InsertPointTy allocaIP =
1784
1827
findAllocaInsertPoint (builder, moduleTranslation);
1785
1828
1786
1829
SmallVector<llvm::Value *> privateReductionVariables (
1787
1830
wsloopOp.getNumReductionVars ());
1831
+
1832
+ splitBB (llvm::OpenMPIRBuilder::InsertPointTy (
1833
+ allocaIP.getBlock (),
1834
+ allocaIP.getBlock ()->getTerminator ()->getIterator ()),
1835
+ true , " omp.region.after_alloca" );
1836
+
1837
+ llvm::Expected<llvm::BasicBlock *> afterAllocas = allocatePrivateVars (
1838
+ builder, moduleTranslation, privateBlockArgs, privateDecls,
1839
+ mlirPrivateVars, llvmPrivateVars, allocaIP);
1840
+ if (handleError (afterAllocas, opInst).failed ())
1841
+ return failure ();
1842
+
1788
1843
DenseMap<Value, llvm::Value *> reductionVariableMap;
1789
1844
1790
1845
MutableArrayRef<BlockArgument> reductionArgs =
1791
1846
cast<omp::BlockArgOpenMPOpInterface>(opInst).getReductionBlockArgs ();
1792
1847
1793
- if (failed (allocAndInitializeReductionVars (
1794
- wsloopOp, reductionArgs, builder, moduleTranslation, allocaIP,
1795
- reductionDecls, privateReductionVariables, reductionVariableMap,
1796
- isByRef)))
1848
+ SmallVector<DeferredStore> deferredStores;
1849
+
1850
+ if (failed (allocReductionVars (wsloopOp, reductionArgs, builder,
1851
+ moduleTranslation, allocaIP, reductionDecls,
1852
+ privateReductionVariables, reductionVariableMap,
1853
+ deferredStores, isByRef)))
1854
+ return failure ();
1855
+
1856
+ if (failed (initFirstPrivateVars (builder, moduleTranslation, mlirPrivateVars,
1857
+ llvmPrivateVars, privateDecls,
1858
+ afterAllocas.get ())))
1859
+ return failure ();
1860
+
1861
+ assert (afterAllocas.get ()->getSinglePredecessor ());
1862
+ if (failed (initReductionVars (wsloopOp, reductionArgs, builder,
1863
+ moduleTranslation,
1864
+ afterAllocas.get ()->getSinglePredecessor (),
1865
+ reductionDecls, privateReductionVariables,
1866
+ reductionVariableMap, isByRef, deferredStores)))
1797
1867
return failure ();
1798
1868
1799
1869
// TODO: Replace this with proper composite translation support.
@@ -1900,9 +1970,13 @@ convertOmpWsloop(Operation &opInst, llvm::IRBuilderBase &builder,
1900
1970
builder.restoreIP (afterIP);
1901
1971
1902
1972
// Process the reductions if required.
1903
- return createReductionsAndCleanup (wsloopOp, builder, moduleTranslation,
1904
- allocaIP, reductionDecls,
1905
- privateReductionVariables, isByRef);
1973
+ if (failed (createReductionsAndCleanup (wsloopOp, builder, moduleTranslation,
1974
+ allocaIP, reductionDecls,
1975
+ privateReductionVariables, isByRef)))
1976
+ return failure ();
1977
+
1978
+ return cleanupPrivateVars (builder, moduleTranslation, wsloopOp.getLoc (),
1979
+ llvmPrivateVars, privateDecls);
1906
1980
}
1907
1981
1908
1982
// / Converts the OpenMP parallel operation to LLVM IR.
@@ -1960,52 +2034,12 @@ convertOmpParallel(omp::ParallelOp opInst, llvm::IRBuilderBase &builder,
1960
2034
deferredStores, isByRef)))
1961
2035
return llvm::make_error<PreviouslyReportedError>();
1962
2036
1963
- // Apply copy region for firstprivate.
1964
- bool needsFirstprivate =
1965
- llvm::any_of (privateDecls, [](omp::PrivateClauseOp &privOp) {
1966
- return privOp.getDataSharingType () ==
1967
- omp::DataSharingClauseType::FirstPrivate;
1968
- });
1969
- if (needsFirstprivate) {
1970
- // Find the end of the allocation blocks
1971
- assert (afterAllocas.get ()->getSinglePredecessor ());
1972
- builder.SetInsertPoint (
1973
- afterAllocas.get ()->getSinglePredecessor ()->getTerminator ());
1974
- llvm::BasicBlock *copyBlock =
1975
- splitBB (builder, /* CreateBranch=*/ true , " omp.private.copy" );
1976
- builder.SetInsertPoint (copyBlock->getFirstNonPHIOrDbgOrAlloca ());
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
- }
2037
+ if (failed (initFirstPrivateVars (builder, moduleTranslation, mlirPrivateVars,
2038
+ llvmPrivateVars, privateDecls,
2039
+ afterAllocas.get ())))
2040
+ return llvm::make_error<PreviouslyReportedError>();
2008
2041
2042
+ assert (afterAllocas.get ()->getSinglePredecessor ());
2009
2043
if (failed (
2010
2044
initReductionVars (opInst, reductionArgs, builder, moduleTranslation,
2011
2045
afterAllocas.get ()->getSinglePredecessor (),
@@ -2090,17 +2124,9 @@ convertOmpParallel(omp::ParallelOp opInst, llvm::IRBuilderBase &builder,
2090
2124
return llvm::createStringError (
2091
2125
" failed to inline `cleanup` region of `omp.declare_reduction`" );
2092
2126
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`" );
2127
+ if (failed (cleanupPrivateVars (builder, moduleTranslation, opInst.getLoc (),
2128
+ llvmPrivateVars, privateDecls)))
2129
+ return llvm::make_error<PreviouslyReportedError>();
2104
2130
2105
2131
builder.restoreIP (oldIP);
2106
2132
return llvm::Error::success ();
0 commit comments