[flang-commits] [flang] [flang][NFC] Remove unreachable legacy FORALL/WHERE lowering code from Bridge.cpp (PR #210639)
via flang-commits
flang-commits at lists.llvm.org
Sun Jul 19 20:49:46 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 HLFIR lowering migration left a cluster of legacy, now-unreachable code in Bridge.cpp behind. None of it has a live caller (FORALL is lowered by genForallNest; DO CONCURRENT by getConcurrentControl):
- forceControlVariableBinding and the old DoLoopOp-based genFIR(const parser::ConcurrentHeader &) FORALL-nest lowering (the ConcurrentHeader is not a PFT evaluation node and is never visited).
- The member genInitializerExprValue, implicitIterationSpace/ explicitIterationSpace, genArrayAssignment, and the NDEBUG-only isFuncResultDesignator.
- The analyzeExplicitSpace overload set, analyzeExplicitSpacePop, and addMaskVariable.
- The explicitIterSpace / implicitIterSpace members.
These were the only Bridge.cpp users of the legacy expression lowering (createSome*Assignment / createSomeInitializerExpression) and of IterationSpace, so their includes (ConvertExpr.h, IterationSpace.h, and Runtime/Ragged.h, used only by addMaskVariable) are removed as well.
Assisted-by: AI
---
Patch is 21.69 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/210639.diff
1 Files Affected:
- (modified) flang/lib/Lower/Bridge.cpp (-428)
``````````diff
diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index 2cce44cdc8a70..348a3ca9a3fac 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -17,14 +17,12 @@
#include "flang/Lower/CUDA.h"
#include "flang/Lower/CallInterface.h"
#include "flang/Lower/ConvertCall.h"
-#include "flang/Lower/ConvertExpr.h"
#include "flang/Lower/ConvertExprToHLFIR.h"
#include "flang/Lower/ConvertType.h"
#include "flang/Lower/ConvertVariable.h"
#include "flang/Lower/DirectivesCommon.h"
#include "flang/Lower/HostAssociations.h"
#include "flang/Lower/IO.h"
-#include "flang/Lower/IterationSpace.h"
#include "flang/Lower/Mangler.h"
#include "flang/Lower/MultiImageFortran.h"
#include "flang/Lower/OpenACC.h"
@@ -44,7 +42,6 @@
#include "flang/Optimizer/Builder/Runtime/EnvironmentDefaults.h"
#include "flang/Optimizer/Builder/Runtime/Exceptions.h"
#include "flang/Optimizer/Builder/Runtime/Main.h"
-#include "flang/Optimizer/Builder/Runtime/Ragged.h"
#include "flang/Optimizer/Builder/Runtime/Stop.h"
#include "flang/Optimizer/Builder/Todo.h"
#include "flang/Optimizer/Dialect/CUF/Attributes/CUFAttr.h"
@@ -3263,136 +3260,6 @@ class FirConverter : public Fortran::lower::AbstractConverter {
genFIR(stmt.statement);
}
- /// Force the binding of an explicit symbol. This is used to bind and re-bind
- /// a concurrent control symbol to its value.
- void forceControlVariableBinding(const Fortran::semantics::Symbol *sym,
- mlir::Value inducVar) {
- mlir::Location loc = toLocation();
- assert(sym && "There must be a symbol to bind");
- mlir::Type toTy = genType(*sym);
- // FIXME: this should be a "per iteration" temporary.
- mlir::Value tmp =
- builder->createTemporary(loc, toTy, toStringRef(sym->name()),
- llvm::ArrayRef<mlir::NamedAttribute>{
- fir::getAdaptToByRefAttr(*builder)});
- mlir::Value cast = builder->createConvert(loc, toTy, inducVar);
- fir::StoreOp::create(*builder, loc, cast, tmp);
- addSymbol(*sym, tmp, /*force=*/true);
- }
-
- /// Process a concurrent header for a FORALL. (Concurrent headers for DO
- /// CONCURRENT loops are lowered elsewhere.)
- void genFIR(const Fortran::parser::ConcurrentHeader &header) {
- llvm::SmallVector<mlir::Value> lows;
- llvm::SmallVector<mlir::Value> highs;
- llvm::SmallVector<mlir::Value> steps;
- if (explicitIterSpace.isOutermostForall()) {
- // For the outermost forall, we evaluate the bounds expressions once.
- // Contrastingly, if this forall is nested, the bounds expressions are
- // assumed to be pure, possibly dependent on outer concurrent control
- // variables, possibly variant with respect to arguments, and will be
- // re-evaluated.
- mlir::Location loc = toLocation();
- mlir::Type idxTy = builder->getIndexType();
- Fortran::lower::StatementContext &stmtCtx =
- explicitIterSpace.stmtContext();
- auto lowerExpr = [&](auto &e) {
- return fir::getBase(genExprValue(e, stmtCtx));
- };
- for (const Fortran::parser::ConcurrentControl &ctrl :
- std::get<std::list<Fortran::parser::ConcurrentControl>>(header.t)) {
- const Fortran::lower::SomeExpr *lo =
- Fortran::semantics::GetExpr(std::get<1>(ctrl.t));
- const Fortran::lower::SomeExpr *hi =
- Fortran::semantics::GetExpr(std::get<2>(ctrl.t));
- auto &optStep =
- std::get<std::optional<Fortran::parser::ScalarIntExpr>>(ctrl.t);
- lows.push_back(builder->createConvert(loc, idxTy, lowerExpr(*lo)));
- highs.push_back(builder->createConvert(loc, idxTy, lowerExpr(*hi)));
- steps.push_back(
- optStep.has_value()
- ? builder->createConvert(
- loc, idxTy,
- lowerExpr(*Fortran::semantics::GetExpr(*optStep)))
- : builder->createIntegerConstant(loc, idxTy, 1));
- }
- }
- auto lambda = [&, lows, highs, steps]() {
- // Create our iteration space from the header spec.
- mlir::Location loc = toLocation();
- mlir::Type idxTy = builder->getIndexType();
- llvm::SmallVector<fir::DoLoopOp> loops;
- Fortran::lower::StatementContext &stmtCtx =
- explicitIterSpace.stmtContext();
- auto lowerExpr = [&](auto &e) {
- return fir::getBase(genExprValue(e, stmtCtx));
- };
- const bool outermost = !lows.empty();
- std::size_t headerIndex = 0;
- for (const Fortran::parser::ConcurrentControl &ctrl :
- std::get<std::list<Fortran::parser::ConcurrentControl>>(header.t)) {
- const Fortran::semantics::Symbol *ctrlVar =
- std::get<Fortran::parser::Name>(ctrl.t).symbol;
- mlir::Value lb;
- mlir::Value ub;
- mlir::Value by;
- if (outermost) {
- assert(headerIndex < lows.size());
- if (headerIndex == 0)
- explicitIterSpace.resetInnerArgs();
- lb = lows[headerIndex];
- ub = highs[headerIndex];
- by = steps[headerIndex++];
- } else {
- const Fortran::lower::SomeExpr *lo =
- Fortran::semantics::GetExpr(std::get<1>(ctrl.t));
- const Fortran::lower::SomeExpr *hi =
- Fortran::semantics::GetExpr(std::get<2>(ctrl.t));
- auto &optStep =
- std::get<std::optional<Fortran::parser::ScalarIntExpr>>(ctrl.t);
- lb = builder->createConvert(loc, idxTy, lowerExpr(*lo));
- ub = builder->createConvert(loc, idxTy, lowerExpr(*hi));
- by = optStep.has_value()
- ? builder->createConvert(
- loc, idxTy,
- lowerExpr(*Fortran::semantics::GetExpr(*optStep)))
- : builder->createIntegerConstant(loc, idxTy, 1);
- }
- auto lp = fir::DoLoopOp::create(
- *builder, loc, lb, ub, by, /*unordered=*/true,
- /*finalCount=*/false, explicitIterSpace.getInnerArgs());
- if ((!loops.empty() || !outermost) && !lp.getRegionIterArgs().empty())
- fir::ResultOp::create(*builder, loc, lp.getResults());
- explicitIterSpace.setInnerArgs(lp.getRegionIterArgs());
- builder->setInsertionPointToStart(lp.getBody());
- forceControlVariableBinding(ctrlVar, lp.getInductionVar());
- loops.push_back(lp);
- }
- if (outermost)
- explicitIterSpace.setOuterLoop(loops[0]);
- explicitIterSpace.appendLoops(loops);
- if (const auto &mask =
- std::get<std::optional<Fortran::parser::ScalarLogicalExpr>>(
- header.t);
- mask.has_value()) {
- mlir::Type i1Ty = builder->getI1Type();
- fir::ExtendedValue maskExv =
- genExprValue(*Fortran::semantics::GetExpr(mask.value()), stmtCtx);
- mlir::Value cond =
- builder->createConvert(loc, i1Ty, fir::getBase(maskExv));
- auto ifOp = fir::IfOp::create(*builder, loc,
- explicitIterSpace.innerArgTypes(), cond,
- /*withElseRegion=*/true);
- fir::ResultOp::create(*builder, loc, ifOp.getResults());
- builder->setInsertionPointToStart(&ifOp.getElseRegion().front());
- fir::ResultOp::create(*builder, loc, explicitIterSpace.getInnerArgs());
- builder->setInsertionPointToStart(&ifOp.getThenRegion().front());
- }
- };
- // Push the lambda to gen the loop nest context.
- explicitIterSpace.pushLoopNest(lambda);
- }
-
void genFIR(const Fortran::parser::ForallAssignmentStmt &stmt) {
Fortran::common::visit([&](const auto &x) { genFIR(x); }, stmt.u);
}
@@ -5010,90 +4877,6 @@ class FirConverter : public Fortran::lower::AbstractConverter {
genLockStatement(*this, stmt);
}
- fir::ExtendedValue
- genInitializerExprValue(const Fortran::lower::SomeExpr &expr,
- Fortran::lower::StatementContext &stmtCtx) {
- return Fortran::lower::createSomeInitializerExpression(
- toLocation(), *this, expr, localSymbols, stmtCtx);
- }
-
- /// Return true if the current context is a conditionalized and implied
- /// iteration space.
- bool implicitIterationSpace() { return !implicitIterSpace.empty(); }
-
- /// Return true if context is currently an explicit iteration space. A scalar
- /// assignment expression may be contextually within a user-defined iteration
- /// space, transforming it into an array expression.
- bool explicitIterationSpace() { return explicitIterSpace.isActive(); }
-
- /// Generate an array assignment.
- /// This is an assignment expression with rank > 0. The assignment may or may
- /// not be in a WHERE and/or FORALL context.
- /// In a FORALL context, the assignment may be a pointer assignment and the \p
- /// lbounds and \p ubounds parameters should only be used in such a pointer
- /// assignment case. (If both are None then the array assignment cannot be a
- /// pointer assignment.)
- void genArrayAssignment(
- const Fortran::evaluate::Assignment &assign,
- Fortran::lower::StatementContext &localStmtCtx,
- std::optional<llvm::SmallVector<mlir::Value>> lbounds = std::nullopt,
- std::optional<llvm::SmallVector<mlir::Value>> ubounds = std::nullopt) {
-
- Fortran::lower::StatementContext &stmtCtx =
- explicitIterationSpace()
- ? explicitIterSpace.stmtContext()
- : (implicitIterationSpace() ? implicitIterSpace.stmtContext()
- : localStmtCtx);
- if (Fortran::lower::isWholeAllocatable(assign.lhs)) {
- // Assignment to allocatables may require the lhs to be
- // deallocated/reallocated. See Fortran 2018 10.2.1.3 p3
- Fortran::lower::createAllocatableArrayAssignment(
- *this, assign.lhs, assign.rhs, explicitIterSpace, implicitIterSpace,
- localSymbols, stmtCtx);
- return;
- }
-
- if (lbounds) {
- // Array of POINTER entities, with elemental assignment.
- if (!Fortran::lower::isWholePointer(assign.lhs))
- fir::emitFatalError(toLocation(), "pointer assignment to non-pointer");
-
- Fortran::lower::createArrayOfPointerAssignment(
- *this, assign.lhs, assign.rhs, explicitIterSpace, implicitIterSpace,
- *lbounds, ubounds, localSymbols, stmtCtx);
- return;
- }
-
- if (!implicitIterationSpace() && !explicitIterationSpace()) {
- // No masks and the iteration space is implied by the array, so create a
- // simple array assignment.
- Fortran::lower::createSomeArrayAssignment(*this, assign.lhs, assign.rhs,
- localSymbols, stmtCtx);
- return;
- }
-
- // If there is an explicit iteration space, generate an array assignment
- // with a user-specified iteration space and possibly with masks. These
- // assignments may *appear* to be scalar expressions, but the scalar
- // expression is evaluated at all points in the user-defined space much like
- // an ordinary array assignment. More specifically, the semantics inside the
- // FORALL much more closely resembles that of WHERE than a scalar
- // assignment.
- // Otherwise, generate a masked array assignment. The iteration space is
- // implied by the lhs array expression.
- Fortran::lower::createAnyMaskedArrayAssignment(
- *this, assign.lhs, assign.rhs, explicitIterSpace, implicitIterSpace,
- localSymbols, stmtCtx);
- }
-
-#if !defined(NDEBUG)
- static bool isFuncResultDesignator(const Fortran::lower::SomeExpr &expr) {
- const Fortran::semantics::Symbol *sym =
- Fortran::evaluate::GetFirstSymbol(expr);
- return sym && sym->IsFuncResult();
- }
-#endif
-
inline fir::MutableBoxValue
genExprMutableBox(mlir::Location loc,
const Fortran::lower::SomeExpr &expr) override final {
@@ -6687,211 +6470,6 @@ class FirConverter : public Fortran::lower::AbstractConverter {
return Fortran::evaluate::GetShape(foldingContext, expr);
}
- //===--------------------------------------------------------------------===//
- // Analysis on a nested explicit iteration space.
- //===--------------------------------------------------------------------===//
-
- void analyzeExplicitSpace(const Fortran::parser::ConcurrentHeader &header) {
- explicitIterSpace.pushLevel();
- for (const Fortran::parser::ConcurrentControl &ctrl :
- std::get<std::list<Fortran::parser::ConcurrentControl>>(header.t)) {
- const Fortran::semantics::Symbol *ctrlVar =
- std::get<Fortran::parser::Name>(ctrl.t).symbol;
- explicitIterSpace.addSymbol(ctrlVar);
- }
- if (const auto &mask =
- std::get<std::optional<Fortran::parser::ScalarLogicalExpr>>(
- header.t);
- mask.has_value())
- analyzeExplicitSpace(*Fortran::semantics::GetExpr(*mask));
- }
- template <bool LHS = false, typename A>
- void analyzeExplicitSpace(const Fortran::evaluate::Expr<A> &e) {
- explicitIterSpace.exprBase(&e, LHS);
- }
- void analyzeExplicitSpace(const Fortran::evaluate::Assignment *assign) {
- auto analyzeAssign = [&](const Fortran::lower::SomeExpr &lhs,
- const Fortran::lower::SomeExpr &rhs) {
- analyzeExplicitSpace</*LHS=*/true>(lhs);
- analyzeExplicitSpace(rhs);
- };
- Fortran::common::visit(
- Fortran::common::visitors{
- [&](const Fortran::evaluate::ProcedureRef &procRef) {
- // Ensure the procRef expressions are the one being visited.
- assert(procRef.arguments().size() == 2);
- const Fortran::lower::SomeExpr *lhs =
- procRef.arguments()[0].value().UnwrapExpr();
- const Fortran::lower::SomeExpr *rhs =
- procRef.arguments()[1].value().UnwrapExpr();
- assert(lhs && rhs &&
- "user defined assignment arguments must be expressions");
- analyzeAssign(*lhs, *rhs);
- },
- [&](const auto &) { analyzeAssign(assign->lhs, assign->rhs); }},
- assign->u);
- explicitIterSpace.endAssign();
- }
- void analyzeExplicitSpace(const Fortran::parser::ForallAssignmentStmt &stmt) {
- Fortran::common::visit([&](const auto &s) { analyzeExplicitSpace(s); },
- stmt.u);
- }
- void analyzeExplicitSpace(const Fortran::parser::AssignmentStmt &s) {
- analyzeExplicitSpace(s.typedAssignment->v.operator->());
- }
- void analyzeExplicitSpace(const Fortran::parser::PointerAssignmentStmt &s) {
- analyzeExplicitSpace(s.typedAssignment->v.operator->());
- }
- void analyzeExplicitSpace(const Fortran::parser::WhereConstruct &c) {
- analyzeExplicitSpace(
- std::get<
- Fortran::parser::Statement<Fortran::parser::WhereConstructStmt>>(
- c.t)
- .statement);
- for (const Fortran::parser::WhereBodyConstruct &body :
- std::get<std::list<Fortran::parser::WhereBodyConstruct>>(c.t))
- analyzeExplicitSpace(body);
- for (const Fortran::parser::WhereConstruct::MaskedElsewhere &e :
- std::get<std::list<Fortran::parser::WhereConstruct::MaskedElsewhere>>(
- c.t))
- analyzeExplicitSpace(e);
- if (const auto &e =
- std::get<std::optional<Fortran::parser::WhereConstruct::Elsewhere>>(
- c.t);
- e.has_value())
- analyzeExplicitSpace(e.operator->());
- }
- void analyzeExplicitSpace(const Fortran::parser::WhereConstructStmt &ws) {
- const Fortran::lower::SomeExpr *exp = Fortran::semantics::GetExpr(
- std::get<Fortran::parser::LogicalExpr>(ws.t));
- addMaskVariable(exp);
- analyzeExplicitSpace(*exp);
- }
- void analyzeExplicitSpace(
- const Fortran::parser::WhereConstruct::MaskedElsewhere &ew) {
- analyzeExplicitSpace(
- std::get<
- Fortran::parser::Statement<Fortran::parser::MaskedElsewhereStmt>>(
- ew.t)
- .statement);
- for (const Fortran::parser::WhereBodyConstruct &e :
- std::get<std::list<Fortran::parser::WhereBodyConstruct>>(ew.t))
- analyzeExplicitSpace(e);
- }
- void analyzeExplicitSpace(const Fortran::parser::WhereBodyConstruct &body) {
- Fortran::common::visit(
- Fortran::common::visitors{
- [&](const Fortran::common::Indirection<
- Fortran::parser::WhereConstruct> &wc) {
- analyzeExplicitSpace(wc.value());
- },
- [&](const auto &s) { analyzeExplicitSpace(s.statement); }},
- body.u);
- }
- void analyzeExplicitSpace(const Fortran::parser::MaskedElsewhereStmt &stmt) {
- const Fortran::lower::SomeExpr *exp = Fortran::semantics::GetExpr(
- std::get<Fortran::parser::LogicalExpr>(stmt.t));
- addMaskVariable(exp);
- analyzeExplicitSpace(*exp);
- }
- void
- analyzeExplicitSpace(const Fortran::parser::WhereConstruct::Elsewhere *ew) {
- for (const Fortran::parser::WhereBodyConstruct &e :
- std::get<std::list<Fortran::parser::WhereBodyConstruct>>(ew->t))
- analyzeExplicitSpace(e);
- }
- void analyzeExplicitSpace(const Fortran::parser::WhereStmt &stmt) {
- const Fortran::lower::SomeExpr *exp = Fortran::semantics::GetExpr(
- std::get<Fortran::parser::LogicalExpr>(stmt.t));
- addMaskVariable(exp);
- analyzeExplicitSpace(*exp);
- const std::optional<Fortran::evaluate::Assignment> &assign =
- std::get<Fortran::parser::AssignmentStmt>(stmt.t).typedAssignment->v;
- assert(assign.has_value() && "WHERE has no statement");
- analyzeExplicitSpace(assign.operator->());
- }
- void analyzeExplicitSpace(const Fortran::parser::ForallStmt &forall) {
- analyzeExplicitSpace(
- std::get<
- Fortran::common::Indirection<Fortran::parser::ConcurrentHeader>>(
- forall.t)
- .value());
- analyzeExplicitSpace(std::get<Fortran::parser::UnlabeledStatement<
- Fortran::parser::ForallAssignmentStmt>>(forall.t)
- .statement);
- analyzeExplicitSpacePop();
- }
- void
- analyzeExplicitSpace(const Fortran::parser::ForallConstructStmt &forall) {
- analyzeExplicitSpace(
- std::get<
- Fortran::common::Indirection<Fortran::parser::ConcurrentHeader>>(
- forall.t)
- .value());
- }
- void analyzeExplicitSpace(const Fortran::parser::ForallConstruct &forall) {
- analyzeExplicitSpace(
- std::get<
- Fortran::parser::Statement<Fortran::parser::ForallConstructStmt>>(
- forall.t)
- .statement);
- for (const Fortran::parser::ForallBodyConstruct &s :
- std::get<std::list<Fortran::parser::ForallBodyConstruct>>(forall.t)) {
- Fortran::common::visit(
- Fortran::common::visitors{
- [&](const Fortran::common::Indirection<
- Fortran::parser::ForallConstruct> &b) {
- analyzeExplicitSpace(b.value());
- },
- [&](const Fortran::parser::WhereConstruct &w) {
- analyzeExplicitSpace(w);
- },
- [&](const auto &b) { analyzeExplicitSpace(b.statement); }},
- s.u);
- }
- analyzeExplicitSpacePop();
- }
-
- void analyzeExplicitSpacePop() { explicitIterSpace.popLevel(); }
-
- void addMaskVariable(Fortran::lower::FrontEndExpr exp) {
- // Note: use i8 to store bool values. This avoids round-down behavior found
- // with sequences of i1. That is, an array of i1 will be truncated in size
- // and be too small. For example, a buffer of type fir.array<7xi1> will have
- // 0 size.
- mlir::Type i64Ty = builder->getIntegerType(64);
- mlir::TupleType ty = fir::factory::getRaggedArrayHeaderType(*builder);
- mlir::Type buffTy = ty.getType(1);
- mlir::Type shTy = ty.getType(2);
- mlir::Location loc = toLocation();
- mlir::Value hdr = builder->createTemporary(loc, ty);
- // FIXME: Is there a way to create a `zeroinitializer` in LLVM-IR dialect?
- // For now, explicitly set lazy ragged header to all zeros.
- // auto nilTup = builder->createNullConstant(loc, ty);
- // fir::StoreOp::create(*builder, loc, nilTup, hdr);
- mlir::Type i32Ty = builder->getIntegerType(32);
- mlir::Value zero = builder->c...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/210639
More information about the flang-commits
mailing list