Skip to content

Commit be5747e

Browse files
committed
[flang] Fixed global name creation for literal constants.
The global names were created using a hash based on the address of std::vector::data address. Since the memory may be reused by different std::vector's, this may cause non-equivalent constant expressions to map to the same name. This is what is happening in the modified flang/test/Lower/constant-literal-mangling.f90 test. I changed the name creation to use a map between the constant expressions and corresponding unique names. The uniquing is done using a name counter in FirConverter. The effect of this change is that the equivalent constant expressions are now mapped to the same global, and the naming is "stable" (i.e. it does not change from compilation to compilation). Though, the issue is not HLFIR specific it was affecting several tests when using HLFIR lowering. Differential Revision: https://reviews.llvm.org/D150380
1 parent 26a7f42 commit be5747e

14 files changed

+781
-617
lines changed

flang/include/flang/Evaluate/constant.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,8 @@ class Constant<Type<TypeCategory::Character, KIND>> : public ConstantBounds {
165165
~Constant();
166166

167167
bool operator==(const Constant &that) const {
168-
return shape() == that.shape() && values_ == that.values_;
168+
return LEN() == that.LEN() && shape() == that.shape() &&
169+
values_ == that.values_;
169170
}
170171
bool empty() const;
171172
std::size_t size() const;

flang/include/flang/Lower/AbstractConverter.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,17 @@ class AbstractConverter {
115115
Fortran::semantics::Symbol::Flag flag, bool collectSymbols = true,
116116
bool collectHostAssociatedSymbols = false) = 0;
117117

118+
/// For the given literal constant \p expression, returns a unique name
119+
/// that can be used to create a global object to represent this
120+
/// literal constant. It will return the same name for equivalent
121+
/// literal constant expressions. \p eleTy specifies the data type
122+
/// of the constant elements. For array constants it specifies
123+
/// the array's element type.
124+
virtual llvm::StringRef
125+
getUniqueLitName(mlir::Location loc,
126+
std::unique_ptr<Fortran::lower::SomeExpr> expression,
127+
mlir::Type eleTy) = 0;
128+
118129
//===--------------------------------------------------------------------===//
119130
// Expressions
120131
//===--------------------------------------------------------------------===//

flang/include/flang/Lower/IterationSpace.h

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -37,30 +37,9 @@ using FrontEndSymbol = const semantics::Symbol *;
3737

3838
class AbstractConverter;
3939

40-
unsigned getHashValue(FrontEndExpr x);
41-
bool isEqual(FrontEndExpr x, FrontEndExpr y);
4240
} // namespace lower
4341
} // namespace Fortran
4442

45-
namespace llvm {
46-
template <>
47-
struct DenseMapInfo<Fortran::lower::FrontEndExpr> {
48-
static inline Fortran::lower::FrontEndExpr getEmptyKey() {
49-
return reinterpret_cast<Fortran::lower::FrontEndExpr>(~0);
50-
}
51-
static inline Fortran::lower::FrontEndExpr getTombstoneKey() {
52-
return reinterpret_cast<Fortran::lower::FrontEndExpr>(~0 - 1);
53-
}
54-
static unsigned getHashValue(Fortran::lower::FrontEndExpr v) {
55-
return Fortran::lower::getHashValue(v);
56-
}
57-
static bool isEqual(Fortran::lower::FrontEndExpr lhs,
58-
Fortran::lower::FrontEndExpr rhs) {
59-
return Fortran::lower::isEqual(lhs, rhs);
60-
}
61-
};
62-
} // namespace llvm
63-
6443
namespace Fortran::lower {
6544

6645
/// Abstraction of the iteration space for building the elemental compute loop

flang/include/flang/Lower/Mangler.h

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ std::string mangleName(const semantics::DerivedTypeSpec &, ScopeBlockIdMap &);
5454
std::string demangleName(llvm::StringRef name);
5555

5656
std::string
57-
mangleArrayLiteral(const uint8_t *addr, size_t size,
57+
mangleArrayLiteral(size_t size,
5858
const Fortran::evaluate::ConstantSubscripts &shape,
5959
Fortran::common::TypeCategory cat, int kind = 0,
6060
Fortran::common::ConstantSubscript charLen = -1,
@@ -64,35 +64,27 @@ template <Fortran::common::TypeCategory TC, int KIND>
6464
std::string mangleArrayLiteral(
6565
mlir::Type,
6666
const Fortran::evaluate::Constant<Fortran::evaluate::Type<TC, KIND>> &x) {
67-
return mangleArrayLiteral(
68-
reinterpret_cast<const uint8_t *>(x.values().data()),
69-
x.values().size() * sizeof(x.values()[0]), x.shape(), TC, KIND);
67+
return mangleArrayLiteral(x.values().size() * sizeof(x.values()[0]),
68+
x.shape(), TC, KIND);
7069
}
7170

7271
template <int KIND>
7372
std::string
7473
mangleArrayLiteral(mlir::Type,
7574
const Fortran::evaluate::Constant<Fortran::evaluate::Type<
7675
Fortran::common::TypeCategory::Character, KIND>> &x) {
77-
return mangleArrayLiteral(
78-
reinterpret_cast<const uint8_t *>(x.values().data()),
79-
x.values().size() * sizeof(x.values()[0]), x.shape(),
80-
Fortran::common::TypeCategory::Character, KIND, x.LEN());
76+
return mangleArrayLiteral(x.values().size() * sizeof(x.values()[0]),
77+
x.shape(), Fortran::common::TypeCategory::Character,
78+
KIND, x.LEN());
8179
}
8280

83-
// FIXME: derived type mangling is safe but not reproducible between two
84-
// compilation of a same file because `values().data()` is a nontrivial compile
85-
// time data structure containing pointers and vectors. In particular, this
86-
// means that similar structure constructors are not "combined" into the same
87-
// global constant by lowering.
8881
inline std::string mangleArrayLiteral(
8982
mlir::Type eleTy,
9083
const Fortran::evaluate::Constant<Fortran::evaluate::SomeDerived> &x) {
91-
return mangleArrayLiteral(
92-
reinterpret_cast<const uint8_t *>(x.values().data()),
93-
x.values().size() * sizeof(x.values()[0]), x.shape(),
94-
Fortran::common::TypeCategory::Derived, /*kind=*/0, /*charLen=*/-1,
95-
eleTy.cast<fir::RecordType>().getName());
84+
return mangleArrayLiteral(x.values().size() * sizeof(x.values()[0]),
85+
x.shape(), Fortran::common::TypeCategory::Derived,
86+
/*kind=*/0, /*charLen=*/-1,
87+
eleTy.cast<fir::RecordType>().getName());
9688
}
9789

9890
/// Return the compiler-generated name of a static namelist variable descriptor.

0 commit comments

Comments
 (0)