https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117474
Bug ID: 117474
Summary: Excessive memory usage during parser stage in
interface blocks with types having type-bound
procedures
Product: gcc
Version: 14.2.1
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: fortran
Assignee: unassigned at gcc dot gnu.org
Reporter: rimvydas.jas at gmail dot com
Target Milestone: ---
After addition of init() methods it was noticed that certain scientific model
sources started to require lots of memory to compile.
Derived type by itself is relatively small.
type phys_base_state_type
real, pointer :: p1 (:,:,:) => null ()
! <snip>
contains
procedure :: init => phys_base_state_type_init
end type
However with addition of type-bound procedures (that take really big type
arguments) blows up both produced module size and memory requirements during
parsing of interface blocks that make use of this type.
$ cat phys_base_state_type_mod.mod | wc -c
2951559
$ zcat phys_base_state_type_mod.mod | wc -c
92422176
Simplified stripped case with 60 interface blocks and no executable code (any
bigger module will do):
$ cat test.f90
subroutine foo
interface; subroutine foo_part01
use phys_base_state_type_mod, only : phys_base_state_type
end subroutine; end interface
! <snip>
interface; subroutine foo_part60
use phys_base_state_type_mod, only : phys_base_state_type
end subroutine; end interface
end subroutine foo
$ /usr/bin/time -v gfortran -I. -c test.f90 -ftime-report 2>&1 | grep -E
"(Maximum|wall|global)"
Time variable usr sys wall
GGC
parser (global) : 144.04 ( 99%) 17.05 (100%) 161.21 ( 99%)
87M (100%)
Elapsed (wall clock) time (h:mm:ss or m:ss): 2:44.02
Maximum resident set size (kbytes): 41411832
Parsing only a single interface block requires just:
Maximum resident set size (kbytes): 824424
Memory requirements grow linearly with every additional interface block present
in the source code.
It is hard to come up with reasonably small reproducer, since types passed to
INIT() methods have huge nesting of other types with their own type-bound
procedures.
It seems that the phys_base_state_type sym tree is created and populated for
every interface block separately without caching, thus increasing memory
requirements during the parsing stage.
Moreover it should be possible to skip populating type-bound procedure tree
nodes inside the interface blocks, other that they exist.