[llvm-branch-commits] [flang] [flang] translate derived type array init to attribute if possible (PR #140268)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Mon May 19 01:51:31 PDT 2025
================
@@ -0,0 +1,204 @@
+//===-- LLVMInsertChainFolder.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
+//
+//===----------------------------------------------------------------------===//
+
+#include "flang/Optimizer/CodeGen/LLVMInsertChainFolder.h"
+#include "mlir/Dialect/LLVMIR/LLVMAttrs.h"
+#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
+#include "mlir/IR/Builders.h"
+#include "llvm/Support/Debug.h"
+
+#define DEBUG_TYPE "flang-insert-folder"
+
+#include <deque>
+
+namespace {
+// Helper class to construct the attribute elements of an aggregate value being
+// folded without creating a full mlir::Attribute representation for each step
+// of the insert value chain, which would both be expensive in terms of
+// compilation time and memory (since the intermediate Attribute would survive,
+// unused, inside the mlir context).
+class InsertChainBackwardFolder {
+ // Type for the current value of an element of the aggregate value being
+ // constructed by the insert chain.
+ // At any point of the insert chain, the value of an element is either:
+ // - nullptr: not yet known, the insert has not yet been seen.
+ // - an mlir::Attribute: the element is fully defined.
+ // - a nested InsertChainBackwardFolder: the element is itself an aggregate
+ // and its sub-elements have been partially defined (insert with mutliple
+ // indices have been seen).
+
+ // The insertion folder assumes backward walk of the insert chain. Once an
+ // element or sub-element has been defined, it is not overriden by new
+ // insertions (last insert wins).
+ using InFlightValue =
+ llvm::PointerUnion<mlir::Attribute, InsertChainBackwardFolder *>;
+
+public:
+ InsertChainBackwardFolder(
+ mlir::Type type, std::deque<InsertChainBackwardFolder> *folderStorage)
+ : values(getNumElements(type), mlir::Attribute{}),
+ folderStorage{folderStorage}, type{type} {}
+
+ /// Push
+ bool pushValue(mlir::Attribute val, llvm::ArrayRef<int64_t> at);
+
+ mlir::Attribute finalize(mlir::Attribute defaultFieldValue);
+
+private:
+ static int64_t getNumElements(mlir::Type type) {
+ if (auto structTy =
+ llvm::dyn_cast_if_present<mlir::LLVM::LLVMStructType>(type))
+ return structTy.getBody().size();
+ if (auto arrayTy =
+ llvm::dyn_cast_if_present<mlir::LLVM::LLVMArrayType>(type))
+ return arrayTy.getNumElements();
+ return 0;
+ }
+
+ static mlir::Type getSubElementType(mlir::Type type, int64_t field) {
+ if (auto arrayTy =
+ llvm::dyn_cast_if_present<mlir::LLVM::LLVMArrayType>(type))
+ return arrayTy.getElementType();
+ if (auto structTy =
+ llvm::dyn_cast_if_present<mlir::LLVM::LLVMStructType>(type))
+ return structTy.getBody()[field];
+ return {};
+ }
----------------
jeanPerier wrote:
That the sub element type could not be retrieved. I changed that to return `nullptr` (which is equivalent to `{}`), and to have the caller directly check the result so that it is clearer. Since mlir::Value, Attribute, Type have a null state, it quite commonly used to indicate failure in helpers (for instance, mlir::Value::getDefiningOp<T> returns a null T if the defining op is not a T).
I however changed the exposed API to return `FailureOr<Attribute>` to make that very clear to external users.
https://github.com/llvm/llvm-project/pull/140268
More information about the llvm-branch-commits
mailing list