Expand Up
@@ -805,12 +805,12 @@ convertOmpTaskgroupOp(omp::TaskGroupOp tgOp, llvm::IRBuilderBase &builder,
// / Allocate space for privatized reduction variables.
template <typename T>
static void
allocReductionVars (T loop, llvm::IRBuilderBase &builder,
LLVM::ModuleTranslation &moduleTranslation,
llvm::OpenMPIRBuilder::InsertPointTy &allocaIP,
SmallVector<omp::ReductionDeclareOp> &reductionDecls,
SmallVector<llvm::Value *> &privateReductionVariables,
DenseMap<Value, llvm::Value *> &reductionVariableMap) {
allocByValReductionVars (T loop, llvm::IRBuilderBase &builder,
LLVM::ModuleTranslation &moduleTranslation,
llvm::OpenMPIRBuilder::InsertPointTy &allocaIP,
SmallVector<omp::ReductionDeclareOp> &reductionDecls,
SmallVector<llvm::Value *> &privateReductionVariables,
DenseMap<Value, llvm::Value *> &reductionVariableMap) {
llvm::IRBuilderBase::InsertPointGuard guard (builder);
builder.restoreIP (allocaIP);
auto args =
Expand Down
Expand Up
@@ -863,6 +863,7 @@ static LogicalResult
convertOmpWsLoop (Operation &opInst, llvm::IRBuilderBase &builder,
LLVM::ModuleTranslation &moduleTranslation) {
auto loop = cast<omp::WsLoopOp>(opInst);
const bool isByRef = loop.getByref ();
// TODO: this should be in the op verifier instead.
if (loop.getLowerBound ().empty ())
return failure ();
Expand All
@@ -888,18 +889,17 @@ convertOmpWsLoop(Operation &opInst, llvm::IRBuilderBase &builder,
SmallVector<llvm::Value *> privateReductionVariables;
DenseMap<Value, llvm::Value *> reductionVariableMap;
allocReductionVars (loop, builder, moduleTranslation, allocaIP, reductionDecls,
privateReductionVariables, reductionVariableMap);
// Store the mapping between reduction variables and their private copies on
// ModuleTranslation stack. It can be then recovered when translating
// omp.reduce operations in a separate call.
LLVM::ModuleTranslation::SaveStack<OpenMPVarMappingStackFrame> mappingGuard (
moduleTranslation, reductionVariableMap);
if (!isByRef) {
allocByValReductionVars (loop, builder, moduleTranslation, allocaIP,
reductionDecls, privateReductionVariables,
reductionVariableMap);
}
// Before the loop, store the initial values of reductions into reduction
// variables. Although this could be done after allocas, we don't want to mess
// up with the alloca insertion point.
MutableArrayRef<BlockArgument> reductionArgs =
loop.getRegion ().getArguments ().take_back (loop.getNumReductionVars ());
for (unsigned i = 0 ; i < loop.getNumReductionVars (); ++i) {
SmallVector<llvm::Value *> phis;
if (failed (inlineConvertOmpRegions (reductionDecls[i].getInitializerRegion (),
Expand All
@@ -908,9 +908,31 @@ convertOmpWsLoop(Operation &opInst, llvm::IRBuilderBase &builder,
return failure ();
assert (phis.size () == 1 && " expected one value to be yielded from the "
" reduction neutral element declaration region" );
builder.CreateStore (phis[0 ], privateReductionVariables[i]);
if (isByRef) {
// Allocate reduction variable (which is a pointer to the real reduction
// variable allocated in the inlined region)
llvm::Value *var = builder.CreateAlloca (
moduleTranslation.convertType (reductionDecls[i].getType ()));
// Store the result of the inlined region to the allocated reduction var
// ptr
builder.CreateStore (phis[0 ], var);
privateReductionVariables.push_back (var);
moduleTranslation.mapValue (reductionArgs[i], phis[0 ]);
reductionVariableMap.try_emplace (loop.getReductionVars ()[i], phis[0 ]);
} else {
// for by-ref case the store is inside of the reduction region
builder.CreateStore (phis[0 ], privateReductionVariables[i]);
// the rest was handled in allocByValReductionVars
}
}
// Store the mapping between reduction variables and their private copies on
// ModuleTranslation stack. It can be then recovered when translating
// omp.reduce operations in a separate call.
LLVM::ModuleTranslation::SaveStack<OpenMPVarMappingStackFrame> mappingGuard (
moduleTranslation, reductionVariableMap);
// Set up the source location value for OpenMP runtime.
llvm::OpenMPIRBuilder::LocationDescription ompLoc (builder);
Expand Down
Expand Up
@@ -1014,7 +1036,7 @@ convertOmpWsLoop(Operation &opInst, llvm::IRBuilderBase &builder,
builder.SetInsertPoint (tempTerminator);
llvm::OpenMPIRBuilder::InsertPointTy contInsertPoint =
ompBuilder->createReductions (builder.saveIP (), allocaIP, reductionInfos,
loop.getNowait ());
loop.getNowait (), isByRef );
if (!contInsertPoint.getBlock ())
return loop->emitOpError () << " failed to convert reductions" ;
auto nextInsertionPoint =
Expand Down
Expand Up
@@ -1068,6 +1090,7 @@ convertOmpParallel(omp::ParallelOp opInst, llvm::IRBuilderBase &builder,
LLVM::ModuleTranslation &moduleTranslation) {
using InsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy;
OmpParallelOpConversionManager raii (opInst);
const bool isByRef = opInst.getByref ();
// TODO: support error propagation in OpenMPIRBuilder and use it instead of
// relying on captured variables.
Expand All
@@ -1082,18 +1105,17 @@ convertOmpParallel(omp::ParallelOp opInst, llvm::IRBuilderBase &builder,
// Allocate reduction vars
SmallVector<llvm::Value *> privateReductionVariables;
DenseMap<Value, llvm::Value *> reductionVariableMap;
allocReductionVars (opInst, builder, moduleTranslation, allocaIP,
reductionDecls, privateReductionVariables,
reductionVariableMap);
// Store the mapping between reduction variables and their private copies on
// ModuleTranslation stack. It can be then recovered when translating
// omp.reduce operations in a separate call.
LLVM::ModuleTranslation::SaveStack<OpenMPVarMappingStackFrame> mappingGuard (
moduleTranslation, reductionVariableMap);
if (!isByRef) {
allocByValReductionVars (opInst, builder, moduleTranslation, allocaIP,
reductionDecls, privateReductionVariables,
reductionVariableMap);
}
// Initialize reduction vars
builder.restoreIP (allocaIP);
MutableArrayRef<BlockArgument> reductionArgs =
opInst.getRegion ().getArguments ().take_back (
opInst.getNumReductionVars ());
for (unsigned i = 0 ; i < opInst.getNumReductionVars (); ++i) {
SmallVector<llvm::Value *> phis;
if (failed (inlineConvertOmpRegions (
Expand All
@@ -1104,9 +1126,32 @@ convertOmpParallel(omp::ParallelOp opInst, llvm::IRBuilderBase &builder,
" expected one value to be yielded from the "
" reduction neutral element declaration region" );
builder.restoreIP (allocaIP);
builder.CreateStore (phis[0 ], privateReductionVariables[i]);
if (isByRef) {
// Allocate reduction variable (which is a pointer to the real reduciton
// variable allocated in the inlined region)
llvm::Value *var = builder.CreateAlloca (
moduleTranslation.convertType (reductionDecls[i].getType ()));
// Store the result of the inlined region to the allocated reduction var
// ptr
builder.CreateStore (phis[0 ], var);
privateReductionVariables.push_back (var);
moduleTranslation.mapValue (reductionArgs[i], phis[0 ]);
reductionVariableMap.try_emplace (opInst.getReductionVars ()[i], phis[0 ]);
} else {
// for by-ref case the store is inside of the reduction init region
builder.CreateStore (phis[0 ], privateReductionVariables[i]);
// the rest is done in allocByValReductionVars
}
}
// Store the mapping between reduction variables and their private copies on
// ModuleTranslation stack. It can be then recovered when translating
// omp.reduce operations in a separate call.
LLVM::ModuleTranslation::SaveStack<OpenMPVarMappingStackFrame> mappingGuard (
moduleTranslation, reductionVariableMap);
// Save the alloca insertion point on ModuleTranslation stack for use in
// nested regions.
LLVM::ModuleTranslation::SaveStack<OpenMPAllocaStackFrame> frame (
Expand Down
Expand Up
@@ -1137,7 +1182,7 @@ convertOmpParallel(omp::ParallelOp opInst, llvm::IRBuilderBase &builder,
llvm::OpenMPIRBuilder::InsertPointTy contInsertPoint =
ompBuilder->createReductions (builder.saveIP (), allocaIP,
reductionInfos, false );
reductionInfos, false , isByRef );
if (!contInsertPoint.getBlock ()) {
bodyGenStatus = opInst->emitOpError () << " failed to convert reductions" ;
return ;
Expand Down