aboutsummaryrefslogtreecommitdiff
path: root/flang
diff options
context:
space:
mode:
authorEric Schweitz <eschweitz@nvidia.com>2021-04-05 17:09:10 +0100
committerKiran Chandramohan <kiran.chandramohan@arm.com>2021-04-09 16:42:06 +0100
commit9da35814e5fb71d8610ed7888d1f05703bfa8b54 (patch)
treeb4418007b8e552319c6d51b0b31650727d465901 /flang
parent[InstCombine] Regenerate 2010-11-23-Distributed.ll tests (diff)
downloadllvm-project-9da35814e5fb71d8610ed7888d1f05703bfa8b54.tar.gz
llvm-project-9da35814e5fb71d8610ed7888d1f05703bfa8b54.tar.bz2
llvm-project-9da35814e5fb71d8610ed7888d1f05703bfa8b54.zip
[Flang] Changes to mangling code
Call static functions using the class name (fir::NameUniquer). Add function for mangling derivedTypes. All the name mangling functions that are ultimately called are tested in unittests/Optimizer/InternalNamesTest.cpp. Differential Revision: https://reviews.llvm.org/D99967
Diffstat (limited to 'flang')
-rw-r--r--flang/include/flang/Lower/Bridge.h6
-rw-r--r--flang/include/flang/Lower/Mangler.h23
-rw-r--r--flang/include/flang/Optimizer/CodeGen/CodeGen.h2
-rw-r--r--flang/lib/Lower/Mangler.cpp67
4 files changed, 69 insertions, 29 deletions
diff --git a/flang/include/flang/Lower/Bridge.h b/flang/include/flang/Lower/Bridge.h
index eafa16dd007b..28ce992fb49a 100644
--- a/flang/include/flang/Lower/Bridge.h
+++ b/flang/include/flang/Lower/Bridge.h
@@ -22,10 +22,6 @@
#include "flang/Optimizer/Support/KindMapping.h"
#include "mlir/IR/BuiltinOps.h"
-namespace fir {
-struct NameUniquer;
-}
-
namespace Fortran {
namespace common {
class IntrinsicTypeDefaultKinds;
@@ -92,7 +88,7 @@ public:
void parseSourceFile(llvm::SourceMgr &);
/// Cross the bridge from the Fortran parse-tree, etc. to MLIR dialects
- void lower(const Fortran::parser::Program &program, fir::NameUniquer &uniquer,
+ void lower(const Fortran::parser::Program &program,
const Fortran::semantics::SemanticsContext &semanticsContext);
private:
diff --git a/flang/include/flang/Lower/Mangler.h b/flang/include/flang/Lower/Mangler.h
index 0029772e0978..d82fdb0ed99a 100644
--- a/flang/include/flang/Lower/Mangler.h
+++ b/flang/include/flang/Lower/Mangler.h
@@ -18,7 +18,6 @@
#include <string>
namespace fir {
-struct NameUniquer;
/// Returns a name suitable to define mlir functions for Fortran intrinsic
/// Procedure. These names are guaranteed to not conflict with user defined
@@ -40,18 +39,26 @@ class Reference;
namespace semantics {
class Symbol;
-}
+class DerivedTypeSpec;
+} // namespace semantics
+
+namespace lower::mangle {
-namespace lower {
-namespace mangle {
+/// Convert a front-end Symbol to an internal name.
+/// If \p keepExternalInScope is true, the mangling of external symbols
+/// retains the scope of the symbol declaring externals. Otherwise,
+/// external symbols are mangled outside of any scope. Keeping the scope is
+/// useful in attributes where all the Fortran context is to be maintained.
+std::string mangleName(const semantics::Symbol &,
+ bool keepExternalInScope = false);
-/// Convert a front-end Symbol to an internal name
-std::string mangleName(fir::NameUniquer &uniquer, const semantics::Symbol &);
+/// Convert a derived type instance to an internal name.
+std::string mangleName(const semantics::DerivedTypeSpec &);
+/// Recover the bare name of the original symbol from an internal name.
std::string demangleName(llvm::StringRef name);
-} // namespace mangle
-} // namespace lower
+} // namespace lower::mangle
} // namespace Fortran
#endif // FORTRAN_LOWER_MANGLER_H
diff --git a/flang/include/flang/Optimizer/CodeGen/CodeGen.h b/flang/include/flang/Optimizer/CodeGen/CodeGen.h
index 7623c59a8a8d..d86354588283 100644
--- a/flang/include/flang/Optimizer/CodeGen/CodeGen.h
+++ b/flang/include/flang/Optimizer/CodeGen/CodeGen.h
@@ -23,7 +23,7 @@ struct NameUniquer;
std::unique_ptr<mlir::Pass> createFirCodeGenRewritePass();
/// Convert FIR to the LLVM IR dialect
-std::unique_ptr<mlir::Pass> createFIRToLLVMPass(NameUniquer &uniquer);
+std::unique_ptr<mlir::Pass> createFIRToLLVMPass();
/// Convert the LLVM IR dialect to LLVM-IR proper
std::unique_ptr<mlir::Pass>
diff --git a/flang/lib/Lower/Mangler.cpp b/flang/lib/Lower/Mangler.cpp
index b590fc932441..07d9e63e0423 100644
--- a/flang/lib/Lower/Mangler.cpp
+++ b/flang/lib/Lower/Mangler.cpp
@@ -8,6 +8,7 @@
#include "flang/Lower/Mangler.h"
#include "flang/Common/reference.h"
+#include "flang/Lower/Todo.h"
#include "flang/Lower/Utils.h"
#include "flang/Optimizer/Dialect/FIRType.h"
#include "flang/Optimizer/Support/InternalNames.h"
@@ -65,8 +66,8 @@ findInterfaceIfSeperateMP(const Fortran::semantics::Symbol &symbol) {
// Mangle the name of `symbol` to make it unique within FIR's symbol table using
// the FIR name mangler, `mangler`
std::string
-Fortran::lower::mangle::mangleName(fir::NameUniquer &uniquer,
- const Fortran::semantics::Symbol &symbol) {
+Fortran::lower::mangle::mangleName(const Fortran::semantics::Symbol &symbol,
+ bool keepExternalInScope) {
// Resolve host and module association before mangling
const auto &ultimateSymbol = symbol.GetUltimate();
auto symbolName = toStringRef(ultimateSymbol.name());
@@ -74,12 +75,14 @@ Fortran::lower::mangle::mangleName(fir::NameUniquer &uniquer,
return std::visit(
Fortran::common::visitors{
[&](const Fortran::semantics::MainProgramDetails &) {
- return uniquer.doProgramEntry().str();
+ return fir::NameUniquer::doProgramEntry().str();
},
[&](const Fortran::semantics::SubprogramDetails &) {
// Mangle external procedure without any scope prefix.
- if (Fortran::semantics::IsExternal(ultimateSymbol))
- return uniquer.doProcedure(llvm::None, llvm::None, symbolName);
+ if (!keepExternalInScope &&
+ Fortran::semantics::IsExternal(ultimateSymbol))
+ return fir::NameUniquer::doProcedure(llvm::None, llvm::None,
+ symbolName);
// Separate module subprograms must be mangled according to the
// scope where they were declared (the symbol we have is the
// definition).
@@ -87,35 +90,69 @@ Fortran::lower::mangle::mangleName(fir::NameUniquer &uniquer,
if (const auto *mpIface = findInterfaceIfSeperateMP(ultimateSymbol))
interface = mpIface;
auto modNames = moduleNames(*interface);
- return uniquer.doProcedure(modNames, hostName(*interface),
- symbolName);
+ return fir::NameUniquer::doProcedure(modNames, hostName(*interface),
+ symbolName);
},
[&](const Fortran::semantics::ProcEntityDetails &) {
// Mangle procedure pointers and dummy procedures as variables
if (Fortran::semantics::IsPointer(ultimateSymbol) ||
Fortran::semantics::IsDummy(ultimateSymbol))
- return uniquer.doVariable(moduleNames(ultimateSymbol),
- hostName(ultimateSymbol), symbolName);
+ return fir::NameUniquer::doVariable(moduleNames(ultimateSymbol),
+ hostName(ultimateSymbol),
+ symbolName);
// Otherwise, this is an external procedure, even if it does not
// have an explicit EXTERNAL attribute. Mangle it without any
// prefix.
- return uniquer.doProcedure(llvm::None, llvm::None, symbolName);
+ return fir::NameUniquer::doProcedure(llvm::None, llvm::None,
+ symbolName);
},
[&](const Fortran::semantics::ObjectEntityDetails &) {
auto modNames = moduleNames(ultimateSymbol);
auto optHost = hostName(ultimateSymbol);
if (Fortran::semantics::IsNamedConstant(ultimateSymbol))
- return uniquer.doConstant(modNames, optHost, symbolName);
- return uniquer.doVariable(modNames, optHost, symbolName);
+ return fir::NameUniquer::doConstant(modNames, optHost,
+ symbolName);
+ return fir::NameUniquer::doVariable(modNames, optHost, symbolName);
},
- [](const auto &) -> std::string {
- assert(false);
- return {};
+ [&](const Fortran::semantics::CommonBlockDetails &) {
+ return fir::NameUniquer::doCommonBlock(symbolName);
},
+ [&](const Fortran::semantics::DerivedTypeDetails &) -> std::string {
+ // Derived type mangling must used mangleName(DerivedTypeSpec&) so
+ // that kind type parameter values can be mangled.
+ llvm::report_fatal_error(
+ "only derived type instances can be mangled");
+ },
+ [](const auto &) -> std::string { TODO_NOLOC("symbol mangling"); },
},
ultimateSymbol.details());
}
+std::string Fortran::lower::mangle::mangleName(
+ const Fortran::semantics::DerivedTypeSpec &derivedType) {
+ // Resolve host and module association before mangling
+ const auto &ultimateSymbol = derivedType.typeSymbol().GetUltimate();
+ auto symbolName = toStringRef(ultimateSymbol.name());
+ auto modNames = moduleNames(ultimateSymbol);
+ auto optHost = hostName(ultimateSymbol);
+ llvm::SmallVector<std::int64_t> kinds;
+ for (const auto &param :
+ Fortran::semantics::OrderParameterDeclarations(ultimateSymbol)) {
+ const auto &paramDetails =
+ param->get<Fortran::semantics::TypeParamDetails>();
+ if (paramDetails.attr() == Fortran::common::TypeParamAttr::Kind) {
+ const auto *paramValue = derivedType.FindParameter(param->name());
+ assert(paramValue && "derived type kind parameter value not found");
+ auto paramExpr = paramValue->GetExplicit();
+ assert(paramExpr && "derived type kind param not explicit");
+ auto init = Fortran::evaluate::ToInt64(paramValue->GetExplicit());
+ assert(init && "derived type kind param is not constant");
+ kinds.emplace_back(*init);
+ }
+ }
+ return fir::NameUniquer::doType(modNames, optHost, symbolName, kinds);
+}
+
std::string Fortran::lower::mangle::demangleName(llvm::StringRef name) {
auto result = fir::NameUniquer::deconstruct(name);
return result.second.name;