Skip to content

Commit 2f8b64d

Browse files
mjklemmclementvalMeinersbur
authored
[flang][runtime] Build ISO_FORTRAN_ENV to export kind arrays as linkable symbols (llvm#95388)
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. Fixes llvm#89403 --------- Co-authored-by: Valentin Clement (バレンタイン クレメン) <[email protected]> Co-authored-by: Michael Kruse <[email protected]>
1 parent 22eb290 commit 2f8b64d

File tree

6 files changed

+191
-97
lines changed

6 files changed

+191
-97
lines changed

flang/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -538,3 +538,4 @@ get_clang_resource_dir(HEADER_INSTALL_DIR SUBDIR include)
538538
install(
539539
FILES include/flang/ISO_Fortran_binding.h
540540
DESTINATION ${HEADER_INSTALL_DIR} )
541+

flang/module/iso_fortran_env.f90

Lines changed: 31 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,23 @@ module iso_fortran_env
2222
compiler_options => __builtin_compiler_options, &
2323
compiler_version => __builtin_compiler_version
2424

25+
use iso_fortran_env_impl, only: &
26+
selectedInt8, selectedInt16, selectedInt32, selectedInt64, selectedInt128, &
27+
safeInt8, safeInt16, safeInt32, safeInt64, safeInt128, &
28+
int8, int16, int32, int64, int128, &
29+
logical8, logical16, logical32, logical64, &
30+
selectedReal16, selectedBfloat16, selectedReal32, &
31+
selectedReal64, selectedReal80, selectedReal64x2, &
32+
selectedReal128, &
33+
safeReal16, safeBfloat16, safeReal32, &
34+
safeReal64, safeReal80, safeReal64x2, &
35+
safeReal128, &
36+
real16, bfloat16, real32, real64, &
37+
real80, real64x2, real128, &
38+
integer_kinds => __builtin_integer_kinds, &
39+
real_kinds => __builtin_real_kinds, &
40+
logical_kinds => __builtin_logical_kinds
41+
2542
implicit none
2643
private
2744

@@ -38,95 +55,22 @@ module iso_fortran_env
3855
pack([selectedUCS_2], selectedUCS_2 >= 0), &
3956
pack([selectedUnicode], selectedUnicode >= 0)]
4057

41-
integer, parameter :: &
42-
selectedInt8 = selected_int_kind(2), &
43-
selectedInt16 = selected_int_kind(4), &
44-
selectedInt32 = selected_int_kind(9), &
45-
selectedInt64 = selected_int_kind(18),&
46-
selectedInt128 = selected_int_kind(38), &
47-
safeInt8 = merge(selectedInt8, selected_int_kind(0), &
48-
selectedInt8 >= 0), &
49-
safeInt16 = merge(selectedInt16, selected_int_kind(0), &
50-
selectedInt16 >= 0), &
51-
safeInt32 = merge(selectedInt32, selected_int_kind(0), &
52-
selectedInt32 >= 0), &
53-
safeInt64 = merge(selectedInt64, selected_int_kind(0), &
54-
selectedInt64 >= 0), &
55-
safeInt128 = merge(selectedInt128, selected_int_kind(0), &
56-
selectedInt128 >= 0)
57-
integer, parameter, public :: &
58-
int8 = merge(selectedInt8, merge(-2, -1, selectedInt8 >= 0), &
59-
digits(int(0,kind=safeInt8)) == 7), &
60-
int16 = merge(selectedInt16, merge(-2, -1, selectedInt16 >= 0), &
61-
digits(int(0,kind=safeInt16)) == 15), &
62-
int32 = merge(selectedInt32, merge(-2, -1, selectedInt32 >= 0), &
63-
digits(int(0,kind=safeInt32)) == 31), &
64-
int64 = merge(selectedInt64, merge(-2, -1, selectedInt64 >= 0), &
65-
digits(int(0,kind=safeInt64)) == 63), &
66-
int128 = merge(selectedInt128, merge(-2, -1, selectedInt128 >= 0), &
67-
digits(int(0,kind=safeInt128)) == 127)
68-
69-
integer, parameter, public :: integer_kinds(*) = [ &
70-
selected_int_kind(0), &
71-
[(pack([selected_int_kind(k)], &
72-
selected_int_kind(k) >= 0 .and. &
73-
selected_int_kind(k) /= selected_int_kind(k-1)), &
74-
integer :: k=1, 39)]]
58+
public :: selectedInt8, selectedInt16, selectedInt32, selectedInt64, selectedInt128, &
59+
safeInt8, safeInt16, safeInt32, safeInt64, safeInt128, &
60+
int8, int16, int32, int64, int128
7561

