The Most Underused Compiler Switches in Visual C++, March 11, 2014 Microsoft's Visual C++ team explains the nine most underused switches and why you should make sure to include them in your build.
A compiler can only optimize away data or a function if it can prove that the data or function will never be referenced. In a non-LTCG compile (i.e., a build with Whole Program Optimization (WPO) disabled), the compiler's visibility is limited to a single module (.obj), so for data and function that has global scope, the compiler will never know if other modules make use of them. As a result, the compiler can never optimize them away. The linker has a good view of all the modules that will be linked together, so the linker is in a good position to optimize away unused global data and unreferenced functions. The linker, however, manipulates on a section level, so if the unreferenced data/functions are mixed with other data or functions in a section, the linker won't be able to extract and remove. To equip the linker to remove unused global data and functions, we need to put each global data or function in a separate section. These small sections are called COMDAT.
/Gy compiler switch instructs the compiler to package only individual functions in the form of packaged functions or COMDATs, each with its own section header information. This enables function-level linkage and linker optimizations
ICF (folding together identical COMDATs) and
REF(eliminating unreferenced COMDATs). In VS2013, we have introduced a new compiler switch
/Gw that extends these linker-optimization benefits to data as well.
These switches enable linker optimizations that greatly help in reducing the size of the application, thus providing better cache locality and overall "goodness" with respect to memory which also results in runtime performance gains.