[flang-commits] [flang] 4cbfd93 - [flang] Make `TypeParamInquiry` monomorphic

peter klausler via flang-commits flang-commits at lists.llvm.org
Mon Aug 31 15:41:01 PDT 2020


Author: peter klausler
Date: 2020-08-31T15:40:40-07:00
New Revision: 4cbfd93a591a2e861bb69dfe896a7cff41931c05

URL: https://github.com/llvm/llvm-project/commit/4cbfd93a591a2e861bb69dfe896a7cff41931c05
DIFF: https://github.com/llvm/llvm-project/commit/4cbfd93a591a2e861bb69dfe896a7cff41931c05.diff

LOG: [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

Added: 
    

Modified: 
    flang/include/flang/Evaluate/expression.h
    flang/include/flang/Evaluate/shape.h
    flang/include/flang/Evaluate/traverse.h
    flang/include/flang/Evaluate/variable.h
    flang/lib/Evaluate/check-expression.cpp
    flang/lib/Evaluate/fold-implementation.h
    flang/lib/Evaluate/fold-integer.cpp
    flang/lib/Evaluate/formatting.cpp
    flang/lib/Evaluate/variable.cpp
    flang/lib/Lower/ConvertType.cpp
    flang/lib/Semantics/expression.cpp
    flang/test/Semantics/kinds03.f90
    flang/test/Semantics/modfile17.f90
    flang/test/Semantics/modfile22.f90
    flang/test/Semantics/modfile33.f90
    flang/test/Semantics/symbol17.f90

Removed: 
    


################################################################################
diff  --git a/flang/include/flang/Evaluate/expression.h b/flang/include/flang/Evaluate/expression.h
index fffd4645cc9f..09847ec95407 100644
--- a/flang/include/flang/Evaluate/expression.h
+++ b/flang/include/flang/Evaluate/expression.h
@@ -516,15 +516,18 @@ class Expr<Type<TypeCategory::Integer, KIND>>
       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;
 };
 

diff  --git a/flang/include/flang/Evaluate/shape.h b/flang/include/flang/Evaluate/shape.h
index d8a1a6f8daff..08fb70efb564 100644
--- a/flang/include/flang/Evaluate/shape.h
+++ b/flang/include/flang/Evaluate/shape.h
@@ -93,9 +93,7 @@ class GetShapeHelper
 
   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();

