https://github.com/python/cpython/commit/d8a1cf469e40b538a84e583ac1d5d34418ed9a6a commit: d8a1cf469e40b538a84e583ac1d5d34418ed9a6a branch: main author: Chris Eibl <138194463+chris-e...@users.noreply.github.com> committer: zooba <steve.do...@microsoft.com> date: 2025-03-04T19:29:03Z summary:
gh-130090: Support PGO for clang-cl on Windows (GH-129907) files: A Misc/NEWS.d/next/Build/2025-02-13-19-21-41.gh-issue-130090.3ngJaV.rst A PCbuild/pyproject-clangcl.props M Misc/ACKS M PCbuild/_freeze_module.vcxproj M PCbuild/pyproject.props M PCbuild/pythoncore.vcxproj M PCbuild/readme.txt diff --git a/Misc/ACKS b/Misc/ACKS index 2a68b69f161041..7bf1d9c99ea24c 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -504,6 +504,7 @@ Grant Edwards Vlad Efanov Zvi Effron John Ehresman +Chris Eibl Tal Einat Eric Eisner Andrew Eland diff --git a/Misc/NEWS.d/next/Build/2025-02-13-19-21-41.gh-issue-130090.3ngJaV.rst b/Misc/NEWS.d/next/Build/2025-02-13-19-21-41.gh-issue-130090.3ngJaV.rst new file mode 100644 index 00000000000000..9ee7d5cdd8ae8a --- /dev/null +++ b/Misc/NEWS.d/next/Build/2025-02-13-19-21-41.gh-issue-130090.3ngJaV.rst @@ -0,0 +1,2 @@ +Building with ``PlatformToolset=ClangCL`` on Windows now supports PGO +(profile guided optimization). Patch by Chris Eibl with invaluable support from Steve Dover. diff --git a/PCbuild/_freeze_module.vcxproj b/PCbuild/_freeze_module.vcxproj index e12876114459bc..44292ee32b19fa 100644 --- a/PCbuild/_freeze_module.vcxproj +++ b/PCbuild/_freeze_module.vcxproj @@ -92,6 +92,7 @@ <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <Optimization>Disabled</Optimization> <WholeProgramOptimization>false</WholeProgramOptimization> + <AdditionalOptions Condition="$(PlatformToolset) == 'ClangCL'">%(AdditionalOptions) -fno-lto</AdditionalOptions> </ClCompile> <Link> <SubSystem>Console</SubSystem> diff --git a/PCbuild/pyproject-clangcl.props b/PCbuild/pyproject-clangcl.props new file mode 100644 index 00000000000000..30db6824f3caf5 --- /dev/null +++ b/PCbuild/pyproject-clangcl.props @@ -0,0 +1,50 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup Label="Globals"> + <__PyprojectClangCl_Props_Imported>true</__PyprojectClangCl_Props_Imported> + </PropertyGroup> + + <PropertyGroup> + <!-- CLANG_PROFILE_PATH is configurable for "remote PGO builds" + For convenience, we also accept paths without trailing slashes. + --> + <CLANG_PROFILE_PATH Condition="'$(CLANG_PROFILE_PATH)' == ''">$(OutDir)</CLANG_PROFILE_PATH> + <_CLANG_PROFILE_PATH>$(CLANG_PROFILE_PATH)</_CLANG_PROFILE_PATH> + <_CLANG_PROFILE_PATH Condition="!HasTrailingSlash($(_CLANG_PROFILE_PATH))">$(_CLANG_PROFILE_PATH)\</_CLANG_PROFILE_PATH> + </PropertyGroup> + + <ItemGroup> + <_profrawFiles Include="$(OutDir)instrumented\$(TargetName)_*.profraw" /> + </ItemGroup> + + <Target Name="EnsureClangProfileData" BeforeTargets="PrepareForBuild" + Condition="'$(SupportPGO)' and $(Configuration) == 'PGUpdate'"> + <Error Text="PGO run did not succeed (no $(TargetName)_*.profraw files) and there is no data to merge" + Condition="$(RequireProfileData) == 'true' and @(_profrawFiles) == ''" /> + </Target> + + <Target Name="MergeClangProfileData" BeforeTargets="PrepareForBuild" + Condition="'$(SupportPGO)' and $(Configuration) == 'PGUpdate'" + Inputs="@(_profrawFiles)" + Outputs="$(OutDir)instrumented\profdata.profdata"> + <Exec + Command='"$(LLVMInstallDir)\bin\llvm-profdata.exe" merge -output="$(OutDir)instrumented\profdata.profdata" "$(OutDir)instrumented\*_*.profraw"' /> + </Target> + + <Target Name="CleanClangProfileData" BeforeTargets="Clean"> + <Delete Files="@(_profrawFiles)" TreatErrorsAsWarnings="true" /> + <Delete Files="$(OutDir)instrumented\profdata.profdata" TreatErrorsAsWarnings="true" /> + </Target> + + <ItemDefinitionGroup> + <ClCompile> + <AdditionalOptions>-Wno-deprecated-non-prototype -Wno-unused-label -Wno-pointer-sign -Wno-incompatible-pointer-types-discards-qualifiers -Wno-unused-function %(AdditionalOptions)</AdditionalOptions> + <AdditionalOptions Condition="'$(Platform)' == 'Win32'">-m32 %(AdditionalOptions)</AdditionalOptions> + <AdditionalOptions Condition="'$(Platform)' == 'x64'">-m64 %(AdditionalOptions)</AdditionalOptions> + <AdditionalOptions Condition="$(Configuration) != 'Debug'">-flto %(AdditionalOptions)</AdditionalOptions> + <AdditionalOptions Condition="$(SupportPGO) and $(Configuration) == 'PGInstrument'">-fprofile-instr-generate=$(_CLANG_PROFILE_PATH)$(TargetName)_%m.profraw %(AdditionalOptions)</AdditionalOptions> + <AdditionalOptions Condition="$(SupportPGO) and $(Configuration) == 'PGUpdate'">-fprofile-instr-use=$(OutDir)instrumented\profdata.profdata -Wno-profile-instr-unprofiled %(AdditionalOptions)</AdditionalOptions> + </ClCompile> + </ItemDefinitionGroup> + +</Project> diff --git a/PCbuild/pyproject.props b/PCbuild/pyproject.props index 17abfa85201a90..2681e2d42e8996 100644 --- a/PCbuild/pyproject.props +++ b/PCbuild/pyproject.props @@ -24,6 +24,9 @@ <LinkIncremental Condition="$(Configuration) != 'Debug'">false</LinkIncremental> </PropertyGroup> + <!-- We need the above overridden OutDir, so this must be imported after PropertyGroup --> + <Import Project="pyproject-clangcl.props" Condition="$(PlatformToolset) == 'ClangCL' and $(__PyprojectClangCl_Props_Imported) != 'true'" /> + <PropertyGroup Condition="$(TargetExt) != ''"> <TargetNameExt>$(TargetName)$(TargetExt)</TargetNameExt> <_TargetNameSep>$(TargetNameExt.LastIndexOf(`.`))</_TargetNameSep> @@ -69,8 +72,6 @@ <ControlFlowGuard Condition="$(EnableControlFlowGuard) != ''">$(EnableControlFlowGuard)</ControlFlowGuard> <MultiProcessorCompilation>true</MultiProcessorCompilation> <AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions> - <AdditionalOptions Condition="$(PlatformToolset) == 'ClangCL'">-Wno-deprecated-non-prototype -Wno-unused-label -Wno-pointer-sign -Wno-incompatible-pointer-types-discards-qualifiers -Wno-unused-function %(AdditionalOptions)</AdditionalOptions> - <AdditionalOptions Condition="$(Configuration) != 'Debug' and $(PlatformToolset) == 'ClangCL'">-flto %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions Condition="$(MSVCHasBrokenARM64Clamping) == 'true' and $(Platform) == 'ARM64'">-d2pattern-opt-disable:-932189325 %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions Condition="$(MSVCHasBrokenARM64SignExtension) == 'true' and $(Platform) == 'ARM64'">-d2ssa-patterns-all- %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions Condition="$(GenerateSourceDependencies) == 'true'">/sourceDependencies "$(IntDir.Trim(`\`))" %(AdditionalOptions)</AdditionalOptions> @@ -186,7 +187,7 @@ public override bool Execute() { Targets="CleanAll" /> </Target> - <Target Name="CopyPGCFiles" BeforeTargets="PrepareForBuild" Condition="$(Configuration) == 'PGUpdate'"> + <Target Name="CopyPGCFiles" BeforeTargets="PrepareForBuild" Condition="$(Configuration) == 'PGUpdate' and $(PlatformToolset) != 'ClangCL'"> <ItemGroup> <_PGCFiles Include="$(OutDir)instrumented\$(TargetName)!*.pgc" /> <_PGDFile Include="$(OutDir)instrumented\$(TargetName).pgd" /> @@ -194,7 +195,7 @@ public override bool Execute() { </ItemGroup> <Delete Files="@(_CopyFiles->'$(OutDir)%(Filename)%(Extension)')" /> <Error Text="PGO run did not succeed (no $(TargetName)!*.pgc files) and there is no data to merge" - Condition="$(RequirePGCFiles) == 'true' and @(_PGCFiles) == ''" /> + Condition="$(RequireProfileData) == 'true' and @(_PGCFiles) == ''" /> <Copy SourceFiles="@(_CopyFiles)" DestinationFolder="$(OutDir)" UseHardLinksIfPossible="true" diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj index 9ebf58ae8a9bc4..3b3c3972987db8 100644 --- a/PCbuild/pythoncore.vcxproj +++ b/PCbuild/pythoncore.vcxproj @@ -81,7 +81,7 @@ </ImportGroup> <PropertyGroup> <KillPython>true</KillPython> - <RequirePGCFiles>true</RequirePGCFiles> + <RequireProfileData>true</RequireProfileData> <IncludeExternals Condition="$(IncludeExternals) == '' and Exists('$(zlibDir)\zlib.h')">true</IncludeExternals> <IncludeExternals Condition="$(IncludeExternals) == ''">false</IncludeExternals> </PropertyGroup> diff --git a/PCbuild/readme.txt b/PCbuild/readme.txt index 693fcee5f90ce2..33952d31681cbc 100644 --- a/PCbuild/readme.txt +++ b/PCbuild/readme.txt @@ -52,6 +52,45 @@ Release settings, though without PGO. +Building Python using Clang/LLVM +-------------------------------- + +See https://learn.microsoft.com/cpp/build/clang-support-msbuild +for how to install and use clang-cl bundled with Microsoft Visual Studio. +You can use the IDE to switch to clang-cl for local development, +but because this alters the *.vcxproj files, the recommended way is +to use build.bat: + +build.bat "/p:PlatformToolset=ClangCL" + +All other build.bat options continue to work as with MSVC, so this +will create a 64bit release binary. + +You can also use a specific version of clang-cl downloaded from +https://github.com/llvm/llvm-project/releases, e.g. +clang+llvm-18.1.8-x86_64-pc-windows-msvc.tar.xz. +Given you have extracted that to <my-clang-dir>, you can use it like so +build.bat --pgo "/p:PlatformToolset=ClangCL" "/p:LLVMInstallDir=<my-clang-dir> "/p:LLVMToolsVersion=18" + +Setting LLVMToolsVersion to the major version is enough, although you +can be specific and use 18.1.8 in the above example, too. + +Use the --pgo option to build with PGO (Profile Guided Optimization). + +However, if you want to run the PGO task +on a different host than the build host, you must pass +"/p:CLANG_PROFILE_PATH=<relative-path-to-instrumented-dir-on-remote-host>" +in the PGInstrument step to make sure the profile data is generated +into the instrumented directory when running the PGO task. +E.g., if you place the instrumented binaries into the folder +"workdir/instrumented" and then run the PGO task using "workdir" +as the current working directory, the usage is +"/p:CLANG_PROFILE_PATH=instrumented" + +Like in the MSVC case, after fetching (or manually copying) the instrumented +folder back into your build tree, you can continue with the PGUpdate +step with no further parameters. + Building Python using the build.bat script ---------------------------------------------- _______________________________________________ Python-checkins mailing list -- python-checkins@python.org To unsubscribe send an email to python-checkins-le...@python.org https://mail.python.org/mailman3/lists/python-checkins.python.org/ Member address: arch...@mail-archive.com