[flang-commits] [flang] [flang][runtime] Build ISO_FORTRAN_ENV to export kind arrays as linkable symbols (PR #95388)

Michael Klemm via flang-commits flang-commits at lists.llvm.org
Thu Jul 18 07:00:28 PDT 2024


https://github.com/mjklemm updated https://github.com/llvm/llvm-project/pull/95388

>From 48b29b489a56ef010866005395b20390ed286a21 Mon Sep 17 00:00:00 2001
From: Michael Klemm <michael.klemm at amd.com>
Date: Thu, 13 Jun 2024 12:42:58 +0200
Subject: [PATCH 01/10] Fixes #89403

Moves definitions of the kind arrays into a Fortran MODULE to not only
emit the MOD file, but also compile that MODULE file into an object
file.  This file is then linked into libFortranRuntime.so.

Eventually this workaround PR shoud be redone and a proper runtime build
should be setup that will then also compile Fortran MODULE files.
---
 flang/CMakeLists.txt                     |   1 +
 flang/module/__fortran_builtin_kinds.f90 | 110 +++++++++++++++++++++
 flang/module/iso_fortran_env.f90         | 118 ++++++-----------------
 flang/runtime/CMakeLists.txt             |   1 +
 flang/tools/f18/CMakeLists.txt           |  42 +++++++-
 flang/tools/flang-driver/CMakeLists.txt  |   2 -
 6 files changed, 182 insertions(+), 92 deletions(-)
 create mode 100644 flang/module/__fortran_builtin_kinds.f90

diff --git a/flang/CMakeLists.txt b/flang/CMakeLists.txt
index cbe8f1186236a..070c39eb6e9ab 100644
--- a/flang/CMakeLists.txt
+++ b/flang/CMakeLists.txt
@@ -538,3 +538,4 @@ get_clang_resource_dir(HEADER_INSTALL_DIR SUBDIR include)
 install(
   FILES include/flang/ISO_Fortran_binding.h
   DESTINATION ${HEADER_INSTALL_DIR} )
+
diff --git a/flang/module/__fortran_builtin_kinds.f90 b/flang/module/__fortran_builtin_kinds.f90
new file mode 100644
index 0000000000000..189055dc26c0c
--- /dev/null
+++ b/flang/module/__fortran_builtin_kinds.f90
@@ -0,0 +1,110 @@
+!===-- module/__fortran_bultin_kinds.f90 --=--------------------------------===!
+!
+! Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+! See https://llvm.org/LICENSE.txt for license information.
+! SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+!
+!===------------------------------------------------------------------------===!
+
+module __fortran_builtin_kinds
+  implicit none
+  private
+
+  ! INTEGER types
+  integer, parameter, public :: &
+    selectedInt8 = selected_int_kind(2), &
+    selectedInt16 = selected_int_kind(4), &
+    selectedInt32 = selected_int_kind(9), &
+    selectedInt64 = selected_int_kind(18),&
+    selectedInt128 = selected_int_kind(38), &
+    safeInt8 = merge(selectedInt8, selected_int_kind(0), &
+                     selectedInt8 >= 0), &
+    safeInt16 = merge(selectedInt16, selected_int_kind(0), &
+                      selectedInt16 >= 0), &
+    safeInt32 = merge(selectedInt32, selected_int_kind(0), &
+                      selectedInt32 >= 0), &
+    safeInt64 = merge(selectedInt64, selected_int_kind(0), &
+                      selectedInt64 >= 0), &
+    safeInt128 = merge(selectedInt128, selected_int_kind(0), &
+                       selectedInt128 >= 0)
+
+  integer, parameter, public :: &
+    int8 = merge(selectedInt8, merge(-2, -1, selectedInt8 >= 0), &
+                 digits(int(0,kind=safeInt8)) == 7), &
+    int16 = merge(selectedInt16, merge(-2, -1, selectedInt16 >= 0), &
+                  digits(int(0,kind=safeInt16)) == 15), &
+    int32 = merge(selectedInt32, merge(-2, -1, selectedInt32 >= 0), &
+                  digits(int(0,kind=safeInt32)) == 31), &
+    int64 = merge(selectedInt64, merge(-2, -1, selectedInt64 >= 0), &
+                  digits(int(0,kind=safeInt64)) == 63), &
+    int128 = merge(selectedInt128, merge(-2, -1, selectedInt128 >= 0), &
+                   digits(int(0,kind=safeInt128)) == 127)
+
+  integer, parameter, dimension(*), public :: __builtin_integer_kinds = [ &
+      selected_int_kind(0), &
+      [(pack([selected_int_kind(k)], &
+             selected_int_kind(k) >= 0 .and. &
+               selected_int_kind(k) /= selected_int_kind(k-1)), &
+        integer :: k=1, 39)]]
+
+  ! LOGICAL TYPES
+  integer, parameter, public :: &
+    logical8 = int8, logical16 = int16, logical32 = int32, logical64 = int64
+
+  integer, parameter, dimension(*), public :: __builtin_logical_kinds = [ &
+      pack([logical8],  logical8 >= 0), &
+      pack([logical16], logical16 >= 0), &
+      pack([logical32], logical32 >= 0), &
+      pack([logical64], logical64 >= 0) &
+    ]
+
+  ! REAL types
+  integer, parameter, public :: &
+    selectedReal16 = selected_real_kind(3, 4), &      ! IEEE half
+    selectedBfloat16 = selected_real_kind(2, 37), &   ! truncated IEEE single
+    selectedReal32 = selected_real_kind(6, 37), &     ! IEEE single
+    selectedReal64 = selected_real_kind(15, 307), &   ! IEEE double
+    selectedReal80 = selected_real_kind(18, 4931), &  ! 80x87 extended
+    selectedReal64x2 = selected_real_kind(31, 307), & ! "double-double"
+    selectedReal128 = selected_real_kind(33, 4931), & ! IEEE quad
+    safeReal16 = merge(selectedReal16, selected_real_kind(0,0), &
+                       selectedReal16 >= 0), &
+    safeBfloat16 = merge(selectedBfloat16, selected_real_kind(0,0), &
+                         selectedBfloat16 >= 0), &
+    safeReal32 = merge(selectedReal32, selected_real_kind(0,0), &
+                       selectedReal32 >= 0), &
+    safeReal64 = merge(selectedReal64, selected_real_kind(0,0), &
+                       selectedReal64 >= 0), &
+    safeReal80 = merge(selectedReal80, selected_real_kind(0,0), &
+                       selectedReal80 >= 0), &
+    safeReal64x2 = merge(selectedReal64x2, selected_real_kind(0,0), &
+                         selectedReal64x2 >= 0), &
+    safeReal128 = merge(selectedReal128, selected_real_kind(0,0), &
+                        selectedReal128 >= 0)
+
+  integer, parameter, public :: &
+    real16 = merge(selectedReal16, merge(-2, -1, selectedReal16 >= 0), &
+                   digits(real(0,kind=safeReal16)) == 11), &
+    bfloat16 = merge(selectedBfloat16, merge(-2, -1, selectedBfloat16 >= 0), &
+                     digits(real(0,kind=safeBfloat16)) == 8), &
+    real32 = merge(selectedReal32, merge(-2, -1, selectedReal32 >= 0), &
+                   digits(real(0,kind=safeReal32)) == 24), &
+    real64 = merge(selectedReal64, merge(-2, -1, selectedReal64 >= 0), &
+                   digits(real(0,kind=safeReal64)) == 53), &
+    real80 = merge(selectedReal80, merge(-2, -1, selectedReal80 >= 0), &
+                   digits(real(0,kind=safeReal80)) == 64), &
+    real64x2 = merge(selectedReal64x2, merge(-2, -1, selectedReal64x2 >= 0), &
+                     digits(real(0,kind=safeReal64x2)) == 106), &
+    real128 = merge(selectedReal128, merge(-2, -1, selectedReal128 >= 0), &
+                    digits(real(0,kind=safeReal128)) == 113)
+
+  integer, parameter, dimension(*), public :: __builtin_real_kinds = [ &
+      pack([real16], real16 >= 0), &
+      pack([bfloat16], bfloat16 >= 0), &
+      pack([real32], real32 >= 0), &
+      pack([real64], real64 >= 0), &
+      pack([real80], real80 >= 0), &
+      pack([real64x2], real64x2 >= 0), &
+      pack([real128], real128 >= 0) &
+    ]
+end module __fortran_builtin_kinds
\ No newline at end of file
diff --git a/flang/module/iso_fortran_env.f90 b/flang/module/iso_fortran_env.f90
index 6ca98e518aeac..f751ba03f7bac 100644
--- a/flang/module/iso_fortran_env.f90
+++ b/flang/module/iso_fortran_env.f90
@@ -22,6 +22,23 @@ module iso_fortran_env
     compiler_options => __builtin_compiler_options, &
     compiler_version => __builtin_compiler_version
 
+  use __fortran_builtin_kinds, only: &
+    selectedInt8, selectedInt16, selectedInt32, selectedInt64, selectedInt128, &
+    safeInt8, safeInt16, safeInt32, safeInt64, safeInt128, &
+    int8, int16, int32, int64, int128, &
+    logical8, logical16, logical32, logical64, &
+    selectedReal16, selectedBfloat16, selectedReal32, &
+    selectedReal64, selectedReal80, selectedReal64x2, &
+    selectedReal128, &
+    safeReal16, safeBfloat16, safeReal32, &
+    safeReal64, safeReal80, safeReal64x2, &
+    safeReal128, &
+    real16, bfloat16, real32, real64, &
+    real80, real64x2, real128, &
+    integer_kinds => __builtin_integer_kinds, &
+    real_kinds => __builtin_real_kinds, &
+    logical_kinds => __builtin_logical_kinds
+
   implicit none
   private
 
@@ -38,95 +55,22 @@ module iso_fortran_env
     pack([selectedUCS_2], selectedUCS_2 >= 0), &
     pack([selectedUnicode], selectedUnicode >= 0)]
 
