This is an archive of the discontinued LLVM Phabricator instance.

[flang] Generate PDT runtime type info in the type definition scope
ClosedPublic

Authored by jeanPerier on Mar 2 2022, 1:29 AM.

Details

Summary

This patches modifies PDT runtime type info generation so that it is
easier to handle derived type descriptor in lowering. It changes three
aspects:

  1. The symbol name suffix of runtime type info for PDT instantiation is changed from a serial number unrelated to the types to an encoding of the instantiated KIND parameters.
  2. New runtime type info is not created for each instantiation of PDT without KIND parameters (only length parameters). Instead, the runtime type info of the type definition is always used. It is updated to contain the component descriptions.
  3. Runtime type info of PDT instantiation is now always generated in the scope where the type is defined. If several PDT type instantiation are made in different scope with the same kind parameters, they will use the same runtime type info.

Rational of the change:

In lowering, derived type descriptors are not mapped when instantiating derived
type objects. They are mapped later when symbol knowledge is not available anymore.
This mapping is based on the FIR representation of derived types. For
PDT, the FIR type information does not allow deducing the instantiation
scope, it only allows retrieving the type name, the type _definition_
scope, and the kind parameter values. Therefore, in order to be able to
retrieve the derived type descriptor from a FIR type, the derived type
descriptor must be generated in the definition scope and must reflect
the kind parameters. This justifies the need for changes 1. and 3.
above (suffix and scope change). Changes 2. comes from the fact that
all runtime type info of type without kind parameters can be generated
from the type definition, and that because of the suffix change, the
symbol name for type definition and type instantiation are the same.

Although this change is first motivated by how lowering handles derived
types, I believe it is also an improvement from a functional point of
view since this change will allow reducing the number of generated
runtime type info for PDTs, since redundant information (different
instantiations with same kind parameters) will only be generated once.

Diff Detail

Event Timeline

jeanPerier created this revision.Mar 2 2022, 1:29 AM
Herald added a project: Restricted Project. · View Herald TranscriptMar 2 2022, 1:29 AM
Herald added a subscriber: jdoerfert. · View Herald Transcript
jeanPerier requested review of this revision.Mar 2 2022, 1:29 AM
Herald added a project: Restricted Project. · View Herald TranscriptMar 2 2022, 1:29 AM

Can you really create the derived type description object in the same scope as the definition of the type when the type is USE-associated from a module file and instantiated in another compilation unit? What happens in that case?

Can you really create the derived type description object in the same scope as the definition of the type when the type is USE-associated from a module file and instantiated in another compilation unit? What happens in that case?

Yes, that works, this was already the case with non-PDT types where runtime type info for module was always generated in the compilation unit using the module _inside_ the used module scope, not at the instantiation scope. However, they used to just be ignored in lowering that relied on the related symbols to be translated while processing the module compilation unit. I am moving away from this approach in lowering, and instead taking an approach where runtime type info will always be generated as fully defined weak constant data in compilation unit that needs it. All the duplicate weak symbols are merged at link time.

Here is an example:

module.f90

subroutine bar()
 use m
 type(t(4)) :: a
 a%i = 1
 print *, a%i
end subroutine
module m
 type t(k)
    integer, kind :: k
    integer :: i(k)
 end type
end module

test.f90

 use m                                                                                         
 type(t(4)) :: a                                                                               
 a%i = 2                                                                                       
 print *, a%i                                                                                  
 call bar()                                                                                    
end

Both bar.o and test.o will contain a definition of weak definitions of _QMmE.dt.t.4 that are merged by the linker into a single one in the final executable.

klausler accepted this revision.Mar 2 2022, 9:38 AM
This revision is now accepted and ready to land.Mar 2 2022, 9:38 AM

Hi @jeanPerier 👋🏻 !

This patch causes build failures when using GCC 11: https://lab.llvm.org/buildbot/#/builders/160/builds/6137. I've submitted a quick fix without a review: https://github.com/llvm/llvm-project/commit/06be148843618980588a4d63bf37bbd2103d5b77. I'm happy to address any post-commit comments, thanks!