forked from OSchip/llvm-project
[flang] Make `TypeParamInquiry` monomorphic
Change the expression representation TypeParamInquiry from being a class that's templatized on the integer KIND of its result into a monomorphic representation that results in a SubscriptInteger that can then be converted. This is a minor simplification, but it's worth doing because it is believed to also be a work-around for bugs in the MSVC compiler with overload resolution that affect the expression traversal framework. Differential Revision: https://reviews.llvm.org/D86551
This commit is contained in:
parent
b79e19e6d6
commit
4cbfd93a59
|
@ -516,15 +516,18 @@ private:
|
|||
Power<Result>, Extremum<Result>>;
|
||||
using Indices = std::conditional_t<KIND == ImpliedDoIndex::Result::kind,
|
||||
std::tuple<ImpliedDoIndex>, std::tuple<>>;
|
||||
using TypeParamInquiries =
|
||||
std::conditional_t<KIND == TypeParamInquiry::Result::kind,
|
||||
std::tuple<TypeParamInquiry>, std::tuple<>>;
|
||||
using DescriptorInquiries =
|
||||
std::conditional_t<KIND == DescriptorInquiry::Result::kind,
|
||||
std::tuple<DescriptorInquiry>, std::tuple<>>;
|
||||
using Others = std::tuple<Constant<Result>, ArrayConstructor<Result>,
|
||||
TypeParamInquiry<KIND>, Designator<Result>, FunctionRef<Result>>;
|
||||
Designator<Result>, FunctionRef<Result>>;
|
||||
|
||||
public:
|
||||
common::TupleToVariant<common::CombineTuples<Operations, Conversions, Indices,
|
||||
DescriptorInquiries, Others>>
|
||||
TypeParamInquiries, DescriptorInquiries, Others>>
|
||||
u;
|
||||
};
|
||||
|
||||
|
|
|
@ -93,9 +93,7 @@ public:
|
|||
|
||||
Result operator()(const ImpliedDoIndex &) const { return Scalar(); }
|
||||
Result operator()(const DescriptorInquiry &) const { return Scalar(); }
|
||||
template <int KIND> Result operator()(const TypeParamInquiry<KIND> &) const {
|
||||
return Scalar();
|
||||
}
|
||||
Result operator()(const TypeParamInquiry &) const { return Scalar(); }
|
||||
Result operator()(const BOZLiteralConstant &) const { return Scalar(); }
|
||||
Result operator()(const StaticDataObject::Pointer &) const {
|
||||
return Scalar();
|
||||
|
|
|
@ -120,7 +120,7 @@ public:
|
|||
return visitor_(x.GetFirstSymbol());
|
||||
}
|
||||
}
|
||||
template <int KIND> Result operator()(const TypeParamInquiry<KIND> &x) const {
|
||||
Result operator()(const TypeParamInquiry &x) const {
|
||||
return visitor_(x.base());
|
||||
}
|
||||
Result operator()(const Triplet &x) const {
|
||||
|
|
|
@ -128,9 +128,9 @@ private:
|
|||
// KIND(x), which is then folded to a constant value.
|
||||
// "Bare" type parameter references within a derived type definition do
|
||||
// not have base objects.
|
||||
template <int KIND> class TypeParamInquiry {
|
||||
class TypeParamInquiry {
|
||||
public:
|
||||
using Result = Type<TypeCategory::Integer, KIND>;
|
||||
using Result = SubscriptInteger;
|
||||
CLASS_BOILERPLATE(TypeParamInquiry)
|
||||
TypeParamInquiry(NamedEntity &&x, const Symbol ¶m)
|
||||
: base_{std::move(x)}, parameter_{param} {}
|
||||
|
@ -150,9 +150,6 @@ private:
|
|||
SymbolRef parameter_;
|
||||
};
|
||||
|
||||
EXPAND_FOR_EACH_INTEGER_KIND(
|
||||
TEMPLATE_INSTANTIATION, extern template class TypeParamInquiry, )
|
||||
|
||||
// R921 subscript-triplet
|
||||
class Triplet {
|
||||
public:
|
||||
|
@ -422,8 +419,6 @@ private:
|
|||
};
|
||||
|
||||
#define INSTANTIATE_VARIABLE_TEMPLATES \
|
||||
EXPAND_FOR_EACH_INTEGER_KIND( \
|
||||
TEMPLATE_INSTANTIATION, template class TypeParamInquiry, ) \
|
||||
FOR_EACH_SPECIFIC_TYPE(template class Designator, )
|
||||
} // namespace Fortran::evaluate
|
||||
#endif // FORTRAN_EVALUATE_VARIABLE_H_
|
||||
|
|
|
@ -29,7 +29,7 @@ public:
|
|||
IsConstantExprHelper() : Base{*this} {}
|
||||
using Base::operator();
|
||||
|
||||
template <int KIND> bool operator()(const TypeParamInquiry<KIND> &inq) const {
|
||||
bool operator()(const TypeParamInquiry &inq) const {
|
||||
return IsKindTypeParameter(inq.parameter());
|
||||
}
|
||||
bool operator()(const semantics::Symbol &symbol) const {
|
||||
|
@ -155,9 +155,7 @@ public:
|
|||
return true;
|
||||
}
|
||||
bool operator()(const StaticDataObject &) const { return false; }
|
||||
template <int KIND> bool operator()(const TypeParamInquiry<KIND> &) const {
|
||||
return false;
|
||||
}
|
||||
bool operator()(const TypeParamInquiry &) const { return false; }
|
||||
bool operator()(const Triplet &x) const {
|
||||
return IsConstantExpr(x.lower()) && IsConstantExpr(x.upper()) &&
|
||||
IsConstantExpr(x.stride());
|
||||
|
@ -310,8 +308,7 @@ public:
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
template <int KIND>
|
||||
Result operator()(const TypeParamInquiry<KIND> &inq) const {
|
||||
Result operator()(const TypeParamInquiry &inq) const {
|
||||
if (scope_.IsDerivedType() && !IsConstantExpr(inq) &&
|
||||
inq.parameter().owner() != scope_) { // C750, C754
|
||||
return "non-constant reference to a type parameter inquiry not "
|
||||
|
|
|
@ -115,9 +115,8 @@ Expr<T> FoldOperation(FoldingContext &context, Designator<T> &&designator) {
|
|||
return Folder<T>{context}.Folding(std::move(designator));
|
||||
}
|
||||
|
||||
template <int KIND>
|
||||
Expr<Type<TypeCategory::Integer, KIND>> FoldOperation(
|
||||
FoldingContext &, TypeParamInquiry<KIND> &&);
|
||||
Expr<TypeParamInquiry::Result> FoldOperation(
|
||||
FoldingContext &, TypeParamInquiry &&);
|
||||
Expr<ImpliedDoIndex::Result> FoldOperation(
|
||||
FoldingContext &context, ImpliedDoIndex &&);
|
||||
template <typename T>
|
||||
|
|
|
@ -600,10 +600,8 @@ Expr<Type<TypeCategory::Integer, KIND>> FoldIntrinsicFunction(
|
|||
}
|
||||
|
||||
// Substitute a bare type parameter reference with its value if it has one now
|
||||
template <int KIND>
|
||||
Expr<Type<TypeCategory::Integer, KIND>> FoldOperation(
|
||||
FoldingContext &context, TypeParamInquiry<KIND> &&inquiry) {
|
||||
using IntKIND = Type<TypeCategory::Integer, KIND>;
|
||||
Expr<TypeParamInquiry::Result> FoldOperation(
|
||||
FoldingContext &context, TypeParamInquiry &&inquiry) {
|
||||
if (!inquiry.base()) {
|
||||
// A "bare" type parameter: replace with its value, if that's now known.
|
||||
if (const auto *pdt{context.pdtInstance()}) {
|
||||
|
@ -617,21 +615,20 @@ Expr<Type<TypeCategory::Integer, KIND>> FoldOperation(
|
|||
IsConstantExpr(*details->init()))) {
|
||||
Expr<SomeInteger> expr{*details->init()};
|
||||
return Fold(context,
|
||||
Expr<IntKIND>{
|
||||
Convert<IntKIND, TypeCategory::Integer>(std::move(expr))});
|
||||
ConvertToType<TypeParamInquiry::Result>(std::move(expr)));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (const auto *value{pdt->FindParameter(inquiry.parameter().name())}) {
|
||||
if (value->isExplicit()) {
|
||||
return Fold(context,
|
||||
Expr<IntKIND>{Convert<IntKIND, TypeCategory::Integer>(
|
||||
Expr<SomeInteger>{value->GetExplicit().value()})});
|
||||
AsExpr(ConvertToType<TypeParamInquiry::Result>(
|
||||
Expr<SomeInteger>{value->GetExplicit().value()})));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return Expr<IntKIND>{std::move(inquiry)};
|
||||
return AsExpr(std::move(inquiry));
|
||||
}
|
||||
|
||||
std::optional<std::int64_t> ToInt64(const Expr<SomeInteger> &expr) {
|
||||
|
|
|
@ -606,9 +606,7 @@ llvm::raw_ostream &BaseObject::AsFortran(llvm::raw_ostream &o) const {
|
|||
return EmitVar(o, u);
|
||||
}
|
||||
|
||||
template <int KIND>
|
||||
llvm::raw_ostream &TypeParamInquiry<KIND>::AsFortran(
|
||||
llvm::raw_ostream &o) const {
|
||||
llvm::raw_ostream &TypeParamInquiry::AsFortran(llvm::raw_ostream &o) const {
|
||||
if (base_) {
|
||||
return base_->AsFortran(o) << '%';
|
||||
}
|
||||
|
|
|
@ -635,9 +635,7 @@ bool NamedEntity::operator==(const NamedEntity &that) const {
|
|||
return !that.IsSymbol() && GetComponent() == that.GetComponent();
|
||||
}
|
||||
}
|
||||
template <int KIND>
|
||||
bool TypeParamInquiry<KIND>::operator==(
|
||||
const TypeParamInquiry<KIND> &that) const {
|
||||
bool TypeParamInquiry::operator==(const TypeParamInquiry &that) const {
|
||||
return &*parameter_ == &*that.parameter_ && base_ == that.base_;
|
||||
}
|
||||
bool Triplet::operator==(const Triplet &that) const {
|
||||
|
|
|
@ -262,13 +262,13 @@ private:
|
|||
//===--------------------------------------------------------------------===//
|
||||
|
||||
mlir::Type gen(const Fortran::evaluate::ImpliedDoIndex &) {
|
||||
return genFIRType<Fortran::common::TypeCategory::Integer>(
|
||||
context, defaultKind<Fortran::common::TypeCategory::Integer>());
|
||||
return genFIRType<Fortran::evaluate::ImpliedDoIndex::Result::category>(
|
||||
context, Fortran::evaluate::ImpliedDoIndex::Result::kind);
|
||||
}
|
||||
|
||||
template <int KIND>
|
||||
mlir::Type gen(const Fortran::evaluate::TypeParamInquiry<KIND> &) {
|
||||
return genFIRType<Fortran::common::TypeCategory::Integer, KIND>(context);
|
||||
mlir::Type gen(const Fortran::evaluate::TypeParamInquiry &) {
|
||||
return genFIRType<Fortran::evaluate::TypeParamInquiry::Result::category>(
|
||||
context, Fortran::evaluate::TypeParamInquiry::Result::kind);
|
||||
}
|
||||
|
||||
template <typename A>
|
||||
|
|
|
@ -643,38 +643,6 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::BOZLiteralConstant &x) {
|
|||
return AsGenericExpr(std::move(value.value));
|
||||
}
|
||||
|
||||
// For use with SearchTypes to create a TypeParamInquiry with the
|
||||
// right integer kind.
|
||||
struct TypeParamInquiryVisitor {
|
||||
using Result = std::optional<Expr<SomeInteger>>;
|
||||
using Types = IntegerTypes;
|
||||
TypeParamInquiryVisitor(int k, NamedEntity &&b, const Symbol ¶m)
|
||||
: kind{k}, base{std::move(b)}, parameter{param} {}
|
||||
TypeParamInquiryVisitor(int k, const Symbol ¶m)
|
||||
: kind{k}, parameter{param} {}
|
||||
template <typename T> Result Test() {
|
||||
if (kind == T::kind) {
|
||||
return Expr<SomeInteger>{
|
||||
Expr<T>{TypeParamInquiry<T::kind>{std::move(base), parameter}}};
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
int kind;
|
||||
std::optional<NamedEntity> base;
|
||||
const Symbol ¶meter;
|
||||
};
|
||||
|
||||
static std::optional<Expr<SomeInteger>> MakeBareTypeParamInquiry(
|
||||
const Symbol *symbol) {
|
||||
if (std::optional<DynamicType> dyType{DynamicType::From(symbol)}) {
|
||||
if (dyType->category() == TypeCategory::Integer) {
|
||||
return common::SearchTypes(
|
||||
TypeParamInquiryVisitor{dyType->kind(), *symbol});
|
||||
}
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
// Names and named constants
|
||||
MaybeExpr ExpressionAnalyzer::Analyze(const parser::Name &n) {
|
||||
if (std::optional<int> kind{IsImpliedDo(n.source)}) {
|
||||
|
@ -690,7 +658,8 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::Name &n) {
|
|||
if (ultimate.has<semantics::TypeParamDetails>()) {
|
||||
// A bare reference to a derived type parameter (within a parameterized
|
||||
// derived type definition)
|
||||
return AsMaybeExpr(MakeBareTypeParamInquiry(&ultimate));
|
||||
return Fold(ConvertToType(
|
||||
ultimate, AsGenericExpr(TypeParamInquiry{std::nullopt, ultimate})));
|
||||
} else {
|
||||
if (n.symbol->attrs().test(semantics::Attr::VOLATILE)) {
|
||||
if (const semantics::Scope *
|
||||
|
@ -989,9 +958,9 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::StructureComponent &sc) {
|
|||
if (auto *designator{UnwrapExpr<Designator<SomeDerived>>(*dtExpr)}) {
|
||||
if (std::optional<DynamicType> dyType{DynamicType::From(*sym)}) {
|
||||
if (dyType->category() == TypeCategory::Integer) {
|
||||
return AsMaybeExpr(
|
||||
common::SearchTypes(TypeParamInquiryVisitor{dyType->kind(),
|
||||
IgnoreAnySubscripts(std::move(*designator)), *sym}));
|
||||
return Fold(ConvertToType(*dyType,
|
||||
AsGenericExpr(TypeParamInquiry{
|
||||
IgnoreAnySubscripts(std::move(*designator)), *sym})));
|
||||
}
|
||||
}
|
||||
Say(name, "Type parameter is not INTEGER"_err_en_US);
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
!REF: /MainProgram1/ipdt/k
|
||||
integer, kind :: k
|
||||
!REF: /MainProgram1/ipdt/k
|
||||
!DEF: /MainProgram1/ipdt/x ObjectEntity INTEGER(int(k,kind=8))
|
||||
!DEF: /MainProgram1/ipdt/x ObjectEntity INTEGER(int(int(k,kind=4),kind=8))
|
||||
integer(kind=k) :: x
|
||||
end type ipdt
|
||||
!DEF: /MainProgram1/rpdt DerivedType
|
||||
|
@ -14,7 +14,7 @@
|
|||
!REF: /MainProgram1/rpdt/k
|
||||
integer, kind :: k
|
||||
!REF: /MainProgram1/rpdt/k
|
||||
!DEF: /MainProgram1/rpdt/x ObjectEntity REAL(int(k,kind=8))
|
||||
!DEF: /MainProgram1/rpdt/x ObjectEntity REAL(int(int(k,kind=4),kind=8))
|
||||
real(kind=k) :: x
|
||||
end type rpdt
|
||||
!DEF: /MainProgram1/zpdt DerivedType
|
||||
|
@ -23,7 +23,7 @@
|
|||
!REF: /MainProgram1/zpdt/k
|
||||
integer, kind :: k
|
||||
!REF: /MainProgram1/zpdt/k
|
||||
!DEF: /MainProgram1/zpdt/x ObjectEntity COMPLEX(int(k,kind=8))
|
||||
!DEF: /MainProgram1/zpdt/x ObjectEntity COMPLEX(int(int(k,kind=4),kind=8))
|
||||
complex(kind=k) :: x
|
||||
end type zpdt
|
||||
!DEF: /MainProgram1/lpdt DerivedType
|
||||
|
@ -32,7 +32,7 @@
|
|||
!REF: /MainProgram1/lpdt/k
|
||||
integer, kind :: k
|
||||
!REF: /MainProgram1/lpdt/k
|
||||
!DEF: /MainProgram1/lpdt/x ObjectEntity LOGICAL(int(k,kind=8))
|
||||
!DEF: /MainProgram1/lpdt/x ObjectEntity LOGICAL(int(int(k,kind=4),kind=8))
|
||||
logical(kind=k) :: x
|
||||
end type lpdt
|
||||
!REF: /MainProgram1/ipdt
|
||||
|
|
|
@ -91,21 +91,21 @@ end module
|
|||
!integer(2),kind::k2
|
||||
!integer(4),kind::k4
|
||||
!integer(8),kind::k8
|
||||
!integer(int(k1,kind=8))::j1
|
||||
!integer(int(k2,kind=8))::j2
|
||||
!integer(int(k4,kind=8))::j4
|
||||
!integer(int(int(k1,kind=1),kind=8))::j1
|
||||
!integer(int(int(k2,kind=2),kind=8))::j2
|
||||
!integer(int(int(k4,kind=4),kind=8))::j4
|
||||
!integer(k8)::j8
|
||||
!end type
|
||||
!type::defaulted(n1,n2,n4,n8)
|
||||
!integer(1),kind::n1=1_1
|
||||
!integer(2),kind::n2=int(int(n1,kind=4)*2_4,kind=2)
|
||||
!integer(4),kind::n4=2_4*int(n2,kind=4)
|
||||
!integer(8),kind::n8=int(12_4-n4,kind=8)
|
||||
!type(capture(k1=n1,k2=n2,k4=n4,k8=n8))::cap
|
||||
!integer(2),kind::n2=int(int(int(n1,kind=1),kind=4)*2_4,kind=2)
|
||||
!integer(4),kind::n4=2_4*int(int(n2,kind=2),kind=4)
|
||||
!integer(8),kind::n8=int(12_4-int(n4,kind=4),kind=8)
|
||||
!type(capture(k1=int(n1,kind=1),k2=int(n2,kind=2),k4=int(n4,kind=4),k8=n8))::cap
|
||||
!end type
|
||||
!type,extends(defaulted)::extension(k5)
|
||||
!integer(4),kind::k5=4_4
|
||||
!integer(int(k5,kind=8))::j5
|
||||
!integer(int(int(k5,kind=4),kind=8))::j5
|
||||
!end type
|
||||
!type(capture(k1=1_1,k2=1_2,k4=1_4,k8=1_8))::x1111
|
||||
!integer(1)::res01_1
|
||||
|
|
|
@ -15,8 +15,8 @@ end module m
|
|||
!module m
|
||||
!type::t(k)
|
||||
!integer(4),kind::k=1_4
|
||||
!character(1_4,int(k,kind=8))::a
|
||||
!character(3_4,int(k,kind=8))::b
|
||||
!character(1_4,int(int(k,kind=4),kind=8))::a
|
||||
!character(3_4,int(int(k,kind=4),kind=8))::b
|
||||
!end type
|
||||
!type(t(k=1_4)),parameter::p=t(k=1_4)(a="x",b="xx ")
|
||||
!character(2_4,1),parameter::c2(1_8:3_8)=[CHARACTER(KIND=1,LEN=2)::"x ","xx","xx"]
|
||||
|
|
|
@ -608,7 +608,7 @@ end
|
|||
!module m7
|
||||
! type :: t(k)
|
||||
! integer(4), kind :: k
|
||||
! real(int(k, kind=8)) :: a
|
||||
! real(int(int(k,kind=4),kind=8))::a
|
||||
! end type
|
||||
! interface operator(+)
|
||||
! procedure :: f1
|
||||
|
|
|
@ -80,7 +80,7 @@ type(fwdpdt(kind(0))) function f2(n)
|
|||
!REF: /f2/fwdpdt/k
|
||||
integer, kind :: k
|
||||
!REF: /f2/fwdpdt/k
|
||||
!DEF: /f2/fwdpdt/n ObjectEntity INTEGER(int(k,kind=8))
|
||||
!DEF: /f2/fwdpdt/n ObjectEntity INTEGER(int(int(k,kind=4),kind=8))
|
||||
integer(kind=k) :: n
|
||||
end type
|
||||
!DEF: /f2/f2 ObjectEntity TYPE(fwdpdt(k=4_4))
|
||||
|
@ -100,7 +100,7 @@ subroutine s2 (q1)
|
|||
!REF: /s2/fwdpdt/k
|
||||
integer, kind :: k
|
||||
!REF: /s2/fwdpdt/k
|
||||
!DEF: /s2/fwdpdt/n ObjectEntity INTEGER(int(k,kind=8))
|
||||
!DEF: /s2/fwdpdt/n ObjectEntity INTEGER(int(int(k,kind=4),kind=8))
|
||||
integer(kind=k) :: n
|
||||
end type
|
||||
!REF: /s2/q1
|
||||
|
|
Loading…
Reference in New Issue