Skip to content

Commit

Permalink
Revert "[flang] Handle array constants of any rank"
Browse files Browse the repository at this point in the history
This reverts commit e26e68a.

This broke gfortran test-suite, test regression/intrinsic_pack_3.f90.
  • Loading branch information
luporl committed May 22, 2023
1 parent 75a0502 commit 4c5b535
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 60 deletions.
26 changes: 10 additions & 16 deletions flang/lib/Lower/ConvertConstant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@
#include "flang/Optimizer/Builder/Complex.h"
#include "flang/Optimizer/Builder/Todo.h"

#include <algorithm>

/// Convert string, \p s, to an APFloat value. Recognize and handle Inf and
/// NaN strings as well. \p s is assumed to not contain any spaces.
static llvm::APFloat consAPFloat(const llvm::fltSemantics &fsem,
Expand Down Expand Up @@ -68,12 +66,17 @@ namespace {
/// Helper class to lower an array constant to a global with an MLIR dense
/// attribute.
///
/// If we have an array of integer, real, or logical, then we can
/// If we have a rank-1 array of integer, real, or logical, then we can
/// create a global array with the dense attribute.
///
/// The mlir tensor type can only handle integer, real, or logical. It
/// does not currently support nested structures which is required for
/// complex.
///
/// Also, we currently handle just rank-1 since tensor type assumes
/// row major array ordering. We will need to reorder the dimensions
/// in the tensor type to support Fortran's column major array ordering.
/// How to create this tensor type is to be determined.
class DenseGlobalBuilder {
public:
static fir::GlobalOp tryCreating(fir::FirOpBuilder &builder,
Expand Down Expand Up @@ -121,6 +124,8 @@ class DenseGlobalBuilder {
&constant) {
static_assert(TC != Fortran::common::TypeCategory::Character,
"must be numerical or logical");
if (constant.Rank() != 1)
return;
auto attrTc = TC == Fortran::common::TypeCategory::Logical
? Fortran::common::TypeCategory::Integer
: TC;
Expand Down Expand Up @@ -153,16 +158,12 @@ class DenseGlobalBuilder {
llvm::StringRef globalName,
mlir::StringAttr linkage,
bool isConst) const {
// Not a "trivial" intrinsic constant array, or empty array.
// Not a rank 1 "trivial" intrinsic constant array, or empty array.
if (!attributeElementType || attributes.empty())
return {};

assert(symTy.isa<fir::SequenceType>() && "expecting an array global");
auto arrTy = symTy.cast<fir::SequenceType>();
llvm::SmallVector<int64_t> tensorShape(arrTy.getShape());
std::reverse(tensorShape.begin(), tensorShape.end());
auto tensorTy =
mlir::RankedTensorType::get(tensorShape, attributeElementType);
mlir::RankedTensorType::get(attributes.size(), attributeElementType);
auto init = mlir::DenseElementsAttr::get(tensorTy, attributes);
return builder.createGlobal(loc, symTy, globalName, linkage, init, isConst);
}
Expand Down Expand Up @@ -543,13 +544,6 @@ genOutlineArrayLit(Fortran::lower::AbstractConverter &converter,
true, constant);
}
if (!global)
// If the number of elements of the array is huge, the compilation may
// use a lot of memory and take a very long time to complete.
// Empirical evidence shows that an array with 150000 elements of
// complex type takes roughly 30 seconds to compile and uses 4GB of RAM,
// on a modern machine.
// It would be nice to add a driver switch to control the array size
// after which flang should not continue to compile.
global = builder.createGlobalConstant(
loc, arrayTy, globalName,
[&](fir::FirOpBuilder &builder) {
Expand Down
11 changes: 8 additions & 3 deletions flang/lib/Lower/ConvertVariable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -431,9 +431,14 @@ static fir::GlobalOp defineGlobal(Fortran::lower::AbstractConverter &converter,

// If this is an array, check to see if we can use a dense attribute
// with a tensor mlir type. This optimization currently only supports
// Fortran arrays of integer, real, or logical. The tensor type does
// not support nested structures which are needed for complex numbers.
if (symTy.isa<fir::SequenceType>() &&
// rank-1 Fortran arrays of integer, real, or logical. The tensor
// type does not support nested structures which are needed for
// complex numbers.
// To get multidimensional arrays to work, we will have to use column major
// array ordering with the tensor type (so it matches column major ordering
// with the Fortran fir.array). By default, tensor types assume row major
// ordering. How to create this tensor type is to be determined.
if (symTy.isa<fir::SequenceType>() && sym.Rank() == 1 &&
!Fortran::semantics::IsAllocatableOrPointer(sym)) {
mlir::Type eleTy = symTy.cast<fir::SequenceType>().getEleTy();
if (eleTy.isa<mlir::IntegerType, mlir::FloatType, fir::LogicalType>()) {
Expand Down
31 changes: 15 additions & 16 deletions flang/test/Lower/array.f90
Original file line number Diff line number Diff line change
Expand Up @@ -102,25 +102,33 @@ subroutine range()
integer, dimension(10) :: a0
real, dimension(2,3) :: a1
integer, dimension(3,4) :: a2
integer, dimension(2,3,4) :: a3

a0 = (/1, 2, 3, 3, 3, 3, 3, 3, 3, 3/)
a1 = reshape((/3.5, 3.5, 3.5, 3.5, 3.5, 3.5/), shape(a1))
a2 = reshape((/1, 3, 3, 5, 3, 3, 3, 3, 9, 9, 9, 8/), shape(a2))
a3 = reshape((/1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12/), shape(a3))
end subroutine range

! a0 array constructor
! CHECK: fir.global internal @_QQro.10xi4.{{.*}}(dense<[1, 2, 3, 3, 3, 3, 3, 3, 3, 3]> : tensor<10xi32>) constant : !fir.array<10xi32>

! a1 array constructor
! CHECK: fir.global internal @_QQro.2x3xr4.{{.*}}(dense<3.500000e+00> : tensor<3x2xf32>) constant : !fir.array<2x3xf32>
! CHECK: fir.global internal @_QQro.2x3xr4.{{.*}} constant : !fir.array<2x3xf32> {
! CHECK-DAG: %cst = arith.constant {{.*}} : f32
! CHECK: %{{.*}} = fir.insert_on_range %{{[0-9]+}}, %cst from (0, 0) to (1, 2) :

! a2 array constructor
! CHECK: fir.global internal @_QQro.3x4xi4.{{.*}}(dense<{{\[\[1, 3, 3], \[5, 3, 3], \[3, 3, 9], \[9, 9, 8]]}}> : tensor<4x3xi32>) constant : !fir.array<3x4xi32>

! a3 array constructor
! CHECK: fir.global internal @_QQro.2x3x4xi4.{{.*}}(dense<{{\[\[\[1, 1], \[2, 2], \[3, 3]], \[\[4, 4], \[5, 5], \[6, 6]], \[\[7, 7], \[8, 8], \[9, 9]], \[\[10, 10], \[11, 11], \[12, 12]]]}}> : tensor<4x3x2xi32>) constant : !fir.array<2x3x4xi32>
! CHECK: fir.global internal @_QQro.3x4xi4.{{.*}} constant : !fir.array<3x4xi32> {
! CHECK-DAG: %[[c1_i32:.*]] = arith.constant 1 : i32
! CHECK-DAG: %[[c3_i32:.*]] = arith.constant 3 : i32
! CHECK-DAG: %[[c5_i32:.*]] = arith.constant 5 : i32
! CHECK-DAG: %[[c8_i32:.*]] = arith.constant 8 : i32
! CHECK-DAG: %[[c9_i32:.*]] = arith.constant 9 : i32
! CHECK: %[[r1:.*]] = fir.insert_value %{{.*}}, %{{.*}}, [0 : index, 0 : index] :
! CHECK: %[[r2:.*]] = fir.insert_on_range %[[r1]], %[[c3_i32]] from (1, 0) to (2, 0) :
! CHECK: %[[r3:.*]] = fir.insert_value %[[r2]], %{{.*}}, [0 : index, 1 : index] :
! CHECK: %[[r4:.*]] = fir.insert_on_range %[[r3]], %[[c3_i32]] from (1, 1) to (1, 2) :
! CHECK: %[[r5:.*]] = fir.insert_on_range %[[r4]], %[[c9_i32]] from (2, 2) to (1, 3) :
! CHECK: %[[r6:.*]] = fir.insert_value %[[r5]], %{{.*}}, [2 : index, 3 : index] :

! CHECK-LABEL rangeGlobal
subroutine rangeGlobal()
Expand All @@ -129,15 +137,6 @@ subroutine rangeGlobal()

end subroutine rangeGlobal

! CHECK-LABEL hugeGlobal
subroutine hugeGlobal()
integer, parameter :: D = 500
integer, dimension(D, D) :: a

! CHECK: fir.global internal @_QQro.500x500xi4.{{.*}}(dense<{{.*}}> : tensor<500x500xi32>) constant : !fir.array<500x500xi32>
a = reshape((/(i, i = 1, D * D)/), shape(a))
end subroutine hugeGlobal

block data
real(selected_real_kind(6)) :: x(5,5)
common /block/ x
Expand Down
25 changes: 0 additions & 25 deletions flang/test/Lower/dense-array-any-rank.f90

This file was deleted.

0 comments on commit 4c5b535

Please sign in to comment.