[Mlir-commits] [mlir] [flang][mlir] Add support for translating task_reduction to LLVMIR (PR #120957)
Kareem Ergawy
llvmlistbot at llvm.org
Thu Jan 9 08:08:45 PST 2025
================
@@ -1787,16 +1779,264 @@ convertOmpTaskOp(omp::TaskOp taskOp, llvm::IRBuilderBase &builder,
return success();
}
+template <typename OP>
+llvm::Value *createTaskReductionFunction(
+ llvm::IRBuilderBase &builder, const std::string &name, llvm::Type *redTy,
+ LLVM::ModuleTranslation &moduleTranslation,
+ SmallVectorImpl<omp::DeclareReductionOp> &reductionDecls, Region ®ion,
+ OP &op, unsigned Cnt, llvm::ArrayRef<bool> &isByRef,
+ SmallVectorImpl<llvm::Value *> &privateReductionVariables,
+ DenseMap<Value, llvm::Value *> &reductionVariableMap) {
+ llvm::LLVMContext &Context = builder.getContext();
+ llvm::Type *OpaquePtrTy = llvm::PointerType::get(Context, 0);
+ if (region.empty()) {
+ return llvm::Constant::getNullValue(OpaquePtrTy);
+ }
+ llvm::FunctionType *funcType = nullptr;
+ if (isByRef[Cnt])
+ funcType = llvm::FunctionType::get(builder.getVoidTy(),
+ {OpaquePtrTy, OpaquePtrTy}, false);
+ else
+ funcType =
+ llvm::FunctionType::get(OpaquePtrTy, {OpaquePtrTy, OpaquePtrTy}, false);
+ llvm::Function *function =
+ llvm::Function::Create(funcType, llvm::Function::ExternalLinkage, name,
+ builder.GetInsertBlock()->getModule());
+ function->setDoesNotRecurse();
+ llvm::BasicBlock *entry =
+ llvm::BasicBlock::Create(Context, "entry", function);
+ llvm::IRBuilder<> bbBuilder(entry);
+
+ llvm::Value *arg0 = function->getArg(0);
+ llvm::Value *arg1 = function->getArg(1);
+
+ if (name == "red_init") {
+ function->addParamAttr(0, llvm::Attribute::NoAlias);
+ function->addParamAttr(1, llvm::Attribute::NoAlias);
+ if (isByRef[Cnt]) {
+ // TODO: Handle case where the initializer uses initialization from
+ // declare reduction construct using `arg1Alloca`.
+ llvm::AllocaInst *arg0Alloca =
+ bbBuilder.CreateAlloca(bbBuilder.getPtrTy());
+ llvm::AllocaInst *arg1Alloca =
+ bbBuilder.CreateAlloca(bbBuilder.getPtrTy());
+ bbBuilder.CreateStore(arg0, arg0Alloca);
+ bbBuilder.CreateStore(arg1, arg1Alloca);
+ llvm::Value *LoadVal =
+ bbBuilder.CreateLoad(bbBuilder.getPtrTy(), arg0Alloca);
+ moduleTranslation.mapValue(reductionDecls[Cnt].getInitializerAllocArg(),
+ LoadVal);
+ } else {
+ mapInitializationArgs(op, moduleTranslation, reductionDecls,
+ reductionVariableMap, Cnt);
+ }
+ } else if (name == "red_comb") {
+ if (isByRef[Cnt]) {
+ llvm::AllocaInst *arg0Alloca =
+ bbBuilder.CreateAlloca(bbBuilder.getPtrTy());
+ llvm::AllocaInst *arg1Alloca =
+ bbBuilder.CreateAlloca(bbBuilder.getPtrTy());
+ bbBuilder.CreateStore(arg0, arg0Alloca);
+ bbBuilder.CreateStore(arg1, arg1Alloca);
+ llvm::Value *arg0L =
+ bbBuilder.CreateLoad(bbBuilder.getPtrTy(), arg0Alloca);
+ llvm::Value *arg1L =
+ bbBuilder.CreateLoad(bbBuilder.getPtrTy(), arg1Alloca);
+ moduleTranslation.mapValue(region.front().getArgument(0), arg0L);
+ moduleTranslation.mapValue(region.front().getArgument(1), arg1L);
+ } else {
+ llvm::Value *arg0L = bbBuilder.CreateLoad(redTy, arg0);
+ llvm::Value *arg1L = bbBuilder.CreateLoad(redTy, arg1);
+ moduleTranslation.mapValue(region.front().getArgument(0), arg0L);
+ moduleTranslation.mapValue(region.front().getArgument(1), arg1L);
+ }
+ }
+
+ SmallVector<llvm::Value *, 1> phis;
+ if (failed(inlineConvertOmpRegions(region, "", bbBuilder, moduleTranslation,
+ &phis)))
+ return nullptr;
----------------
ergawy wrote:
I think it would be better to return a `LogicalResult` and pass an output parameter for the created function value. This is less error prone compared to directly using the return value of this function to store it somewhere for example like we do below.
https://github.com/llvm/llvm-project/pull/120957
More information about the Mlir-commits
mailing list