Skip to content

Commit

Permalink
Fixes #89403
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
mjklemm committed Jun 13, 2024
1 parent 00bb18a commit 5c864ee
Show file tree
Hide file tree
Showing 6 changed files with 182 additions and 92 deletions.
1 change: 1 addition & 0 deletions flang/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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} )

110 changes: 110 additions & 0 deletions flang/module/__fortran_builtin_kinds.f90
Original file line number Diff line number Diff line change
@@ -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
118 changes: 31 additions & 87 deletions flang/module/iso_fortran_env.f90
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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, &
Expand Down
1 change: 1 addition & 0 deletions flang/runtime/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand Down
42 changes: 39 additions & 3 deletions flang/tools/f18/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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
Expand All @@ -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)
Expand All @@ -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.
Expand Down
2 changes: 0 additions & 2 deletions flang/tools/flang-driver/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 5c864ee

Please sign in to comment.