76-
integer, parameter, public :: &
77-
logical8 = int8, logical16 = int16, logical32 = int32, logical64 = int64
78-
integer, parameter, public :: logical_kinds(*) = [ &
79-
pack([logical8], logical8 >= 0), &
80-
pack([logical16], logical16 >= 0), &
81-
pack([logical32], logical32 >= 0), &
82-
pack([logical64], logical64 >= 0)]
62+
public :: logical8, logical16, logical32, logical64
8363

84-
integer, parameter :: &
85-
selectedReal16 = selected_real_kind(3, 4), & ! IEEE half
86-
selectedBfloat16 = selected_real_kind(2, 37), & ! truncated IEEE single
87-
selectedReal32 = selected_real_kind(6, 37), & ! IEEE single
88-
selectedReal64 = selected_real_kind(15, 307), & ! IEEE double
89-
selectedReal80 = selected_real_kind(18, 4931), & ! 80x87 extended
90-
selectedReal64x2 = selected_real_kind(31, 307), & ! "double-double"
91-
selectedReal128 = selected_real_kind(33, 4931), & ! IEEE quad
92-
safeReal16 = merge(selectedReal16, selected_real_kind(0,0), &
93-
selectedReal16 >= 0), &
94-
safeBfloat16 = merge(selectedBfloat16, selected_real_kind(0,0), &
95-
selectedBfloat16 >= 0), &
96-
safeReal32 = merge(selectedReal32, selected_real_kind(0,0), &
97-
selectedReal32 >= 0), &
98-
safeReal64 = merge(selectedReal64, selected_real_kind(0,0), &
99-
selectedReal64 >= 0), &
100-
safeReal80 = merge(selectedReal80, selected_real_kind(0,0), &
101-
selectedReal80 >= 0), &
102-
safeReal64x2 = merge(selectedReal64x2, selected_real_kind(0,0), &
103-
selectedReal64x2 >= 0), &
104-
safeReal128 = merge(selectedReal128, selected_real_kind(0,0), &
105-
selectedReal128 >= 0)
106-
integer, parameter, public :: &
107-
real16 = merge(selectedReal16, merge(-2, -1, selectedReal16 >= 0), &
108-
digits(real(0,kind=safeReal16)) == 11), &
109-
bfloat16 = merge(selectedBfloat16, merge(-2, -1, selectedBfloat16 >= 0), &
110-
digits(real(0,kind=safeBfloat16)) == 8), &
111-
real32 = merge(selectedReal32, merge(-2, -1, selectedReal32 >= 0), &
112-
digits(real(0,kind=safeReal32)) == 24), &
113-
real64 = merge(selectedReal64, merge(-2, -1, selectedReal64 >= 0), &
114-
digits(real(0,kind=safeReal64)) == 53), &
115-
real80 = merge(selectedReal80, merge(-2, -1, selectedReal80 >= 0), &
116-
digits(real(0,kind=safeReal80)) == 64), &
117-
real64x2 = merge(selectedReal64x2, merge(-2, -1, selectedReal64x2 >= 0), &
118-
digits(real(0,kind=safeReal64x2)) == 106), &
119-
real128 = merge(selectedReal128, merge(-2, -1, selectedReal128 >= 0), &
120-
digits(real(0,kind=safeReal128)) == 113)
121-
122-
integer, parameter, public :: real_kinds(*) = [ &
123-
pack([real16], real16 >= 0), &
124-
pack([bfloat16], bfloat16 >= 0), &
125-
pack([real32], real32 >= 0), &
126-
pack([real64], real64 >= 0), &
127-
pack([real80], real80 >= 0), &
128-
pack([real64x2], real64x2 >= 0), &
129-
pack([real128], real128 >= 0)]
64+
public :: selectedReal16, selectedBfloat16, selectedReal32, &
65+
selectedReal64, selectedReal80, selectedReal64x2, &
66+
selectedReal128, &
67+
safeReal16, safeBfloat16, safeReal32, &
68+
safeReal64, safeReal80, safeReal64x2, &
69+
safeReal128, &
70+
real16, bfloat16, real32, real64, &
71+
real80, real64x2, real128
72+
73+
public :: integer_kinds, real_kinds, logical_kinds
13074

