[Mlir-commits] [mlir] [mlir] Translating task_reduction clause for pass-by-value vars to LLVMIR (PR #125218)
Jack Styles
llvmlistbot at llvm.org
Mon Jan 5 04:12:31 PST 2026
================
@@ -2469,6 +2473,240 @@ convertOmpTaskOp(omp::TaskOp taskOp, llvm::IRBuilderBase &builder,
return success();
}
+/*
+ * Utility function for translating `red_init`, `red_comb`, and `red_fini` to
+ * LLVMIR. The ulitity first (commonly) generates a skeleton for any of the
+ * three functions, and then generates the function body based on the
+ * specific operations involved in `red_init` (codegen related to initialization
+ * of task reduction variables) and `red_comb` (codegen related to combination).
+ * Currently, codegen for `red_fini` is skipped since finalization is optional
+ * for `task_reduction` clause, but this ulitity has the capability of defining
+ * finalization if needed. Finally, the returned `llvm::Function` is used to
+ * populate the relevant entries in the task reduction specific data structure.
+ */
+static llvm::Value *createTaskReductionFunction(
+ omp::TaskgroupOp &op, llvm::IRBuilderBase &builder, const std::string &name,
+ llvm::Type *redTy, LLVM::ModuleTranslation &moduleTranslation,
+ omp::DeclareReductionOp &reductionDecl, Region ®ion, unsigned cnt,
+ SmallVectorImpl<llvm::Value *> &privateReductionVariables,
+ DenseMap<Value, llvm::Value *> &reductionVariableMap) {
+
+ llvm::LLVMContext &Context = builder.getContext();
+ // TODO: by-ref reduction variables are yet to be handled.
+ llvm::DataLayout DL = builder.GetInsertBlock()->getModule()->getDataLayout();
+ llvm::Type *OpaquePtrTy =
+ llvm::PointerType::get(Context, DL.getProgramAddressSpace());
+ if (region.empty() && name == "red_fini")
+ // Finalization is optional for reductions.
+ return llvm::Constant::getNullValue(OpaquePtrTy);
+
+ // Prepare a general structure of the function to be emitted
+ llvm::FunctionType *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);
+
+ // Prepare the function arguments
+ llvm::Value *arg0 = function->getArg(0);
+ llvm::Value *arg1 = function->getArg(1);
+
+ if (name == "red_init") {
+ // For the initialization, map the reduction variables
+ // to the arguments of the function
+ function->addParamAttr(0, llvm::Attribute::NoAlias);
+ function->addParamAttr(1, llvm::Attribute::NoAlias);
+ Region &initializerRegion = reductionDecl.getInitializerRegion();
+ Block &entry = initializerRegion.front();
+
+ mlir::Value mlirSource = op.getTaskReductionVars()[cnt];
+ llvm::Value *llvmSource = moduleTranslation.lookupValue(mlirSource);
+ llvm::Value *origVal = llvmSource;
+
+ moduleTranslation.mapValue(reductionDecl.getInitializerMoldArg(), origVal);
+
+ if (entry.getNumArguments() > 1) {
+ llvm::Value *allocation =
----------------
Stylie777 wrote:
```suggestion
llvm::Value *allocation = reductionVariableMap.lookup(mlirSource);
```
We can reuse the value for mlirSource from above.
https://github.com/llvm/llvm-project/pull/125218
More information about the Mlir-commits
mailing list