[flang-commits] [clang] [flang] [mlir] [Flang][OpenMP] Lower DECLARE TARGET INDIRECT clause (PR #208387)
via flang-commits
flang-commits at lists.llvm.org
Mon Aug 10 13:59:23 PDT 2026
================
@@ -0,0 +1,94 @@
+//===- IndirectCallLookup.cpp ---------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// On a GPU target device, rewrites indirect fir.call ops so the callee (a host
+// function address held in a procedure pointer) is resolved to the device
+// address via the `__llvm_omp_indirect_call_lookup` runtime function.
+//
+//===----------------------------------------------------------------------===//
+
+#include "flang/Optimizer/Dialect/FIRDialect.h"
+#include "flang/Optimizer/Dialect/FIROps.h"
+#include "flang/Optimizer/OpenMP/Passes.h"
+
+#include "mlir/Dialect/Func/IR/FuncOps.h"
+#include "mlir/Dialect/OpenMP/OpenMPDialect.h"
+#include "mlir/Dialect/OpenMP/OpenMPInterfaces.h"
+#include "mlir/IR/Builders.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace flangomp {
+#define GEN_PASS_DEF_INDIRECTCALLLOOKUPPASS
+#include "flang/Optimizer/OpenMP/Passes.h.inc"
+} // namespace flangomp
+
+using namespace mlir;
+
+/// Runtime function that maps a host function address to the device address.
+static constexpr llvm::StringRef indirectCallLookupName =
+ "__llvm_omp_indirect_call_lookup";
+
+namespace {
+class IndirectCallLookupPass
+ : public flangomp::impl::IndirectCallLookupPassBase<
+ IndirectCallLookupPass> {
+public:
+ void runOnOperation() override {
+ mlir::ModuleOp module = getOperation();
+ auto offloadMod = mlir::dyn_cast<mlir::omp::OffloadModuleInterface>(
+ module.getOperation());
+
+ // Only a GPU target device needs host-to-device address translation.
+ if (!offloadMod || !offloadMod.getIsTargetDevice() ||
+ !offloadMod.getIsGPU())
+ return;
+
+ // An indirect fir.call has no callee symbol; operand 0 is the callee value.
+ llvm::SmallVector<fir::CallOp> indirectCalls;
+ module.walk([&](fir::CallOp call) {
+ if (!call.getCallee())
+ indirectCalls.push_back(call);
+ });
+ if (indirectCalls.empty())
+ return;
+
+ mlir::MLIRContext *ctx = &getContext();
+ mlir::OpBuilder builder(ctx);
+
+ // A function value lowers to a pointer, so an opaque `() -> ()` type
+ // matches the runtime function's ptr argument and result.
+ auto opaqueFnTy = mlir::FunctionType::get(ctx, {}, {});
+
+ // Declare the runtime lookup function once.
+ auto lookupFn =
+ module.lookupSymbol<mlir::func::FuncOp>(indirectCallLookupName);
+ if (!lookupFn) {
+ builder.setInsertionPointToStart(module.getBody());
+ lookupFn = mlir::func::FuncOp::create(
+ builder, module.getLoc(), indirectCallLookupName,
+ mlir::FunctionType::get(ctx, {opaqueFnTy}, {opaqueFnTy}));
----------------
chichunchen wrote:
The lookup seems to lose address space. Could `mlir::FunctionType` be lowered using the module's address space? (need test for address space as well)
https://github.com/llvm/llvm-project/pull/208387
More information about the flang-commits
mailing list