13175
integer, parameter, public :: current_team = -1, &
13276
initial_team = -2, &

flang/module/iso_fortran_env_impl.f90

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
!===-- module/iso_fortran_env_impl.f90 --=--------------------------------===!
2+
!
3+
! Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
! See https://llvm.org/LICENSE.txt for license information.
5+
! SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
!
7+
!===------------------------------------------------------------------------===!
8+
9+
! This MODULE implements part of the ISO_FORTRAN_ENV module file, which
10+
! partially requires linkable symbols for some entities defined
11+
! (e.g., real_kinds).
12+
13+
module iso_fortran_env_impl
14+
implicit none
15+
private
16+
17+
! INTEGER types
18+
integer, parameter, public :: &
19+
selectedInt8 = selected_int_kind(2), &
20+
selectedInt16 = selected_int_kind(4), &
21+
selectedInt32 = selected_int_kind(9), &
22+
selectedInt64 = selected_int_kind(18),&
23+
selectedInt128 = selected_int_kind(38), &
24+
safeInt8 = merge(selectedInt8, selected_int_kind(0), &
25+
selectedInt8 >= 0), &
26+
safeInt16 = merge(selectedInt16, selected_int_kind(0), &
27+
selectedInt16 >= 0), &
28+
safeInt32 = merge(selectedInt32, selected_int_kind(0), &
29+
selectedInt32 >= 0), &
30+
safeInt64 = merge(selectedInt64, selected_int_kind(0), &
31+
selectedInt64 >= 0), &
32+
safeInt128 = merge(selectedInt128, selected_int_kind(0), &
33+
selectedInt128 >= 0)
34+
35+
integer, parameter, public :: &
36+
int8 = merge(selectedInt8, merge(-2, -1, selectedInt8 >= 0), &
37+
digits(int(0,kind=safeInt8)) == 7), &
38+
int16 = merge(selectedInt16, merge(-2, -1, selectedInt16 >= 0), &
39+
digits(int(0,kind=safeInt16)) == 15), &
40+
int32 = merge(selectedInt32, merge(-2, -1, selectedInt32 >= 0), &
41+
digits(int(0,kind=safeInt32)) == 31), &
42+
int64 = merge(selectedInt64, merge(-2, -1, selectedInt64 >= 0), &
43+
digits(int(0,kind=safeInt64)) == 63), &
44+
int128 = merge(selectedInt128, merge(-2, -1, selectedInt128 >= 0), &
45+
digits(int(0,kind=safeInt128)) == 127)
46+
47+
integer, parameter, dimension(*), public :: __builtin_integer_kinds = [ &
48+
selected_int_kind(0), &
49+
[(pack([selected_int_kind(k)], &
50+
selected_int_kind(k) >= 0 .and. &
51+
selected_int_kind(k) /= selected_int_kind(k-1)), &
52+
integer :: k=1, 39)]]
53+
54+
! LOGICAL TYPES
55+
integer, parameter, public :: &
56+
logical8 = int8, logical16 = int16, logical32 = int32, logical64 = int64
57+
58+
integer, parameter, dimension(*), public :: __builtin_logical_kinds = [ &
59+
pack([logical8], logical8 >= 0), &
60+
pack([logical16], logical16 >= 0), &
61+
pack([logical32], logical32 >= 0), &
62+
pack([logical64], logical64 >= 0) &
63+
]
64+
65+
! REAL types
66+
integer, parameter, public :: &
67+
selectedReal16 = selected_real_kind(3, 4), & ! IEEE half
68+
selectedBfloat16 = selected_real_kind(2, 37), & ! truncated IEEE single
69+
selectedReal32 = selected_real_kind(6, 37), & ! IEEE single
70+
selectedReal64 = selected_real_kind(15, 307), & ! IEEE double
71+
selectedReal80 = selected_real_kind(18, 4931), & ! 80x87 extended
72+
selectedReal64x2 = selected_real_kind(31, 307), & ! "double-double"
73+
selectedReal128 = selected_real_kind(33, 4931), & ! IEEE quad
74+
safeReal16 = merge(selectedReal16, selected_real_kind(0,0), &
75+
selectedReal16 >= 0), &
76+
safeBfloat16 = merge(selectedBfloat16, selected_real_kind(0,0), &
77+
selectedBfloat16 >= 0), &
78+
safeReal32 = merge(selectedReal32, selected_real_kind(0,0), &
79+
selectedReal32 >= 0), &
80+
safeReal64 = merge(selectedReal64, selected_real_kind(0,0), &
81+
selectedReal64 >= 0), &
82+
safeReal80 = merge(selectedReal80, selected_real_kind(0,0), &
83+
selectedReal80 >= 0), &
84+
safeReal64x2 = merge(selectedReal64x2, selected_real_kind(0,0), &
85+
selectedReal64x2 >= 0), &
86+
safeReal128 = merge(selectedReal128, selected_real_kind(0,0), &
87+
selectedReal128 >= 0)
88+
89+
integer, parameter, public :: &
90+
real16 = merge(selectedReal16, merge(-2, -1, selectedReal16 >= 0), &
91+
digits(real(0,kind=safeReal16)) == 11), &
92+
bfloat16 = merge(selectedBfloat16, merge(-2, -1, selectedBfloat16 >= 0), &
93+
digits(real(0,kind=safeBfloat16)) == 8), &
94+
real32 = merge(selectedReal32, merge(-2, -1, selectedReal32 >= 0), &
95+
digits(real(0,kind=safeReal32)) == 24), &
96+
real64 = merge(selectedReal64, merge(-2, -1, selectedReal64 >= 0), &
97+
digits(real(0,kind=safeReal64)) == 53), &
98+
real80 = merge(selectedReal80, merge(-2, -1, selectedReal80 >= 0), &
99+
digits(real(0,kind=safeReal80)) == 64), &
100+
real64x2 = merge(selectedReal64x2, merge(-2, -1, selectedReal64x2 >= 0), &
101+
digits(real(0,kind=safeReal64x2)) == 106), &
102+
real128 = merge(selectedReal128, merge(-2, -1, selectedReal128 >= 0), &
103+
digits(real(0,kind=safeReal128)) == 113)
104+
105+
integer, parameter, dimension(*), public :: __builtin_real_kinds = [ &
106+
pack([real16], real16 >= 0), &
107+
pack([bfloat16], bfloat16 >= 0), &
108+
pack([real32], real32 >= 0), &
109+
pack([real64], real64 >= 0), &
110+
pack([real80], real80 >= 0), &
111+
pack([real64x2], real64x2 >= 0), &
112+
pack([real128], real128 >= 0) &
113+
]
114+
end module iso_fortran_env_impl