diff  --git a/flang/include/flang/Evaluate/traverse.h b/flang/include/flang/Evaluate/traverse.h
index a81f511d9dfa..9238e58a1fb3 100644
--- a/flang/include/flang/Evaluate/traverse.h
+++ b/flang/include/flang/Evaluate/traverse.h
@@ -120,7 +120,7 @@ template <typename Visitor, typename Result> class Traverse {
       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 {

diff  --git a/flang/include/flang/Evaluate/variable.h b/flang/include/flang/Evaluate/variable.h
index fd4f92b7f0ed..6265bed61f53 100644
--- a/flang/include/flang/Evaluate/variable.h
+++ b/flang/include/flang/Evaluate/variable.h
@@ -128,9 +128,9 @@ class NamedEntity {
 // 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 &param)
       : base_{std::move(x)}, parameter_{param} {}
@@ -150,9 +150,6 @@ template <int KIND> class TypeParamInquiry {
   SymbolRef parameter_;
 };
 
-EXPAND_FOR_EACH_INTEGER_KIND(
-    TEMPLATE_INSTANTIATION, extern template class TypeParamInquiry, )
-
 // R921 subscript-triplet
 class Triplet {
 public:
@@ -422,8 +419,6 @@ class DescriptorInquiry {
 };
 
 #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_

diff  --git a/flang/lib/Evaluate/check-expression.cpp b/flang/lib/Evaluate/check-expression.cpp
index a7cc094033d0..09c14179d256 100644
--- a/flang/lib/Evaluate/check-expression.cpp
+++ b/flang/lib/Evaluate/check-expression.cpp
@@ -29,7 +29,7 @@ class IsConstantExprHelper : public AllTraverse<IsConstantExprHelper, true> {
   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 @@ class IsInitialDataTargetHelper
     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 @@ class CheckSpecificationExprHelper
     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 "

diff  --git a/flang/lib/Evaluate/fold-implementation.h b/flang/lib/Evaluate/fold-implementation.h
index ebe826fcbc12..e01c7de72f8d 100644
--- a/flang/lib/Evaluate/fold-implementation.h
+++ b/flang/lib/Evaluate/fold-implementation.h
@@ -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>

diff  --git a/flang/lib/Evaluate/fold-integer.cpp b/flang/lib/Evaluate/fold-integer.cpp
index 9b96a479df59..c48148900bbd 100644
--- a/flang/lib/Evaluate/fold-integer.cpp
+++ b/flang/lib/Evaluate/fold-integer.cpp
@@ -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) {

diff  --git a/flang/lib/Evaluate/formatting.cpp b/flang/lib/Evaluate/formatting.cpp
index c2cbe4521d45..bed7fc4efee7 100644
--- a/flang/lib/Evaluate/formatting.cpp
+++ b/flang/lib/Evaluate/formatting.cpp
@@ -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) << '%';
   }

diff  --git a/flang/lib/Evaluate/variable.cpp b/flang/lib/Evaluate/variable.cpp
index cfde6ffb6fd1..d87c71688f1a 100644
--- a/flang/lib/Evaluate/variable.cpp
+++ b/flang/lib/Evaluate/variable.cpp
@@ -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 {

diff  --git a/flang/lib/Lower/ConvertType.cpp b/flang/lib/Lower/ConvertType.cpp
index 276df03d6288..c01c6bc64595 100644
--- a/flang/lib/Lower/ConvertType.cpp
+++ b/flang/lib/Lower/ConvertType.cpp
@@ -262,13 +262,13 @@ class TypeBuilder {
   //===--------------------------------------------------------------------===//
 
   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>

diff  --git a/flang/lib/Semantics/expression.cpp b/flang/lib/Semantics/expression.cpp
index 21f6bdfe94b8..ec4dae2d3279 100644
--- a/flang/lib/Semantics/expression.cpp
+++ b/flang/lib/Semantics/expression.cpp
@@ -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 &param)
-      : kind{k}, base{std::move(b)}, parameter{param} {}
-  TypeParamInquiryVisitor(int k, const Symbol &param)
-      : 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);

diff  --git a/flang/test/Semantics/kinds03.f90 b/flang/test/Semantics/kinds03.f90
index 424a79903693..00e6c1fd9c56 100644
--- a/flang/test/Semantics/kinds03.f90
+++ b/flang/test/Semantics/kinds03.f90
@@ -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

diff  --git a/flang/test/Semantics/modfile17.f90 b/flang/test/Semantics/modfile17.f90
index 921d2f2b6008..414043c02d3a 100644
--- a/flang/test/Semantics/modfile17.f90
+++ b/flang/test/Semantics/modfile17.f90
@@ -91,21 +91,21 @@ module m
 !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

diff  --git a/flang/test/Semantics/modfile22.f90 b/flang/test/Semantics/modfile22.f90
index f03621523e06..bef096bcec15 100644
--- a/flang/test/Semantics/modfile22.f90
+++ b/flang/test/Semantics/modfile22.f90
@@ -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"]

diff  --git a/flang/test/Semantics/modfile33.f90 b/flang/test/Semantics/modfile33.f90
index 861c2132bc57..93845fabf307 100644
--- a/flang/test/Semantics/modfile33.f90
+++ b/flang/test/Semantics/modfile33.f90
@@ -608,7 +608,7 @@ subroutine s2(x, y, z)
 !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

diff  --git a/flang/test/Semantics/symbol17.f90 b/flang/test/Semantics/symbol17.f90
index 1994cf9977da..f453e2e6772b 100644
--- a/flang/test/Semantics/symbol17.f90
+++ b/flang/test/Semantics/symbol17.f90
@@ -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


        


More information about the flang-commits mailing list