-  integer, parameter :: &
-    selectedInt8 = selected_int_kind(2), &
-    selectedInt16 = selected_int_kind(4), &
-    selectedInt32 = selected_int_kind(9), &
-    selectedInt64 = selected_int_kind(18),&
-    selectedInt128 = selected_int_kind(38), &
-    safeInt8 = merge(selectedInt8, selected_int_kind(0), &
-                     selectedInt8 >= 0), &
-    safeInt16 = merge(selectedInt16, selected_int_kind(0), &
-                      selectedInt16 >= 0), &
-    safeInt32 = merge(selectedInt32, selected_int_kind(0), &
-                      selectedInt32 >= 0), &
-    safeInt64 = merge(selectedInt64, selected_int_kind(0), &
-                      selectedInt64 >= 0), &
-    safeInt128 = merge(selectedInt128, selected_int_kind(0), &
-                       selectedInt128 >= 0)
-  integer, parameter, public :: &
-    int8 = merge(selectedInt8, merge(-2, -1, selectedInt8 >= 0), &
-                 digits(int(0,kind=safeInt8)) == 7), &
-    int16 = merge(selectedInt16, merge(-2, -1, selectedInt16 >= 0), &
-                  digits(int(0,kind=safeInt16)) == 15), &
-    int32 = merge(selectedInt32, merge(-2, -1, selectedInt32 >= 0), &
-                  digits(int(0,kind=safeInt32)) == 31), &
-    int64 = merge(selectedInt64, merge(-2, -1, selectedInt64 >= 0), &
-                  digits(int(0,kind=safeInt64)) == 63), &
-    int128 = merge(selectedInt128, merge(-2, -1, selectedInt128 >= 0), &
-                   digits(int(0,kind=safeInt128)) == 127)
-
-  integer, parameter, public :: integer_kinds(*) = [ &
-    selected_int_kind(0), &
-    [(pack([selected_int_kind(k)], &
-           selected_int_kind(k) >= 0 .and. &
-             selected_int_kind(k) /= selected_int_kind(k-1)), &
-      integer :: k=1, 39)]]
+  public :: selectedInt8, selectedInt16, selectedInt32, selectedInt64, selectedInt128, &
+    safeInt8, safeInt16, safeInt32, safeInt64, safeInt128, &
+    int8, int16, int32, int64, int128
 