flang/runtime/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ set(sources
169169
unit-map.cpp
170170
unit.cpp
171171
utf.cpp
172+
${FORTRAN_MODULE_OBJECTS}
172173
)
173174

174175
include(AddFlangOffloadRuntime)

flang/tools/f18/CMakeLists.txt

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,16 @@ set(LLVM_LINK_COMPONENTS
44
Support
55
)
66

7-
set(MODULES
7+
# Define the list of Fortran module files that need to be compiled
8+
# to produce an object file for inclusion into the FortranRuntime
9+
# library.
10+
set(MODULES_WITH_IMPLEMENTATION
11+
"iso_fortran_env_impl"
12+
)
13+
14+
# Define the list of Fortran module files for which it is
15+
# sufficient to generate the module file via -fsyntax-only.
16+
set(MODULES_WITHOUT_IMPLEMENTATION
817
"__fortran_builtins"
918
"__fortran_ieee_exceptions"
1019
"__fortran_type_info"
@@ -20,6 +29,12 @@ set(MODULES
2029
"iso_fortran_env"
2130
)
2231

32+
set(MODULES ${MODULES_WITH_IMPLEMENTATION} ${MODULES_WITHOUT_IMPLEMENTATION})
33+
34+
# Init variable to hold extra object files coming from the Fortran modules;
35+
# these module files will be contributed from the CMakeLists in flang/tools/f18.
36+
set(module_objects "")
37+
2338
# Create module files directly from the top-level module source directory.
2439
# If CMAKE_CROSSCOMPILING, then the newly built flang-new executable was
2540
# cross compiled, and thus can't be executed on the build system and thus
@@ -41,6 +56,9 @@ if (NOT CMAKE_CROSSCOMPILING)
4156
if(NOT ${filename} STREQUAL "__fortran_type_info")
4257
set(depends ${depends} ${FLANG_INTRINSIC_MODULES_DIR}/__fortran_type_info.mod)
4358
endif()
59+
if(${filename} STREQUAL "iso_fortran_env")
60+
set(depends ${depends} ${FLANG_INTRINSIC_MODULES_DIR}/iso_fortran_env_impl.mod)
61+
endif()
4462
if(${filename} STREQUAL "ieee_arithmetic" OR
4563
${filename} STREQUAL "ieee_exceptions")
4664
set(depends ${depends} ${FLANG_INTRINSIC_MODULES_DIR}/__fortran_ieee_exceptions.mod)
@@ -58,18 +76,41 @@ if (NOT CMAKE_CROSSCOMPILING)
5876
endif()
5977
endif()
6078

79+
80+
# Some modules have an implementation part that needs to be added to the
81+
# FortranRuntime library.
82+
set(compile_with "-fsyntax-only")
83+
set(object_output "")
84+
set(include_in_link FALSE)
85+
if(${filename} IN_LIST MODULES_WITH_IMPLEMENTATION)
86+
set(object_output "${CMAKE_CURRENT_BINARY_DIR}/${filename}${CMAKE_CXX_OUTPUT_EXTENSION}")
87+
set(compile_with -c -o ${object_output})
88+
set(include_in_link TRUE)
89+
endif()
90+
6191
set(base ${FLANG_INTRINSIC_MODULES_DIR}/${filename})
6292
# TODO: We may need to flag this with conditional, in case Flang is built w/o OpenMP support
63-
add_custom_command(OUTPUT ${base}.mod
93+
add_custom_command(OUTPUT ${base}.mod ${object_output}
6494
COMMAND ${CMAKE_COMMAND} -E make_directory ${FLANG_INTRINSIC_MODULES_DIR}
65-
COMMAND flang-new ${opts} -cpp -fsyntax-only -module-dir ${FLANG_INTRINSIC_MODULES_DIR}
95+
COMMAND flang-new ${opts} -cpp ${compile_with} -module-dir ${FLANG_INTRINSIC_MODULES_DIR}
6696
${FLANG_SOURCE_DIR}/module/${filename}.f90
6797
DEPENDS flang-new ${FLANG_SOURCE_DIR}/module/${filename}.f90 ${FLANG_SOURCE_DIR}/module/__fortran_builtins.f90 ${depends}
6898
)
6999
list(APPEND MODULE_FILES ${base}.mod)
70100
install(FILES ${base}.mod DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/flang")
101+
102+
# If a module has been compiled into an object file, add the file to
103+
# the link line for the FortranRuntime library.
104+
if(include_in_link)
105+
list(APPEND module_objects ${object_output})
106+
endif()
71107
endforeach()
72108

109+
# Set a CACHE variable that is visible to the CMakeLists.txt in runtime/, so that
110+
# the compiled Fortran modules can be added to the link line of the FortranRuntime
111+
# library.
112+
set(FORTRAN_MODULE_OBJECTS ${module_objects} CACHE INTERNAL "" FORCE)
113+
73114
# Special case for omp_lib.mod, because its source comes from openmp/runtime/src/include.
74115
# It also produces two module files: omp_lib.mod and omp_lib_kinds.mod. Compile these
75116
# files only if OpenMP support has been configured.

flang/tools/flang-driver/CMakeLists.txt

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,6 @@ set( LLVM_LINK_COMPONENTS
1414
add_flang_tool(flang-new
1515
driver.cpp
1616
fc1_main.cpp
17-
18-
DEPENDS
19-
# These libraries are used in the linker invocation generated by the driver
20-
# (i.e. when constructing the linker job). Without them the driver would be
21-
# unable to generate executables.
22-
FortranRuntime
23-
FortranDecimal
2417
)
2518

2619
target_link_libraries(flang-new

0 commit comments

Comments
 (0)