[Mlir-commits] [flang] [mlir] [flang][acc] Add ACCOptimizeFirstprivateMap pass (PR #178546)

Razvan Lupusoru llvmlistbot at llvm.org
Thu Jan 29 10:45:13 PST 2026


================
@@ -0,0 +1,190 @@
+//===- ACCOptimizeFirstprivateMap.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
+//
+//===----------------------------------------------------------------------===//
+//
+// This pass optimizes firstprivate mapping operations (acc.firstprivate_map).
+// The optimization hoists loads from the firstprivate variable to before the
+// compute region, effectively converting the firstprivate copy to a
+// pass-by-value pattern. This eliminates the need for runtime copying into
+// global memory.
+//
+// Example transformation:
+//
+//   Before:
+//     %decl = fir.declare %alloca : !fir.ref<i32>
+//     %fp = acc.firstprivate_map varPtr(%decl) -> !fir.ref<i32>
+//     acc.parallel {
+//       %val = fir.load %fp : !fir.ref<i32>  // load inside region
+//       ...
+//     }
+//
+//   After:
+//     %decl = fir.declare %alloca : !fir.ref<i32>
+//     %val = fir.load %decl : !fir.ref<i32>  // load hoisted before region
+//     acc.parallel {
+//       ...  // uses %val directly
+//     }
+//
+//===----------------------------------------------------------------------===//
+
+#include "flang/Optimizer/Dialect/FIROps.h"
+#include "flang/Optimizer/Dialect/FIRType.h"
+#include "flang/Optimizer/Dialect/FortranVariableInterface.h"
+#include "flang/Optimizer/OpenACC/Passes.h"
+#include "flang/Optimizer/OpenACC/Support/FIROpenACCUtils.h"
+#include "mlir/Dialect/OpenACC/OpenACC.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace fir::acc {
+#define GEN_PASS_DEF_ACCOPTIMIZEFIRSTPRIVATEMAP
+#include "flang/Optimizer/OpenACC/Passes.h.inc"
+} // namespace fir::acc
+
+using namespace mlir;
+
+namespace {
+
+/// Returns the enclosing offload region interface, or nullptr if not inside
+/// one.
+static acc::OffloadRegionOpInterface getEnclosingOffloadRegion(Operation *op) {
+  Operation *parent = op->getParentOp();
+  while (parent) {
+    if (auto offloadOp = dyn_cast<acc::OffloadRegionOpInterface>(parent))
+      return offloadOp;
+    parent = parent->getParentOp();
+  }
+  return nullptr;
----------------
razvanlupusoru wrote:

Done. Thank you.

https://github.com/llvm/llvm-project/pull/178546


More information about the Mlir-commits mailing list