Skip to content

Commit

Permalink
Workaround for MSVC ARM64 build performance regression (#65215)
Browse files Browse the repository at this point in the history
MSVC has a major performance regression observed when targeting ARM64
since v19.32 (VS 17.2.0). `cl.exe` spends a lot of time on compiling
`StandardLibrary.cpp` and `CGBuiltin.cpp`, and total build duration
rises extremely. This makes builds stagnate even on a real hardware, but
VM-based builds (like building on cloud agents from GitHub Actions and
Azure Pipelines) are experiencing most damage as they also performance-
and time-limited.

The issue appears to be related to some optimizations applied in `/O2`
mode. It is reported on [Developer
Community](https://developercommunity.visualstudio.com/t/Compiling-a-specific-code-for-ARM64-with/10444970).
While the investigation is in progress, we could apply a workaround to
improve build time. `/O2` actually enables a set of optimizations, and
only one of them does all slowdown. The idea is to disable
optimizations, and then apply all but one back, effectively excluding
the problematic option from the set.

This patch alters the CMake configuration for aforementioned files.
Changes are limited to:
- non-debug builds
- MSVC of the specific version
- target arch (ARM64).
  • Loading branch information
lxbndr authored Oct 20, 2023
1 parent 2483763 commit c6f0f88
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 0 deletions.
20 changes: 20 additions & 0 deletions clang/lib/CodeGen/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,26 @@ set(LLVM_LINK_COMPONENTS
TransformUtils
)

# Workaround for MSVC ARM64 performance regression:
# https://developercommunity.visualstudio.com/t/Compiling-a-specific-code-for-ARM64-with/10444970
# Since /O1 and /O2 represent a set of optimizations,
# our goal is to disable the /Og flag while retaining the other optimizations from the /O1|/O2 set
if(MSVC AND NOT CMAKE_CXX_COMPILER_ID MATCHES Clang
AND MSVC_VERSION VERSION_GREATER_EQUAL 1932
AND CMAKE_SYSTEM_PROCESSOR MATCHES "ARM64")

string(TOUPPER "${CMAKE_BUILD_TYPE}" uppercase_CMAKE_BUILD_TYPE)
string(REGEX MATCHALL "/[Oo][12]" opt_flags "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${uppercase_CMAKE_BUILD_TYPE}}")
if (opt_flags)
if(opt_flags MATCHES "1$")
set(opt_flags "/Od;/Os;/Oy;/Ob2;/GF;/Gy")
elseif (opt_flags MATCHES "2$")
set(opt_flags "/Od;/Oi;/Ot;/Oy;/Ob2;/GF;/Gy")
endif()
set_source_files_properties(CGBuiltin.cpp PROPERTIES COMPILE_OPTIONS "${opt_flags}")
endif()
endif()

add_clang_library(clangCodeGen
ABIInfo.cpp
ABIInfoImpl.cpp
Expand Down
20 changes: 20 additions & 0 deletions clang/lib/Tooling/Inclusions/Stdlib/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
# Workaround for MSVC ARM64 performance regression:
# https://developercommunity.visualstudio.com/t/Compiling-a-specific-code-for-ARM64-with/10444970
# Since /O1 and /O2 represent a set of optimizations,
# our goal is to disable the /Og flag while retaining the other optimizations from the /O1|/O2 set
if(MSVC AND NOT CMAKE_CXX_COMPILER_ID MATCHES Clang
AND MSVC_VERSION VERSION_GREATER_EQUAL 1932
AND CMAKE_SYSTEM_PROCESSOR MATCHES "ARM64")

string(TOUPPER "${CMAKE_BUILD_TYPE}" uppercase_CMAKE_BUILD_TYPE)
string(REGEX MATCHALL "/[Oo][12]" opt_flags "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${uppercase_CMAKE_BUILD_TYPE}}")
if (opt_flags)
if(opt_flags MATCHES "1$")
set(opt_flags "/Od;/Os;/Oy;/Ob2;/GF;/Gy")
elseif (opt_flags MATCHES "2$")
set(opt_flags "/Od;/Oi;/Ot;/Oy;/Ob2;/GF;/Gy")
endif()
set_source_files_properties(StandardLibrary.cpp PROPERTIES COMPILE_OPTIONS "${opt_flags}")
endif()
endif()

add_clang_library(clangToolingInclusionsStdlib
StandardLibrary.cpp

Expand Down

0 comments on commit c6f0f88

Please sign in to comment.