[flang-commits] [flang] [flang][NFC] Delete the legacy expression lowering (ConvertExpr.cpp) and its support files (PR #210873)
via flang-commits
flang-commits at lists.llvm.org
Tue Jul 21 20:37:16 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-fir-hlfir
Author: Eugene Epshteyn (eugeneepshteyn)
<details>
<summary>Changes</summary>
The legacy (non-HLFIR) lowering was removed in cc4922b27694 (#<!-- -->196205), but ConvertExpr.cpp and its ComponentPath/IterationSpace support files were left behind. Their last callers have since been migrated or removed (#<!-- -->210385: OpenMP iterator subscripts via genExprValue; #<!-- -->210621: initial values via ConvertConstant; #<!-- -->210639: unreachable FORALL/WHERE machinery deleted from Bridge.cpp), so nothing outside these files references them anymore.
- Delete ConvertExpr.{cpp,h}, ComponentPath.{cpp,h}, IterationSpace.{cpp,h}. (createArrayLoads/createArrayMergeStores are declared in IterationSpace.h but were defined in ConvertExpr.cpp - they die together; no external callers.)
- CMakeLists.txt: drop the three sources and the ConvertExpr.h / IterationSpace.h PRECOMPILE_HEADERS entries.
- Remove stale includes (verified symbol-free): IO.cpp, OpenMP/OpenMP.cpp, DirectivesCommon.h (ConvertExpr.h); Allocatable.cpp, Support/Utils.cpp (IterationSpace.h).
- Support/Utils.{h,cpp}: remove the ExplicitSpaceArrayBases alias and its getHashValue/isEqual overloads; the SomeExpr* and Component* variants stay (live via ExprToValueMap and HLFIR lowering).
This also deletes six small Optimizer/Builder helpers whose last callers were in ConvertExpr.cpp — fir::factory::genLenOfCharacter, getNonDeferredLenParams, getExtentFromTriplet (FIRBuilder), getExtentAtDimension (BoxValue), fir::factory::getRealloc (LowLevelIntrinsics), and the genCharacterCopy template (Factory.h). Their removal orphans nothing further; Factory.h and LowLevelIntrinsics retain their live content.
- Docs: drop the ConvertExpr.cpp section from fstack-arrays.md and the stale ConvertExpr.cpp TODO inventories from ParameterizedDerivedTypes.md and ProcedurePointer.md.
No functional change: everything removed is unreachable. Downstream forks using the deleted entry points will break at compile time; this is intended (precedent: cc4922b27694).
Assisted-by: AI
---
Patch is 430.37 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/210873.diff
23 Files Affected:
- (modified) flang/docs/ParameterizedDerivedTypes.md (-11)
- (modified) flang/docs/ProcedurePointer.md (-1)
- (modified) flang/docs/fstack-arrays.md (-29)
- (removed) flang/include/flang/Lower/ComponentPath.h (-84)
- (removed) flang/include/flang/Lower/ConvertExpr.h (-233)
- (modified) flang/include/flang/Lower/DirectivesCommon.h (-1)
- (removed) flang/include/flang/Lower/IterationSpace.h (-563)
- (modified) flang/include/flang/Lower/Support/Utils.h (-20)
- (modified) flang/include/flang/Optimizer/Builder/BoxValue.h (-5)
- (modified) flang/include/flang/Optimizer/Builder/FIRBuilder.h (-24)
- (modified) flang/include/flang/Optimizer/Builder/Factory.h (-108)
- (modified) flang/include/flang/Optimizer/Builder/LowLevelIntrinsics.h (-3)
- (modified) flang/lib/Lower/Allocatable.cpp (-1)
- (modified) flang/lib/Lower/CMakeLists.txt (-5)
- (removed) flang/lib/Lower/ComponentPath.cpp (-61)
- (removed) flang/lib/Lower/ConvertExpr.cpp (-7750)
- (modified) flang/lib/Lower/IO.cpp (-1)
- (removed) flang/lib/Lower/IterationSpace.cpp (-377)
- (modified) flang/lib/Lower/OpenMP/OpenMP.cpp (-1)
- (modified) flang/lib/Lower/Support/Utils.cpp (-26)
- (modified) flang/lib/Optimizer/Builder/BoxValue.cpp (-12)
- (modified) flang/lib/Optimizer/Builder/FIRBuilder.cpp (-104)
- (modified) flang/lib/Optimizer/Builder/LowLevelIntrinsics.cpp (-7)
``````````diff
diff --git a/flang/docs/ParameterizedDerivedTypes.md b/flang/docs/ParameterizedDerivedTypes.md
index 0e6b62fffe7e9..be0cec7b55114 100644
--- a/flang/docs/ParameterizedDerivedTypes.md
+++ b/flang/docs/ParameterizedDerivedTypes.md
@@ -974,17 +974,6 @@ Current list of TODOs in lowering:
- `flang/lib/Lower/Allocatable.cpp:461` not yet implement: derived type length parameters in allocate
- `flang/lib/Lower/Allocatable.cpp:645` not yet implement: deferred length type parameters
- `flang/lib/Lower/Bridge.cpp:454` not yet implemented: get length parameters from derived type BoxValue
-- `flang/lib/Lower/ConvertExpr.cpp:341` not yet implemented: copy derived type with length parameters
-- `flang/lib/Lower/ConvertExpr.cpp:993` not yet implemented: component with length parameters in structure constructor
-- `flang/lib/Lower/ConvertExpr.cpp:1063` not yet implemented: component with length parameters in structure constructor
-- `flang/lib/Lower/ConvertExpr.cpp:1146` not yet implemented: type parameter inquiry
-- `flang/lib/Lower/ConvertExpr.cpp:2424` not yet implemented: creating temporary for derived type with length parameters
-- `flang/lib/Lower/ConvertExpr.cpp:3742` not yet implemented: gather rhs LEN parameters in assignment to allocatable
-- `flang/lib/Lower/ConvertExpr.cpp:4725` not yet implemented: derived type array expression temp with LEN parameters
-- `flang/lib/Lower/ConvertExpr.cpp:6400` not yet implemented: PDT size
-- `flang/lib/Lower/ConvertExpr.cpp:6419` not yet implemented: PDT offset
-- `flang/lib/Lower/ConvertExpr.cpp:6679` not yet implemented: array expr type parameter inquiry
-- `flang/lib/Lower/ConvertExpr.cpp:7135` not yet implemented: need to adjust type parameter(s) to reflect the final component
- `flang/lib/Lower/ConvertType.cpp:334` not yet implemented: parameterized derived types
- `flang/lib/Lower/ConvertType.cpp:370` not yet implemented: derived type length parameters
- `flang/lib/Lower/ConvertVariable.cpp:169` not yet implemented: initial-data-target with derived type length parameters
diff --git a/flang/docs/ProcedurePointer.md b/flang/docs/ProcedurePointer.md
index 77e54bb505c7b..ed4381bd23331 100644
--- a/flang/docs/ProcedurePointer.md
+++ b/flang/docs/ProcedurePointer.md
@@ -457,7 +457,6 @@ Current list of TODOs in lowering:
- `flang/lib/Lower/CallInterface.cpp:708`: not yet implemented: procedure pointer result not yet handled
- `flang/lib/Lower/CallInterface.cpp:961`: not yet implemented: procedure pointer arguments
- `flang/lib/Lower/CallInterface.cpp:993`: not yet implemented: procedure pointer results
-- `flang/lib/Lower/ConvertExpr.cpp:1119`: not yet implemented: procedure pointer component in derived type assignment
- `flang/lib/Lower/ConvertType.cpp:228`: not yet implemented: procedure pointers
- `flang/lib/Lower/Bridge.cpp:2438`: not yet implemented: procedure pointer assignment
- `flang/lib/Lower/ConvertVariable.cpp:348`: not yet implemented: procedure pointer component default initialization
diff --git a/flang/docs/fstack-arrays.md b/flang/docs/fstack-arrays.md
index 0ee6bf8ee8e79..8eaa5d3f70e67 100644
--- a/flang/docs/fstack-arrays.md
+++ b/flang/docs/fstack-arrays.md
@@ -49,7 +49,6 @@ Flang allocates most arrays on the stack by default, but there are a few cases
where temporary arrays are allocated on the heap:
- `flang/lib/Optimizer/Transforms/ArrayValueCopy.cpp`
- `flang/lib/Optimizer/Transforms/MemoryAllocation.cpp`
-- `flang/lib/Lower/ConvertExpr.cpp`
- `flang/lib/Lower/IntrinsicCall.cpp`
- `flang/lib/Lower/ConvertVariable.cpp`
@@ -71,34 +70,6 @@ x(3,4) = x(1,2)
The default options for the Memory Allocation transformation ensure that no
array allocations, no matter how large, are moved from the stack to the heap.
-#### `ConvertExpr.cpp`
-`ConvertExpr.cpp` allocates many array temporaries on the heap:
- - Passing array arguments by value or when they need re-shaping
- - Lowering elemental array expressions
- - Lowering mask expressions
- - Array constructors
-
-The last two of these cases are **not** covered by the current stack arrays pass
-design.
-
-The FIR code generated for mask expressions (the WHERE construct) sets a
-boolean variable to indicate whether a heap allocation was necessary. The
-allocation is only freed if the variable indicates that the allocation was
-performed to begin with. The proposed dataflow analysis is not intelligent
-enough to statically determine that the boolean variable will always be true
-when the allocation is performed. Beyond this, the control flow in the generated
-FIR code passes the allocated memory through `fir.result`, resulting in a
-different SSA value to be allocated and freed, causing the analysis not to
-realise that the allocated memory is freed. The most convenient solution here
-would be to generate less complicated FIR code, as the existing codegen has
-known bugs: https://github.com/llvm/llvm-project/issues/56921,
-https://github.com/llvm/llvm-project/issues/59803.
-
-Code generated for array constructors uses `realloc()` to grow the allocated
-buffer because the size of the resulting array cannot always be determined
-ahead of running the constructor. This makes this temporary unsuitable
-for allocation on the stack.
-
#### `IntrinsicCall.cpp`
The existing design is for the runtime to do the allocation and the lowering
code to insert `fir.freemem` to remove the allocation. It is not clear whether
diff --git a/flang/include/flang/Lower/ComponentPath.h b/flang/include/flang/Lower/ComponentPath.h
deleted file mode 100644
index daf65db79dc7e..0000000000000
--- a/flang/include/flang/Lower/ComponentPath.h
+++ /dev/null
@@ -1,84 +0,0 @@
-//===-- ComponentPath.h -----------------------------------------*- C++ -*-===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef FORTRAN_LOWER_COMPONENTPATH_H
-#define FORTRAN_LOWER_COMPONENTPATH_H
-
-#include "flang/Lower/IterationSpace.h"
-#include "llvm/ADT/SmallVector.h"
-#include <optional>
-
-namespace fir {
-class ArrayLoadOp;
-}
-namespace Fortran::evaluate {
-class ArrayRef;
-}
-
-namespace Fortran::lower {
-
-namespace details {
-class ImplicitSubscripts {};
-} // namespace details
-
-using PathComponent =
- std::variant<const evaluate::ArrayRef *, const evaluate::Component *,
- const evaluate::ComplexPart *, details::ImplicitSubscripts>;
-
-/// Collection of components.
-///
-/// This class is used both to collect front-end post-order functional Expr
-/// trees and their translations to Values to be used in a pre-order list of
-/// arguments.
-class ComponentPath {
-public:
- using ExtendRefFunc = std::function<mlir::Value(const mlir::Value &)>;
-
- ComponentPath(bool isImplicit) { setPC(isImplicit); }
- ComponentPath(bool isImplicit, const evaluate::Substring *ss)
- : substring(ss) {
- setPC(isImplicit);
- }
- ComponentPath() = delete;
-
- bool isSlice() const { return !trips.empty() || hasComponents(); }
- bool hasComponents() const { return !suffixComponents.empty(); }
- void clear();
-
- bool hasExtendCoorRef() const { return extendCoorRef.has_value(); }
- ExtendRefFunc getExtendCoorRef() const;
- void resetExtendCoorRef() { extendCoorRef = std::nullopt; }
- void resetPC();
-
- llvm::SmallVector<PathComponent> reversePath;
- const evaluate::Substring *substring = nullptr;
- bool applied = false;
-
- llvm::SmallVector<mlir::Value> prefixComponents;
- llvm::SmallVector<mlir::Value> trips;
- llvm::SmallVector<mlir::Value> suffixComponents;
- std::function<IterationSpace(const IterationSpace &)> pc;
-
- /// In the case where a path of components involves members that are POINTER
- /// or ALLOCATABLE, a dereference is required in FIR for semantic correctness.
- /// This optional continuation allows the generation of those dereferences.
- /// These accesses are always on Fortran entities of record types, which are
- /// implicitly in-memory objects.
- std::optional<ExtendRefFunc> extendCoorRef;
-
-private:
- void setPC(bool isImplicit);
-};
-
-/// Examine each subscript expression of \p x and return true if and only if any
-/// of the subscripts is a vector or has a rank greater than 0.
-bool isRankedArrayAccess(const Fortran::evaluate::ArrayRef &x);
-
-} // namespace Fortran::lower
-
-#endif // FORTRAN_LOWER_COMPONENTPATH_H
diff --git a/flang/include/flang/Lower/ConvertExpr.h b/flang/include/flang/Lower/ConvertExpr.h
deleted file mode 100644
index 8adcf30394092..0000000000000
--- a/flang/include/flang/Lower/ConvertExpr.h
+++ /dev/null
@@ -1,233 +0,0 @@
-//===-- Lower/ConvertExpr.h -- lowering of expressions ----------*- C++ -*-===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-//
-// Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/
-//
-//===----------------------------------------------------------------------===//
-///
-/// Implements the conversion from Fortran::evaluate::Expr trees to FIR.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef FORTRAN_LOWER_CONVERTEXPR_H
-#define FORTRAN_LOWER_CONVERTEXPR_H
-
-#include "flang/Lower/Support/Utils.h"
-#include "flang/Optimizer/Builder/BoxValue.h"
-#include "flang/Optimizer/Builder/FIRBuilder.h"
-#include <optional>
-
-namespace mlir {
-class Location;
-class Value;
-} // namespace mlir
-
-namespace fir {
-class AllocMemOp;
-class ArrayLoadOp;
-class ShapeOp;
-} // namespace fir
-
-namespace Fortran::lower {
-
-class AbstractConverter;
-class ExplicitIterSpace;
-class ImplicitIterSpace;
-class StatementContext;
-class SymMap;
-
-/// Create an extended expression value.
-fir::ExtendedValue createSomeExtendedExpression(mlir::Location loc,
- AbstractConverter &converter,
- const SomeExpr &expr,
- SymMap &symMap,
- StatementContext &stmtCtx);
-
-/// Create the IR for the expression \p expr in an initialization context.
-/// Expressions that appear in initializers may not allocate temporaries, do not
-/// have a stack, etc.
-fir::ExtendedValue createSomeInitializerExpression(mlir::Location loc,
- AbstractConverter &converter,
- const SomeExpr &expr,
- SymMap &symMap,
- StatementContext &stmtCtx);
-
-/// Create an extended expression address.
-fir::ExtendedValue createSomeExtendedAddress(mlir::Location loc,
- AbstractConverter &converter,
- const SomeExpr &expr,
- SymMap &symMap,
- StatementContext &stmtCtx);
-
-/// Create an address in an initializer context. Must be a constant or a symbol
-/// to be resolved at link-time. Expressions that appear in initializers may not
-/// allocate temporaries, do not have a stack, etc.
-fir::ExtendedValue createInitializerAddress(mlir::Location loc,
- AbstractConverter &converter,
- const SomeExpr &expr,
- SymMap &symMap,
- StatementContext &stmtCtx);
-
-/// Create the address of the box.
-/// \p expr must be the designator of an allocatable/pointer entity.
-fir::MutableBoxValue createMutableBox(mlir::Location loc,
- AbstractConverter &converter,
- const SomeExpr &expr, SymMap &symMap);
-
-/// Return true iff the expression is pointing to a parent component.
-bool isParentComponent(const SomeExpr &expr);
-
-/// Update the extended value to represent the parent component.
-fir::ExtendedValue updateBoxForParentComponent(AbstractConverter &converter,
- fir::ExtendedValue exv,
- const SomeExpr &expr);
-
-/// Create a fir::BoxValue describing the value of \p expr.
-/// If \p expr is a variable without vector subscripts, the fir::BoxValue
-/// described the variable storage. Otherwise, the created fir::BoxValue
-/// describes a temporary storage containing \p expr evaluation, and clean-up
-/// for the temporary is added to the provided StatementContext \p stmtCtx.
-fir::ExtendedValue createBoxValue(mlir::Location loc,
- AbstractConverter &converter,
- const SomeExpr &expr, SymMap &symMap,
- StatementContext &stmtCtx);
-
-/// Lower an array assignment expression.
-///
-/// 1. Evaluate the lhs to determine the rank and how to form the ArrayLoad
-/// (e.g., if there is a slicing op).
-/// 2. Scan the rhs, creating the ArrayLoads and evaluate the scalar subparts to
-/// be added to the map.
-/// 3. Create the loop nest and evaluate the elemental expression, threading the
-/// results.
-/// 4. Copy the resulting array back with ArrayMergeStore to the lhs as
-/// determined per step 1.
-void createSomeArrayAssignment(AbstractConverter &converter,
- const SomeExpr &lhs, const SomeExpr &rhs,
- SymMap &symMap, StatementContext &stmtCtx);
-
-/// Lower an array assignment expression with a pre-evaluated left hand side.
-///
-/// 1. Scan the rhs, creating the ArrayLoads and evaluate the scalar subparts to
-/// be added to the map.
-/// 2. Create the loop nest and evaluate the elemental expression, threading the
-/// results.
-/// 3. Copy the resulting array back with ArrayMergeStore to the lhs as
-/// determined per step 1.
-void createSomeArrayAssignment(AbstractConverter &converter,
- const fir::ExtendedValue &lhs,
- const SomeExpr &rhs, SymMap &symMap,
- StatementContext &stmtCtx);
-
-/// Lower an array assignment expression with pre-evaluated left and right
-/// hand sides. This implements an array copy taking into account
-/// non-contiguity and potential overlaps.
-void createSomeArrayAssignment(AbstractConverter &converter,
- const fir::ExtendedValue &lhs,
- const fir::ExtendedValue &rhs, SymMap &symMap,
- StatementContext &stmtCtx);
-
-/// Common entry point for both explicit iteration spaces and implicit iteration
-/// spaces with masks.
-///
-/// For an implicit iteration space with masking, lowers an array assignment
-/// expression with masking expression(s).
-///
-/// 1. Evaluate the lhs to determine the rank and how to form the ArrayLoad
-/// (e.g., if there is a slicing op).
-/// 2. Scan the rhs, creating the ArrayLoads and evaluate the scalar subparts to
-/// be added to the map.
-/// 3. Create the loop nest.
-/// 4. Create the masking condition. Step 5 is conditionally executed only when
-/// the mask condition evaluates to true.
-/// 5. Evaluate the elemental expression, threading the results.
-/// 6. Copy the resulting array back with ArrayMergeStore to the lhs as
-/// determined per step 1.
-///
-/// For an explicit iteration space, lower a scalar or array assignment
-/// expression with a user-defined iteration space and possibly with masking
-/// expression(s).
-///
-/// If the expression is scalar, then the assignment is an array assignment but
-/// the array accesses are explicitly defined by the user and not implied for
-/// each element in the array. Mask expressions are optional.
-///
-/// If the expression has rank, then the assignment has a combined user-defined
-/// iteration space as well as a inner (subordinate) implied iteration
-/// space. The implied iteration space may include WHERE conditions, `masks`.
-void createAnyMaskedArrayAssignment(AbstractConverter &converter,
- const SomeExpr &lhs, const SomeExpr &rhs,
- ExplicitIterSpace &explicitIterSpace,
- ImplicitIterSpace &implicitIterSpace,
- SymMap &symMap, StatementContext &stmtCtx);
-
-/// Lower an assignment to an allocatable array, allocating the array if
-/// it is not allocated yet or reallocation it if it does not conform
-/// with the right hand side.
-void createAllocatableArrayAssignment(AbstractConverter &converter,
- const SomeExpr &lhs, const SomeExpr &rhs,
- ExplicitIterSpace &explicitIterSpace,
- ImplicitIterSpace &implicitIterSpace,
- SymMap &symMap,
- StatementContext &stmtCtx);
-
-/// Lower a pointer assignment in an explicit iteration space. The explicit
-/// space iterates over a data structure with a type of `!fir.array<...
-/// !fir.box<!fir.ptr<T>> ...>`. Lower the assignment by copying the rhs box
-/// value to each array element.
-void createArrayOfPointerAssignment(
- AbstractConverter &converter, const SomeExpr &lhs, const SomeExpr &rhs,
- ExplicitIterSpace &explicitIterSpace, ImplicitIterSpace &implicitIterSpace,
- const llvm::SmallVector<mlir::Value> &lbounds,
- std::optional<llvm::SmallVector<mlir::Value>> ubounds, SymMap &symMap,
- StatementContext &stmtCtx);
-
-/// Lower an array expression with "parallel" semantics. Such a rhs expression
-/// is fully evaluated prior to being assigned back to a temporary array.
-fir::ExtendedValue createSomeArrayTempValue(AbstractConverter &converter,
- const SomeExpr &expr,
- SymMap &symMap,
- StatementContext &stmtCtx);
-
-/// Somewhat similar to createSomeArrayTempValue, but the temporary buffer is
-/// allocated lazily (inside the loops instead of before the loops) to
-/// accomodate buffers with shapes that cannot be precomputed. In fact, the
-/// buffer need not even be hyperrectangular. The buffer may be created as an
-/// instance of a ragged array, which may be useful if an array's extents are
-/// functions of other loop indices. The ragged array structure is built with \p
-/// raggedHeader being the root header variable. The header is a tuple of
-/// `{rank, data-is-headers, [data]*, [extents]*}`, which is built recursively.
-/// The base header, \p raggedHeader, must be initialized to zeros.
-void createLazyArrayTempValue(AbstractConverter &converter,
- const SomeExpr &expr, mlir::Value raggedHeader,
- SymMap &symMap, StatementContext &stmtCtx);
-
-/// Lower an array expression to a value of type box. The expression must be a
-/// variable.
-fir::ExtendedValue createSomeArrayBox(AbstractConverter &converter,
- const SomeExpr &expr, SymMap &symMap,
- StatementContext &stmtCtx);
-
-/// Lower a subroutine call. This handles both elemental and non elemental
-/// subroutines. \p isUserDefAssignment must be set if this is called in the
-/// context of a user defined assignment. For subroutines with alternate
-/// returns, the returned value indicates which label the code should jump to.
-/// The returned value is null otherwise.
-mlir::Value createSubroutineCall(AbstractConverter &converter,
- const evaluate::ProcedureRef &call,
- ExplicitIterSpace &explicitIterSpace,
- ImplicitIterSpace &implicitIterSpace,
- SymMap &symMap, StatementContext &stmtCtx,
- ...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/210873
More information about the flang-commits
mailing list