[flang-commits] [flang] [llvm] Reland [flang][HLFIR] make copyin/copyout allocation inline (#224063) (PR #224570)
via flang-commits
flang-commits at lists.llvm.org
Fri Sep 18 01:54:44 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-fir-hlfir
Author: jeanPerier
<details>
<summary>Changes</summary>
Reland #<!-- -->224063 with shared library fix (second commit, FIRDialectSupport was missing as a dependency in FIRSupport).
---
Patch is 186.83 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/224570.diff
38 Files Affected:
- (modified) flang-rt/include/flang-rt/runtime/tools.h (+5-4)
- (modified) flang-rt/lib/runtime/assign.cpp (+17-11)
- (modified) flang-rt/lib/runtime/tools.cpp (+1-1)
- (modified) flang/include/flang/Optimizer/Builder/Runtime/Assign.h (+3)
- (modified) flang/include/flang/Optimizer/HLFIR/HLFIROps.td (+16-10)
- (modified) flang/include/flang/Optimizer/HLFIR/Passes.td (+2)
- (modified) flang/include/flang/Optimizer/Support/AllocationPolicy.h (+21)
- (modified) flang/include/flang/Runtime/assign.h (+11-7)
- (modified) flang/lib/Lower/ConvertCall.cpp (+15-13)
- (modified) flang/lib/Optimizer/Builder/Runtime/Assign.cpp (+15)
- (modified) flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp (+4-3)
- (modified) flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp (+119-52)
- (modified) flang/lib/Optimizer/HLFIR/Transforms/InlineHLFIRCopy.cpp (+9-58)
- (modified) flang/lib/Optimizer/Support/AllocationPolicy.cpp (+30)
- (modified) flang/lib/Optimizer/Support/CMakeLists.txt (+1)
- (modified) flang/test/Fir/allocation-policy-pipeline.fir (+52-3)
- (modified) flang/test/HLFIR/assumed-type-actual-args.f90 (+27-24)
- (modified) flang/test/HLFIR/assumed_shape_with_value_keyword.f90 (+16-16)
- (modified) flang/test/HLFIR/copy-in-out-codegen.fir (+71-95)
- (modified) flang/test/HLFIR/copy-in-out.fir (+14-13)
- (modified) flang/test/HLFIR/inline-hlfir-copy-stack.fir (+9-9)
- (modified) flang/test/HLFIR/inline-hlfir-copy.fir (+27-27)
- (modified) flang/test/HLFIR/memory-effects.fir (+6-6)
- (modified) flang/test/Lower/HLFIR/assumed-rank-calls.f90 (+6-6)
- (modified) flang/test/Lower/HLFIR/call-postponed-associate.f90 (+2-2)
- (modified) flang/test/Lower/HLFIR/call-sequence-associated-descriptors.f90 (+8-8)
- (modified) flang/test/Lower/HLFIR/calls-assumed-shape.f90 (+4-4)
- (modified) flang/test/Lower/HLFIR/calls-constant-expr-arg.f90 (+2-2)
- (modified) flang/test/Lower/HLFIR/calls-optional.f90 (+7-6)
- (modified) flang/test/Lower/HLFIR/calls-poly-to-assumed-type.f90 (+2-2)
- (modified) flang/test/Lower/HLFIR/calls-poly-to-nonpoly.f90 (+3-3)
- (modified) flang/test/Lower/HLFIR/poly_expr_for_nonpoly_dummy.f90 (+4-4)
- (modified) flang/test/Lower/OpenMP/copyin.f90 (+3-3)
- (modified) flang/test/Lower/call-copy-in-out.f90 (+3-3)
- (modified) flang/test/Lower/components.f90 (+8-8)
- (modified) flang/test/Lower/dummy-argument-assumed-shape-optional.f90 (+33-30)
- (modified) flang/test/Lower/dummy-argument-optional-2.f90 (+49-42)
- (modified) flang/test/Lower/parent-component.f90 (+8-8)
``````````diff
diff --git a/flang-rt/include/flang-rt/runtime/tools.h b/flang-rt/include/flang-rt/runtime/tools.h
index 245d2829f8ee5a..d856bb206f6343 100644
--- a/flang-rt/include/flang-rt/runtime/tools.h
+++ b/flang-rt/include/flang-rt/runtime/tools.h
@@ -534,10 +534,11 @@ RT_API_ATTRS void ShallowCopy(const Descriptor &to, const Descriptor &from);
// actually modified — while a modifying copy-out never traverses the data
// more than once nor stores more than the unconditional copy would. The
// comparison is bitwise, so it is exact when 'from' was originally produced
-// from 'to' by ShallowCopy() (as CopyInAssign() does): unmodified elements
-// compare equal even for NaNs and padding bytes, which a value comparison
-// would misjudge.
-// (Host-only: the sole caller is CopyOutAssign, outside the offload group.)
+// from 'to' by ShallowCopy() (as CopyInAssign() and the copy-in emitted
+// inline by the compiler do): unmodified elements compare equal even for
+// NaNs and padding bytes, which a value comparison would misjudge.
+// (Host-only: the sole caller is CopyOutAssignDirect, outside the offload
+// group.)
void ShallowCopyModifiedSuffix(const Descriptor &to, const Descriptor &from);
// Ensures that a character string is null-terminated, allocating a /p length +1
diff --git a/flang-rt/lib/runtime/assign.cpp b/flang-rt/lib/runtime/assign.cpp
index 0ae105d9df6717..6f8cfd94e5735a 100644
--- a/flang-rt/lib/runtime/assign.cpp
+++ b/flang-rt/lib/runtime/assign.cpp
@@ -834,15 +834,15 @@ void RTDEF(CopyInAssign)(Descriptor &temp, const Descriptor &var,
ShallowCopy(temp, var);
}
-void RTDEF(CopyOutAssign)(
- Descriptor *var, Descriptor &temp, const char *sourceFile, int sourceLine) {
- Terminator terminator{sourceFile, sourceLine};
+void RTDEF(CopyOutAssignDirect)(const Descriptor &var, Descriptor &temp,
+ const char *sourceFile, int sourceLine) {
// Copyout from the temporary must not cause any finalizations
// for LHS. The variable must be properly initialized already.
// Scan for the first bitwise difference and copy from there to the end
- // (fused, one pass): the temporary was created as a bitwise copy (see
- // CopyInAssign above), so it can only differ where the callee modified it,
- // and an unmodifying copy-out must not store at all. This keeps a
+ // (fused, one pass): the temporary was created as a bitwise copy of the
+ // variable (see CopyInAssign above and the copy-in emitted inline by the
+ // compiler), so it can only differ where the callee modified it, and an
+ // unmodifying copy-out must not store at all. This keeps a
// compiler-generated copy-out from writing into read-only storage when the
// effective argument is not definable (e.g., a named constant) and the
// callee, conformingly, never modified it. From the first difference
@@ -851,12 +851,18 @@ void RTDEF(CopyOutAssign)(
// writable anyway.
// Setting the system environment variable FLANG_RT_COPYOUT_MODIFIED_ONLY=0
// restores the unconditional copy-out.
+ if (executionEnvironment.copyOutModifiedOnly) {
+ ShallowCopyModifiedSuffix(var, temp);
+ } else {
+ ShallowCopy(var, temp);
+ }
+}
+
+void RTDEF(CopyOutAssign)(
+ Descriptor *var, Descriptor &temp, const char *sourceFile, int sourceLine) {
+ Terminator terminator{sourceFile, sourceLine};
if (var) {
- if (executionEnvironment.copyOutModifiedOnly) {
- ShallowCopyModifiedSuffix(*var, temp);
- } else {
- ShallowCopy(*var, temp);
- }
+ RTNAME(CopyOutAssignDirect)(*var, temp, sourceFile, sourceLine);
}
temp.Deallocate();
}
diff --git a/flang-rt/lib/runtime/tools.cpp b/flang-rt/lib/runtime/tools.cpp
index 603a646048da86..8152f99c4ad0bb 100644
--- a/flang-rt/lib/runtime/tools.cpp
+++ b/flang-rt/lib/runtime/tools.cpp
@@ -368,7 +368,7 @@ RT_API_ATTRS void CreatePartialReductionResult(Descriptor &result,
RT_OFFLOAD_API_GROUP_END
// The ShallowCopyModifiedSuffix family is deliberately outside the offload
-// API group: its only caller is CopyOutAssign, which is host-only, and
+// API group: its only caller is CopyOutAssignDirect, which is host-only, and
// instantiating it for the device would only add dead device code.
// Compares one element bitwise. As in the ShallowCopy* helpers above, the
// compile-time element size lets the compiler inline the comparison.
diff --git a/flang/include/flang/Optimizer/Builder/Runtime/Assign.h b/flang/include/flang/Optimizer/Builder/Runtime/Assign.h
index fda941c3261e5d..da7bae9654b289 100644
--- a/flang/include/flang/Optimizer/Builder/Runtime/Assign.h
+++ b/flang/include/flang/Optimizer/Builder/Runtime/Assign.h
@@ -59,6 +59,9 @@ void genAssignTemporary(fir::FirOpBuilder &builder, mlir::Location loc,
/// Generate runtime call to "CopyInAssign" runtime API.
void genCopyInAssign(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::Value tempBoxAddr, mlir::Value varBoxAddr);
+/// Generate runtime call to allocation-free "CopyOutAssignDirect" runtime API.
+void genCopyOutAssignDirect(fir::FirOpBuilder &builder, mlir::Location loc,
+ mlir::Value varBox, mlir::Value tempBoxAddr);
/// Generate runtime call to "CopyOutAssign" runtime API.
void genCopyOutAssign(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::Value varBoxAddr, mlir::Value tempBoxAddr);
diff --git a/flang/include/flang/Optimizer/HLFIR/HLFIROps.td b/flang/include/flang/Optimizer/HLFIR/HLFIROps.td
index f05554079816c3..5e09fe31a91eb3 100644
--- a/flang/include/flang/Optimizer/HLFIR/HLFIROps.td
+++ b/flang/include/flang/Optimizer/HLFIR/HLFIROps.td
@@ -1260,14 +1260,14 @@ def hlfir_CopyInOp : hlfir_Op<"copy_in", [MemoryEffects<[MemAlloc]>]> {
an absent optional and is not contiguous at runtime. When a copy is made this
operation returns the temporary as first result, otherwise, it returns the
potentially absent variable storage. The second result indicates if a copy
- was made.
+ was made, and the third indicates if the returned storage must be freed.
- A descriptor address must be provided for the temporary. This descriptor will
- be set if a temporary copy was made.
+ A descriptor address must be provided for the temporary. This descriptor is
+ set if a temporary copy is made.
This operation is meant to be used in combination with the hlfir.copy_out
- operation that takes the address of the descriptor for the temporary, deletes
- the temporary if it was created, and copies the data back if needed.
+ operation that takes the descriptor address and flags, deletes the temporary
+ if needed, and copies the data back if needed.
This operation allows passing non contiguous arrays to contiguous dummy
arguments, which is possible in Fortran procedure references.
@@ -1280,7 +1280,7 @@ def hlfir_CopyInOp : hlfir_Op<"copy_in", [MemoryEffects<[MemAlloc]>]> {
Arg<AnyReferenceLike, "", [MemWrite]>:$tempBox,
Optional<I1>:$var_is_present);
- let results = (outs fir_BaseBoxType, I1);
+ let results = (outs fir_BaseBoxType, I1, I1);
let assemblyFormat = [{
$var `to` $tempBox (`handle_optional` $var_is_present^)?
@@ -1302,6 +1302,11 @@ def hlfir_CopyInOp : hlfir_Op<"copy_in", [MemoryEffects<[MemAlloc]>]> {
mlir::Value getWasCopied() {
return getResult(1);
}
+
+ /// Get the result indicating if the copied-in storage must be freed.
+ mlir::Value getMustFree() {
+ return getResult(2);
+ }
}];
}
@@ -1310,19 +1315,20 @@ def hlfir_CopyOutOp : hlfir_Op<"copy_out", [MemoryEffects<[MemFree]>]> {
let description = [{
If the variable was copied in a temporary in the related hlfir.copy_in,
optionally copy back the temporary value to it (that may have been
- modified between the hlfir.copy_in and hlfir.copy_out). Then deallocate
- the temporary.
+ modified between the hlfir.copy_in and hlfir.copy_out). Then free the
+ temporary if needed.
The copy back is done if $var is provided and $was_copied is true.
- The deallocation of $temp is done if $was_copied is true.
+ The deallocation of $temp is done if $must_free is true.
$temp must be the descriptor address that was provided to hlfir.copy_in.
}];
let arguments = (ins Arg<AnyReferenceLike, "", [MemRead]>:$temp,
I1:$was_copied,
+ I1:$must_free,
Arg<Optional<fir_BaseBoxType>, "", [MemWrite]>:$var);
let assemblyFormat = [{
- $temp `,` $was_copied (`to` $var^)?
+ $temp `,` $was_copied `,` $must_free (`to` $var^)?
attr-dict `:` functional-type(operands, results)
}];
}
diff --git a/flang/include/flang/Optimizer/HLFIR/Passes.td b/flang/include/flang/Optimizer/HLFIR/Passes.td
index ecde8e093c0619..2835b3119fa2fb 100644
--- a/flang/include/flang/Optimizer/HLFIR/Passes.td
+++ b/flang/include/flang/Optimizer/HLFIR/Passes.td
@@ -14,6 +14,8 @@ def ConvertHLFIRtoFIR : Pass<"convert-hlfir-to-fir", "::mlir::ModuleOp"> {
let summary = "Lower High-Level FIR to FIR";
let dependentDialects = [
"mlir::func::FuncDialect",
+ "mlir::DLTIDialect",
+ "mlir::LLVM::LLVMDialect",
];
}
diff --git a/flang/include/flang/Optimizer/Support/AllocationPolicy.h b/flang/include/flang/Optimizer/Support/AllocationPolicy.h
index fbe3d9c99f0f71..4f9ce3df4c8261 100644
--- a/flang/include/flang/Optimizer/Support/AllocationPolicy.h
+++ b/flang/include/flang/Optimizer/Support/AllocationPolicy.h
@@ -21,14 +21,19 @@
#ifndef FORTRAN_OPTIMIZER_SUPPORT_ALLOCATIONPOLICY_H
#define FORTRAN_OPTIMIZER_SUPPORT_ALLOCATIONPOLICY_H
+#include "flang/Optimizer/Dialect/Support/FIRContext.h"
+#include "flang/Optimizer/Dialect/Support/KindMapping.h"
+#include "flang/Optimizer/Support/DataLayout.h"
#include <cstddef>
#include <cstdint>
#include <functional>
#include <optional>
namespace mlir {
+class Location;
class ModuleOp;
class Operation;
+class Type;
} // namespace mlir
namespace fir {
@@ -81,6 +86,22 @@ struct PendingAllocationInfo {
std::optional<std::int64_t> byteSize;
};
+/// Module-level information needed to compute constant allocation sizes.
+struct AllocationSizeContext {
+ std::optional<mlir::DataLayout> dataLayout;
+ std::optional<fir::KindMapping> kindMap;
+};
+
+/// Gather the module-level information needed to compute allocation sizes.
+AllocationSizeContext getAllocationSizeContext(mlir::Operation *op);
+
+/// Return true if a copy-in buffer should be allocated on the stack. Unlike
+/// general array allocation placement, copy-in buffers with dynamic size are
+/// kept on the heap even under -fstack-arrays.
+bool shouldUseStackForCopyin(mlir::Location loc, mlir::Type sequenceType,
+ const AllocationPolicy &policy,
+ const AllocationSizeContext &sizeContext);
+
/// Facts about a single existing array allocation used to decide its placement.
struct AllocationInfo : PendingAllocationInfo {
/// The allocation operation (fir.alloca or fir.allocmem).
diff --git a/flang/include/flang/Runtime/assign.h b/flang/include/flang/Runtime/assign.h
index 172453334ef152..24be6448d9eb5c 100644
--- a/flang/include/flang/Runtime/assign.h
+++ b/flang/include/flang/Runtime/assign.h
@@ -65,14 +65,18 @@ void RTDECL(AssignTemporary)(Descriptor &to, const Descriptor &from,
// AssignTemporary.
void RTDECL(CopyInAssign)(Descriptor &temp, const Descriptor &var,
const char *sourceFile = nullptr, int sourceLine = 0);
-// When "var" is provided, copy "temp" to it assuming "var" is already
-// initialized. The copy is performed only from the first element of "temp"
-// whose bit pattern differs from the corresponding element of "var" through
-// the last element; when "temp" is bitwise identical to "var", nothing is
-// stored, so a "var" backed by read-only storage is not written to unless
-// it was actually modified. Setting the system environment variable
+// Copy "temp" to the already initialized "var" without deallocating "temp".
+// The copy is performed only from the first element of "temp" whose bit
+// pattern differs from the corresponding element of "var" through the last
+// element; when "temp" is bitwise identical to "var", nothing is stored, so
+// a "var" backed by read-only storage is not written to unless it was
+// actually modified. Setting the system environment variable
// FLANG_RT_COPYOUT_MODIFIED_ONLY=0 restores the unconditional whole-object
-// copy. Destroy and deallocate "temp" in all cases.
+// copy.
+void RTDECL(CopyOutAssignDirect)(const Descriptor &var, Descriptor &temp,
+ const char *sourceFile = nullptr, int sourceLine = 0);
+// When "var" is provided, copy "temp" to it as CopyOutAssignDirect does.
+// Destroy and deallocate "temp" in all cases.
void RTDECL(CopyOutAssign)(Descriptor *var, Descriptor &temp,
const char *sourceFile = nullptr, int sourceLine = 0);
// This variant is for assignments to explicit-length CHARACTER left-hand
diff --git a/flang/lib/Lower/ConvertCall.cpp b/flang/lib/Lower/ConvertCall.cpp
index 19678e429249b4..8c70c8145b8200 100644
--- a/flang/lib/Lower/ConvertCall.cpp
+++ b/flang/lib/Lower/ConvertCall.cpp
@@ -1101,12 +1101,15 @@ namespace {
struct CallCleanUp {
struct CopyIn {
void genCleanUp(mlir::Location loc, fir::FirOpBuilder &builder) {
- hlfir::CopyOutOp::create(builder, loc, tempBox, wasCopied, copyBackVar);
+ hlfir::CopyOutOp::create(builder, loc, tempBox, wasCopied, mustFree,
+ copyBackVar);
}
- // address of the descriptor holding the temp if a temp was created.
+ // Address of the descriptor holding the temp if a temp was created.
mlir::Value tempBox;
// Boolean indicating if a copy was made or not.
mlir::Value wasCopied;
+ // Boolean indicating if the temporary storage must be freed.
+ mlir::Value mustFree;
// copyBackVar may be null if copy back is not needed.
mlir::Value copyBackVar;
};
@@ -1146,9 +1149,9 @@ struct CallCleanUp {
/// clean-ups to be done after the call.
struct PreparedDummyArgument {
void pushCopyInCleanUp(mlir::Value tempBox, mlir::Value wasCopied,
- mlir::Value copyBackVar) {
- cleanups.emplace_back(
- CallCleanUp{CallCleanUp::CopyIn{tempBox, wasCopied, copyBackVar}});
+ mlir::Value mustFree, mlir::Value copyBackVar) {
+ cleanups.emplace_back(CallCleanUp{
+ CallCleanUp::CopyIn{tempBox, wasCopied, mustFree, copyBackVar}});
}
void pushExprAssociateCleanUp(mlir::Value tempVar, mlir::Value wasCopied) {
cleanups.emplace_back(
@@ -1188,6 +1191,7 @@ struct ConditionallyPreparedDummy {
if (const auto *copyInCleanUp =
std::get_if<CallCleanUp::CopyIn>(&c.cleanUp)) {
thenResultValues.push_back(copyInCleanUp->wasCopied);
+ thenResultValues.push_back(copyInCleanUp->mustFree);
if (copyInCleanUp->copyBackVar)
thenResultValues.push_back(copyInCleanUp->copyBackVar);
} else {
@@ -1244,7 +1248,8 @@ struct ConditionallyPreparedDummy {
// tempBox is an hlfir.copy_in argument created outside of the
// fir.if region. It needs not to be threaded as a fir.if result.
preparedDummy.pushCopyInCleanUp(copyInCleanUp->tempBox,
- ifOp.getResults()[1], copyBackVar);
+ ifOp.getResults()[1],
+ ifOp.getResults()[2], copyBackVar);
} else {
preparedDummy.pushExprAssociateCleanUp(ifOp.getResults()[1],
ifOp.getResults()[2]);
@@ -1455,16 +1460,13 @@ static PreparedDummyArgument preparePresentUserCallActualArgument(
auto genCopyIn = [&](hlfir::Entity var, bool doCopyOut) -> hlfir::Entity {
auto baseBoxTy = mlir::dyn_cast<fir::BaseBoxType>(var.getType());
assert(baseBoxTy && "expect non simply contiguous variables to be boxes");
- // Create allocatable descriptor for the potential temporary.
- mlir::Type tempBoxType = baseBoxTy.getBoxTypeWithNewAttr(
- fir::BaseBoxType::Attribute::Allocatable);
- mlir::Value tempBox = builder.createTemporary(loc, tempBoxType);
+ mlir::Value tempBox = builder.createTemporary(loc, var.getType());
auto copyIn = hlfir::CopyInOp::create(builder, loc, var, tempBox,
/*var_is_present=*/mlir::Value{});
// Register the copy-out after the call.
- preparedDummy.pushCopyInCleanUp(copyIn.getTempBox(), copyIn.getWasCopied(),
- doCopyOut ? copyIn.getVar()
- : mlir::Value{});
+ preparedDummy.pushCopyInCleanUp(
+ copyIn.getTempBox(), copyIn.getWasCopied(), copyIn.getMustFree(),
+ doCopyOut ? copyIn.getVar() : mlir::Value{});
return hlfir::Entity{copyIn.getCopiedIn()};
};
diff --git a/flang/lib/Optimizer/Builder/Runtime/Assign.cpp b/flang/lib/Optimizer/Builder/Runtime/Assign.cpp
index fc9c6b0eb51e34..aaa90dcd510923 100644
--- a/flang/lib/Optimizer/Builder/Runtime/Assign.cpp
+++ b/flang/lib/Optimizer/Builder/Runtime/Assign.cpp
@@ -82,6 +82,21 @@ void fir::runtime::genCopyInAssign(fir::FirOpBuilder &builder,
fir::CallOp::create(builder, loc, func, args);
}
+void fir::runtime::genCopyOutAssignDirect(fir::FirOpBuilder &builder,
+ mlir::Location loc,
+ mlir::Value destBox,
+ mlir::Value sourceBoxAddr) {
+ auto func =
+ fir::runtime::getRuntimeFunc<mkRTKey(CopyOutAssignDirect)>(loc, builder);
+ auto fTy = func.getFunctionType();
+ auto sourceFile = fir::factory::locationToFilename(builder, loc);
+ auto sourceLine =
+ fir::factory::locationToLineNo(builder, loc, fTy.getInput(3));
+ auto args = fir::runtime::createArguments(
+ builder, loc, fTy, destBox, sourceBoxAddr, sourceFile, sourceLine);
+ fir::CallOp::create(builder, loc, func, args);
+}
+
void fir::runtime::genCopyOutAssign(fir::FirOpBuilder &builder,
mlir::Location loc, mlir::Value destBox,
mlir::Value sourceBox) {
diff --git a/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp b/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp
index 53c9b6f500d056..9503d64bd5d374 100644
--- a/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp
+++ b/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp
@@ -1949,9 +1949,10 @@ llvm::LogicalResult hlfir::DestroyOp::verify() {
void hlfir::CopyInOp::build(mlir::OpBuilder &builder,
mlir::OperationState &odsState, mlir::Value var,
- mlir::Value tempBox, mlir::Value var_is_present) {
- return build(builder, odsState, {var.getType(), builder.getI1Type()}, var,
- tempBox, var_is_present);
+ mlir::Value temp_box, mlir::Value var_is_present) {
+ return build(builder, odsState,
+ {var.getType(), builder.getI1Type(), builder.getI1Type()}, var,
+ temp_box, var_is_present);
}
//===----------------------------------------------------------------------===//
diff --git a/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp b/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp
index 2be94d40ebd500..3b02ea5b1740d3 100644
--- a/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp
+++ b/flang/lib/Optimizer/HLFIR/Transforms/ConvertToFIR.cpp
@@ -15,6 +15,7 @@
#include "flang/Optimizer/Builder/Runtime/Assign.h"
#include "flang/Optimizer/Builder/Runtime/Derived.h"
#include "flang/Optimizer/Builder/Runtime/Inquiry.h"
+#include "flang/Optimizer/Builder/Runtime/Transformational.h"
#include "flang/Optimizer/Builder/Todo.h"
#include "flang/Optimizer/Dialect/CUF/Attributes/CUFAttr.h"
#include "flang/Optimizer/Dialect/FIROps.h"
@@ -22,6 +23,11 @@
#include "flang/Optimizer/Dialect/Support/FIRContext.h"
#include "flang/Optimizer/HLFIR/HLFIROps.h"
#include "flang/Optimizer/HLFIR/Passes.h"
+#include "flang/Optimizer/Support/AllocationPolicy.h"
+#include "flang/Optimizer/Support/DataLayout.h"
+#include "mlir/Dialect/Arith/IR/Arith.h"
+#include "mlir/Dialect/DLTI/DLTI.h"
+#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
#include "mlir/Transforms/DialectConversion.h"
#include "llvm/...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/224570
More information about the flang-commits
mailing list