[flang] Add DerivedTypeSpec::VectorTypeAsFortran for PPC vector type
authorKelvin Li <kli@ca.ibm.com>
Mon, 29 May 2023 20:27:38 +0000 (16:27 -0400)
committerKelvin Li <kli@ca.ibm.com>
Wed, 31 May 2023 20:38:48 +0000 (16:38 -0400)
VectorTypeAsFortran is added for writing PPC vector types to modules.

Coauthor: @tislam

Differential Revision: https://reviews.llvm.org/D151757

flang/include/flang/Semantics/type.h
flang/lib/Semantics/type.cpp
flang/test/Semantics/ppc-vector-types01.f90 [moved from flang/test/Semantics/ppc-vector-types.f90 with 100% similarity]
flang/test/Semantics/ppc-vector-types02.f90 [new file with mode: 0644]

index 7de436a..5228c15 100644 (file)
@@ -306,6 +306,7 @@ public:
   // explicit and equal, len type parameters are ignored.
   bool Match(const DerivedTypeSpec &) const;
   std::string AsFortran() const;
+  std::string VectorTypeAsFortran() const;
 
   Category category() const { return category_; }
   void set_category(Category category) { category_ = category; }
index cf04f24..1be59d7 100644 (file)
@@ -567,6 +567,60 @@ DerivedTypeSpec InstantiateHelper::CreateDerivedTypeSpec(
   return result;
 }
 
