[flang-commits] [flang] 2c2e5a5 - [flang] Basic local variable lowering
Valentin Clement via flang-commits
flang-commits at lists.llvm.org
Mon Feb 7 00:14:16 PST 2022
Author: Valentin Clement
Date: 2022-02-07T09:14:09+01:00
New Revision: 2c2e5a5d0f191027ab447899599baeaf744fc2eb
URL: https://github.com/llvm/llvm-project/commit/2c2e5a5d0f191027ab447899599baeaf744fc2eb
DIFF: https://github.com/llvm/llvm-project/commit/2c2e5a5d0f191027ab447899599baeaf744fc2eb.diff
LOG: [flang] Basic local variable lowering
This patch add lowering for simple local variable.
- The signatures in `ConvertType.h` have been simplified to take advantage of the `AbstractConverter`.
- The lowering make use of the `allocateLocal` from the `FirOpBuilder`.
This lowering is used in patch D118982
This patch is part of the upstreaming effort from fir-dev branch.
Reviewed By: kiranchandramohan, jeanPerier, schweitz
Differential Revision: https://reviews.llvm.org/D118978
Added:
flang/include/flang/Lower/ConvertVariable.h
flang/lib/Lower/ConvertVariable.cpp
Modified:
flang/include/flang/Lower/ConvertType.h
flang/lib/Lower/Bridge.cpp
flang/lib/Lower/CMakeLists.txt
flang/lib/Lower/ConvertExpr.cpp
flang/lib/Lower/ConvertType.cpp
Removed:
################################################################################
diff --git a/flang/include/flang/Lower/ConvertType.h b/flang/include/flang/Lower/ConvertType.h
index e10772fa5b722..6a815f5affc2e 100644
--- a/flang/include/flang/Lower/ConvertType.h
+++ b/flang/include/flang/Lower/ConvertType.h
@@ -53,6 +53,7 @@ class Symbol;
} // namespace semantics
namespace lower {
+class AbstractConverter;
namespace pft {
struct Variable;
}
@@ -65,33 +66,24 @@ mlir::Type getFIRType(mlir::MLIRContext *ctxt, common::TypeCategory tc,
int kind);
/// Get a FIR type based on a category.
-mlir::Type getFIRType(mlir::MLIRContext *ctxt,
- common::IntrinsicTypeDefaultKinds const &defaults,
+mlir::Type getFIRType(Fortran::lower::AbstractConverter &,
common::TypeCategory tc);
/// Translate a Fortran::evaluate::DataRef to an mlir::Type.
-mlir::Type
-translateDataRefToFIRType(mlir::MLIRContext *ctxt,
- common::IntrinsicTypeDefaultKinds const &defaults,
- const evaluate::DataRef &dataRef);
+mlir::Type translateDataRefToFIRType(Fortran::lower::AbstractConverter &,
+ const evaluate::DataRef &dataRef);
/// Translate a SomeExpr to an mlir::Type.
-mlir::Type
-translateSomeExprToFIRType(mlir::MLIRContext *ctxt,
- common::IntrinsicTypeDefaultKinds const &defaults,
- const SomeExpr *expr);
+mlir::Type translateSomeExprToFIRType(Fortran::lower::AbstractConverter &,
+ const SomeExpr *expr);
/// Translate a Fortran::semantics::Symbol to an mlir::Type.
-mlir::Type
-translateSymbolToFIRType(mlir::MLIRContext *ctxt,
- common::IntrinsicTypeDefaultKinds const &defaults,
- const SymbolRef symbol);
+mlir::Type translateSymbolToFIRType(Fortran::lower::AbstractConverter &,
+ const SymbolRef symbol);
/// Translate a Fortran::lower::pft::Variable to an mlir::Type.
-mlir::Type
-translateVariableToFIRType(mlir::MLIRContext *ctxt,
- common::IntrinsicTypeDefaultKinds const &defaults,
- const pft::Variable &variable);
+mlir::Type translateVariableToFIRType(Fortran::lower::AbstractConverter &,
+ const pft::Variable &variable);
/// Translate a REAL of KIND to the mlir::Type.
mlir::Type convertReal(mlir::MLIRContext *ctxt, int KIND);
diff --git a/flang/include/flang/Lower/ConvertVariable.h b/flang/include/flang/Lower/ConvertVariable.h
new file mode 100644
index 0000000000000..011eab6113a6b
--- /dev/null
+++ b/flang/include/flang/Lower/ConvertVariable.h
@@ -0,0 +1,35 @@
+//===- Lower/ConvertVariable.h -- lowering of variables to FIR --*- 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/
+//
+//===----------------------------------------------------------------------===//
+///
+/// Instantiation of pft::Variable in FIR/MLIR.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef FORTRAN_LOWER_CONVERT_VARIABLE_H
+#define FORTRAN_LOWER_CONVERT_VARIABLE_H
+
+namespace Fortran ::lower {
+class AbstractConverter;
+class SymMap;
+namespace pft {
+struct Variable;
+}
+
+/// Instantiate variable \p var and add it to \p symMap.
+/// The AbstractConverter builder must be set.
+/// The AbstractConverter own symbol mapping is not used during the
+/// instantiation and can be
diff erent form \p symMap.
+void instantiateVariable(AbstractConverter &, const pft::Variable &var,
+ SymMap &symMap);
+
+} // namespace Fortran::lower
+#endif // FORTRAN_LOWER_CONVERT_VARIABLE_H
diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index f3e90d69620f1..82666df0b0615 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -15,6 +15,7 @@
#include "flang/Lower/CallInterface.h"
#include "flang/Lower/ConvertExpr.h"
#include "flang/Lower/ConvertType.h"
+#include "flang/Lower/ConvertVariable.h"
#include "flang/Lower/Mangler.h"
#include "flang/Lower/PFTBuilder.h"
#include "flang/Lower/Runtime.h"
@@ -109,9 +110,8 @@ class FirConverter : public Fortran::lower::AbstractConverter {
int kind) override final {
return Fortran::lower::getFIRType(&getMLIRContext(), tc, kind);
}
- mlir::Type genType(const Fortran::lower::pft::Variable &) override final {
- TODO_NOLOC("Not implemented genType Variable. Needed for more complex "
- "expression lowering");
+ mlir::Type genType(const Fortran::lower::pft::Variable &var) override final {
+ return Fortran::lower::translateVariableToFIRType(*this, var);
}
void setCurrentPosition(const Fortran::parser::CharBlock &position) {
@@ -196,6 +196,12 @@ class FirConverter : public Fortran::lower::AbstractConverter {
localSymbols.clear();
}
+ /// Instantiate variable \p var and add it to the symbol map.
+ /// See ConvertVariable.cpp.
+ void instantiateVar(const Fortran::lower::pft::Variable &var) {
+ Fortran::lower::instantiateVariable(*this, var, localSymbols);
+ }
+
/// Prepare to translate a new function
void startNewFunction(Fortran::lower::pft::FunctionLikeUnit &funit) {
assert(!builder && "expected nullptr");
@@ -205,6 +211,13 @@ class FirConverter : public Fortran::lower::AbstractConverter {
builder = new fir::FirOpBuilder(func, bridge.getKindMap());
assert(builder && "FirOpBuilder did not instantiate");
builder->setInsertionPointToStart(&func.front());
+
+ for (const Fortran::lower::pft::Variable &var :
+ funit.getOrderedSymbolTable()) {
+ const Fortran::semantics::Symbol &sym = var.getSymbol();
+ if (!sym.IsFuncResult() || !funit.primaryResult)
+ instantiateVar(var);
+ }
}
/// Lower a procedure (nest).
diff --git a/flang/lib/Lower/CMakeLists.txt b/flang/lib/Lower/CMakeLists.txt
index 025abdcd8d56a..7d72360fce70b 100644
--- a/flang/lib/Lower/CMakeLists.txt
+++ b/flang/lib/Lower/CMakeLists.txt
@@ -6,6 +6,7 @@ add_flang_library(FortranLower
Coarray.cpp
ConvertExpr.cpp
ConvertType.cpp
+ ConvertVariable.cpp
Mangler.cpp
OpenACC.cpp
OpenMP.cpp
diff --git a/flang/lib/Lower/ConvertExpr.cpp b/flang/lib/Lower/ConvertExpr.cpp
index e77ef422d4340..2f159fe0f3fdd 100644
--- a/flang/lib/Lower/ConvertExpr.cpp
+++ b/flang/lib/Lower/ConvertExpr.cpp
@@ -15,6 +15,7 @@
#include "flang/Evaluate/real.h"
#include "flang/Evaluate/traverse.h"
#include "flang/Lower/AbstractConverter.h"
+#include "flang/Lower/SymbolMap.h"
#include "flang/Lower/Todo.h"
#include "flang/Semantics/expression.h"
#include "flang/Semantics/symbol.h"
@@ -36,6 +37,32 @@
// to the correct FIR representation in SSA form.
//===----------------------------------------------------------------------===//
+/// Generate a load of a value from an address. Beware that this will lose
+/// any dynamic type information for polymorphic entities (note that unlimited
+/// polymorphic cannot be loaded and must not be provided here).
+static fir::ExtendedValue genLoad(fir::FirOpBuilder &builder,
+ mlir::Location loc,
+ const fir::ExtendedValue &addr) {
+ return addr.match(
+ [](const fir::CharBoxValue &box) -> fir::ExtendedValue { return box; },
+ [&](const fir::UnboxedValue &v) -> fir::ExtendedValue {
+ if (fir::unwrapRefType(fir::getBase(v).getType())
+ .isa<fir::RecordType>())
+ return v;
+ return builder.create<fir::LoadOp>(loc, fir::getBase(v));
+ },
+ [&](const fir::MutableBoxValue &box) -> fir::ExtendedValue {
+ TODO(loc, "genLoad for MutableBoxValue");
+ },
+ [&](const fir::BoxValue &box) -> fir::ExtendedValue {
+ TODO(loc, "genLoad for BoxValue");
+ },
+ [&](const auto &) -> fir::ExtendedValue {
+ fir::emitFatalError(
+ loc, "attempting to load whole array or procedure address");
+ });
+}
+
namespace {
/// Lowering of Fortran::evaluate::Expr<T> expressions
@@ -44,9 +71,10 @@ class ScalarExprLowering {
using ExtValue = fir::ExtendedValue;
explicit ScalarExprLowering(mlir::Location loc,
- Fortran::lower::AbstractConverter &converter)
+ Fortran::lower::AbstractConverter &converter,
+ Fortran::lower::SymMap &symMap)
: location{loc}, converter{converter},
- builder{converter.getFirOpBuilder()} {}
+ builder{converter.getFirOpBuilder()}, symMap{symMap} {}
mlir::Location getLoc() { return location; }
@@ -64,8 +92,26 @@ class ScalarExprLowering {
return builder.createBool(getLoc(), value);
}
+ /// Returns a reference to a symbol or its box/boxChar descriptor if it has
+ /// one.
+ ExtValue gen(Fortran::semantics::SymbolRef sym) {
+ if (Fortran::lower::SymbolBox val = symMap.lookupSymbol(sym))
+ return val.match([&val](auto &) { return val.toExtendedValue(); });
+ LLVM_DEBUG(llvm::dbgs()
+ << "unknown symbol: " << sym << "\nmap: " << symMap << '\n');
+ fir::emitFatalError(getLoc(), "symbol is not mapped to any IR value");
+ }
+
+ ExtValue genLoad(const ExtValue &exv) {
+ return ::genLoad(builder, getLoc(), exv);
+ }
+
ExtValue genval(Fortran::semantics::SymbolRef sym) {
- TODO(getLoc(), "genval SymbolRef");
+ ExtValue var = gen(sym);
+ if (const fir::UnboxedValue *s = var.getUnboxed())
+ if (fir::isReferenceLike(s->getType()))
+ return genLoad(*s);
+ return var;
}
ExtValue genval(const Fortran::evaluate::BOZLiteralConstant &) {
@@ -306,7 +352,7 @@ class ScalarExprLowering {
template <typename A>
ExtValue genval(const Fortran::evaluate::Designator<A> &des) {
- TODO(getLoc(), "genval Designator<A>");
+ return std::visit([&](const auto &x) { return genval(x); }, des.u);
}
template <typename A>
@@ -340,12 +386,13 @@ class ScalarExprLowering {
mlir::Location location;
Fortran::lower::AbstractConverter &converter;
fir::FirOpBuilder &builder;
+ Fortran::lower::SymMap &symMap;
};
} // namespace
fir::ExtendedValue Fortran::lower::createSomeExtendedExpression(
mlir::Location loc, Fortran::lower::AbstractConverter &converter,
- const Fortran::lower::SomeExpr &expr, Fortran::lower::SymMap &) {
+ const Fortran::lower::SomeExpr &expr, Fortran::lower::SymMap &symMap) {
LLVM_DEBUG(expr.AsFortran(llvm::dbgs() << "expr: ") << '\n');
- return ScalarExprLowering{loc, converter}.genval(expr);
+ return ScalarExprLowering{loc, converter, symMap}.genval(expr);
}
diff --git a/flang/lib/Lower/ConvertType.cpp b/flang/lib/Lower/ConvertType.cpp
index a411c0fcea5c8..ffff36df41f71 100644
--- a/flang/lib/Lower/ConvertType.cpp
+++ b/flang/lib/Lower/ConvertType.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "flang/Lower/ConvertType.h"
+#include "flang/Lower/AbstractConverter.h"
#include "flang/Lower/PFTBuilder.h"
#include "flang/Lower/Utils.h"
#include "flang/Optimizer/Dialect/FIRType.h"
@@ -177,11 +178,8 @@ namespace {
/// mlir::Type. The type returned may be an MLIR standard or FIR type.
class TypeBuilder {
public:
- /// Constructor.
- explicit TypeBuilder(
- mlir::MLIRContext *context,
- const Fortran::common::IntrinsicTypeDefaultKinds &defaults)
- : context{context}, defaults{defaults} {}
+ TypeBuilder(Fortran::lower::AbstractConverter &converter)
+ : converter{converter}, context{&converter.getMLIRContext()} {}
//===--------------------------------------------------------------------===//
// Generate type entry points
@@ -221,7 +219,7 @@ class TypeBuilder {
return genVariant(dref);
}
- mlir::Type gen(const Fortran::lower::pft::Variable &var) {
+ mlir::Type genVariableType(const Fortran::lower::pft::Variable &var) {
return genSymbolHelper(var.getSymbol(), var.isHeapAlloc(), var.isPointer());
}
@@ -425,9 +423,7 @@ class TypeBuilder {
int defaultKind() {
return defaultKind(TC);
}
- int defaultKind(Fortran::common::TypeCategory TC) {
- return defaults.GetDefaultKind(TC);
- }
+ int defaultKind(Fortran::common::TypeCategory TC) { return 0; }
fir::SequenceType::Shape seqShapeHelper(Fortran::semantics::SymbolRef symbol,
fir::SequenceType::Shape &bounds) {
@@ -469,8 +465,8 @@ class TypeBuilder {
//===--------------------------------------------------------------------===//
+ Fortran::lower::AbstractConverter &converter;
mlir::MLIRContext *context;
- const Fortran::common::IntrinsicTypeDefaultKinds &defaults;
};
} // namespace
@@ -520,39 +516,32 @@ mlir::Type Fortran::lower::getFIRType(mlir::MLIRContext *context,
return genFIRType(context, tc, kind);
}
-mlir::Type Fortran::lower::getFIRType(
- mlir::MLIRContext *context,
- const Fortran::common::IntrinsicTypeDefaultKinds &defaults,
- Fortran::common::TypeCategory tc) {
- return TypeBuilder{context, defaults}.genFIRTy(tc);
+mlir::Type
+Fortran::lower::getFIRType(Fortran::lower::AbstractConverter &converter,
+ Fortran::common::TypeCategory tc) {
+ return TypeBuilder{converter}.genFIRTy(tc);
}
mlir::Type Fortran::lower::translateDataRefToFIRType(
- mlir::MLIRContext *context,
- const Fortran::common::IntrinsicTypeDefaultKinds &defaults,
+ Fortran::lower::AbstractConverter &converter,
const Fortran::evaluate::DataRef &dataRef) {
- return TypeBuilder{context, defaults}.gen(dataRef);
+ return TypeBuilder{converter}.gen(dataRef);
}
mlir::Type Fortran::lower::translateSomeExprToFIRType(
- mlir::MLIRContext *context,
- const Fortran::common::IntrinsicTypeDefaultKinds &defaults,
- const SomeExpr *expr) {
- return TypeBuilder{context, defaults}.gen(*expr);
+ Fortran::lower::AbstractConverter &converter, const SomeExpr *expr) {
+ return TypeBuilder{converter}.gen(*expr);
}
mlir::Type Fortran::lower::translateSymbolToFIRType(
- mlir::MLIRContext *context,
- const Fortran::common::IntrinsicTypeDefaultKinds &defaults,
- const SymbolRef symbol) {
- return TypeBuilder{context, defaults}.gen(symbol);
+ Fortran::lower::AbstractConverter &converter, const SymbolRef symbol) {
+ return TypeBuilder{converter}.gen(symbol);
}
mlir::Type Fortran::lower::translateVariableToFIRType(
- mlir::MLIRContext *context,
- const Fortran::common::IntrinsicTypeDefaultKinds &defaults,
+ Fortran::lower::AbstractConverter &converter,
const Fortran::lower::pft::Variable &var) {
- return TypeBuilder{context, defaults}.gen(var);
+ return TypeBuilder{converter}.genVariableType(var);
}
mlir::Type Fortran::lower::convertReal(mlir::MLIRContext *context, int kind) {
diff --git a/flang/lib/Lower/ConvertVariable.cpp b/flang/lib/Lower/ConvertVariable.cpp
new file mode 100644
index 0000000000000..c207f60437695
--- /dev/null
+++ b/flang/lib/Lower/ConvertVariable.cpp
@@ -0,0 +1,93 @@
+//===-- ConvertVariable.cpp -- bridge to lower to MLIR --------------------===//
+//
+// 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/
+//
+//===----------------------------------------------------------------------===//
+
+#include "flang/Lower/ConvertVariable.h"
+#include "flang/Lower/AbstractConverter.h"
+#include "flang/Lower/CallInterface.h"
+#include "flang/Lower/ConvertExpr.h"
+#include "flang/Lower/Mangler.h"
+#include "flang/Lower/PFTBuilder.h"
+#include "flang/Lower/Support/Utils.h"
+#include "flang/Lower/SymbolMap.h"
+#include "flang/Lower/Todo.h"
+#include "flang/Optimizer/Builder/Character.h"
+#include "flang/Optimizer/Builder/FIRBuilder.h"
+#include "flang/Optimizer/Builder/Runtime/Derived.h"
+#include "flang/Optimizer/Dialect/FIRAttr.h"
+#include "flang/Optimizer/Dialect/FIRDialect.h"
+#include "flang/Optimizer/Dialect/FIROps.h"
+#include "flang/Optimizer/Support/FIRContext.h"
+#include "flang/Optimizer/Support/FatalError.h"
+#include "flang/Semantics/tools.h"
+#include "llvm/Support/Debug.h"
+
+#define DEBUG_TYPE "flang-lower-variable"
+
+//===----------------------------------------------------------------===//
+// Local variables instantiation (not for alias)
+//===----------------------------------------------------------------===//
+
+/// Create a stack slot for a local variable. Precondition: the insertion
+/// point of the builder must be in the entry block, which is currently being
+/// constructed.
+static mlir::Value createNewLocal(Fortran::lower::AbstractConverter &converter,
+ mlir::Location loc,
+ const Fortran::lower::pft::Variable &var,
+ mlir::Value preAlloc,
+ llvm::ArrayRef<mlir::Value> shape = {},
+ llvm::ArrayRef<mlir::Value> lenParams = {}) {
+ if (preAlloc)
+ return preAlloc;
+ fir::FirOpBuilder &builder = converter.getFirOpBuilder();
+ std::string nm = Fortran::lower::mangle::mangleName(var.getSymbol());
+ mlir::Type ty = converter.genType(var);
+ const Fortran::semantics::Symbol &ultimateSymbol =
+ var.getSymbol().GetUltimate();
+ llvm::StringRef symNm = toStringRef(ultimateSymbol.name());
+ bool isTarg = var.isTarget();
+ // Let the builder do all the heavy lifting.
+ return builder.allocateLocal(loc, ty, nm, symNm, shape, lenParams, isTarg);
+}
+
+/// Instantiate a local variable. Precondition: Each variable will be visited
+/// such that if its properties depend on other variables, the variables upon
+/// which its properties depend will already have been visited.
+static void instantiateLocal(Fortran::lower::AbstractConverter &converter,
+ const Fortran::lower::pft::Variable &var,
+ Fortran::lower::SymMap &symMap) {
+ assert(!var.isAlias());
+ const Fortran::semantics::Symbol &sym = var.getSymbol();
+ if (symMap.lookupSymbol(sym))
+ return;
+ const mlir::Location loc = converter.genLocation(sym.name());
+ mlir::Value local = createNewLocal(converter, loc, var, {});
+ symMap.addSymbol(sym, local);
+}
+
+void Fortran::lower::instantiateVariable(AbstractConverter &converter,
+ const pft::Variable &var,
+ SymMap &symMap) {
+ const Fortran::semantics::Symbol &sym = var.getSymbol();
+ const mlir::Location loc = converter.genLocation(sym.name());
+ if (var.isAggregateStore()) {
+ TODO(loc, "instantiateVariable AggregateStore");
+ } else if (Fortran::semantics::FindCommonBlockContaining(
+ var.getSymbol().GetUltimate())) {
+ TODO(loc, "instantiateVariable Common");
+ } else if (var.isAlias()) {
+ TODO(loc, "instantiateVariable Alias");
+ } else if (var.isGlobal()) {
+ TODO(loc, "instantiateVariable Global");
+ } else {
+ instantiateLocal(converter, var, symMap);
+ }
+}
More information about the flang-commits
mailing list