@@ -1352,8 +1352,7 @@ findAssociatedValue(Value privateVar, llvm::IRBuilderBase &builder,
1352
1352
static llvm::Error initPrivateVar (
1353
1353
llvm::IRBuilderBase &builder, LLVM::ModuleTranslation &moduleTranslation,
1354
1354
omp::PrivateClauseOp &privDecl, Value mlirPrivVar, BlockArgument &blockArg,
1355
- llvm::SmallVectorImpl<llvm::Value *>::iterator llvmPrivateVarIt,
1356
- llvm::BasicBlock *privInitBlock,
1355
+ llvm::Value **llvmPrivateVarIt, llvm::BasicBlock *privInitBlock,
1357
1356
llvm::DenseMap<Value, Value> *mappedPrivateVars = nullptr ) {
1358
1357
Region &initRegion = privDecl.getInitRegion ();
1359
1358
if (initRegion.empty ()) {
@@ -1783,31 +1782,82 @@ convertOmpTaskOp(omp::TaskOp taskOp, llvm::IRBuilderBase &builder,
1783
1782
for (mlir::Value privateVar : taskOp.getPrivateVars ())
1784
1783
mlirPrivateVars.push_back (privateVar);
1785
1784
1786
- auto bodyCB = [&](InsertPointTy allocaIP,
1787
- InsertPointTy codegenIP) -> llvm::Error {
1788
- // Save the alloca insertion point on ModuleTranslation stack for use in
1789
- // nested regions.
1790
- LLVM::ModuleTranslation::SaveStack<OpenMPAllocaStackFrame> frame (
1791
- moduleTranslation, allocaIP);
1785
+ // Allocate and copy private variables before creating the task. This avoids
1786
+ // accessing invalid memory if (after this scope ends) the private variables
1787
+ // are initialized from host variables or if the variables are copied into
1788
+ // from host variables (firstprivate). The insertion point is just before
1789
+ // where the code for creating and scheduling the task will go. That puts this
1790
+ // code outside of the outlined task region, which is what we want because
1791
+ // this way the initialization and copy regions are executed immediately while
1792
+ // the host variable data are still live.
1792
1793
1793
- llvm::Expected<llvm::BasicBlock *> afterAllocas = allocatePrivateVars (
1794
- builder, moduleTranslation, privateBlockArgs, privateDecls,
1795
- mlirPrivateVars, llvmPrivateVars, allocaIP);
1796
- if (handleError (afterAllocas, *taskOp).failed ())
1797
- return llvm::make_error<PreviouslyReportedError>();
1794
+ llvm::OpenMPIRBuilder::InsertPointTy allocaIP =
1795
+ findAllocaInsertPoint (builder, moduleTranslation);
1798
1796
1799
- builder.restoreIP (codegenIP);
1800
- if (handleError (initPrivateVars (builder, moduleTranslation,
1801
- privateBlockArgs, privateDecls,
1802
- mlirPrivateVars, llvmPrivateVars),
1803
- *taskOp)
1804
- .failed ())
1805
- return llvm::make_error<PreviouslyReportedError>();
1797
+ // Not using splitBB() because that requires the current block to have a
1798
+ // terminator.
1799
+ assert (builder.GetInsertPoint () == builder.GetInsertBlock ()->end ());
1800
+ llvm::BasicBlock *taskStartBlock = llvm::BasicBlock::Create (
1801
+ builder.getContext (), " omp.task.start" ,
1802
+ /* Parent=*/ builder.GetInsertBlock ()->getParent ());
1803
+ llvm::Instruction *branchToTaskStartBlock = builder.CreateBr (taskStartBlock);
1804
+ builder.SetInsertPoint (branchToTaskStartBlock);
1806
1805
1807
- if (failed (copyFirstPrivateVars (builder, moduleTranslation, mlirPrivateVars,
1808
- llvmPrivateVars, privateDecls)))
1809
- return llvm::make_error<PreviouslyReportedError>();
1806
+ // Now do this again to make the initialization and copy blocks
1807
+ llvm::BasicBlock *copyBlock =
1808
+ splitBB (builder, /* CreateBranch=*/ true , " omp.private.copy" );
1809
+ llvm::BasicBlock *initBlock =
1810
+ splitBB (builder, /* CreateBranch=*/ true , " omp.private.init" );
1811
+
1812
+ // Now the control flow graph should look like
1813
+ // starter_block:
1814
+ // <---- where we started when convertOmpTaskOp was called
1815
+ // br %omp.private.init
1816
+ // omp.private.init:
1817
+ // br %omp.private.copy
1818
+ // omp.private.copy:
1819
+ // br %omp.task.start
1820
+ // omp.task.start:
1821
+ // <---- where we want the insertion point to be when we call createTask()
1822
+
1823
+ // Save the alloca insertion point on ModuleTranslation stack for use in
1824
+ // nested regions.
1825
+ LLVM::ModuleTranslation::SaveStack<OpenMPAllocaStackFrame> frame (
1826
+ moduleTranslation, allocaIP);
1827
+
1828
+ // Allocate and initialize private variables
1829
+ // TODO: package private variables up in a structure
1830
+ for (auto [privDecl, mlirPrivVar, blockArg] :
1831
+ llvm::zip_equal (privateDecls, mlirPrivateVars, privateBlockArgs)) {
1832
+ llvm::Type *llvmAllocType =
1833
+ moduleTranslation.convertType (privDecl.getType ());
1834
+
1835
+ // Allocations:
1836
+ builder.SetInsertPoint (allocaIP.getBlock ()->getTerminator ());
1837
+ llvm::Value *llvmPrivateVar = builder.CreateAlloca (
1838
+ llvmAllocType, /* ArraySize=*/ nullptr , " omp.private.alloc" );
1839
+
1840
+ builder.SetInsertPoint (initBlock->getTerminator ());
1841
+ auto err = initPrivateVar (builder, moduleTranslation, privDecl, mlirPrivVar,
1842
+ blockArg, &llvmPrivateVar, initBlock);
1843
+ if (err)
1844
+ return handleError (std::move (err), *taskOp.getOperation ());
1845
+
1846
+ llvmPrivateVars.push_back (llvmPrivateVar);
1847
+ }
1848
+
1849
+ // firstprivate copy region
1850
+ builder.SetInsertPoint (copyBlock->getTerminator ());
1851
+ if (failed (copyFirstPrivateVars (builder, moduleTranslation, mlirPrivateVars,
1852
+ llvmPrivateVars, privateDecls)))
1853
+ return llvm::failure ();
1854
+
1855
+ // Set up for call to createTask()
1856
+ builder.SetInsertPoint (taskStartBlock);
1810
1857
1858
+ auto bodyCB = [&](InsertPointTy allocaIP,
1859
+ InsertPointTy codegenIP) -> llvm::Error {
1860
+ builder.restoreIP (codegenIP);
1811
1861
// translate the body of the task:
1812
1862
auto continuationBlockOrError = convertOmpOpRegions (
1813
1863
taskOp.getRegion (), " omp.task.region" , builder, moduleTranslation);
@@ -1827,8 +1877,6 @@ convertOmpTaskOp(omp::TaskOp taskOp, llvm::IRBuilderBase &builder,
1827
1877
buildDependData (taskOp.getDependKinds (), taskOp.getDependVars (),
1828
1878
moduleTranslation, dds);
1829
1879
1830
- llvm::OpenMPIRBuilder::InsertPointTy allocaIP =
1831
- findAllocaInsertPoint (builder, moduleTranslation);
1832
1880
llvm::OpenMPIRBuilder::LocationDescription ompLoc (builder);
1833
1881
llvm::OpenMPIRBuilder::InsertPointOrErrorTy afterIP =
1834
1882
moduleTranslation.getOpenMPBuilder ()->createTask (
0 commit comments