Compiler option to detect unused subroutines?

Compiler option to detect unused subroutines?

Does the current Intel Fortran compiler have an option to detect unused subroutines and/or functions?



17 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

Hello John,

The Intel Fortran Compiler does not have an option to detect unused subroutines or functions. I have filed a feature request for this. The issue number is DPD200182251. I would not expect this to be a high priorety feature request, but I will post any updates I recieve to this thread.

Intel Developer Support

I doubt that the compiler can do what is asked, because it does not know when compiling a source file whether other objects and libraries will be linked to the current object being produced. The linker, on the other hand, can remove unneeded subroutines and functions.

Typically, Linux and Unix linkers (ld) regard each object (*.o file) as an indivisible unit rather than each of the routines within the object.

Linkers can detect object files which aren't called in a static link, but Intel doesn't make the linkers used with Intel compilers. So, it seems that the IPO pre-link pass would be the only opportunity for Intel to implement this. It's not reasonable to expect the linker to detect whether an object file might be used to pre-empt a function called in a shared object library, which you might need to do for an error handler, for example.
Years ago, a widely used method to sort out object files in order of calling (or not) in a static link was with the lorder and tsort tools. The original purpose of lorder was to enable a single pass scan of a library, but we used it to shorten the average distance between linked code segments and to sift out those which were never called.
If you mean checking whether a function is called during execution of given data sets, that's the function of test coverage facilities. Here is documentation of code coverage usage of the profile guided facility of Intel compilers. I can't tell how old that one is.

You may be able to find a CREF tool for relatively new FORTRAN.
There are (were) some variants of CREF that did not care about language.

(CREF = Cross Refference)

Jim Dempsey


maybe I should add a few words to that:

It is possible using the optimization report for IPO.
However, it requires to build & link with IPO turned on (-ipo or /Qipo).

You have to consider the following two points:

  • IPO needs to be used for each compilation unit you like to verify for unused subroutines. This is required so the compiler can do a "global" optimization and detect subroutines as not needed.
  • In-lining might make things complicated: A subroutine might be reported as dead and hence removed (also from the symbol table). However, it might have been in-lined to another subroutine/function or main program before.

How to detect removed subroutines? Answer: Enable IPO and IPO reporting, e.g. for Linux and Fortran

$ ifort -ipo f1.f90 -c
$ ifort -ipo f2.f90 -c
$ ifort f1.o f2.o ... -o f.exe -ipo -opt-report-phase ipo

You'll see unused (dead) subroutines reported, like



  Routine is dead static


  Routine is dead static

However, at the same time you'll see that subroutine "called_" was also in-lined:

INLINING REPORT: (MAIN__) [1/3=33.3%]
  -> INLINE: called_(4) (isz = 577) (sz = 634 (182+452))

In conclusion:
Subroutine "called_" was removed from the symbol table but it has been in-lined (and hence used) in "MAIN__".
Subroutine "dead_" is really unused as there's no in-lining report for it.

This should give you some help in how to use the compiler optimization reports to find unused subroutines.
Btw.: This also works for C/C++!

Admittedly, a dedicated feature listing unused subroutines right away would be better. Annalee already filed a feature request for that.

Best regards,

Georg Zitzlsberger

I am looking for unused routines (I know they exist and just to prove a point I created one...)

I added compile option /Qipo and set additional options: /Qopt-report-file  ipo.txt /Qopt-report-phase:all

I do not see any DEAD STATIC FUNCTION ELIMINATION: in the ipo.txt file , what am I missing?

I just tried it, and it worked for me with for every simple program I created.   

The unused routine you created, what can you say about it?  Was it a contained routine?  Was it a module routine?  Was it in a separate file, or in a library?

Oh, and what version of Intel Fortran are you using?

           Thanks --


I am probably misunderstanding something. I have attached a simple hello world project (VS2010, XE [IA-32]), the build log, source and the ipo output report. I was expecting to see a "DEAD FUNCTION"


Downloadapplication/zip console1.zip2.5 KB

(NOTE: This thread started out in the Linux/OSX Fortran forum, but app4619's question is more pertinent to the Windows Fortran forum)

The command

ifort /Qipo /Qopt-report-phase:ipo Console1.f90
produced, among other output, the following pertinent messages from the compiler:
 Routine is dead static

Hi mecej4, I get the same result as you on the command line but not in VS. The command line and buildlog was in my original post BTW. I have just tried several variations with removing other build options but I still do not get the desired results..... It seems I am getting a reduced version of the output.

In order to get the output mecej4 mentions, you have to enable both whole-program optimization (On the General page in VS) and optimization reports for the IPO phase (type in /Qopt-report-phase:ipo under Command Line > Additional Options.)

Retired 12/31/2016


Based on the recommendations, I added /Qipo to the compile option and /Qipo /Qopt-report-file /Qopt-report-phase:ipo to the linking options.

I got the BuildLog.htm and it gave the "dead" functions, subroutines.

However, although it lists:

  Routine is dead static
My subroutine GEN_BIG_A_SLOW is used:

if (time==start_time) then

    call gen_big_A_slow


In other words, at start time, it will run once. I thought in this case, it'll not be consider "dead", as long as it is used at least once. Is there some error here?



Are those vars every initialise? Is  call gen_big_A_slow actually reachable?

Hi app4619,

what do you mean by "every initialise"? gen_big_A_slow is a subroutine and it is called usually at the 1st timestep, so it should be reachable.

That may well be so but from the code snippet I cannot tell. I was just suggesting that in the case of initialised variables (for example) that that condition might never be true so the call could be an unreachable statement....



As stated above, the only way this can be done is if the compiler sees the whole program, which it does with -ipo. If the optimizer can see at compile time that the routine is never called, then you'll get the "DEAD STATIC" message in the optimization report. 

Retired 12/31/2016

Leave a Comment

Please sign in to add a comment. Not a member? Join today