[flang-commits] [flang] [flang] Lowering FIR memory ops to MemRef dialect (PR #173507)

Valentin Clement バレンタイン クレメン via flang-commits flang-commits at lists.llvm.org
Sat Dec 27 18:18:11 PST 2025


================
@@ -0,0 +1,225 @@
+//===---- FIRToMemRefTypeConverter.h - FIR type conversion to MemRef ------===//
+//
+// 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 file defines `FIRToMemRefTypeConverter`, a helper used by the
+// FIR-to-MemRef conversion pass to convert FIR types (scalars, arrays,
+// descriptors) into MemRef types suitable for the MemRef dialect.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef FORTRAN_OPTIMIZER_TRANSFORMS_FIRTOMEMREFTYPECONVERTER_H
+#define FORTRAN_OPTIMIZER_TRANSFORMS_FIRTOMEMREFTYPECONVERTER_H
+
+#include "flang/Optimizer/Dialect/FIRDialect.h"
+#include "flang/Optimizer/Dialect/FIROps.h"
+#include "flang/Optimizer/Dialect/FIRType.h"
+#include "flang/Optimizer/Dialect/Support/FIRContext.h"
+#include "flang/Optimizer/Dialect/Support/KindMapping.h"
+
+#include "mlir/IR/BuiltinAttributes.h"
+#include "mlir/IR/BuiltinTypes.h"
+#include "mlir/Transforms/DialectConversion.h"
+
+namespace fir {
+
+class FIRToMemRefTypeConverter : public mlir::TypeConverter {
+private:
+  KindMapping kindMapping;
+  bool convertComplexTypes = false;
+  bool convertScalarTypesOnly = false;
+
+public:
+  explicit FIRToMemRefTypeConverter(mlir::ModuleOp mod)
+      : kindMapping(fir::getKindMapping(mod)) {
+    addConversion([](mlir::Type type) { return type; });
+
+    addConversion([&](fir::LogicalType type) -> mlir::Type {
+      return mlir::IntegerType::get(
+          type.getContext(), kindMapping.getLogicalBitsize(type.getFKind()));
+    });
+
+    addSourceMaterialization([](mlir::OpBuilder &builder, mlir::Type type,
+                                mlir::ValueRange inputs,
+                                mlir::Location loc) -> mlir::Value {
+      assert(!inputs.empty() && "expected a single input for materialization");
+      builder.setInsertionPointAfter(inputs[0].getDefiningOp());
+      return fir::ConvertOp::create(builder, loc, type, inputs[0]);
+    });
+
+    addTargetMaterialization([](mlir::OpBuilder &builder, mlir::Type type,
+                                mlir::ValueRange inputs,
+                                mlir::Location loc) -> mlir::Value {
+      return fir::ConvertOp::create(builder, loc, type, inputs[0]);
+    });
+  }
+
+  /// Control whether complex types are considered convertible.
+  void setConvertComplexTypes(bool value) { convertComplexTypes = value; }
+
+  /// Control whether only scalar types are considered during convertibleType.
+  void setConvertScalarTypesOnly(bool value) { convertScalarTypesOnly = value; }
+
+  /// Return true if the given FIR type can be converted to a MemRef-typed
+  /// descriptor (i.e. is a supported base element for MemRef converting).
+  bool convertibleMemrefType(mlir::Type ty) {
+    if (auto refTy = mlir::dyn_cast<fir::ReferenceType>(ty)) {
+      auto elTy = refTy.getElementType();
+      return convertibleMemrefType(elTy);
+    } else if (auto pointerTy = mlir::dyn_cast<fir::PointerType>(ty)) {
+      auto elTy = pointerTy.getElementType();
+      return convertibleMemrefType(elTy);
+    } else if (auto heapTy = mlir::dyn_cast<fir::HeapType>(ty)) {
+      auto elTy = heapTy.getElementType();
+      return convertibleMemrefType(elTy);
+    } else if (auto seqTy = mlir::dyn_cast<fir::SequenceType>(ty)) {
+      auto elTy = seqTy.getElementType();
+      return convertibleMemrefType(elTy);
+    } else if (auto boxTy = mlir::dyn_cast<fir::BoxType>(ty)) {
+      auto elTy = boxTy.getElementType();
+      return convertibleMemrefType(elTy);
+    }
+
+    setConvertScalarTypesOnly(true);
+    bool result = convertibleType(ty);
+    setConvertScalarTypesOnly(false);
+    return result;
+  }
+
+  /// Return true if the given FIR type represents an empty array (has a zero
+  /// extent in its shape).
+  bool isEmptyArray(mlir::Type ty) const {
+    if (auto refTy = mlir::dyn_cast<fir::ReferenceType>(ty)) {
+      auto elTy = refTy.getElementType();
+      return isEmptyArray(elTy);
----------------
clementval wrote:

Same here in this if-else-if block

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


More information about the flang-commits mailing list