Quantcast
Channel: Intel® Fortran Compiler for Linux* and macOS*
Viewing all articles
Browse latest Browse all 2583

How to enforce inlining ?

$
0
0

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.


Viewing all articles
Browse latest Browse all 2583

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>