Intel® C++ Compiler
Community support and assistance for creating C++ code that runs on platforms based on Intel® processors.

Finding dead Code

abhijeet_thatte
Beginner
952 Views
Hi,

I am not sure if this question is to be asked in this forum or Visual studio forum.

I use ICC environment coupled with VC2005 for my development. I know that xilink invokes "link" and then linking is done by VC. But xilink (in turn link) is failing to find dead code in my files.
I have kept /Wall /Wx options ON for both compiler and linker. Still it is not able to catch. However, I can see debug files "vc80.pdb" are not found while building exe file. Currently I ignose these warnings. If I want I can include these files.

So, I want to know what can be the reason for not finding the dead code. Will inclusion of "vc80.pdb" solve my problem.
0 Kudos
9 Replies
TimP
Honored Contributor III
952 Views
It's not clear what you want here. I don't think the Microsoft tools would have a role in optimizing away dead code, if that's what you mean. I would think it desirable if the ICL opt-report would tell you about dead code elimination, but I doubt it's designed to do that. If you compiled with optimization plus debug symbols, and brought up the GUI debugger, it might not allow you to set a break point in dead code which has been optimized away.
Code coverage tools might be another approach to finding dead code, without depending on the compiler to diagnose it.
0 Kudos
abhijeet_thatte
Beginner
952 Views
Hi,

I guess you got my question. I have huge code base and want to remove the dead code. I am already using code coverage tools but they list functions responsible for negative code paths along with actual dead code.
Now some of the negative test cases are diffcult to generate and those paths are not checked but that does not mean I dont want that code. So, I end up getting huge list of functions which is mix of dead and negative.
Now I want to separate dead functions in that list. I was thinking linker can help me here. It already has all symbol information and should have been possible.

Let me know if there are any other options. (GUI/breakpt based solution may not be usefull when I have 1200 source files.)
0 Kudos
TimP
Honored Contributor III
952 Views
If you compile each function to a separate object file, and make a static library, linkers have ways of showing you which objects were referenced and so included in the link. I don't know enough about Microsoft linker to know whether /link /verbose or /map would do that better. Even if you don't weed out the unused functions from the library, this would keep them out of your .exe.
Traditionally, for operating systems which required static libraries to be built in a certain order, there were tools to help with that, which would also sort out objects not referenced by others.
0 Kudos
mecej4
Honored Contributor III
952 Views
Let's break this down:

(i) object files whose non-inclusion in the link does not result in unsatisfied externals. The sources for these objects can be archived and removed from the project. You may need to produce a map file and analyse it, or use special-purpose tools to identify candidates for removal.

(ii) functions/procedures that exist among other functions/procedures and static data in object files. A smart linker can ensure that these functions are not included in the executable image, or you may proceed as in (i) to identify and remove the unneeded parts from the source files. If you have a smart linker, and you are not worried about excessive link times and executable size, you may just leave things alone. There are source file splitters which will work with some languages (e.g. Fortran) to reduce this category to category (i).

(iii) Lines of code within procedure that have no execution path to them, regardless of the arguments passed to them and regardless of the values of global variables. Compilers are quite efficient at detecting, announcing and not producing code for these parts. You can use the warnings to remove this type of dead code from the source.

(iv) Code that is not executed for all the likely input arguments, etc., that the program is intended to work with. Code coverage tools only show up code that was not executed for the specific input values given to a specific run. There is no guarantee that with other input data the same code will not be executed. In contrast, the logic needed to flag a portion of code as unneeded, rooted in mathematics or some other domain, may not be available to the compiler. For example:

double x, y;
...
y=exp(x);
if(y < 0){block}
..
The block will never be executed, but which compilers can detect that? Is it safe to replace the block by an assertion or an "it can't happen" message?

It is the last category (iv) that is most troublesome, most interesting and the one that earns programmers their keep -- most interesting because the analysis that is needed has the potential to reveal the properties and structure of the code.

Note also that defensive programming may cause the creation of some lines of code that fall into category (iv). Such code should be left alone, absent any proof that it will never be needed.
0 Kudos
jimdempseyatthecove
Honored Contributor III
952 Views
In addition to the list provided by mecej4...

It is not unusual for a large project to contain functions/subroutines that have been superseded by newer routines. While it may seem advantageous to identify these routines and eliminate them from the project, you run a risk that the successor routines have errors or do not function correctly for seldom use input arguments. Deleting the "legacy" routines will also delete the historical content (intent) of the original programmer. It is better that these routines be preserved in conditional compilation sections that disable compilation.

Jim Dempsey
0 Kudos
abhijeet_thatte
Beginner
952 Views
Hi All,

Thanks for your replies. Currently I am mainly focusing on low hanging fruits like unused functions (dead functions where no code path ever reaches). Idealy I was expecting linker to detect them.
Compiler does find static functions which are not used. But surpringly linker fails to detect dead non-static functions. As mentioned at the start of the post, I am on VC and it does not detect. I am not sure if GCC can do that. Even if GCC does it , I am not sure if I want to port some 2000 file project to linux.

Map file is going to be more efforts and less automation. So, currently, I am looking for some smart linker(like what u suggested). I want it for 'C'. I am exploring lint. I am not sure if it can do what I want.

Let me know any of you know any tool/linker which can be used to solve this problem.
0 Kudos
abhijeet_thatte
Beginner
952 Views
Hi,

I am trying one way to go about it.
I am using /OPT:REF option to not include dead code and then running scripts on generated map files to find which functions are actually referenced. That list I am comparing against a list of functions I have and then identifying unused functions.

What do you guys think of this option?
0 Kudos
mecej4
Honored Contributor III
952 Views
I think this should work well for you, but watch out for changes to the MAP file format when you install a new version of the compiler and/or the linker. Your scripts may need revision at that point.

Why do you need the script after LINK /opt:REF has done the necessary pruning for you? I cannot think of a reason since, if the linker is properly implementing the requested option, you would not find any unused symbols in the MAP file.

I would appreciate it if you can share the script that you created to parse the MAP files output by the linker.
0 Kudos
abhijeet_thatte
Beginner
952 Views
You are right. I dont need a script cause linker will do its work. However, I want to take out these functions from the code. It is just confusing at the time of development. So, I will be chopping of these unecessary functions based on difference between map files with and w/o /OPT:REF.
I will share that script with you once I get a green signal to implement this approach.
0 Kudos
Reply