@@ -1352,8 +1352,7 @@ findAssociatedValue(Value privateVar, llvm::IRBuilderBase &builder,
13521352static llvm::Error initPrivateVar (
13531353 llvm::IRBuilderBase &builder, LLVM::ModuleTranslation &moduleTranslation,
13541354 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,
13571356 llvm::DenseMap<Value, Value> *mappedPrivateVars = nullptr ) {
13581357 Region &initRegion = privDecl.getInitRegion ();
13591358 if (initRegion.empty ()) {
@@ -1783,31 +1782,82 @@ convertOmpTaskOp(omp::TaskOp taskOp, llvm::IRBuilderBase &builder,
17831782 for (mlir::Value privateVar : taskOp.getPrivateVars ())
17841783 mlirPrivateVars.push_back (privateVar);
17851784
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.
17921793
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);
17981796
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);
18061805
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);
18101857
1858+ auto bodyCB = [&](InsertPointTy allocaIP,
1859+ InsertPointTy codegenIP) -> llvm::Error {
1860+ builder.restoreIP (codegenIP);
18111861 // translate the body of the task:
18121862 auto continuationBlockOrError = convertOmpOpRegions (
18131863 taskOp.getRegion (), " omp.task.region" , builder, moduleTranslation);
@@ -1827,8 +1877,6 @@ convertOmpTaskOp(omp::TaskOp taskOp, llvm::IRBuilderBase &builder,
18271877 buildDependData (taskOp.getDependKinds (), taskOp.getDependVars (),
18281878 moduleTranslation, dds);
18291879
1830- llvm::OpenMPIRBuilder::InsertPointTy allocaIP =
1831- findAllocaInsertPoint (builder, moduleTranslation);
18321880 llvm::OpenMPIRBuilder::LocationDescription ompLoc (builder);
18331881 llvm::OpenMPIRBuilder::InsertPointOrErrorTy afterIP =
18341882 moduleTranslation.getOpenMPBuilder ()->createTask (
0 commit comments