[Mlir-commits] [mlir] [mlir][acc] Introduce ACCToLLVM and executable directive codegen (PR #213165)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Thu Jul 30 15:50:34 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mlir-openacc
Author: Razvan Lupusoru (razvanlupusoru)
<details>
<summary>Changes</summary>
Adds initial infrastructure for converting the acc dialect to LLVM, specifically around generating libacctarget runtime calls. The current libacctarget APIs are not yet finalized, but the draft proposal can be found at https://github.com/llvm/llvm-project/pull/197894. This PR adds codegen for acc init, shutdown, set, and wait.
---
Patch is 53.07 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/213165.diff
16 Files Affected:
- (added) mlir/include/mlir/Conversion/OpenACCToLLVM/ACCToLLVM.h (+38)
- (added) mlir/include/mlir/Conversion/OpenACCToLLVM/ACCToLLVMUtils.h (+52)
- (modified) mlir/include/mlir/Conversion/Passes.h (+1)
- (modified) mlir/include/mlir/Conversion/Passes.td (+9)
- (added) mlir/include/mlir/Dialect/OpenACC/OpenACCRuntimeFunctions.def (+57)
- (added) mlir/include/mlir/Dialect/OpenACC/OpenACCRuntimeUtils.h (+102)
- (modified) mlir/lib/Conversion/CMakeLists.txt (+1)
- (added) mlir/lib/Conversion/OpenACCToLLVM/ACCExecutableDirectivePatterns.cpp (+305)
- (added) mlir/lib/Conversion/OpenACCToLLVM/ACCToLLVM.cpp (+53)
- (added) mlir/lib/Conversion/OpenACCToLLVM/ACCToLLVMUtils.cpp (+171)
- (added) mlir/lib/Conversion/OpenACCToLLVM/CMakeLists.txt (+22)
- (modified) mlir/lib/Dialect/OpenACC/Utils/CMakeLists.txt (+2)
- (added) mlir/lib/Dialect/OpenACC/Utils/OpenACCRuntimeUtils.cpp (+127)
- (added) mlir/test/Conversion/OpenACCToLLVM/init-shutdown-set.mlir (+156)
- (added) mlir/test/Conversion/OpenACCToLLVM/runtime-declaration-mismatch.mlir (+26)
- (added) mlir/test/Conversion/OpenACCToLLVM/wait.mlir (+144)
``````````diff
diff --git a/mlir/include/mlir/Conversion/OpenACCToLLVM/ACCToLLVM.h b/mlir/include/mlir/Conversion/OpenACCToLLVM/ACCToLLVM.h
new file mode 100644
index 0000000000000..02bb6104a238d
--- /dev/null
+++ b/mlir/include/mlir/Conversion/OpenACCToLLVM/ACCToLLVM.h
@@ -0,0 +1,38 @@
+//===- ACCToLLVM.h - Convert OpenACC to LLVM dialect ------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_CONVERSION_OPENACCTOLLVM_ACCTOLLVM_H
+#define MLIR_CONVERSION_OPENACCTOLLVM_ACCTOLLVM_H
+
+#include "mlir/Dialect/OpenACC/OpenACCRuntimeUtils.h"
+
+#include <memory>
+
+namespace mlir {
+class ConversionTarget;
+class LLVMTypeConverter;
+class Pass;
+class RewritePatternSet;
+
+#define GEN_PASS_DECL_CONVERTACCTOLLVMPASS
+#include "mlir/Conversion/Passes.h.inc"
+
+/// Configure conversion legality for OpenACC executable directives lowered to
+/// runtime calls.
+void configureACCExecutableDirectiveConversionLegality(
+ ConversionTarget &target);
+
+/// Populate patterns that lower OpenACC executable directives (init, shutdown,
+/// wait, set) to LLVM runtime calls.
+void populateACCExecutableDirectivePatterns(
+ LLVMTypeConverter &converter, RewritePatternSet &patterns,
+ const acc::ACCRuntimeCallConfig &config = {});
+
+} // namespace mlir
+
+#endif // MLIR_CONVERSION_OPENACCTOLLVM_ACCTOLLVM_H
diff --git a/mlir/include/mlir/Conversion/OpenACCToLLVM/ACCToLLVMUtils.h b/mlir/include/mlir/Conversion/OpenACCToLLVM/ACCToLLVMUtils.h
new file mode 100644
index 0000000000000..7e16cf17c4489
--- /dev/null
+++ b/mlir/include/mlir/Conversion/OpenACCToLLVM/ACCToLLVMUtils.h
@@ -0,0 +1,52 @@
+//===- ACCToLLVMUtils.h - OpenACC to LLVM helpers ---------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_CONVERSION_OPENACCTOLLVM_ACCTOLLVMUTILS_H
+#define MLIR_CONVERSION_OPENACCTOLLVM_ACCTOLLVMUTILS_H
+
+#include "mlir/Dialect/OpenACC/OpenACCRuntimeUtils.h"
+#include "mlir/IR/Builders.h"
+#include "mlir/IR/BuiltinOps.h"
+#include "mlir/IR/Location.h"
+#include "llvm/ADT/StringRef.h"
+
+#include <optional>
+#include <string>
+
+namespace mlir {
+namespace acc {
+
+/// Unfuses fused locations, returning the last sub-location.
+Location unfuseLoc(Location loc);
+
+/// Returns file:line:column location information when available.
+std::optional<FileLineColLoc> getFileLineColLoc(Location loc,
+ bool errorOnInvalidLocation);
+
+/// Returns the enclosing function symbol name for \p op.
+StringRef getParentFunctionName(Operation *op);
+
+/// Returns the enclosing function symbol name for \p value's defining op.
+StringRef getParentFunctionName(Value value);
+
+/// Returns the first non-empty enclosing function name from \p values.
+StringRef getParentFunctionName(ValueRange values);
+
+/// Creates or reuses a module-internal null-terminated string global.
+Value getOrCreateGlobalString(Location loc, OpBuilder &builder, StringRef name,
+ StringRef value, ModuleOp module);
+
+/// Returns a pointer to a constant global holding an ident_t for OpenACC
+/// runtime calls.
+Value createIdent(Location loc, StringRef functionName, OpBuilder &builder,
+ ModuleOp module, const ACCRuntimeCallConfig &config);
+
+} // namespace acc
+} // namespace mlir
+
+#endif // MLIR_CONVERSION_OPENACCTOLLVM_ACCTOLLVMUTILS_H
diff --git a/mlir/include/mlir/Conversion/Passes.h b/mlir/include/mlir/Conversion/Passes.h
index ca971fe4b90d8..8758f5c96c3db 100644
--- a/mlir/include/mlir/Conversion/Passes.h
+++ b/mlir/include/mlir/Conversion/Passes.h
@@ -58,6 +58,7 @@
#include "mlir/Conversion/MemRefToSPIRV/MemRefToSPIRVPass.h"
#include "mlir/Conversion/NVGPUToNVVM/NVGPUToNVVM.h"
#include "mlir/Conversion/NVVMToLLVM/NVVMToLLVM.h"
+#include "mlir/Conversion/OpenACCToLLVM/ACCToLLVM.h"
#include "mlir/Conversion/OpenACCToSCF/ConvertOpenACCToSCF.h"
#include "mlir/Conversion/OpenMPToLLVM/ConvertOpenMPToLLVM.h"
#include "mlir/Conversion/PDLToPDLInterp/PDLToPDLInterp.h"
diff --git a/mlir/include/mlir/Conversion/Passes.td b/mlir/include/mlir/Conversion/Passes.td
index f0567d347ee39..f13cb9a801139 100644
--- a/mlir/include/mlir/Conversion/Passes.td
+++ b/mlir/include/mlir/Conversion/Passes.td
@@ -1122,6 +1122,15 @@ def ConvertOpenACCToSCFPass : Pass<"convert-openacc-to-scf", "ModuleOp"> {
let dependentDialects = ["scf::SCFDialect", "acc::OpenACCDialect"];
}
+//===----------------------------------------------------------------------===//
+// OpenACCToLLVM
+//===----------------------------------------------------------------------===//
+
+def ConvertACCToLLVMPass : Pass<"acc-to-llvm", "ModuleOp"> {
+ let summary = "Lower OpenACC operations to LLVM dialect.";
+ let dependentDialects = ["LLVM::LLVMDialect", "acc::OpenACCDialect"];
+}
+
//===----------------------------------------------------------------------===//
// OpenMPToLLVM
//===----------------------------------------------------------------------===//
diff --git a/mlir/include/mlir/Dialect/OpenACC/OpenACCRuntimeFunctions.def b/mlir/include/mlir/Dialect/OpenACC/OpenACCRuntimeFunctions.def
new file mode 100644
index 0000000000000..338f3950216f5
--- /dev/null
+++ b/mlir/include/mlir/Dialect/OpenACC/OpenACCRuntimeFunctions.def
@@ -0,0 +1,57 @@
+//===- OpenACCRuntimeFunctions.def - ACC runtime catalog --------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+/// \file
+///
+/// X-macro catalog of OpenACC compiler-to-runtime entry points
+/// (`__tgt_acc_*`). Include this file after defining ACC_RTL.
+///
+/// ACC_RTL(Enum, NameStr, IsVarArg, ReturnType, ...)
+/// Enum - enumerator used as RuntimeFunction::Enum
+/// NameStr - default runtime symbol name
+/// IsVarArg - whether the function is variadic
+/// ReturnType - MLIR LLVM return type token (e.g. Void, Int32, Ptr)
+/// ... - MLIR LLVM parameter type tokens
+///
+/// Use __ACC_RTL(Name, ...), which expands to
+/// ACC_RTL(ACCRTL_##Name, "__" #Name, ...).
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef ACC_RTL
+#error "define ACC_RTL before including OpenACCRuntimeFunctions.def"
+#endif
+
+#define __ACC_RTL(Name, IsVarArg, ReturnType, ...) \
+ ACC_RTL(ACCRTL_##Name, "__" #Name, IsVarArg, ReturnType, __VA_ARGS__)
+
+// void __tgt_acc_init(ident_t *, int64_t flags, int64_t device_type,
+// int64_t device_num);
+__ACC_RTL(tgt_acc_init, false, Void, Ptr, Int64, Int64, Int64)
+
+// void __tgt_acc_shutdown(ident_t *, int64_t flags, int64_t device_type,
+// int64_t device_num);
+__ACC_RTL(tgt_acc_shutdown, false, Void, Ptr, Int64, Int64, Int64)
+
+// int32_t __tgt_acc_wait(ident_t *, int64_t flags, int64_t device_type,
+// int32_t device_num, int32_t wait_num, int64_t *waits,
+// int64_t async_queue);
+__ACC_RTL(tgt_acc_wait, false, Int32, Ptr, Int64, Int64, Int32, Int32, Ptr,
+ Int64)
+
+// void __tgt_acc_set_default_async(ident_t *, int64_t async_queue);
+__ACC_RTL(tgt_acc_set_default_async, false, Void, Ptr, Int64)
+
+// void __tgt_acc_set_device_num(ident_t *, int64_t flags, int64_t device_type,
+// int64_t device_num);
+__ACC_RTL(tgt_acc_set_device_num, false, Void, Ptr, Int64, Int64, Int64)
+
+// void __tgt_acc_set_device_type(ident_t *, int64_t flags, int64_t device_type);
+__ACC_RTL(tgt_acc_set_device_type, false, Void, Ptr, Int64, Int64)
+
+#undef __ACC_RTL
+#undef ACC_RTL
diff --git a/mlir/include/mlir/Dialect/OpenACC/OpenACCRuntimeUtils.h b/mlir/include/mlir/Dialect/OpenACC/OpenACCRuntimeUtils.h
new file mode 100644
index 0000000000000..4274bacd974eb
--- /dev/null
+++ b/mlir/include/mlir/Dialect/OpenACC/OpenACCRuntimeUtils.h
@@ -0,0 +1,102 @@
+//===- OpenACCRuntimeUtils.h - OpenACC runtime call utilities ---*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Utilities for resolving OpenACC compiler-to-runtime entry points declared in
+// OpenACCRuntimeFunctions.def.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_DIALECT_OPENACC_OPENACCRUNTIMEUTILS_H
+#define MLIR_DIALECT_OPENACC_OPENACCRUNTIMEUTILS_H
+
+#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
+#include "mlir/Dialect/OpenACC/OpenACC.h"
+#include "mlir/IR/Builders.h"
+#include "mlir/IR/BuiltinOps.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/StringRef.h"
+
+#include <cstdint>
+#include <functional>
+#include <string>
+
+namespace mlir {
+namespace acc {
+
+/// IDs for OpenACC compiler-to-runtime entry points (`__tgt_acc_*`).
+enum class RuntimeFunction {
+#define ACC_RTL(Enum, ...) Enum,
+#include "mlir/Dialect/OpenACC/OpenACCRuntimeFunctions.def"
+};
+
+/// Returns the default runtime symbol name for \p fn.
+StringRef getRuntimeFunctionName(RuntimeFunction fn);
+
+/// Builds the LLVM function type for \p fn in \p ctx.
+LLVM::LLVMFunctionType getRuntimeFunctionType(MLIRContext *ctx,
+ RuntimeFunction fn);
+
+/// Optional overrides for OpenACC to LLVM runtime lowering.
+class ACCRuntimeCallConfig {
+public:
+ using FunctionDisplayNameFn = std::function<std::string(StringRef)>;
+
+ void setName(RuntimeFunction fn, StringRef name);
+ StringRef getName(RuntimeFunction fn) const;
+
+ void setFunctionDisplayNameFn(FunctionDisplayNameFn fn);
+ std::string getFunctionDisplayName(StringRef mangledOrSymbol) const;
+
+ /// Map an OpenACC dialect \p DeviceType to the integer encoding expected by
+ /// the target runtime. Dialect ordinals and runtime ABI values are not
+ /// required to match; callers must install a mapping that matches their
+ /// runtime. Querying an unmapped type is an error.
+ void setDeviceTypeRuntimeValue(DeviceType type, int64_t runtimeValue);
+ int64_t getDeviceTypeRuntimeValue(DeviceType type) const;
+
+ /// Runtime encoding of `acc_async_sync`, used when an operation carries no
+ /// `async` clause. OpenACC defines the name of this queue but leaves its
+ /// value to the implementation, so it is part of the runtime ABI.
+ void setAsyncSyncRuntimeValue(int64_t runtimeValue);
+ int64_t getAsyncSyncRuntimeValue() const;
+
+ /// Runtime encoding of `acc_async_noval`, used for an `async` clause without
+ /// an argument. As with `acc_async_sync`, the value is implementation-defined
+ void setAsyncNoValueRuntimeValue(int64_t runtimeValue);
+ int64_t getAsyncNoValueRuntimeValue() const;
+
+private:
+ DenseMap<RuntimeFunction, std::string> overrides;
+ DenseMap<DeviceType, int64_t> deviceTypeRuntimeValues;
+ FunctionDisplayNameFn functionDisplayNameFn;
+ // Default to the encodings used by openacc.h (`acc_async_sync` /
+ // `acc_async_noval`).
+ int64_t asyncSyncRuntimeValue = -1;
+ int64_t asyncNoValueRuntimeValue = -4;
+};
+
+/// Install a device-type mapping that uses OpenACC dialect enum ordinals as the
+/// runtime encoding. This is only correct when the target runtime happens to
+/// use the same numbering; runtimes with a different ABI must install their
+/// own mapping via \c setDeviceTypeRuntimeValue.
+void populateDialectIdentityDeviceTypeMapping(ACCRuntimeCallConfig &config);
+
+/// Declares (if needed) and returns a call to the runtime function identified
+/// by \p fn using the name from \p config. Fails and emits a diagnostic if the
+/// symbol is already declared with a signature the runtime cannot be called
+/// through.
+FailureOr<LLVM::CallOp> createRuntimeCall(Location loc, OpBuilder &builder,
+ ModuleOp module, RuntimeFunction fn,
+ const ACCRuntimeCallConfig &config,
+ ArrayRef<Value> arguments);
+
+} // namespace acc
+} // namespace mlir
+
+#endif // MLIR_DIALECT_OPENACC_OPENACCRUNTIMEUTILS_H
diff --git a/mlir/lib/Conversion/CMakeLists.txt b/mlir/lib/Conversion/CMakeLists.txt
index c926ee89151ba..cee1a069ad3b1 100644
--- a/mlir/lib/Conversion/CMakeLists.txt
+++ b/mlir/lib/Conversion/CMakeLists.txt
@@ -51,6 +51,7 @@ add_subdirectory(ShardToMPI)
add_subdirectory(MPIToLLVM)
add_subdirectory(NVGPUToNVVM)
add_subdirectory(NVVMToLLVM)
+add_subdirectory(OpenACCToLLVM)
add_subdirectory(OpenACCToSCF)
add_subdirectory(OpenMPToLLVM)
add_subdirectory(PDLToPDLInterp)
diff --git a/mlir/lib/Conversion/OpenACCToLLVM/ACCExecutableDirectivePatterns.cpp b/mlir/lib/Conversion/OpenACCToLLVM/ACCExecutableDirectivePatterns.cpp
new file mode 100644
index 0000000000000..ae4090d00bd26
--- /dev/null
+++ b/mlir/lib/Conversion/OpenACCToLLVM/ACCExecutableDirectivePatterns.cpp
@@ -0,0 +1,305 @@
+//===- ACCExecutableDirectivePatterns.cpp - ACC exec patterns ---*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Lowers OpenACC executable directives (init, shutdown, wait, set) to calls to
+// an OpenACC offloading runtime compiler interface.
+//
+//===----------------------------------------------------------------------===//
+
+#include "mlir/Conversion/OpenACCToLLVM/ACCToLLVM.h"
+#include "mlir/Conversion/OpenACCToLLVM/ACCToLLVMUtils.h"
+
+#include "mlir/Conversion/LLVMCommon/Pattern.h"
+#include "mlir/Dialect/Arith/IR/Arith.h"
+#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
+#include "mlir/Dialect/OpenACC/OpenACC.h"
+#include "mlir/IR/PatternMatch.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/STLFunctionalExtras.h"
+
+#include <cstdint>
+#include <iterator>
+
+using namespace mlir;
+using namespace mlir::acc;
+
+namespace {
+static Value castToI64(Location loc, Value value,
+ ConversionPatternRewriter &rewriter) {
+ Type i64Ty = IntegerType::get(rewriter.getContext(), 64);
+ unsigned bitwidth = value.getType().getIntOrFloatBitWidth();
+ if (bitwidth > 64)
+ return arith::TruncIOp::create(rewriter, loc, i64Ty, value);
+ if (bitwidth < 64)
+ return arith::ExtSIOp::create(rewriter, loc, i64Ty, value);
+ return value;
+}
+
+static Value getAsyncQueue(WaitOp op, ConversionPatternRewriter &rewriter,
+ const ACCRuntimeCallConfig &config) {
+ Location loc = op->getLoc();
+ Type i64Ty = IntegerType::get(rewriter.getContext(), 64);
+ if (op.getAsync())
+ return LLVM::ConstantOp::create(rewriter, loc, i64Ty,
+ config.getAsyncNoValueRuntimeValue());
+ if (Value asyncValue = op.getAsyncOperand()) {
+ asyncValue = rewriter.getRemappedValue(asyncValue);
+ return castToI64(loc, asyncValue, rewriter);
+ }
+ return LLVM::ConstantOp::create(rewriter, loc, i64Ty,
+ config.getAsyncSyncRuntimeValue());
+}
+
+static LogicalResult createIfThen(Location loc, Value ifCond,
+ ConversionPatternRewriter &rewriter,
+ function_ref<LogicalResult()> thenFn) {
+ Block *parentBlock = rewriter.getInsertionBlock();
+ Block *continueBlock =
+ rewriter.splitBlock(parentBlock, rewriter.getInsertionPoint());
+ Block *thenBlock = rewriter.createBlock(
+ parentBlock->getParent(), std::next(Region::iterator(parentBlock)));
+
+ rewriter.setInsertionPointToEnd(parentBlock);
+ LLVM::CondBrOp::create(rewriter, loc, ifCond, thenBlock, ValueRange{},
+ continueBlock, ValueRange{});
+
+ rewriter.setInsertionPointToStart(thenBlock);
+ LogicalResult result = thenFn();
+ rewriter.setInsertionPointToEnd(thenBlock);
+ LLVM::BrOp::create(rewriter, loc, ValueRange{}, continueBlock);
+ rewriter.setInsertionPointToStart(continueBlock);
+ return result;
+}
+
+/// Run \p emitFn, guarded by a branch on \p ifCond when it is present.
+static LogicalResult emitGuardedByIfCond(Location loc, Value ifCond,
+ ConversionPatternRewriter &rewriter,
+ function_ref<LogicalResult()> emitFn) {
+ if (ifCond)
+ return createIfThen(loc, ifCond, rewriter, emitFn);
+ return emitFn();
+}
+
+template <typename OpTy>
+struct ACCExecutableDirectivePattern : public ConvertOpToLLVMPattern<OpTy> {
+ ACCExecutableDirectivePattern(const LLVMTypeConverter &converter,
+ const ACCRuntimeCallConfig &config,
+ PatternBenefit benefit = 1)
+ : ConvertOpToLLVMPattern<OpTy>(converter, benefit), config(config) {}
+
+ ACCRuntimeCallConfig config;
+};
+
+struct WaitOpLowering : public ACCExecutableDirectivePattern<WaitOp> {
+ using ACCExecutableDirectivePattern<WaitOp>::ACCExecutableDirectivePattern;
+
+ LogicalResult
+ matchAndRewrite(WaitOp op, WaitOp::Adaptor,
+ ConversionPatternRewriter &rewriter) const override {
+ Location loc = op->getLoc();
+ ModuleOp module = op->getParentOfType<ModuleOp>();
+ Type i32Ty = rewriter.getI32Type();
+ Type i64Ty = rewriter.getI64Type();
+ Type ptrTy = LLVM::LLVMPointerType::get(rewriter.getContext());
+
+ auto emitWait = [&]() -> LogicalResult {
+ Value asyncQueue = getAsyncQueue(op, rewriter, config);
+ SmallVector<Value> waitValues;
+ for (Value operand : op.getWaitOperands())
+ waitValues.push_back(
+ castToI64(loc, rewriter.getRemappedValue(operand), rewriter));
+
+ unsigned size = waitValues.size();
+ Value waitNum = LLVM::ConstantOp::create(rewriter, loc, i32Ty, size);
+ Value waitList;
+ if (size == 0) {
+ waitList = LLVM::ZeroOp::create(rewriter, loc, ptrTy);
+ } else {
+ waitList = LLVM::AllocaOp::create(rewriter, loc, ptrTy, i64Ty, waitNum);
+ for (auto [index, waitValue] : llvm::enumerate(waitValues)) {
+ Value idx = LLVM::ConstantOp::create(rewriter, loc, i32Ty,
+ static_cast<int64_t>(index));
+ Value elementPtr = LLVM::GEPOp::create(
+ rewriter, loc, ptrTy, i64Ty, waitList, ArrayRef<Value>{idx});
+ LLVM::StoreOp::create(rewriter, loc, waitValue, elementPtr);
+ }
+ }
+
+ StringRef functionName = getParentFunctionName(waitValues);
+ if (functionName.empty())
+ functionName = getParentFunctionName(op);
+ Value ident = createIdent(loc, functionName, rewriter, module, config);
+ Value flags = LLVM::ConstantOp::create(rewriter, loc, i64Ty, 0);
+ Value deviceType = LLVM::ConstantOp::create(
+ rewriter, loc, i64Ty,
+ config.getDeviceTypeRuntimeValue(DeviceType::None));
+ Value deviceNum = LLVM::ConstantOp::create(rewriter, loc, i32Ty, 0);
+
+ return createRuntimeCall(
+ loc, rewriter, module, RuntimeFunction::ACCRTL_tgt_acc_wait, config,
+ {ident, flags, deviceType, deviceNum, waitNum, waitList, asyncQueue});
+ };
+
+ if (failed(emitGuardedByIfCond(loc, op.getIfCond(), rewriter, emitWait)))
+ return failure();
+
+ rewriter.eraseOp(op);
+ return success();
+ }
+};
+
+/// Emit a call to a runtime entry point taking
+/// `(ident, flags, deviceType, deviceNum)`. A null `deviceNum` selects the
+/// current device.
+static LogicalResult
+emitDeviceOperationCall(Location loc, RuntimeFunction fn, DeviceType d...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/213165
More information about the Mlir-commits
mailing list