https://github.com/marcpems updated 
https://github.com/llvm/llvm-project/pull/219263

>From 26399f0d236fb624a953d7b2cd3e7d397ba67921 Mon Sep 17 00:00:00 2001
From: marcpems <[email protected]>
Date: Fri, 28 Aug 2026 11:05:26 +0100
Subject: [PATCH 1/4] [Windows] Add optional ThinLTO, PDB debug info, and
 enhanced PGO training to release-binaries.yml

Adds minimal, additive inputs to the existing release-binaries.yml
workflow (rather than a separate duplicate workflow file):

- enable-thinlto: build stage2 with ThinLTO (default off, matches
  current behavior).
- enable-pdb: also generate and upload PDB debug info as a separate
  artifact (default off).
- enhanced-pgo: PGO training always runs (matching the pre-existing,
  unconditional upstream behavior); this flag only selects the
  training method. Default false uses the legacy single-file
  Sema.cpp training step (byte-for-byte the same as current upstream
  behavior). Setting it to true trains by building LLVMSupport
  instead, exercising the compiler across many more translation
  units for a broader, more representative profile.

Default behavior (enable-thinlto=false, enable-pdb=false,
enhanced-pgo=false) is unchanged from current upstream.

Co-authored-by: Copilot <[email protected]>
---
 .github/workflows/release-binaries.yml    | 95 +++++++++++++++++++++--
 llvm/utils/release/build_llvm_release.bat | 81 +++++++++++++++----
 2 files changed, 156 insertions(+), 20 deletions(-)

diff --git a/.github/workflows/release-binaries.yml 
b/.github/workflows/release-binaries.yml
index e95a6c5936137..0ff52df0809be 100644
--- a/.github/workflows/release-binaries.yml
+++ b/.github/workflows/release-binaries.yml
@@ -12,6 +12,21 @@ on:
         required: true
         default: false
         type: boolean
+      enable-thinlto:
+        description: "Windows only: build stage2 with ThinLTO"
+        required: false
+        default: false
+        type: boolean
+      enable-pdb:
+        description: "Windows only: also generate and upload PDB debug info"
+        required: false
+        default: false
+        type: boolean
+      enhanced-pgo:
+        description: "Windows only: train the instrumented clang by building 
LLVMSupport instead of the legacy single-file Sema.cpp training step (PGO 
training always runs; this only selects the method)"
+        required: false
+        default: false
+        type: boolean
       runs-on:
         description: "Runner to use for the build"
         required: true
@@ -36,6 +51,21 @@ on:
         required: true
         default: false
         type: boolean
+      enable-thinlto:
+        description: "Windows only: build stage2 with ThinLTO"
+        required: false
+        default: false
+        type: boolean
+      enable-pdb:
+        description: "Windows only: also generate and upload PDB debug info"
+        required: false
+        default: false
+        type: boolean
+      enhanced-pgo:
+        description: "Windows only: train the instrumented clang by building 
LLVMSupport instead of the legacy single-file Sema.cpp training step (PGO 
training always runs; this only selects the method)"
+        required: false
+        default: false
+        type: boolean
       runs-on:
         description: "Runner to use for the build"
         required: true
@@ -69,6 +99,9 @@ jobs:
       build-runs-on: ${{ steps.vars.outputs.build-runs-on }}
       test-runs-on: ${{ steps.vars.outputs.build-runs-on }}
       attestation-name: ${{ steps.vars.outputs.attestation-name }}
+      windows-enable-thinlto: ${{ steps.vars.outputs.windows-enable-thinlto }}
+      windows-enable-pdb: ${{ steps.vars.outputs.windows-enable-pdb }}
+      windows-enhanced-pgo: ${{ steps.vars.outputs.windows-enhanced-pgo }}
 
     steps:
     - name: Validate Release Version
@@ -90,6 +123,9 @@ jobs:
         LLVM_VERSION_MAJOR: ${{ steps.version-from-source.outputs.major }}
         INPUTS_RUNS_ON: ${{ inputs.runs-on }}
         INPUTS_RELEASE_VERSION: ${{ inputs.release-version }}
+        INPUTS_ENABLE_THINLTO: ${{ inputs.enable-thinlto }}
+        INPUTS_ENABLE_PDB: ${{ inputs.enable-pdb }}
+        INPUTS_ENHANCED_PGO: ${{ inputs.enhanced-pgo }}
       shell: bash
       # In order for the test-release.sh script to run correctly, the LLVM
       # source needs to be at the following location relative to the build dir:
@@ -160,8 +196,10 @@ jobs:
         fi
 
         if [ "$RUNNER_OS" = "Windows" ]; then