-  integer, parameter, public :: &
-    logical8 = int8, logical16 = int16, logical32 = int32, logical64 = int64
-  integer, parameter, public :: logical_kinds(*) = [ &
-    pack([logical8],  logical8 >= 0), &
-    pack([logical16], logical16 >= 0), &
-    pack([logical32], logical32 >= 0), &
-    pack([logical64], logical64 >= 0)]
+  public :: logical8, logical16, logical32, logical64
 
-  integer, parameter :: &
-    selectedReal16 = selected_real_kind(3, 4), &      ! IEEE half
-    selectedBfloat16 = selected_real_kind(2, 37), &   ! truncated IEEE single
-    selectedReal32 = selected_real_kind(6, 37), &     ! IEEE single
-    selectedReal64 = selected_real_kind(15, 307), &   ! IEEE double
-    selectedReal80 = selected_real_kind(18, 4931), &  ! 80x87 extended
-    selectedReal64x2 = selected_real_kind(31, 307), & ! "double-double"
-    selectedReal128 = selected_real_kind(33, 4931), & ! IEEE quad
-    safeReal16 = merge(selectedReal16, selected_real_kind(0,0), &
-                       selectedReal16 >= 0), &
-    safeBfloat16 = merge(selectedBfloat16, selected_real_kind(0,0), &
-                         selectedBfloat16 >= 0), &
-    safeReal32 = merge(selectedReal32, selected_real_kind(0,0), &
-                       selectedReal32 >= 0), &
-    safeReal64 = merge(selectedReal64, selected_real_kind(0,0), &
-                       selectedReal64 >= 0), &
-    safeReal80 = merge(selectedReal80, selected_real_kind(0,0), &
-                       selectedReal80 >= 0), &
-    safeReal64x2 = merge(selectedReal64x2, selected_real_kind(0,0), &
-                         selectedReal64x2 >= 0), &
-    safeReal128 = merge(selectedReal128, selected_real_kind(0,0), &
-                        selectedReal128 >= 0)
-  integer, parameter, public :: &
-    real16 = merge(selectedReal16, merge(-2, -1, selectedReal16 >= 0), &
-                   digits(real(0,kind=safeReal16)) == 11), &
-    bfloat16 = merge(selectedBfloat16, merge(-2, -1, selectedBfloat16 >= 0), &
-                     digits(real(0,kind=safeBfloat16)) == 8), &
-    real32 = merge(selectedReal32, merge(-2, -1, selectedReal32 >= 0), &
-                   digits(real(0,kind=safeReal32)) == 24), &
-    real64 = merge(selectedReal64, merge(-2, -1, selectedReal64 >= 0), &
-                   digits(real(0,kind=safeReal64)) == 53), &
-    real80 = merge(selectedReal80, merge(-2, -1, selectedReal80 >= 0), &
-                   digits(real(0,kind=safeReal80)) == 64), &
-    real64x2 = merge(selectedReal64x2, merge(-2, -1, selectedReal64x2 >= 0), &
-                     digits(real(0,kind=safeReal64x2)) == 106), &
-    real128 = merge(selectedReal128, merge(-2, -1, selectedReal128 >= 0), &
-                    digits(real(0,kind=safeReal128)) == 113)
-
-  integer, parameter, public :: real_kinds(*) = [ &
-    pack([real16], real16 >= 0), &
-    pack([bfloat16], bfloat16 >= 0), &
-    pack([real32], real32 >= 0), &
-    pack([real64], real64 >= 0), &
-    pack([real80], real80 >= 0), &
-    pack([real64x2], real64x2 >= 0), &
-    pack([real128], real128 >= 0)]
+  public :: selectedReal16, selectedBfloat16, selectedReal32, &
+    selectedReal64, selectedReal80, selectedReal64x2, &
+    selectedReal128, &
+    safeReal16, safeBfloat16, safeReal32, &
+    safeReal64, safeReal80, safeReal64x2, &
+    safeReal128, &
+    real16, bfloat16, real32, real64, &
+    real80, real64x2, real128
+
+  public :: integer_kinds, real_kinds, logical_kinds
 
   integer, parameter, public :: current_team = -1, &
     initial_team = -2, &
