From: peter klausler Date: Tue, 29 Jan 2019 18:22:18 +0000 (-0800) Subject: [flang] array constructor folding with test X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2a88fef29055b8dc076ae76f220dfd08a3eadf82;p=platform%2Fupstream%2Fllvm.git [flang] array constructor folding with test Original-commit: flang-compiler/f18@37e7a8e666eae80d4d5485e8c9c59bfb23d08fa9 Reviewed-on: https://github.com/flang-compiler/f18/pull/271 Tree-same-pre-rewrite: false --- diff --git a/flang/lib/evaluate/constant.cc b/flang/lib/evaluate/constant.cc index 6a8ec01..2cde28b 100644 --- a/flang/lib/evaluate/constant.cc +++ b/flang/lib/evaluate/constant.cc @@ -19,10 +19,19 @@ namespace Fortran::evaluate { template std::ostream &Constant::AsFortran(std::ostream &o) const { + if (Rank() > 1) { + o << "reshape("; + } if (Rank() > 0) { - o << "reshape([" << GetType().AsFortran() << "::"; + 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::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; diff --git a/flang/lib/evaluate/fold.cc b/flang/lib/evaluate/fold.cc index bfc6114..fec3b5f 100644 --- a/flang/lib/evaluate/fold.cc +++ b/flang/lib/evaluate/fold.cc @@ -223,14 +223,14 @@ Expr FoldOperation( template class ArrayConstructorFolder { public: - explicit ArrayConstructorFolder(const FoldingContext &c) : context_{c} { - context_.impliedDos.clear(); - } + explicit ArrayConstructorFolder(const FoldingContext &c) : context_{c} {} + Expr FoldArray(ArrayConstructor &&array) { if (FoldArray(array.values)) { std::int64_t n = elements_.size(); - return Expr{ + Expr result{ Constant{std::move(elements_), std::vector{n}}}; + return result; } else { return Expr{std::move(array)}; } @@ -246,7 +246,10 @@ private: std::vector 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 FoldOperation(FoldingContext &context, ArrayConstructor &&array) { Expr FoldOperation( FoldingContext &context, ArrayConstructor &&array) { - // TODO pmk: derived type array constructor folding (no Scalar to use) return Expr{std::move(array)}; } diff --git a/flang/test/semantics/CMakeLists.txt b/flang/test/semantics/CMakeLists.txt index 9487194..eb3d26f 100644 --- a/flang/test/semantics/CMakeLists.txt +++ b/flang/test/semantics/CMakeLists.txt @@ -103,6 +103,7 @@ set(MODFILE_TESTS modfile15.f90 modfile16.f90 modfile17.f90 + modfile18.f90 ) set(LABEL_TESTS diff --git a/flang/test/semantics/modfile18.f90 b/flang/test/semantics/modfile18.f90 new file mode 100644 index 0000000..c8b654e --- /dev/null +++ b/flang/test/semantics/modfile18.f90 @@ -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