-          # The build times out on Windows, so we need to disable LTO.
-          target_cmake_flags="$target_cmake_flags 
-DLLVM_RELEASE_ENABLE_LTO=OFF"
+          # Disable LTO by default; use --enable-thinlto to enable ThinLTO.
+          if [ "$INPUTS_ENABLE_THINLTO" != "true" ]; then
+            target_cmake_flags="$target_cmake_flags 
-DLLVM_RELEASE_ENABLE_LTO=OFF"
+          fi
         fi
 
         case "$INPUTS_RUNS_ON" in
@@ -206,10 +244,29 @@ jobs:
 
         target_cmake_flags="$target_cmake_flags 
-D${bootstrap_prefix}_CPACK_PACKAGE_FILE_NAME=$release_binary_basename"
 
+        # Translate --enable-thinlto/--enable-pdb/--enhanced-pgo into 
individual
+        # flags consumed by the Windows build_llvm_release.bat invocation below
+        # (only meaningful for Windows builds).
+        windows_enable_thinlto="false"
+        if [ "$INPUTS_ENABLE_THINLTO" = "true" ]; then
+          windows_enable_thinlto="true"
+        fi
+        windows_enable_pdb="false"
+        if [ "$INPUTS_ENABLE_PDB" = "true" ]; then
+          windows_enable_pdb="true"
+        fi
+        windows_enhanced_pgo="false"
+        if [ "$INPUTS_ENHANCED_PGO" = "true" ]; then
+          windows_enhanced_pgo="true"
+        fi
+
         echo "target-cmake-flags=$target_cmake_flags" >> $GITHUB_OUTPUT
         echo "build-runs-on=$build_runs_on" >> $GITHUB_OUTPUT
         echo "test-runs-on=$test_runs_on" >> $GITHUB_OUTPUT
         echo 
"attestation-name=$RUNNER_OS-$RUNNER_ARCH-release-binary-attestation" >> 
$GITHUB_OUTPUT
+        echo "windows-enable-thinlto=$windows_enable_thinlto" >> $GITHUB_OUTPUT
+        echo "windows-enable-pdb=$windows_enable_pdb" >> $GITHUB_OUTPUT
+        echo "windows-enhanced-pgo=$windows_enhanced_pgo" >> $GITHUB_OUTPUT
 
   build-release-package:
     name: "Build Release Package"
@@ -297,21 +354,42 @@ jobs:
       env:
         INPUTS_RUNS_ON: ${{ inputs.runs-on }}
         LLVM_VERSION: ${{ needs.prepare.outputs.release-version }}
-        EXTRA_ARGS: ${{ case(needs.prepare.outputs.build-runs-on == 
'windows-11-arm', '--fast-build', '--fast-build') }}
+        BUILD_RUNS_ON: ${{ needs.prepare.outputs.build-runs-on }}
+        WINDOWS_ENABLE_THINLTO: ${{ 
needs.prepare.outputs.windows-enable-thinlto }}
+        WINDOWS_ENABLE_PDB: ${{ needs.prepare.outputs.windows-enable-pdb }}
+        WINDOWS_ENHANCED_PGO: ${{ needs.prepare.outputs.windows-enhanced-pgo }}
       run: |
         subst S: ${{ github.workspace }}
         cd S:\llvm\utils\release\
-        .\build_llvm_release.bat "--$($env:RUNNER_ARCH.ToLower())" --version 
$env:LLVM_VERSION --local-python --skip-checkout $env:EXTRA_ARGS
+        $variantArgs = @()
+        # --fast-build trades PGO training and stage0 test coverage for
+        # build speed; it exists solely so the GitHub-hosted windows-11-arm
+        # runner can finish within its 6-hour job timeout. Other runners
+        # (including our self-hosted ones) don't need that trade-off, and
+        # --enhanced-pgo/--enable-thinlto/--enable-pdb below are explicit,
+        # deliberate opt-ins that should not be silently defeated by it.
+        if ($env:BUILD_RUNS_ON -eq "windows-11-arm") { $variantArgs += 
"--fast-build" }
+        if ($env:WINDOWS_ENABLE_THINLTO -eq "true") { $variantArgs += 
"--enable-thinlto" }
+        if ($env:WINDOWS_ENABLE_PDB -eq "true") { $variantArgs += 
"--enable-pdb" }
+        if ($env:WINDOWS_ENHANCED_PGO -eq "true") { $variantArgs += 
"--enhanced-pgo" }
+        .\build_llvm_release.bat "--$($env:RUNNER_ARCH.ToLower())" --version 
$env:LLVM_VERSION --local-python --skip-checkout @variantArgs
         if ($env:INPUTS_RUNS_ON -eq "windows-11-arm") {
           $zstd = (Get-ChildItem -Recurse -Filter "zstd.exe" | Select-Object 
-First 1).fullName
           mv $zstd $env:GITHUB_WORKSPACE
         }
         $installer = (Get-ChildItem -Recurse -Filter "LLVM-*.msi" | 
Select-Object -First 1).fullName
-        $tarball = (Get-ChildItem -Recurse -Filter "*.tar.xz" | Select-Object 
-First 1).fullName
+        $tarball = (Get-ChildItem -Recurse -Filter "*.tar.xz" | Where-Object { 
$_.Name -notlike "*-pdb.tar.xz" } | Select-Object -First 1).fullName
         # Move installer to top-level directory so it is easier to upload.
         mv $installer $env:GITHUB_WORKSPACE
         mv $tarball $env:GITHUB_WORKSPACE
         echo "windows-installer-filename=$(Split-Path -Path $installer -Leaf)" 
