[llvm] 0e6f9b2 - [docs] Parallelize Sphinx builds by default (#217161)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 19 11:09:50 PDT 2026
Author: Reid Kleckner
Date: 2026-08-19T18:09:44Z
New Revision: 0e6f9b26868c37cfb27fdc99af0524ed78e1dfd8
URL: https://github.com/llvm/llvm-project/commit/0e6f9b26868c37cfb27fdc99af0524ed78e1dfd8
DIFF: https://github.com/llvm/llvm-project/commit/0e6f9b26868c37cfb27fdc99af0524ed78e1dfd8.diff
LOG: [docs] Parallelize Sphinx builds by default (#217161)
Sphinx doc builds are slow now that we're using the furo theme. We can
speed them up by using the sphinx-build -j flag. This adds and documents
two new cmake options:
1. `LLVM_PARALLEL_SPHINX_JOBS`: Controls the sphinx-build ninja pool
depth, just like LLVM_PARALLEL_LINK_JOBS does.
2. `LLVM_SPHINX_BUILD_JOBS`: Controls the sphinx-build -j flag, which
controls internal parallelism. Defaults to nproc+1/2.
This is imperfect because we may oversubscribe the CPU with tasks, but
doc build actions are usually on the critical path at the end of the
build, or they are in large, non-incremental batch build actions that
build all targets. This approximate approach seems reasonable.
3-run hyperfine comparison for clean docs-llvm-html builds, removing the
html output and doctree cache before each timing run:
before (no sphinx -j): 97.897 s +/- 1.231 s
after (-j 8): 52.334 s +/- 15.348 s
speedup: 1.87x +/- 0.55x
The variance here was huge because I was doing a ton of other stuff in
the background.
Added:
Modified:
llvm/cmake/modules/AddSphinxTarget.cmake
llvm/docs/CMake.md
Removed:
################################################################################
diff --git a/llvm/cmake/modules/AddSphinxTarget.cmake b/llvm/cmake/modules/AddSphinxTarget.cmake
index 02a869b7941a9..6b3987cbbc7c0 100644
--- a/llvm/cmake/modules/AddSphinxTarget.cmake
+++ b/llvm/cmake/modules/AddSphinxTarget.cmake
@@ -4,6 +4,23 @@ include(GNUInstallDirs)
if (LLVM_ENABLE_SPHINX)
message(STATUS "Sphinx enabled.")
find_package(Sphinx REQUIRED)
+
+ # Sphinx has internal parallelism, so give it a custom job pool. Sphinx tends
+ # not to use all available CPU, so this is not enabled by default.
+ set(LLVM_PARALLEL_SPHINX_JOBS "" CACHE STRING
+ "Define the maximum number of concurrent sphinx-build invocations (Ninja only).")
+ if (LLVM_PARALLEL_SPHINX_JOBS)
+ if (CMAKE_GENERATOR MATCHES "Ninja")
+ get_property(_sphinx_job_pools GLOBAL PROPERTY JOB_POOLS)
+ if (NOT "sphinx_job_pool=${LLVM_PARALLEL_SPHINX_JOBS}" IN_LIST _sphinx_job_pools)
+ set_property(GLOBAL APPEND PROPERTY JOB_POOLS sphinx_job_pool=${LLVM_PARALLEL_SPHINX_JOBS})
+ endif()
+ set(sphinx_job_pool JOB_POOL sphinx_job_pool)
+ else()
+ message(WARNING "Job pooling is only available with Ninja generators.")
+ endif()
+ endif()
+
if (LLVM_BUILD_DOCS AND NOT TARGET sphinx)
add_custom_target(sphinx ALL)
set_target_properties(sphinx PROPERTIES FOLDER "LLVM/Docs")
@@ -136,6 +153,22 @@ function (add_sphinx_target builder project)
set(ARG_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
endif()
+ # Give Sphinx some internal job parallelism, since it tends to be on the
+ # critical path at the end of the build. This can speed up doc builds by
+ # ~80%. Sphinx rarely consumes all cores available, so it's safe to
+ # overallocate a bit.
+ if (NOT DEFINED LLVM_SPHINX_THREADS)
+ cmake_host_system_information(RESULT number_of_logical_cores
+ QUERY NUMBER_OF_LOGICAL_CORES)
+ math(EXPR LLVM_SPHINX_THREADS
+ "(${number_of_logical_cores} + 1) / 2")
+ endif()
+ set(LLVM_SPHINX_THREADS "${LLVM_SPHINX_BUILD_JOBS}"
+ CACHE STRING "Define the number of parallel jobs for each Sphinx build.")
+ if (LLVM_SPHINX_THREADS)
+ set(sphinx_jobs_flag -j ${LLVM_SPHINX_THREADS})
+ endif()
+
if ("${LLVM_VERSION_SUFFIX}" STREQUAL "git")
set(PreReleaseTag "-tPreRelease")
endif()
@@ -146,6 +179,7 @@ function (add_sphinx_target builder project)
${SPHINX_EXECUTABLE}
-b ${builder}
-d "${SPHINX_DOC_TREE_DIR}"
+ ${sphinx_jobs_flag}
-q # Quiet: no output other than errors and warnings.
-t builder-${builder} # tag for builder
-D version=${LLVM_VERSION_MAJOR}
@@ -154,6 +188,7 @@ function (add_sphinx_target builder project)
${SPHINX_WARNINGS_AS_ERRORS_FLAG} # Treat warnings as errors if requested
"${ARG_SOURCE_DIR}" # Source
"${SPHINX_BUILD_DIR}" # Output
+ ${sphinx_job_pool}
COMMENT
"Generating ${builder} Sphinx documentation for ${project} into \"${SPHINX_BUILD_DIR}\"")
get_subproject_title(subproject_title)
diff --git a/llvm/docs/CMake.md b/llvm/docs/CMake.md
index c64b419cd06ba..a87e20dd600a2 100644
--- a/llvm/docs/CMake.md
+++ b/llvm/docs/CMake.md
@@ -910,11 +910,11 @@ sub-projects. Nearly all of these variable names begin with `LLVM_`.
use during the build. Enabling this option can significantly speed up build
times, especially when building LLVM in Debug configurations.
-**LLVM_PARALLEL\_{COMPILE,LINK,TABLEGEN}\_JOBS**:STRING
+**LLVM_PARALLEL\_{COMPILE,LINK,TABLEGEN,SPHINX}\_JOBS**:STRING
-: Limit the maximum number of concurrent compilation, link or tablegen jobs
- respectively. The default total number of parallel jobs is determined by
- the number of logical CPUs.
+: Limit the maximum number of concurrent compilation, link, tablegen, or
+ `sphinx-build` invocations respectively. These limits are implemented with
+ Ninja job pools and only take effect when using a Ninja generator.
**LLVM_PROFDATA_FILE**:PATH
@@ -940,6 +940,13 @@ sub-projects. Nearly all of these variable names begin with `LLVM_`.
reverse order. This is useful for uncovering non-determinism caused by
iteration of unordered containers.
+**LLVM_SPHINX_THREADS**:STRING
+
+: Controls `sphinx-build -j`, which is the internal Sphinx worker count.
+ Defaults to half the number of logical cores, rounded up. The default is
+ high because Sphinx is often on the critical path, and rarely uses all
+ available cores. Set to an empty string to omit the Sphinx `-j` option.
+
**LLVM_STATIC_LINK_CXX_STDLIB**:BOOL
: Statically link to the C++ standard library if possible. This uses the flag
More information about the llvm-commits
mailing list