Reland #145901 with a fix for shared library builds. So far flang generates runtime derived type info global definitions (as opposed to declarations) for all the types used in the current compilation unit even when the derived types are defined in other compilation units. It is using linkonce_odr to achieve derived type descriptor address "uniqueness" aspect needed to match two derived type inside the runtime. This comes at a big compile time cost because of all the extra globals and their definitions in apps with many and complex derived types. This patch adds and experimental option to only generate the rtti definition for the types defined in the current compilation unit and to only generate external declaration for the derived type descriptor object of types defined elsewhere. Note that objects compiled with this option are not compatible with object files compiled without because files compiled without it may drop the rtti for type they defined if it is not used in the compilation unit because of the linkonce_odr aspect. I am adding the option so that we can better measure the extra cost of the current approach on apps and allow speeding up some compilation where devirtualization does not matter (and the build config links to all module file object anyway).
48 lines
1.6 KiB
Fortran
48 lines
1.6 KiB
Fortran
! Test -skip-external-rtti-definition option
|
|
|
|
!RUN: rm -rf %t && mkdir -p %t
|
|
!RUN: %flang_fc1 -fsyntax-only -DSTEP=1 -J%t %s
|
|
!RUN: %flang_fc1 -emit-llvm -J%t %s -o - | FileCheck %s -check-prefix=LINKONCE
|
|
!RUN: %flang_fc1 -emit-llvm -J%t -mllvm -skip-external-rtti-definition %s -o - | FileCheck %s -check-prefix=EXTERNAL
|
|
|
|
#if STEP == 1
|
|
module module_external_type_definition
|
|
type t1
|
|
end type
|
|
end module
|
|
#else
|
|
|
|
module module_same_unit_type_definition
|
|
type t2
|
|
end type
|
|
end module
|
|
|
|
subroutine test
|
|
use module_external_type_definition
|
|
use module_same_unit_type_definition
|
|
interface
|
|
subroutine needs_descriptor(x)
|
|
class(*) :: x
|
|
end subroutine
|
|
end interface
|
|
type(t1) :: x1
|
|
type(t2) :: x2
|
|
call needs_descriptor(x1)
|
|
call needs_descriptor(x2)
|
|
end subroutine
|
|
|
|
#endif
|
|
|
|
! LINKONCE-DAG: @_QMmodule_external_type_definitionEXnXt1 = linkonce_odr constant [2 x i8] c"t1", comdat
|
|
! LINKONCE-DAG: @_QMmodule_external_type_definitionEXdtXt1 = linkonce_odr constant {{.*}} {
|
|
! LINKONCE-DAG: @_QMmodule_same_unit_type_definitionEXnXt2 = linkonce_odr constant [2 x i8] c"t2", comdat
|
|
! LINKONCE-DAG: @_QMmodule_same_unit_type_definitionEXdtXt2 = linkonce_odr constant {{.*}} {
|
|
|
|
! EXTERNAL-NOT: @_QMmodule_external_type_definitionEXnXt1
|
|
! EXTERNAL: @_QMmodule_same_unit_type_definitionEXnXt2 = constant [2 x i8] c"t2"
|
|
! EXTERNAL-NOT: @_QMmodule_external_type_definitionEXnXt1
|
|
! EXTERNAL: @_QMmodule_same_unit_type_definitionEXdtXt2 = constant {{.*}} {
|
|
! EXTERNAL-NOT: @_QMmodule_external_type_definitionEXnXt1
|
|
! EXTERNAL: @_QMmodule_external_type_definitionEXdtXt1 = external constant ptr
|
|
! EXTERNAL-NOT: @_QMmodule_external_type_definitionEXnXt1
|