mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-14 12:12:07 +00:00
[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
This commit is contained in:
parent
24562babdf
commit
2c2e5a5d0f
@ -53,6 +53,7 @@ class Symbol;
|
||||
} // namespace semantics
|
||||
|
||||
namespace lower {
|
||||
class AbstractConverter;
|
||||
namespace pft {
|
||||
struct Variable;
|
||||
}
|
||||
@ -65,32 +66,23 @@ 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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
mlir::Type translateVariableToFIRType(Fortran::lower::AbstractConverter &,
|
||||
const pft::Variable &variable);
|
||||
|
||||
/// Translate a REAL of KIND to the mlir::Type.
|
||||
|
35
flang/include/flang/Lower/ConvertVariable.h
Normal file
35
flang/include/flang/Lower/ConvertVariable.h
Normal file
@ -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 different form \p symMap.
|
||||
void instantiateVariable(AbstractConverter &, const pft::Variable &var,
|
||||
SymMap &symMap);
|
||||
|
||||
} // namespace Fortran::lower
|
||||
#endif // FORTRAN_LOWER_CONVERT_VARIABLE_H
|
@ -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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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).
|
||||
|
@ -6,6 +6,7 @@ add_flang_library(FortranLower
|
||||
Coarray.cpp
|
||||
ConvertExpr.cpp
|
||||
ConvertType.cpp
|
||||
ConvertVariable.cpp
|
||||
Mangler.cpp
|
||||
OpenACC.cpp
|
||||
OpenMP.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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
|
||||
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 @@ private:
|
||||
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);
|
||||
}
|
||||
|
@ -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 @@ public:
|
||||
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 @@ private:
|
||||
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 @@ private:
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
||||
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,
|
||||
mlir::Type
|
||||
Fortran::lower::getFIRType(Fortran::lower::AbstractConverter &converter,
|
||||
Fortran::common::TypeCategory tc) {
|
||||
return TypeBuilder{context, defaults}.genFIRTy(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) {
|
||||
|
93
flang/lib/Lower/ConvertVariable.cpp
Normal file
93
flang/lib/Lower/ConvertVariable.cpp
Normal file
@ -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);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user