Skip to content

Commit 9da3581

Browse files
schweitzpgikiranchandramohan
authored andcommitted
[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
1 parent aeff03d commit 9da3581

File tree

4 files changed

+69
-29
lines changed

4 files changed

+69
-29
lines changed

flang/include/flang/Lower/Bridge.h

+1-5
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,6 @@
2222
#include "flang/Optimizer/Support/KindMapping.h"
2323
#include "mlir/IR/BuiltinOps.h"
2424

25-
namespace fir {
26-
struct NameUniquer;
27-
}
28-
2925
namespace Fortran {
3026
namespace common {
3127
class IntrinsicTypeDefaultKinds;
@@ -92,7 +88,7 @@ class LoweringBridge {
9288
void parseSourceFile(llvm::SourceMgr &);
9389

9490
/// Cross the bridge from the Fortran parse-tree, etc. to MLIR dialects
95-
void lower(const Fortran::parser::Program &program, fir::NameUniquer &uniquer,
91+
void lower(const Fortran::parser::Program &program,
9692
const Fortran::semantics::SemanticsContext &semanticsContext);
9793

9894
private:

flang/include/flang/Lower/Mangler.h

+15-8
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
#include <string>
1919

2020
namespace fir {
21-
struct NameUniquer;
2221

2322
/// Returns a name suitable to define mlir functions for Fortran intrinsic
2423
/// Procedure. These names are guaranteed to not conflict with user defined
@@ -40,18 +39,26 @@ class Reference;
4039

4140
namespace semantics {
4241
class Symbol;
43-
}
42+
class DerivedTypeSpec;
43+
} // namespace semantics
44+
45+
namespace lower::mangle {
4446

45-
namespace lower {
46-
namespace mangle {
47+
/// Convert a front-end Symbol to an internal name.
48+
/// If \p keepExternalInScope is true, the mangling of external symbols
49+
/// retains the scope of the symbol declaring externals. Otherwise,
50+
/// external symbols are mangled outside of any scope. Keeping the scope is
51+
/// useful in attributes where all the Fortran context is to be maintained.
52+
std::string mangleName(const semantics::Symbol &,
53+
bool keepExternalInScope = false);
4754

48-
/// Convert a front-end Symbol to an internal name
49-
std::string mangleName(fir::NameUniquer &uniquer, const semantics::Symbol &);
55+
/// Convert a derived type instance to an internal name.
56+
std::string mangleName(const semantics::DerivedTypeSpec &);
5057

58+
/// Recover the bare name of the original symbol from an internal name.
5159
std::string demangleName(llvm::StringRef name);
5260

53-
} // namespace mangle
54-
} // namespace lower
61+
} // namespace lower::mangle
5562
} // namespace Fortran
5663

5764
#endif // FORTRAN_LOWER_MANGLER_H

flang/include/flang/Optimizer/CodeGen/CodeGen.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ struct NameUniquer;
2323
std::unique_ptr<mlir::Pass> createFirCodeGenRewritePass();
2424

2525
/// Convert FIR to the LLVM IR dialect
26-
std::unique_ptr<mlir::Pass> createFIRToLLVMPass(NameUniquer &uniquer);
26+
std::unique_ptr<mlir::Pass> createFIRToLLVMPass();
2727

2828
/// Convert the LLVM IR dialect to LLVM-IR proper
2929
std::unique_ptr<mlir::Pass>

flang/lib/Lower/Mangler.cpp

+52-15
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#include "flang/Lower/Mangler.h"
1010
#include "flang/Common/reference.h"
11+
#include "flang/Lower/Todo.h"
1112
#include "flang/Lower/Utils.h"
1213
#include "flang/Optimizer/Dialect/FIRType.h"
1314
#include "flang/Optimizer/Support/InternalNames.h"
@@ -65,57 +66,93 @@ findInterfaceIfSeperateMP(const Fortran::semantics::Symbol &symbol) {
6566
// Mangle the name of `symbol` to make it unique within FIR's symbol table using
6667
// the FIR name mangler, `mangler`
6768
std::string
68-
Fortran::lower::mangle::mangleName(fir::NameUniquer &uniquer,
69-
const Fortran::semantics::Symbol &symbol) {
69+
Fortran::lower::mangle::mangleName(const Fortran::semantics::Symbol &symbol,
70+
bool keepExternalInScope) {
7071
// Resolve host and module association before mangling
7172
const auto &ultimateSymbol = symbol.GetUltimate();
7273
auto symbolName = toStringRef(ultimateSymbol.name());
7374

7475
return std::visit(
7576
Fortran::common::visitors{
7677
[&](const Fortran::semantics::MainProgramDetails &) {
77-
return uniquer.doProgramEntry().str();
78+
return fir::NameUniquer::doProgramEntry().str();
7879
},
7980
[&](const Fortran::semantics::SubprogramDetails &) {
8081
// Mangle external procedure without any scope prefix.
81-
if (Fortran::semantics::IsExternal(ultimateSymbol))
82-
return uniquer.doProcedure(llvm::None, llvm::None, symbolName);
82+
if (!keepExternalInScope &&
83+
Fortran::semantics::IsExternal(ultimateSymbol))
84+
return fir::NameUniquer::doProcedure(llvm::None, llvm::None,
85+
symbolName);
8386
// Separate module subprograms must be mangled according to the
8487
// scope where they were declared (the symbol we have is the
8588
// definition).
8689
const auto *interface = &ultimateSymbol;
8790
if (const auto *mpIface = findInterfaceIfSeperateMP(ultimateSymbol))
8891
interface = mpIface;
8992
auto modNames = moduleNames(*interface);
90-
return uniquer.doProcedure(modNames, hostName(*interface),
91-
symbolName);
93+
return fir::NameUniquer::doProcedure(modNames, hostName(*interface),
94+
symbolName);
9295
},
9396
[&](const Fortran::semantics::ProcEntityDetails &) {
9497
// Mangle procedure pointers and dummy procedures as variables
9598
if (Fortran::semantics::IsPointer(ultimateSymbol) ||
9699
Fortran::semantics::IsDummy(ultimateSymbol))
97-
return uniquer.doVariable(moduleNames(ultimateSymbol),
98-
hostName(ultimateSymbol), symbolName);
100+
return fir::NameUniquer::doVariable(moduleNames(ultimateSymbol),
101+
hostName(ultimateSymbol),
102+
symbolName);
99103
// Otherwise, this is an external procedure, even if it does not
100104
// have an explicit EXTERNAL attribute. Mangle it without any
101105
// prefix.
102-
return uniquer.doProcedure(llvm::None, llvm::None, symbolName);
106+
return fir::NameUniquer::doProcedure(llvm::None, llvm::None,
107+
symbolName);
103108
},
104109
[&](const Fortran::semantics::ObjectEntityDetails &) {
105110
auto modNames = moduleNames(ultimateSymbol);
106111
auto optHost = hostName(ultimateSymbol);
107112
if (Fortran::semantics::IsNamedConstant(ultimateSymbol))
108-
return uniquer.doConstant(modNames, optHost, symbolName);
109-
return uniquer.doVariable(modNames, optHost, symbolName);
113+
return fir::NameUniquer::doConstant(modNames, optHost,
114+
symbolName);
115+
return fir::NameUniquer::doVariable(modNames, optHost, symbolName);
110116
},
111-
[](const auto &) -> std::string {
112-
assert(false);
113-
return {};
117+
[&](const Fortran::semantics::CommonBlockDetails &) {
118+
return fir::NameUniquer::doCommonBlock(symbolName);
114119
},
120+
[&](const Fortran::semantics::DerivedTypeDetails &) -> std::string {
121+
// Derived type mangling must used mangleName(DerivedTypeSpec&) so
122+
// that kind type parameter values can be mangled.
123+
llvm::report_fatal_error(
124+
"only derived type instances can be mangled");
125+
},
126+
[](const auto &) -> std::string { TODO_NOLOC("symbol mangling"); },
115127
},
116128
ultimateSymbol.details());
117129
}
118130

131+
std::string Fortran::lower::mangle::mangleName(
132+
const Fortran::semantics::DerivedTypeSpec &derivedType) {
133+
// Resolve host and module association before mangling
134+
const auto &ultimateSymbol = derivedType.typeSymbol().GetUltimate();
135+
auto symbolName = toStringRef(ultimateSymbol.name());
136+
auto modNames = moduleNames(ultimateSymbol);
137+
auto optHost = hostName(ultimateSymbol);
138+
llvm::SmallVector<std::int64_t> kinds;
139+
for (const auto &param :
140+
Fortran::semantics::OrderParameterDeclarations(ultimateSymbol)) {
141+
const auto &paramDetails =
142+
param->get<Fortran::semantics::TypeParamDetails>();
143+
if (paramDetails.attr() == Fortran::common::TypeParamAttr::Kind) {
144+
const auto *paramValue = derivedType.FindParameter(param->name());
145+
assert(paramValue && "derived type kind parameter value not found");
146+
auto paramExpr = paramValue->GetExplicit();
147+
assert(paramExpr && "derived type kind param not explicit");
148+
auto init = Fortran::evaluate::ToInt64(paramValue->GetExplicit());
149+
assert(init && "derived type kind param is not constant");
150+
kinds.emplace_back(*init);
151+
}
152+
}
153+
return fir::NameUniquer::doType(modNames, optHost, symbolName, kinds);
154+
}
155+
119156
std::string Fortran::lower::mangle::demangleName(llvm::StringRef name) {
120157
auto result = fir::NameUniquer::deconstruct(name);
121158
return result.second.name;

0 commit comments

Comments
 (0)