>> $env:GITHUB_OUTPUT
+        if ($env:WINDOWS_ENABLE_PDB -eq "true") {
+          $pdbArchive = (Get-ChildItem -Recurse -Filter "*-pdb.tar.xz" | 
Select-Object -First 1).fullName
+          if ($pdbArchive) {
+            mv $pdbArchive $env:GITHUB_WORKSPACE
+            echo "windows-pdb-filename=$(Split-Path -Path $pdbArchive -Leaf)" 
>> $env:GITHUB_OUTPUT
+          }
+        }
     
     - name: Dump Wix logs
       if: runner.os == 'Windows' && failure()
@@ -364,6 +442,13 @@ jobs:
           ${{ needs.prepare.outputs.release-binary-filename-zstd }}
           ${{ steps.build-windows.outputs.windows-installer-filename }}
 
+    - name: Upload Windows PDB debug info
+      if: runner.os == 'Windows' && 
steps.build-windows.outputs.windows-pdb-filename != ''
+      uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # 
v7.0.1
+      with:
+        name: ${{ runner.os }}-${{ runner.arch }}-release-pdb
+        path: ${{ steps.build-windows.outputs.windows-pdb-filename }}
+
     - name: Run Tests
       # These almost always fail so don't let them fail the build and prevent 
the uploads.
       if : runner.os != 'Windows'
diff --git a/llvm/utils/release/build_llvm_release.bat 
b/llvm/utils/release/build_llvm_release.bat
index 66c4a0380667a..1c66adb388b56 100644
--- a/llvm/utils/release/build_llvm_release.bat
+++ b/llvm/utils/release/build_llvm_release.bat
@@ -10,7 +10,7 @@ goto begin
 echo Script for building the LLVM installer on Windows,
 echo used for the releases at https://github.com/llvm/llvm-project/releases
 echo.
-echo Usage: build_llvm_release.bat --version ^<version^> [--x86,--x64, 
--arm64] [--skip-checkout] [--local-python] [--force-msvc] [--fast-build]
+echo Usage: build_llvm_release.bat --version ^<version^> [--x86,--x64, 
--arm64] [--skip-checkout] [--local-python] [--force-msvc] [--fast-build] 
[--enhanced-pgo] [--enable-thinlto] [--enable-pdb]
 echo.
 echo Options:
 echo --version: [required] version to build
@@ -21,6 +21,11 @@ echo --arm64: build and test arm64 variant
 echo --skip-checkout: use local git checkout instead of downloading src.zip
 echo --local-python: use installed Python and does not try to use a specific 
version (3.11)
 echo --force-msvc: use MSVC compiler for stage0, even if clang-cl is present
+echo --enhanced-pgo: train the instrumented stage1 clang by building 
LLVMSupport instead of
+echo   the legacy single-file Sema.cpp training step, and use the resulting 
profile for
+echo   stage2 (64-bit builds only).
+echo --enable-thinlto: build stage2 with ThinLTO (64-bit builds only)
+echo --enable-pdb: generate PDB debug info files for stage2 and include them 
as an additional artifact (64-bit builds only)
 echo.
 echo Note: At least one variant to build is required.
 echo.
@@ -40,7 +45,10 @@ set arm64=
 set skip-checkout=
 set local-python=
 set force-msvc=
-set fast-build=
+set fast-build=
+set enhanced-pgo=
+set enable-thinlto=
+set enable-pdb=
 call :parse_args %*
 
 if "%help%" NEQ "" goto usage
@@ -355,12 +363,21 @@ set cmake_flags=%all_cmake_flags:\=/%
 
 mkdir build_%arch%
 cd build_%arch%
