From 567fabe88e97c3e39503fd353b484648bcf1cbb2 Mon Sep 17 00:00:00 2001 From: Niels Dekker Date: Sun, 9 Sep 2018 23:04:59 +0200 Subject: IPO: INTERPROCEDURAL_OPTIMIZATION (LTCG) for Visual Studio Add IPO support for Visual Studio (which is referred to by VS as "Link Time Code Generation" and "Whole Program Optimization"), for VS version >= 10. This allows CMake/VS users to enable IPO by setting property `INTERPROCEDURAL_OPTIMIZATION`. Fixes: #16748 --- Help/release/dev/vs-ipo.rst | 6 ++++++ Modules/CheckIPOSupported.cmake | 2 +- Source/cmGlobalVisualStudio10Generator.h | 2 ++ Source/cmVisualStudio10TargetGenerator.cxx | 9 +++++++-- Source/cmVisualStudio10TargetGenerator.h | 1 + Tests/RunCMake/CMP0069/RunCMakeTest.cmake | 2 +- Tests/RunCMake/CheckIPOSupported/RunCMakeTest.cmake | 2 +- 7 files changed, 19 insertions(+), 5 deletions(-) create mode 100644 Help/release/dev/vs-ipo.rst diff --git a/Help/release/dev/vs-ipo.rst b/Help/release/dev/vs-ipo.rst new file mode 100644 index 0000000..a31601f --- /dev/null +++ b/Help/release/dev/vs-ipo.rst @@ -0,0 +1,6 @@ +vs-ipo +------ + +* The :ref:`Visual Studio Generators` for VS 2010 and above learned to + support the :prop_tgt:`INTERPROCEDURAL_OPTIMIZATION` target property + and supporting :module:`CheckIPOSupported` module. diff --git a/Modules/CheckIPOSupported.cmake b/Modules/CheckIPOSupported.cmake index 3344834..ad8852c 100644 --- a/Modules/CheckIPOSupported.cmake +++ b/Modules/CheckIPOSupported.cmake @@ -226,7 +226,7 @@ function(check_ipo_supported) endif() endforeach() - if(CMAKE_GENERATOR MATCHES "^Visual Studio ") + if(CMAKE_GENERATOR MATCHES "^Visual Studio 9 ") _ipo_not_supported("CMake doesn't support IPO for current generator") return() endif() diff --git a/Source/cmGlobalVisualStudio10Generator.h b/Source/cmGlobalVisualStudio10Generator.h index 6eb597c..63e6903 100644 --- a/Source/cmGlobalVisualStudio10Generator.h +++ b/Source/cmGlobalVisualStudio10Generator.h @@ -111,6 +111,8 @@ public: bool FindMakeProgram(cmMakefile* mf) override; + bool IsIPOSupported() const override { return true; } + static std::string GetInstalledNsightTegraVersion(); cmIDEFlagTable const* GetClFlagTable() const; diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index 9e74335..c0b0435 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -1122,6 +1122,9 @@ void cmVisualStudio10TargetGenerator::WriteMSToolConfigurationValues( this->GeneratorTarget->GetPropertyAsBool("VS_WINRT_EXTENSIONS")) { e1.Element("WindowsAppContainer", "true"); } + if (this->IPOEnabledConfigurations.count(config) > 0) { + e1.Element("WholeProgramOptimization", "true"); + } } void cmVisualStudio10TargetGenerator::WriteMSToolConfigurationValuesManaged( @@ -2485,8 +2488,10 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions( clOptions.AddFlag("CompileAs", "CompileAsCpp"); } - // Check IPO related warning/error. - this->GeneratorTarget->IsIPOEnabled(linkLanguage, configName); + // Put the IPO enabled configurations into a set. + if (this->GeneratorTarget->IsIPOEnabled(linkLanguage, configName)) { + this->IPOEnabledConfigurations.insert(configName); + } // Get preprocessor definitions for this directory. std::string defineFlags = this->Makefile->GetDefineFlags(); diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h index 15e47b4..829d2bf 100644 --- a/Source/cmVisualStudio10TargetGenerator.h +++ b/Source/cmVisualStudio10TargetGenerator.h @@ -204,6 +204,7 @@ private: bool NsightTegra; unsigned int NsightTegraVersion[4]; bool TargetCompileAsWinRT; + std::set IPOEnabledConfigurations; cmGlobalVisualStudio10Generator* const GlobalGenerator; cmLocalVisualStudio10Generator* const LocalGenerator; std::set CSharpCustomCommandNames; diff --git a/Tests/RunCMake/CMP0069/RunCMakeTest.cmake b/Tests/RunCMake/CMP0069/RunCMakeTest.cmake index f44f840..456e6a6 100644 --- a/Tests/RunCMake/CMP0069/RunCMakeTest.cmake +++ b/Tests/RunCMake/CMP0069/RunCMakeTest.cmake @@ -5,6 +5,6 @@ run_cmake(CMP0069-NEW-cmake) run_cmake(CMP0069-NEW-compiler) run_cmake(CMP0069-WARN) -if(RunCMake_GENERATOR MATCHES "^Visual Studio ") +if(RunCMake_GENERATOR MATCHES "^Visual Studio 9 ") run_cmake(CMP0069-NEW-generator) endif() diff --git a/Tests/RunCMake/CheckIPOSupported/RunCMakeTest.cmake b/Tests/RunCMake/CheckIPOSupported/RunCMakeTest.cmake index e145569..b7d524c 100644 --- a/Tests/RunCMake/CheckIPOSupported/RunCMakeTest.cmake +++ b/Tests/RunCMake/CheckIPOSupported/RunCMakeTest.cmake @@ -8,6 +8,6 @@ run_cmake(not-supported-by-compiler) run_cmake(save-to-result) run_cmake(cmp0069-is-old) -if(RunCMake_GENERATOR MATCHES "^Visual Studio ") +if(RunCMake_GENERATOR MATCHES "^Visual Studio 9 ") run_cmake(not-supported-by-generator) endif() -- cgit v0.12 From bef80e66231a0bd2feffab02fe8d1d8f55eb793c Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 12 Sep 2018 13:45:05 -0400 Subject: VS: Do not specify incremental linking if LTCG is enabled Otherwise the linker may warn: LNK4075: ignoring '/INCREMENTAL' due to '/LTCG' specification --- Source/cmVisualStudio10TargetGenerator.cxx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index c0b0435..2a54cfc 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -2374,9 +2374,11 @@ void cmVisualStudio10TargetGenerator::OutputLinkIncremental( Options& linkOptions = *(this->LinkOptions[configName]); const std::string cond = this->CalcCondition(configName); - const char* incremental = linkOptions.GetFlag("LinkIncremental"); - e1.WritePlatformConfigTag("LinkIncremental", cond, - (incremental ? incremental : "true")); + if (this->IPOEnabledConfigurations.count(configName) == 0) { + const char* incremental = linkOptions.GetFlag("LinkIncremental"); + e1.WritePlatformConfigTag("LinkIncremental", cond, + (incremental ? incremental : "true")); + } linkOptions.RemoveFlag("LinkIncremental"); const char* manifest = linkOptions.GetFlag("GenerateManifest"); -- cgit v0.12