+std::string DerivedTypeSpec::VectorTypeAsFortran() const {
+  std::string buf;
+  llvm::raw_string_ostream ss{buf};
+
+  switch (category()) {
+    SWITCH_COVERS_ALL_CASES
+  case (Fortran::semantics::DerivedTypeSpec::Category::IntrinsicVector): {
+    int64_t vecElemKind;
+    int64_t vecElemCategory;
+
+    for (const auto &pair : parameters()) {
+      if (pair.first == "element_category") {
+        vecElemCategory =
+            Fortran::evaluate::ToInt64(pair.second.GetExplicit()).value_or(-1);
+      } else if (pair.first == "element_kind") {
+        vecElemKind =
+            Fortran::evaluate::ToInt64(pair.second.GetExplicit()).value_or(0);
+      }
+    }
+
+    assert((vecElemCategory >= 0 &&
+               static_cast<size_t>(vecElemCategory) <
+                   Fortran::common::VectorElementCategory_enumSize) &&
+        "Vector element type is not specified");
+    assert(vecElemKind && "Vector element kind is not specified");
+
+    ss << "vector(";
+    switch (static_cast<common::VectorElementCategory>(vecElemCategory)) {
+      SWITCH_COVERS_ALL_CASES
+    case common::VectorElementCategory::Integer:
+      ss << "integer(" << vecElemKind << ")";
+      break;
+    case common::VectorElementCategory::Unsigned:
+      ss << "unsigned(" << vecElemKind << ")";
+      break;
+    case common::VectorElementCategory::Real:
+      ss << "real(" << vecElemKind << ")";
+      break;
+    }
+    ss << ")";
+    break;
+  }
+  case (Fortran::semantics::DerivedTypeSpec::Category::PairVector):
+    ss << "__vector_pair";
+    break;
+  case (Fortran::semantics::DerivedTypeSpec::Category::QuadVector):
+    ss << "__vector_quad";
+    break;
+  case (Fortran::semantics::DerivedTypeSpec::Category::DerivedType):
+    Fortran::common::die("Vector element type not implemented");
+  }
+  return ss.str();
+}
+
 std::string DerivedTypeSpec::AsFortran() const {
   std::string buf;
   llvm::raw_string_ostream ss{buf};
@@ -781,6 +835,8 @@ std::string DeclTypeSpec::AsFortran() const {
             .get<DerivedTypeDetails>()
             .isDECStructure()) {
       return "RECORD" + derivedTypeSpec().typeSymbol().name().ToString();
+    } else if (derivedTypeSpec().IsVectorType()) {
+      return derivedTypeSpec().VectorTypeAsFortran();
     } else {
       return "TYPE(" + derivedTypeSpec().AsFortran() + ')';
     }
diff --git a/flang/test/Semantics/ppc-vector-types02.f90 b/flang/test/Semantics/ppc-vector-types02.f90
new file mode 100644 (file)
index 0000000..8c96684
--- /dev/null
@@ -0,0 +1,60 @@
+! RUN: %flang_fc1 -fdebug-dump-symbols %s | FileCheck %s
+! REQUIRES: target=powerpc{{.*}}
+
+! C: MainProgram scope: ppc_vec_types
+! CHECK-LABEL: MainProgram scope: ppc_vec_types size={{[0-9]*}} alignment={{[0-9]*}}
+program ppc_vec_types
+  implicit none
+  vector(integer(4)) :: vi
+  vector(real(8)) :: vr
+  vector(unsigned(2)) :: vu
+  __vector_pair :: vp
+  __vector_quad :: vq
+! CHECK-DAG: vi size=16 offset={{[0-9]*}}: ObjectEntity type: vector(integer(4))
+! CHECK-DAG: vr size=16 offset={{[0-9]*}}: ObjectEntity type: vector(real(8))
+! CHECK-DAG: vu size=16 offset={{[0-9]*}}: ObjectEntity type: vector(unsigned(2))
+! CHECK-DAG: vp size=32 offset={{[0-9]*}}: ObjectEntity type: __vector_pair
+! CHECK-DAG: vq size=64 offset={{[0-9]*}}: ObjectEntity type: __vector_quad
+
+contains
+! CHECK-LABEL: Subprogram scope: test_vec_integer_func size={{[0-9]*}} alignment={{[0-9]*}}
+  function test_vec_integer_func(arg1)
+    vector(integer(4)) :: arg1
+    vector(integer(4)) :: test_vec_integer_func
+! CHECK-DAG: arg1 size=16 offset={{[0-9]*}}: ObjectEntity dummy type: vector(integer(4))
+! CHECK-DAG: test_vec_integer_func size=16 offset={{[0-9]*}}: ObjectEntity funcResult type: vector(integer(4))
+  end function test_vec_integer_func
+
+! CHECK-LABEL: Subprogram scope: test_vec_real_func size={{[0-9]*}} alignment={{[0-9]*}}
+  function test_vec_real_func(arg1)
+    vector(real(8)) :: arg1
+    vector(real(8)) :: test_vec_real_func
+! CHECK-DAG: arg1 size=16 offset={{[0-9]*}}: ObjectEntity dummy type: vector(real(8))
+! CHECK-DAG: test_vec_real_func size=16 offset={{[0-9]*}}: ObjectEntity funcResult type: vector(real(8))
+  end function test_vec_real_func
+
+! CHECK-LABEL: Subprogram scope: test_vec_unsigned_func
+  function test_vec_unsigned_func(arg1)
+    vector(unsigned(2)) :: arg1
+    vector(unsigned(2)) :: test_vec_unsigned_func
+! CHECK-DAG: arg1 size=16 offset={{[0-9]*}}: ObjectEntity dummy type: vector(unsigned(2))
+! CHECK-DAG: test_vec_unsigned_func size=16 offset={{[0-9]*}}: ObjectEntity funcResult type: vector(unsigned(2))
+  end function test_vec_unsigned_func
+
+! CHECK-LABEL: Subprogram scope: test_vec_pair_func
+  function test_vec_pair_func(arg1)
+    __vector_pair :: arg1
+    __vector_pair :: test_vec_pair_func
+! CHECK-DAG: arg1 size=32 offset={{[0-9]*}}: ObjectEntity dummy type: __vector_pair
+! CHECK-DAG: test_vec_pair_func size=32 offset={{[0-9]*}}: ObjectEntity funcResult type: __vector_pair
+  end function test_vec_pair_func
+
+! CHECK-LABEL: Subprogram scope: test_vec_quad_func
+  function test_vec_quad_func(arg1)
+    __vector_quad :: arg1
+    __vector_quad :: test_vec_quad_func
+! CHECK-DAG: arg1 size=64 offset={{[0-9]*}}: ObjectEntity dummy type: __vector_quad
+! CHECK-DAG: test_vec_quad_func size=64 offset={{[0-9]*}}: ObjectEntity funcResult type: __vector_quad
+  end function test_vec_quad_func
+
+end program ppc_vec_types