Hi,
My code involves a derived-type variable (denoted 'Object' hereafter) holding another derived-type variable as a component (denoted 'SubObject').
The SubObject has a type-bound procedure for computing some quantity, let say Q.
The Object also has a procedure for computing Q, but the actual computation is delegated to the SubObject component.
Here is simple example:
Module SubObject_Module implicit none private public :: SubObject_Type Type :: SubObject_Type contains procedure :: Compute => Compute_SubObj End Type contains Pure Subroutine Compute_SubObj( This, Inp, Out ) class(SubObject_Type) ,intent(in) :: This integer ,intent(in) :: Inp integer ,intent(out) :: Out Out = Inp * 2 End Subroutine End Module Module Object_Module use SubObject_Module ,only: SubObject_Type implicit none private public :: Object_Type Type :: Object_Type private type(SubObject_Type) :: Sub contains procedure :: Compute => Compute_Obj End Type contains Pure Subroutine Compute_Obj( This, Inp, Out ) class(Object_Type) ,intent(in) :: This integer ,intent(in) :: Inp integer ,intent(out) :: Out call This%Sub%Compute( Inp, Out ) End Subroutine End Module Program Main use Object_Module ,only: Object_Type implicit none type(Object_Type) :: Object integer :: Inp = 5, Out call Object%Compute( Inp, Out ) End Program
As you can see, in the main program I'm calling the TBP from the Object variable using "call Object%Compute(...)" (line 43).
The only task of this TBP is to call the TBP from the SubObject component, using "call This%Sub%Compute(...)" (line 34)
My real code heavily uses this delegation approach, which leads to lots of TBP being actually only wrappers to components' TBP calls.
Now, I want to avoid the extra cost of calling all those "useless" TBP (Compute_Obj) by forcing inlining of the call to the component's TBP (Compute_SubObj).
How should I do so ?
For now, I'm adding the "!DEC$ ATTRIBUTES FORCEINLINE :: Compute_SubObj" line before the "Compute_SubObj" procedure:
!DEC$ ATTRIBUTES FORCEINLINE :: Compute_SubObj Pure Subroutine Compute_SubObj( This, Inp, Out ) class(SubObject_Type) ,intent(in) :: This integer ,intent(in) :: Inp integer ,intent(out) :: Out Out = Inp * 2 End Subroutine
Is it the correct way to enforce inlining?
I know that inlining can also be changed using the following compiler options:
-inline-factor
-inline-min-size
-inline-max-size
-inline-max-total-size
-inline-max-per-routine
-inline-max-per-compile
but with no guarantee that the inlining is actually going to happen.
Am I right ?
Thank for yous enlightenment.