@@ -1339,8 +1339,7 @@ findAssociatedValue(Value privateVar, llvm::IRBuilderBase &builder,
13391339static llvm::Error initPrivateVar (
13401340 llvm::IRBuilderBase &builder, LLVM::ModuleTranslation &moduleTranslation,
13411341 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,
13441343 llvm::DenseMap<Value, Value> *mappedPrivateVars = nullptr ) {
13451344 Region &initRegion = privDecl.getInitRegion ();
13461345 if (initRegion.empty ()) {
@@ -1771,31 +1770,82 @@ convertOmpTaskOp(omp::TaskOp taskOp, llvm::IRBuilderBase &builder,
17711770 for (mlir::Value privateVar : taskOp.getPrivateVars ())
17721771 mlirPrivateVars.push_back (privateVar);
17731772
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.
17801781
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);
17861784
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);
17941793
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);
17981845
1846+ auto bodyCB = [&](InsertPointTy allocaIP,
1847+ InsertPointTy codegenIP) -> llvm::Error {
1848+ builder.restoreIP (codegenIP);
17991849 // translate the body of the task:
18001850 auto continuationBlockOrError = convertOmpOpRegions (
18011851 taskOp.getRegion (), " omp.task.region" , builder, moduleTranslation);
@@ -1815,8 +1865,6 @@ convertOmpTaskOp(omp::TaskOp taskOp, llvm::IRBuilderBase &builder,
18151865 buildDependData (taskOp.getDependKinds (), taskOp.getDependVars (),
18161866 moduleTranslation, dds);
18171867
1818- llvm::OpenMPIRBuilder::InsertPointTy allocaIP =
1819- findAllocaInsertPoint (builder, moduleTranslation);
18201868 llvm::OpenMPIRBuilder::LocationDescription ompLoc (builder);
18211869 llvm::OpenMPIRBuilder::InsertPointOrErrorTy afterIP =
18221870 moduleTranslation.getOpenMPBuilder ()->createTask (
0 commit comments