[flang] array constructor folding with test

Original-commit: flang-compiler/f18@37e7a8e666
Reviewed-on: https://github.com/flang-compiler/f18/pull/271
Tree-same-pre-rewrite: false
This commit is contained in:
peter klausler 2019-01-29 10:22:18 -08:00
parent ab71bd343c
commit 2a88fef290
4 changed files with 62 additions and 9 deletions

View File

@ -19,10 +19,19 @@
namespace Fortran::evaluate {
template<typename T>
std::ostream &Constant<T>::AsFortran(std::ostream &o) const {
if (Rank() > 0) {
o << "reshape([" << GetType().AsFortran() << "::";
if (Rank() > 1) {
o << "reshape(";
}
if (Rank() > 0) {
o << '[' << GetType().AsFortran() << "::";
}
bool first{true};
for (const auto &value : values_) {
if (first) {
first = false;
} else {
o << ',';
}
if constexpr (T::category == TypeCategory::Integer) {
o << value.SignedDecimal() << '_' << T::kind;
} else if constexpr (T::category == TypeCategory::Real ||
@ -42,7 +51,10 @@ std::ostream &Constant<T>::AsFortran(std::ostream &o) const {
}
}
if (Rank() > 0) {
o << "],shape=";
o << ']';
}
if (Rank() > 1) {
o << ",shape=";
char ch{'['};
for (auto dim : shape_) {
o << ch << dim;

View File

@ -223,14 +223,14 @@ Expr<ImpliedDoIndex::Result> FoldOperation(
template<typename T> class ArrayConstructorFolder {
public:
explicit ArrayConstructorFolder(const FoldingContext &c) : context_{c} {
context_.impliedDos.clear();
}
explicit ArrayConstructorFolder(const FoldingContext &c) : context_{c} {}
Expr<T> FoldArray(ArrayConstructor<T> &&array) {
if (FoldArray(array.values)) {
std::int64_t n = elements_.size();
return Expr<T>{
Expr<T> result{
Constant<T>{std::move(elements_), std::vector<std::int64_t>{n}}};
return result;
} else {
return Expr<T>{std::move(array)};
}
@ -246,7 +246,10 @@ private:
std::vector<std::int64_t> index(shape.size(), 1);
for (std::size_t n{c->size()}; n-- > 0;) {
elements_.push_back(c->At(index));
for (int d{0}; d < rank && ++index[d] <= shape[d]; ++d) {
for (int d{0}; d < rank; ++d) {
if (++index[d] <= shape[d]) {
break;
}
index[d] = 1;
}
}
@ -302,7 +305,6 @@ Expr<T> FoldOperation(FoldingContext &context, ArrayConstructor<T> &&array) {
Expr<SomeDerived> FoldOperation(
FoldingContext &context, ArrayConstructor<SomeDerived> &&array) {
// TODO pmk: derived type array constructor folding (no Scalar<T> to use)
return Expr<SomeDerived>{std::move(array)};
}

View File

@ -103,6 +103,7 @@ set(MODFILE_TESTS
modfile15.f90
modfile16.f90
modfile17.f90
modfile18.f90
)
set(LABEL_TESTS

View File

@ -0,0 +1,38 @@
! Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
!
! Licensed under the Apache License, Version 2.0 (the "License");
! you may not use this file except in compliance with the License.
! You may obtain a copy of the License at
!
! http://www.apache.org/licenses/LICENSE-2.0
!
! Unless required by applicable law or agreed to in writing, software
! distributed under the License is distributed on an "AS IS" BASIS,
! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
! See the License for the specific language governing permissions and
! limitations under the License.
! Tests folding of array constructors
module m
real, parameter :: a0 = 1.0_8
real, parameter :: a1(2) = [real::2.0, 3.0]
real, parameter :: a2(2) = [4.0, 5.0]
real, parameter :: a3(0) = [real::]
real, parameter :: a4(55) = [real::((1.0*k,k=1,j),j=1,10)]
real, parameter :: a5(:) = [6.0, 7.0, 8.0]
real, parameter :: a6(2) = [9, 10]
real, parameter :: a7(6) = [([(1.0*k,k=1,j)],j=1,3)]
end module m
!Expect: m.mod
!module m
!real(4),parameter::a0=1._8
!real(4),parameter::a1(1_8:2_8)=[Real(4)::2._4,3._4]
!real(4),parameter::a2(1_8:2_8)=[Real(4)::4._4,5._4]
!real(4),parameter::a3(1_8:0_8)=[Real(4)::]
!real(4),parameter::a4(1_8:55_8)=[Real(4)::1._4,1._4,2._4,1._4,2._4,3._4,1._4,2._4,3._4,4._4,1._4,2._4,3._4,4._4,5._4,1._4,2._4,3._4,4._4,5._4,6._4,1._4,2._4,3._4,4._4,5._4,6._4,7._4,1._4,2._4,3._4,4._4,5._4,6._4,7._4,8._4,1._4,2._4,3._4,4._4,5._4,6._4,7._4,8._4,9._4,1._4,2._4,3._4,4._4,5._4,6._4,7._4,8._4,9._4,1.e1_4]
!real(4),parameter::a5(1_8:)=[Real(4)::6._4,7._4,8._4]
!real(4),parameter::a6(1_8:2_8)=[Integer(4)::9_4,10_4]
!real(4),parameter::a7(1_8:6_8)=[Real(4)::1._4,1._4,2._4,1._4,2._4,3._4]
!end