-if "%fast-build%" neq "true" (
+REM --fast-build skips PGO training for CI speed on time-constrained
+REM runners (see build_llvm_release.bat's usage doc), but --enhanced-pgo
+REM is an explicit, deliberate opt-in and should not be silently defeated
+REM by it; only skip training when enhanced-pgo was not also requested.
+if "%fast-build%" == "true" if "%enhanced-pgo%" neq "true" (
+  echo Skipping PGO training due to --fast-build.
+) else (
   call :do_generate_profile || exit /b 1
-)
+)
+set lto_cmake_flag=
+if "%enable-thinlto%" == "true" set lto_cmake_flag=-DLLVM_ENABLE_LTO=Thin
 cmake -GNinja %cmake_flags% ^
   -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra;lld;lldb;flang;mlir" ^
   -DLLVM_ENABLE_RUNTIMES="compiler-rt;openmp" ^
+  %lto_cmake_flag% ^
   %common_lldb_flags% ^
   -DPYTHON_HOME=%PYTHONHOME% ^
   %cmake_profile_flags% %llvm_src%\llvm || exit /b 1
@@ -384,14 +401,31 @@ if "%arch%"=="amd64" (
 ) else (
   set filename=clang+llvm-%version%-aarch64-pc-windows-msvc
 )
+REM NOTE: LLVM_ENABLE_PDB is intentionally only set for this toolchain-only
+REM (tarball) reconfigure, not for the MSI/WiX "ninja package" build above:
+REM bundling PDBs into the WiX-generated MSI causes CPack/WiX packaging
+REM failures, so PDBs are packaged separately as their own tarball instead.
+set pdb_cmake_flag=
+if "%enable-pdb%" == "true" set pdb_cmake_flag=-DLLVM_ENABLE_PDB=ON
 cmake -GNinja %cmake_flags% %cmake_profile_flags% 
-DLLVM_INSTALL_TOOLCHAIN_ONLY=OFF ^
-  -DCMAKE_INSTALL_PREFIX=%build_dir%/%filename% %llvm_src%\llvm || exit /b 1
+  -DCMAKE_INSTALL_PREFIX=%build_dir%/%filename% ^
+  %pdb_cmake_flag% ^
+  %llvm_src%\llvm || exit /b 1
 ninja install || exit /b 1
 :: check llvm_config is present & returns something
 %build_dir%/%filename%/bin/llvm-config.exe --bindir || exit /b 1
 cd ..
 7z a -ttar -so %filename%.tar %filename% | 7z a -txz -si %filename%.tar.xz
 
+if "%enable-pdb%" == "true" (
+  :: Package the PDB debug info files produced alongside the install tree
+  :: into their own archive so they can be uploaded as a separate artifact.
+  set pdb_filename=%filename%-pdb
+  pushd %filename%
+  7z a -ttar -so ..\!pdb_filename!.tar bin\*.pdb lib\*.pdb | 7z a -txz -si 
..\!pdb_filename!.tar.xz
+  popd
+)
+
 exit /b 0
 
 
::==============================================================================
@@ -503,18 +537,35 @@ cmake -GNinja %cmake_flags% 
-DLLVM_TARGETS_TO_BUILD=Native ^
 ninja clang || exit /b 1
 set instrumented_clang=%cd:\=/%/bin/clang-cl.exe
 cd ..
-REM Use that to build part of llvm to generate a profile.
 mkdir train
 cd train
-cmake -GNinja %cmake_flags% ^
-  -DCMAKE_C_COMPILER=%instrumented_clang% ^
-  -DCMAKE_CXX_COMPILER=%instrumented_clang% ^
-  -DLLVM_ENABLE_PROJECTS=clang ^
-  -DLLVM_TARGETS_TO_BUILD=Native ^
-  %llvm_src%\llvm || exit /b 1
-REM Drop profiles generated from running cmake; those are not representative.
-del ..\instrument\profiles\*.profraw
-ninja tools/clang/lib/Sema/CMakeFiles/obj.clangSema.dir/Sema.cpp.obj
+if "%enhanced-pgo%" == "true" (
+  REM Build LLVMSupport with the instrumented clang to generate a broad 
profile.
+  REM This mirrors Linux and Mac perf-training approach.
+  cmake -GNinja ^
+    -DCMAKE_BUILD_TYPE=Release ^
+    -DCMAKE_C_COMPILER=%instrumented_clang% ^
+    -DCMAKE_CXX_COMPILER=%instrumented_clang% ^
+    -DLLVM_TARGETS_TO_BUILD=Native ^
+    -DLLVM_ENABLE_PROJECTS="" ^
+    -DLLVM_ENABLE_RUNTIMES="" ^
+    %llvm_src%\llvm || exit /b 1
+  REM Drop profiles generated from running cmake; those are not representative.
+  del ..\instrument\profiles\*.profraw
+  ninja LLVMSupport || exit /b 1
+) else (
+  REM Use instrumented build of clang to compile a complex single file to
+  REM deliver minimum build times.
+  cmake -GNinja %cmake_flags% ^
+    -DCMAKE_C_COMPILER=%instrumented_clang% ^
+    -DCMAKE_CXX_COMPILER=%instrumented_clang% ^
+    -DLLVM_ENABLE_PROJECTS=clang ^
+    -DLLVM_TARGETS_TO_BUILD=Native ^
+    %llvm_src%\llvm || exit /b 1
+  REM Drop profiles generated from running cmake; those are not representative.
+  del ..\instrument\profiles\*.profraw
+  ninja tools/clang/lib/Sema/CMakeFiles/obj.clangSema.dir/Sema.cpp.obj || exit 
/b 1
+)
 cd ..
 set profile=%cd:\=/%/profile.profdata
 %stage0_bin_dir%\llvm-profdata merge -output=%profile% 
instrument\profiles\*.profraw || exit /b 1

>From 8c2b613e2690c6fd5221646f4f8b522b1364c3fa Mon Sep 17 00:00:00 2001
From: marcpems <[email protected]>
Date: Tue, 1 Sep 2026 07:27:54 +0100
Subject: [PATCH 2/4] Fix double-packaging of PDB files in Windows release main
 tarball

Previously, when --enable-pdb was set, the main release tarball
included the full install tree (with all bin\*.pdb and lib\*.pdb
files) *and* a separate dedicated -pdb.tar.xz archive packaged those
same PDBs again, roughly doubling the compressed payload and
needlessly inflating the main artifact.

Fix: package the dedicated PDB archive first (as before), then delete
bin\*.pdb and lib\*.pdb from the install tree, then run the main
archive command. The main archive command itself is left completely
unmodified from upstream (byte-for-byte identical to the pre-existing
single 7z line) since the PDBs are simply no longer present in the
tree by the time it runs; only the ordering changed and one "del"
line was added inside the existing PDB-packaging block.

This is deliberately simpler than an earlier version of this fix that
added a "-xr!pattern" 7-Zip exclusion to the main archive command:
that syntax requires a literal "!", which is fragile under this
script's `setlocal enabledelayedexpansion` and needs extra
setlocal/endlocal scoping and careful comment placement to avoid
cmd.exe parser pitfalls. Deleting the files before archiving avoids
that whole class of issues and keeps the main archive command
identical to upstream's non-PDB behavior.

Verified locally in real cmd.exe with a synthetic install tree
(including a decoy nested\bin\keep.pdb outside the top-level bin/lib
directories, to confirm the deletion is scoped the same way the prior
"-xr!" recursive exclusion was): the PDB archive contains exactly
bin\*.pdb and lib\*.pdb, the main archive contains everything else
(including the decoy nested PDB, correctly left untouched), and the
non-PDB (enable-pdb=false) path is completely unchanged.

Co-authored-by: Copilot <[email protected]>
---
 llvm/utils/release/build_llvm_release.bat | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/llvm/utils/release/build_llvm_release.bat 
b/llvm/utils/release/build_llvm_release.bat
index 1c66adb388b56..231dafc395ada 100644
--- a/llvm/utils/release/build_llvm_release.bat
+++ b/llvm/utils/release/build_llvm_release.bat
@@ -415,16 +415,18 @@ ninja install || exit /b 1
 :: check llvm_config is present & returns something
 %build_dir%/%filename%/bin/llvm-config.exe --bindir || exit /b 1
 cd ..
-7z a -ttar -so %filename%.tar %filename% | 7z a -txz -si %filename%.tar.xz
-
 if "%enable-pdb%" == "true" (
   :: Package the PDB debug info files produced alongside the install tree
-  :: into their own archive so they can be uploaded as a separate artifact.
+  :: into their own archive so they can be uploaded as a separate artifact,
+  :: then delete them from the install tree so the main archive command
+  :: below does not compress them a second time.
   set pdb_filename=%filename%-pdb
   pushd %filename%
   7z a -ttar -so ..\!pdb_filename!.tar bin\*.pdb lib\*.pdb | 7z a -txz -si 
..\!pdb_filename!.tar.xz
+  del /s /q bin\*.pdb lib\*.pdb
   popd
 )
+7z a -ttar -so %filename%.tar %filename% | 7z a -txz -si %filename%.tar.xz
 
 exit /b 0
 

>From 9983d086f24b2f12f30f90aa03e13059811f1b3c Mon Sep 17 00:00:00 2001
From: marcpems <[email protected]>
Date: Wed, 2 Sep 2026 11:28:07 +0100
Subject: [PATCH 3/4] Run PDB reconfigure/recompile concurrently with test
 suite and packaging

LLVM_ENABLE_PDB flips the /Zi compile flag, which invalidates every
object file from the main build and previously forced a full serial
recompile+relink after WiX/MSI packaging finished (~41 min observed).
That recompile does not depend on the test suite or WiX packaging, so
kick it off in a separate build directory right after the main build
completes, and let it run concurrently with them in the background,
hiding most/all of its wall-clock cost instead of paying for it
serially at the end.

Uses a dedicated minimized console (start /min) to avoid console
handle contention with the foreground script's output, and delayed
expansion (cmd /v:on + ^!errorlevel^!) to reliably capture ninja's
real exit code from the background job.

Validated on the self-hosted ARM64 runner: the concurrent PDB rebuild
was fully hidden behind the ~78 min test-suite phase with zero added
wall-clock cost, and no behavioral regressions were observed.
---
 llvm/utils/release/build_llvm_release.bat | 93 +++++++++++++++++++----
 1 file changed, 78 insertions(+), 15 deletions(-)

diff --git a/llvm/utils/release/build_llvm_release.bat 
b/llvm/utils/release/build_llvm_release.bat
index 231dafc395ada..74c2df9293c5c 100644
--- a/llvm/utils/release/build_llvm_release.bat
+++ b/llvm/utils/release/build_llvm_release.bat
@@ -382,6 +382,54 @@ cmake -GNinja %cmake_flags% ^
   -DPYTHON_HOME=%PYTHONHOME% ^
   %cmake_profile_flags% %llvm_src%\llvm || exit /b 1
 ninja || exit /b 1
+
+:: generate tarball with install toolchain only off
+if "%arch%"=="amd64" (
+  set filename=clang+llvm-%version%-x86_64-pc-windows-msvc
+) else (
+  set filename=clang+llvm-%version%-aarch64-pc-windows-msvc
+)
+REM LLVM_ENABLE_PDB flips the /Zi compile flag, which invalidates every
+REM object file from the build above and forces a full recompile+relink.
+REM That recompile does not depend on the test suite or WiX packaging
+REM below, so kick it off now in a separate build directory and let it
+REM run concurrently with them, hiding most/all of its wall-clock cost
+REM instead of paying for it serially at the end. LLVM_ENABLE_PDB is
+REM still never set for the MSI/WiX "ninja package" build below:
+REM bundling PDBs into the WiX-generated MSI causes CPack/WiX packaging
+REM failures, so PDBs are packaged separately as their own tarball
+REM instead.
+if "%enable-pdb%" == "true" (
+  cd ..
+  mkdir build_%arch%_pdb
+  cd build_%arch%_pdb
+  cmake -GNinja %cmake_flags% ^
+    -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra;lld;lldb;flang;mlir" ^
+    -DLLVM_ENABLE_RUNTIMES="compiler-rt;openmp" ^
+    %lto_cmake_flag% ^
+    %common_lldb_flags% ^
+    -DPYTHON_HOME=%PYTHONHOME% ^
+    %cmake_profile_flags% -DLLVM_INSTALL_TOOLCHAIN_ONLY=OFF ^
+    -DCMAKE_INSTALL_PREFIX=%build_dir%/%filename% ^
+    -DLLVM_ENABLE_PDB=ON ^
+    %llvm_src%\llvm || exit /b 1
+  del /q ..\pdb_build.done 2>nul
+  REM Use "start /min" (a genuinely separate, minimized console) rather
+  REM than "start /b" (which shares the parent's console/IO handles):
+  REM the background job's own console output can otherwise bleed into
+  REM and interleave with this foreground script's captured output
+  REM despite the ">" file redirection below, consistent with
+  REM console-handle contention between the two concurrently-running
+  REM processes. A dedicated console avoids sharing those handles at all.
+  REM "/v:on" + "^!errorlevel^!" (rather than "%%errorlevel%%") is
+  REM required so ninja's real exit code is captured. Without delayed
+  REM expansion, cmd.exe substitutes %errorlevel% once when the whole
+  REM "cmd1 & cmd2" line is parsed (before ninja even runs), so it would
+  REM always report the pre-existing errorlevel instead of ninja's
+  REM result.
+  start "pdb_build" /min cmd /v:on /c "ninja install > ..\pdb_build.log 2>&1 & 
echo ^!errorlevel^! > ..\pdb_build.done" < nul
+  cd ..\build_%arch%
+)
 ninja check-llvm || exit /b 1
 ninja check-clang || exit /b 1
 ninja check-lld || exit /b 1
@@ -395,23 +443,14 @@ REM ninja check-mlir || exit /b 1
 REM ninja check-lldb || exit /b 1
 ninja package || exit /b 1
 
-:: generate tarball with install toolchain only off
-if "%arch%"=="amd64" (
-  set filename=clang+llvm-%version%-x86_64-pc-windows-msvc
+if "%enable-pdb%" == "true" (
+  call :wait_for_pdb_build || exit /b 1
 ) else (
-  set filename=clang+llvm-%version%-aarch64-pc-windows-msvc
+  cmake -GNinja %cmake_flags% %cmake_profile_flags% 
-DLLVM_INSTALL_TOOLCHAIN_ONLY=OFF ^
+    -DCMAKE_INSTALL_PREFIX=%build_dir%/%filename% ^
+    %llvm_src%\llvm || exit /b 1
+  ninja install || exit /b 1
 )
-REM NOTE: LLVM_ENABLE_PDB is intentionally only set for this toolchain-only
-REM (tarball) reconfigure, not for the MSI/WiX "ninja package" build above:
-REM bundling PDBs into the WiX-generated MSI causes CPack/WiX packaging
-REM failures, so PDBs are packaged separately as their own tarball instead.
-set pdb_cmake_flag=
-if "%enable-pdb%" == "true" set pdb_cmake_flag=-DLLVM_ENABLE_PDB=ON
-cmake -GNinja %cmake_flags% %cmake_profile_flags% 
-DLLVM_INSTALL_TOOLCHAIN_ONLY=OFF ^
-  -DCMAKE_INSTALL_PREFIX=%build_dir%/%filename% ^
-  %pdb_cmake_flag% ^
-  %llvm_src%\llvm || exit /b 1
-ninja install || exit /b 1
 :: check llvm_config is present & returns something
 %build_dir%/%filename%/bin/llvm-config.exe --bindir || exit /b 1
 cd ..
@@ -430,6 +469,30 @@ if "%enable-pdb%" == "true" (
 
 exit /b 0
 
+::==============================================================================
+:: Poll for the concurrent PDB build kicked off earlier in this function to
+:: finish, and propagate its exit code. Must be a standalone function (not
+:: an inline goto/label inside a parenthesized if-block) since cmd.exe does
+:: not reliably support jumping to a label defined inside the same
+:: "( ... )" block.
+::==============================================================================
+:wait_for_pdb_build
+if not exist ..\pdb_build.done (
+  ping -n 6 127.0.0.1 >nul
+  goto :wait_for_pdb_build
+)
+REM Use "for /f" rather than "set /p" to read the exit code: "for /f"
+REM tokenizes on whitespace and strips it, whereas "set /p" would take any
+REM trailing spaces/junk in the file literally, breaking the "== 0" check
+REM below even when the underlying build actually succeeded.
+set pdb_build_rc=
+for /f %%r in (..\pdb_build.done) do set pdb_build_rc=%%r
+if not "%pdb_build_rc%" == "0" (
+  type ..\pdb_build.log
+  exit /b 1
+)
+exit /b 0
+
 
::==============================================================================
 :: Set PATH and some environment variables.
 
::==============================================================================

>From dfd643390cda6fce4f1495bdf26c701e9829d6d7 Mon Sep 17 00:00:00 2001
From: marcpems <[email protected]>
Date: Fri, 4 Sep 2026 14:36:38 +0100
Subject: [PATCH 4/4] Fix Windows release artifact bloat: strip FatLTO bitcode
 from .lib and stop PDB build polluting main archive

The CPack strip script only globbed lib/*.a, so Windows .lib archives kept
their embedded FatLTO bitcode. Separately, --enable-pdb reused the same
install prefix for both the PDB-enabled tree and the main archive, so the
main tarball inherited debug-heavy .lib members too. Together these
inflated Windows-ARM64-release-binary from ~1GB to ~6.8GB.

Fix: also strip .lib in the CPack pre-build script, and give the PDB build
its own -pdb-root install prefix with a clean, separate non-PDB install for
the main archive. Validated on GB300: main artifact 6.80 GiB -> 1.75 GiB,
PDB artifact correctly restored to 4.15 GiB.

Co-authored-by: Copilot <[email protected]>
---
 .../release_cpack_pre_build_strip_lto.cmake   |  4 ++-
 llvm/utils/release/build_llvm_release.bat     | 33 +++++++++++--------
 2 files changed, 23 insertions(+), 14 deletions(-)

diff --git a/clang/cmake/caches/release_cpack_pre_build_strip_lto.cmake 
b/clang/cmake/caches/release_cpack_pre_build_strip_lto.cmake
index e7d8830515439..633a226fae9c7 100644
--- a/clang/cmake/caches/release_cpack_pre_build_strip_lto.cmake
+++ b/clang/cmake/caches/release_cpack_pre_build_strip_lto.cmake
@@ -1,4 +1,6 @@
-file(GLOB files ${CPACK_TEMPORARY_INSTALL_DIRECTORY}/lib/*.a)
+file(GLOB files
+  ${CPACK_TEMPORARY_INSTALL_DIRECTORY}/lib/*.a
+  ${CPACK_TEMPORARY_INSTALL_DIRECTORY}/lib/*.lib)
 
 if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
   set(strip_command
diff --git a/llvm/utils/release/build_llvm_release.bat 
b/llvm/utils/release/build_llvm_release.bat
index 74c2df9293c5c..9f65d46e52839 100644
--- a/llvm/utils/release/build_llvm_release.bat
+++ b/llvm/utils/release/build_llvm_release.bat
@@ -389,6 +389,8 @@ if "%arch%"=="amd64" (
 ) else (
   set filename=clang+llvm-%version%-aarch64-pc-windows-msvc
 )
+set main_install_dir=%build_dir%/%filename%
+set pdb_install_dir=%build_dir%/%filename%-pdb-root
 REM LLVM_ENABLE_PDB flips the /Zi compile flag, which invalidates every
 REM object file from the build above and forces a full recompile+relink.
 REM That recompile does not depend on the test suite or WiX packaging
@@ -410,7 +412,7 @@ if "%enable-pdb%" == "true" (
     %common_lldb_flags% ^
     -DPYTHON_HOME=%PYTHONHOME% ^
     %cmake_profile_flags% -DLLVM_INSTALL_TOOLCHAIN_ONLY=OFF ^
-    -DCMAKE_INSTALL_PREFIX=%build_dir%/%filename% ^
+    -DCMAKE_INSTALL_PREFIX=%pdb_install_dir% ^
     -DLLVM_ENABLE_PDB=ON ^
     %llvm_src%\llvm || exit /b 1
   del /q ..\pdb_build.done 2>nul
@@ -445,24 +447,29 @@ ninja package || exit /b 1
 
 if "%enable-pdb%" == "true" (
   call :wait_for_pdb_build || exit /b 1
-) else (
-  cmake -GNinja %cmake_flags% %cmake_profile_flags% 
-DLLVM_INSTALL_TOOLCHAIN_ONLY=OFF ^
-    -DCMAKE_INSTALL_PREFIX=%build_dir%/%filename% ^
-    %llvm_src%\llvm || exit /b 1
-  ninja install || exit /b 1
 )
+cmake -GNinja %cmake_flags% %cmake_profile_flags% 
-DLLVM_INSTALL_TOOLCHAIN_ONLY=OFF ^
+  -DCMAKE_INSTALL_PREFIX=%main_install_dir% ^
+  %llvm_src%\llvm || exit /b 1
+ninja install || exit /b 1
 :: check llvm_config is present & returns something
-%build_dir%/%filename%/bin/llvm-config.exe --bindir || exit /b 1
+%main_install_dir%/bin/llvm-config.exe --bindir || exit /b 1
 cd ..
 if "%enable-pdb%" == "true" (
-  :: Package the PDB debug info files produced alongside the install tree
-  :: into their own archive so they can be uploaded as a separate artifact,
-  :: then delete them from the install tree so the main archive command
-  :: below does not compress them a second time.
+  :: Package PDBs from the separate PDB-enabled install tree so the main
+  :: archive can still come from the clean non-PDB install tree above.
   set pdb_filename=%filename%-pdb
-  pushd %filename%
+  REM Use a plain relative directory name here, not the absolute
+  REM %pdb_install_dir% path: on this runner "pushd" fails with
+  REM "The system cannot find the drive specified" when given an
+  REM absolute path that mixes backslash and forward-slash separators
+  REM (as %pdb_install_dir% does, since it's built with a "/" against
+  REM the backslash-based %build_dir%). cwd is already %build_dir%
+  REM (see "cd .." above), and %filename%-pdb-root is a direct child
+  REM of it, so the relative form below is equivalent and avoids the
+  REM issue entirely.
+  pushd %filename%-pdb-root
   7z a -ttar -so ..\!pdb_filename!.tar bin\*.pdb lib\*.pdb | 7z a -txz -si 
..\!pdb_filename!.tar.xz
-  del /s /q bin\*.pdb lib\*.pdb
   popd
 )
 7z a -ttar -so %filename%.tar %filename% | 7z a -txz -si %filename%.tar.xz

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to