diff --git a/flang/include/flang/Semantics/type.h b/flang/include/flang/Semantics/type.h --- a/flang/include/flang/Semantics/type.h +++ b/flang/include/flang/Semantics/type.h @@ -306,6 +306,7 @@ // 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; } diff --git a/flang/lib/Semantics/type.cpp b/flang/lib/Semantics/type.cpp --- a/flang/lib/Semantics/type.cpp +++ b/flang/lib/Semantics/type.cpp @@ -567,6 +567,60 @@ 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(vecElemCategory) < + Fortran::common::VectorElementCategory_enumSize) && + "Vector element type is not specified"); + assert(vecElemKind && "Vector element kind is not specified"); + + ss << "vector("; + switch (static_cast(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 @@ .get() .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-types.f90 b/flang/test/Semantics/ppc-vector-types01.f90 rename from flang/test/Semantics/ppc-vector-types.f90 rename to flang/test/Semantics/ppc-vector-types01.f90 diff --git a/flang/test/Semantics/ppc-vector-types02.f90 b/flang/test/Semantics/ppc-vector-types02.f90 new file mode 100644 --- /dev/null +++ b/flang/test/Semantics/ppc-vector-types02.f90 @@ -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