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