diff --git a/flang/runtime/CMakeLists.txt b/flang/runtime/CMakeLists.txt
index a826980e19411..c3bec4043e760 100644
--- a/flang/runtime/CMakeLists.txt
+++ b/flang/runtime/CMakeLists.txt
@@ -260,6 +260,7 @@ if (NOT DEFINED MSVC)
 
     INSTALL_WITH_TOOLCHAIN
   )
+  target_link_libraries(FortranRuntime PRIVATE ${FORTRAN_MODULE_OBJECTS})
 else()
   add_flang_library(FortranRuntime
     ${sources}
diff --git a/flang/tools/f18/CMakeLists.txt b/flang/tools/f18/CMakeLists.txt
index 4771199651602..5f4c49e42c36e 100644
--- a/flang/tools/f18/CMakeLists.txt
+++ b/flang/tools/f18/CMakeLists.txt
@@ -4,7 +4,16 @@ set(LLVM_LINK_COMPONENTS
   Support
   )
 
-set(MODULES
+# Define the list of Fortran module files that need to be compiled
+# to produce an object file for inclusion into the FortranRuntime
+# library.
+set(MODULES_WITH_IMPLEMENTATION
+  "__fortran_builtin_kinds"
+)
+
+# Define the list of Fortran module files for which it is
+# sufficient to generate the module file via -fsyntax-only.
+set(MODULES_WITHOUT_IMPLEMENTATION
   "__fortran_builtins"
   "__fortran_ieee_exceptions"
   "__fortran_type_info"
@@ -20,6 +29,12 @@ set(MODULES
   "iso_fortran_env"
 )
 
+set(MODULES ${MODULES_WITH_IMPLEMENTATION} ${MODULES_WITHOUT_IMPLEMENTATION})
+
+# Init variable to hold extra object files coming from the Fortran modules;
+# these module files will be contributed from the CMakeLists in flang/tools/f18.
+unset(FORTRAN_MODULE_OBJECTS CACHE)
+
 # Create module files directly from the top-level module source directory.
 # If CMAKE_CROSSCOMPILING, then the newly built flang-new executable was
 # cross compiled, and thus can't be executed on the build system and thus
@@ -41,6 +56,9 @@ if (NOT CMAKE_CROSSCOMPILING)
       if(NOT ${filename} STREQUAL "__fortran_type_info")
         set(depends ${depends} ${FLANG_INTRINSIC_MODULES_DIR}/__fortran_type_info.mod)
       endif()
+      if(${filename} STREQUAL "iso_fortran_env")
+        set(depends ${depends} ${FLANG_INTRINSIC_MODULES_DIR}/__fortran_builtin_kinds.mod)
+      endif()
       if(${filename} STREQUAL "ieee_arithmetic" OR
          ${filename} STREQUAL "ieee_exceptions")
         set(depends ${depends} ${FLANG_INTRINSIC_MODULES_DIR}/__fortran_ieee_exceptions.mod)
@@ -58,16 +76,34 @@ if (NOT CMAKE_CROSSCOMPILING)
       endif()
     endif()
 
+
+    # Some modules have an implementation part that needs to be added to the
+    # FortranRuntime library.
+    set(compile_with "-fsyntax-only")
+    set(object_output "")
+    set(include_in_link FALSE)
+    if(${filename} IN_LIST MODULES_WITH_IMPLEMENTATION)
+      set(compile_with "-c")
+      set(object_output "${CMAKE_CURRENT_BINARY_DIR}/${filename}${CMAKE_CXX_OUTPUT_EXTENSION}")
+      set(include_in_link TRUE)
+    endif()
+
     set(base ${FLANG_INTRINSIC_MODULES_DIR}/${filename})
     # TODO: We may need to flag this with conditional, in case Flang is built w/o OpenMP support
-    add_custom_command(OUTPUT ${base}.mod
+    add_custom_command(OUTPUT ${base}.mod ${object_output}
       COMMAND ${CMAKE_COMMAND} -E make_directory ${FLANG_INTRINSIC_MODULES_DIR}
-      COMMAND flang-new ${opts} -cpp -fsyntax-only -module-dir ${FLANG_INTRINSIC_MODULES_DIR}
+      COMMAND flang-new ${opts} -cpp ${compile_with} -module-dir ${FLANG_INTRINSIC_MODULES_DIR}
         ${FLANG_SOURCE_DIR}/module/${filename}.f90
       DEPENDS flang-new ${FLANG_SOURCE_DIR}/module/${filename}.f90 ${FLANG_SOURCE_DIR}/module/__fortran_builtins.f90 ${depends}
     )
     list(APPEND MODULE_FILES ${base}.mod)
     install(FILES ${base}.mod DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/flang")
+
+    # If a module has been compiled into an object file, add the file to
+    # the link line for the FortranRuntime library.
+    if(include_in_link)
+      set(FORTRAN_MODULE_OBJECTS "${FORTRAN_MODULE_OBJECTS}" "${object_output}" CACHE INTERNAL "")
+    endif()
   endforeach()
 
   # Special case for omp_lib.mod, because its source comes from openmp/runtime/src/include.
diff --git a/flang/tools/flang-driver/CMakeLists.txt b/flang/tools/flang-driver/CMakeLists.txt
index ce30ecff028dc..5bf535b18ad78 100644
--- a/flang/tools/flang-driver/CMakeLists.txt
+++ b/flang/tools/flang-driver/CMakeLists.txt
@@ -19,8 +19,6 @@ add_flang_tool(flang-new
   # These libraries are used in the linker invocation generated by the driver
   # (i.e. when constructing the linker job). Without them the driver would be
   # unable to generate executables.
-  FortranRuntime
-  FortranDecimal
 )
 
 target_link_libraries(flang-new

>From 933135e3765c612459d7d5846e04c081c313263b Mon Sep 17 00:00:00 2001
From: Michael Klemm <michael.klemm at amd.com>
Date: Tue, 25 Jun 2024 09:28:31 +0200
Subject: [PATCH 02/10] Remove obsolete comment

---
 flang/tools/flang-driver/CMakeLists.txt | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/flang/tools/flang-driver/CMakeLists.txt b/flang/tools/flang-driver/CMakeLists.txt
index 5bf535b18ad78..9f33cdfe3fa90 100644
--- a/flang/tools/flang-driver/CMakeLists.txt
+++ b/flang/tools/flang-driver/CMakeLists.txt
@@ -14,11 +14,6 @@ set( LLVM_LINK_COMPONENTS
 add_flang_tool(flang-new
   driver.cpp
   fc1_main.cpp
-
-  DEPENDS
-  # These libraries are used in the linker invocation generated by the driver
-  # (i.e. when constructing the linker job). Without them the driver would be
-  # unable to generate executables.
 )
 
 target_link_libraries(flang-new

>From 3a80ca59ece8372007755ff6de8520f63c85d070 Mon Sep 17 00:00:00 2001
From: Michael Klemm <michael.klemm at amd.com>
Date: Fri, 19 Apr 2024 19:36:16 +0200
Subject: [PATCH 03/10] Compile and link ISO_FORTRAN_ENV

---
 flang/module/iso_fortran_env.f90                          | 2 +-
 ...fortran_builtin_kinds.f90 => iso_fortran_env_impl.f90} | 8 ++++++--
 flang/runtime/CMakeLists.txt                              | 1 +
 flang/tools/f18/CMakeLists.txt                            | 6 +++---
 4 files changed, 11 insertions(+), 6 deletions(-)
 rename flang/module/{__fortran_builtin_kinds.f90 => iso_fortran_env_impl.f90} (95%)

diff --git a/flang/module/iso_fortran_env.f90 b/flang/module/iso_fortran_env.f90
index f751ba03f7bac..cc1f58e7feccb 100644
--- a/flang/module/iso_fortran_env.f90
+++ b/flang/module/iso_fortran_env.f90
@@ -22,7 +22,7 @@ module iso_fortran_env
     compiler_options => __builtin_compiler_options, &
     compiler_version => __builtin_compiler_version
 
-  use __fortran_builtin_kinds, only: &
+  use iso_fortran_env_impl, only: &
     selectedInt8, selectedInt16, selectedInt32, selectedInt64, selectedInt128, &
     safeInt8, safeInt16, safeInt32, safeInt64, safeInt128, &
     int8, int16, int32, int64, int128, &
diff --git a/flang/module/__fortran_builtin_kinds.f90 b/flang/module/iso_fortran_env_impl.f90
similarity index 95%
rename from flang/module/__fortran_builtin_kinds.f90
rename to flang/module/iso_fortran_env_impl.f90
index 189055dc26c0c..a996eb2c53466 100644
--- a/flang/module/__fortran_builtin_kinds.f90
+++ b/flang/module/iso_fortran_env_impl.f90
@@ -6,7 +6,11 @@
 !
 !===------------------------------------------------------------------------===!
 
-module __fortran_builtin_kinds
+! This MODULE implements part of the ISO_FORTRAN_ENV module file, which
+! partially requires linkable symbols for some entities defined
+! (e.g., real_kinds).
+
+module iso_fortran_env_impl
   implicit none
   private
 
@@ -107,4 +111,4 @@
       pack([real64x2], real64x2 >= 0), &
       pack([real128], real128 >= 0) &
     ]
-end module __fortran_builtin_kinds
\ No newline at end of file
+end module iso_fortran_env_impl
\ No newline at end of file
diff --git a/flang/runtime/CMakeLists.txt b/flang/runtime/CMakeLists.txt
index c3bec4043e760..dad4ca2ff0de2 100644
--- a/flang/runtime/CMakeLists.txt
+++ b/flang/runtime/CMakeLists.txt
@@ -169,6 +169,7 @@ set(sources
   unit-map.cpp
   unit.cpp
   utf.cpp
+  ${FORTRAN_MODULE_OBJECTS}
 )
 
 include(AddFlangOffloadRuntime)
diff --git a/flang/tools/f18/CMakeLists.txt b/flang/tools/f18/CMakeLists.txt
index 5f4c49e42c36e..ea42606af30ae 100644
--- a/flang/tools/f18/CMakeLists.txt
+++ b/flang/tools/f18/CMakeLists.txt
@@ -8,7 +8,7 @@ set(LLVM_LINK_COMPONENTS
 # to produce an object file for inclusion into the FortranRuntime
 # library.
 set(MODULES_WITH_IMPLEMENTATION
-  "__fortran_builtin_kinds"
+  "iso_fortran_env_impl"
 )
 
 # Define the list of Fortran module files for which it is
@@ -57,7 +57,7 @@ if (NOT CMAKE_CROSSCOMPILING)
         set(depends ${depends} ${FLANG_INTRINSIC_MODULES_DIR}/__fortran_type_info.mod)
       endif()
       if(${filename} STREQUAL "iso_fortran_env")
-        set(depends ${depends} ${FLANG_INTRINSIC_MODULES_DIR}/__fortran_builtin_kinds.mod)
+        set(depends ${depends} ${FLANG_INTRINSIC_MODULES_DIR}/iso_fortran_env_impl.mod)
       endif()
       if(${filename} STREQUAL "ieee_arithmetic" OR
          ${filename} STREQUAL "ieee_exceptions")
@@ -83,8 +83,8 @@ if (NOT CMAKE_CROSSCOMPILING)
     set(object_output "")
     set(include_in_link FALSE)
     if(${filename} IN_LIST MODULES_WITH_IMPLEMENTATION)
-      set(compile_with "-c")
       set(object_output "${CMAKE_CURRENT_BINARY_DIR}/${filename}${CMAKE_CXX_OUTPUT_EXTENSION}")
+      set(compile_with -c -o ${object_output})
       set(include_in_link TRUE)
     endif()
 

>From 01179b17717abbc251a476fb260c59c4550d7292 Mon Sep 17 00:00:00 2001
From: Michael Klemm <michael.klemm at amd.com>
Date: Mon, 15 Jul 2024 10:03:49 +0200
Subject: [PATCH 04/10] Set the CACHE variable only once

---
 flang/runtime/CMakeLists.txt   | 1 -
 flang/tools/f18/CMakeLists.txt | 9 +++++++--
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/flang/runtime/CMakeLists.txt b/flang/runtime/CMakeLists.txt
index dad4ca2ff0de2..8588af7e16eec 100644
--- a/flang/runtime/CMakeLists.txt
+++ b/flang/runtime/CMakeLists.txt
@@ -261,7 +261,6 @@ if (NOT DEFINED MSVC)
 
     INSTALL_WITH_TOOLCHAIN
   )
-  target_link_libraries(FortranRuntime PRIVATE ${FORTRAN_MODULE_OBJECTS})
 else()
   add_flang_library(FortranRuntime
     ${sources}
diff --git a/flang/tools/f18/CMakeLists.txt b/flang/tools/f18/CMakeLists.txt
index ea42606af30ae..862c954fa0d59 100644
--- a/flang/tools/f18/CMakeLists.txt
+++ b/flang/tools/f18/CMakeLists.txt
@@ -33,7 +33,7 @@ set(MODULES ${MODULES_WITH_IMPLEMENTATION} ${MODULES_WITHOUT_IMPLEMENTATION})
 
 # Init variable to hold extra object files coming from the Fortran modules;
 # these module files will be contributed from the CMakeLists in flang/tools/f18.
-unset(FORTRAN_MODULE_OBJECTS CACHE)
+set(module_objects "")
 
 # Create module files directly from the top-level module source directory.
 # If CMAKE_CROSSCOMPILING, then the newly built flang-new executable was
@@ -102,10 +102,15 @@ if (NOT CMAKE_CROSSCOMPILING)
     # If a module has been compiled into an object file, add the file to
     # the link line for the FortranRuntime library.
     if(include_in_link)
-      set(FORTRAN_MODULE_OBJECTS "${FORTRAN_MODULE_OBJECTS}" "${object_output}" CACHE INTERNAL "")
+      set(module_objects ${module_} ${object_output})
     endif()
   endforeach()
 
+  # Set a CACHE variable that is visible to the CMakeLists.txt in runtime/, so that
+  # the compiled Fortran modules can be added to the link line of the FortranRuntime
+  # library.
+  set(FORTRAN_MODULE_OBJECTS ${module_objects} CACHE INTERNAL "")
+
   # Special case for omp_lib.mod, because its source comes from openmp/runtime/src/include.
   # It also produces two module files: omp_lib.mod and omp_lib_kinds.mod.  Compile these
   # files only if OpenMP support has been configured.

>From 6f02773b8a6b40a9c90b6da5495a6fd95315b5ad Mon Sep 17 00:00:00 2001
From: Michael Klemm <michael.klemm at amd.com>
Date: Tue, 16 Jul 2024 20:01:00 +0200
Subject: [PATCH 05/10] Update iso_fortran_env_impl.f90
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Co-authored-by: Valentin Clement (バレンタイン クレメン) <clementval at gmail.com>
---
 flang/module/iso_fortran_env_impl.f90 | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/flang/module/iso_fortran_env_impl.f90 b/flang/module/iso_fortran_env_impl.f90
index a996eb2c53466..84249c17315e1 100644
--- a/flang/module/iso_fortran_env_impl.f90
+++ b/flang/module/iso_fortran_env_impl.f90
@@ -1,4 +1,4 @@
-!===-- module/__fortran_bultin_kinds.f90 --=--------------------------------===!
+!===-- module/iso_fortran_env_impl.f90 --=--------------------------------===!
 !
 ! Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 ! See https://llvm.org/LICENSE.txt for license information.

>From 95beb287874c02d15ac288102650b3c783cd1fbb Mon Sep 17 00:00:00 2001
From: Michael Klemm <michael.klemm at amd.com>
Date: Wed, 17 Jul 2024 14:39:41 +0200
Subject: [PATCH 06/10] Update flang/tools/f18/CMakeLists.txt

Co-authored-by: Michael Kruse <github at meinersbur.de>
---
 flang/tools/f18/CMakeLists.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/flang/tools/f18/CMakeLists.txt b/flang/tools/f18/CMakeLists.txt
index 862c954fa0d59..094660766acf1 100644
--- a/flang/tools/f18/CMakeLists.txt
+++ b/flang/tools/f18/CMakeLists.txt
@@ -109,7 +109,7 @@ if (NOT CMAKE_CROSSCOMPILING)
   # Set a CACHE variable that is visible to the CMakeLists.txt in runtime/, so that
   # the compiled Fortran modules can be added to the link line of the FortranRuntime
   # library.
-  set(FORTRAN_MODULE_OBJECTS ${module_objects} CACHE INTERNAL "")
+  set(FORTRAN_MODULE_OBJECTS ${module_objects} CACHE INTERNAL "" FORCE)
 
   # Special case for omp_lib.mod, because its source comes from openmp/runtime/src/include.
   # It also produces two module files: omp_lib.mod and omp_lib_kinds.mod.  Compile these

>From bcaf8366fc3694bf91121e68b445480d891c9b6f Mon Sep 17 00:00:00 2001
From: Michael Klemm <michael.klemm at amd.com>
Date: Thu, 18 Jul 2024 15:05:32 +0200
Subject: [PATCH 07/10] Update flang/tools/f18/CMakeLists.txt

Co-authored-by: Michael Kruse <github at meinersbur.de>
---
 flang/tools/f18/CMakeLists.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/flang/tools/f18/CMakeLists.txt b/flang/tools/f18/CMakeLists.txt
index 094660766acf1..48486699c2d6a 100644
--- a/flang/tools/f18/CMakeLists.txt
+++ b/flang/tools/f18/CMakeLists.txt
@@ -102,7 +102,7 @@ if (NOT CMAKE_CROSSCOMPILING)
     # If a module has been compiled into an object file, add the file to
     # the link line for the FortranRuntime library.
     if(include_in_link)
-      set(module_objects ${module_} ${object_output})
+      list(APPEND module_objects ${module_})
     endif()
   endforeach()
 

>From 9d30f41294329c203f22df1398215983b99e83fa Mon Sep 17 00:00:00 2001
From: Michael Klemm <michael.klemm at amd.com>
Date: Thu, 18 Jul 2024 15:08:01 +0200
Subject: [PATCH 08/10] Add newline

---
 flang/module/iso_fortran_env_impl.f90 | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/flang/module/iso_fortran_env_impl.f90 b/flang/module/iso_fortran_env_impl.f90
index 84249c17315e1..4de54dda7bab1 100644
--- a/flang/module/iso_fortran_env_impl.f90
+++ b/flang/module/iso_fortran_env_impl.f90
@@ -111,4 +111,4 @@ module iso_fortran_env_impl
       pack([real64x2], real64x2 >= 0), &
       pack([real128], real128 >= 0) &
     ]
-end module iso_fortran_env_impl
\ No newline at end of file
+end module iso_fortran_env_impl

>From 268aca4a81a3092534204ee67372e4f06e494010 Mon Sep 17 00:00:00 2001
From: Michael Klemm <michael.klemm at amd.com>
Date: Thu, 18 Jul 2024 15:22:24 +0200
Subject: [PATCH 09/10] Fix typo that came in from suggestion

---
 flang/tools/f18/CMakeLists.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/flang/tools/f18/CMakeLists.txt b/flang/tools/f18/CMakeLists.txt
index 48486699c2d6a..cec4e2d810720 100644
--- a/flang/tools/f18/CMakeLists.txt
+++ b/flang/tools/f18/CMakeLists.txt
@@ -102,7 +102,7 @@ if (NOT CMAKE_CROSSCOMPILING)
     # If a module has been compiled into an object file, add the file to
     # the link line for the FortranRuntime library.
     if(include_in_link)
-      list(APPEND module_objects ${module_})
+      list(APPEND module_objects ${object_output})
     endif()
   endforeach()
 

>From 04f52d65d4a3691c92a9cb9908535fdd64aa18ba Mon Sep 17 00:00:00 2001
From: Michael Klemm <michael.klemm at amd.com>
Date: Thu, 18 Jul 2024 16:00:12 +0200
Subject: [PATCH 10/10] Add test

The test compiles and links a short program that uses the three kind
arrays.  It is supposed to fail and link time if the symbols are not
provided in the runtime.
---
 flang/test/Runtime/kind_arrays_symbols.f90 | 15 +++++++++++++++
 1 file changed, 15 insertions(+)
 create mode 100644 flang/test/Runtime/kind_arrays_symbols.f90

diff --git a/flang/test/Runtime/kind_arrays_symbols.f90 b/flang/test/Runtime/kind_arrays_symbols.f90
new file mode 100644
index 0000000000000..aab64dc8619aa
--- /dev/null
+++ b/flang/test/Runtime/kind_arrays_symbols.f90
@@ -0,0 +1,15 @@
+!RUN: %flang -o %t %s
+
+program kind_array_symbols
+    use iso_fortran_env, only: integer_kinds, real_kinds, logical_kinds
+    implicit none
+
+    integer :: i
+    i = 1
+
+    ! accesses via a variable array index cause code-gen
+    ! to emit used symbols in the object code
+    print *, integer_kinds(i)
+    print *, real_kinds(i)
+    print *, logical_kinds(i)
+end program kind_array_symbols



More information about the flang-commits mailing list