blob: 57ca13c30a573a2557fc30b3c57b62296fb05044 [file] [log] [blame]
<!DOCTYPE HTML>
<html lang="en" class="light sidebar-visible" dir="ltr">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Optimized build - Rust Compiler Development Guide</title>
<!-- Custom HTML head -->
<meta name="description" content="A guide to developing the Rust compiler (rustc)">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff">
<link rel="icon" href="../favicon.svg">
<link rel="shortcut icon" href="../favicon.png">
<link rel="stylesheet" href="../css/variables.css">
<link rel="stylesheet" href="../css/general.css">
<link rel="stylesheet" href="../css/chrome.css">
<link rel="stylesheet" href="../css/print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="../fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" id="highlight-css" href="../highlight.css">
<link rel="stylesheet" id="tomorrow-night-css" href="../tomorrow-night.css">
<link rel="stylesheet" id="ayu-highlight-css" href="../ayu-highlight.css">
<!-- Custom theme stylesheets -->
<link rel="stylesheet" href="../pagetoc.css">
<!-- Provide site root and default themes to javascript -->
<script>
const path_to_root = "../";
const default_light_theme = "light";
const default_dark_theme = "navy";
window.path_to_searchindex_js = "../searchindex.js";
</script>
<!-- Start loading toc.js asap -->
<script src="../toc.js"></script>
</head>
<body>
<div id="mdbook-help-container">
<div id="mdbook-help-popup">
<h2 class="mdbook-help-title">Keyboard shortcuts</h2>
<div>
<p>Press <kbd></kbd> or <kbd></kbd> to navigate between chapters</p>
<p>Press <kbd>S</kbd> or <kbd>/</kbd> to search in the book</p>
<p>Press <kbd>?</kbd> to show this help</p>
<p>Press <kbd>Esc</kbd> to hide this help</p>
</div>
</div>
</div>
<div id="body-container">
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script>
try {
let theme = localStorage.getItem('mdbook-theme');
let sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') && theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
</script>
<!-- Set the theme before any content is loaded, prevents flash -->
<script>
const default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? default_dark_theme : default_light_theme;
let theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
const html = document.documentElement;
html.classList.remove('light')
html.classList.add(theme);
html.classList.add("js");
</script>
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
<!-- Hide / unhide sidebar before it is displayed -->
<script>
let sidebar = null;
const sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
} else {
sidebar = 'hidden';
sidebar_toggle.checked = false;
}
if (sidebar === 'visible') {
sidebar_toggle.checked = true;
} else {
html.classList.remove('sidebar-visible');
}
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<!-- populated by js -->
<mdbook-sidebar-scrollbox class="sidebar-scrollbox"></mdbook-sidebar-scrollbox>
<noscript>
<iframe class="sidebar-iframe-outer" src="../toc.html"></iframe>
</noscript>
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
<div class="sidebar-resize-indicator"></div>
</div>
</nav>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky">
<div class="left-buttons">
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</label>
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
<i class="fa fa-paint-brush"></i>
</button>
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
<li role="none"><button role="menuitem" class="theme" id="default_theme">Auto</button></li>
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
<button id="search-toggle" class="icon-button" type="button" title="Search (`/`)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="/ s" aria-controls="searchbar">
<i class="fa fa-search"></i>
</button>
</div>
<h1 class="menu-title">Rust Compiler Development Guide</h1>
<div class="right-buttons">
<a href="../print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
<a href="https://github.com/rust-lang/rustc-dev-guide" title="Git repository" aria-label="Git repository">
<i id="git-repository-button" class="fa fa-github"></i>
</a>
<a href="https://github.com/rust-lang/rustc-dev-guide/edit/main/src/building/optimized-build.md" title="Suggest an edit" aria-label="Suggest an edit" rel="edit">
<i id="git-edit-button" class="fa fa-edit"></i>
</a>
</div>
</div>
<div id="search-wrapper" class="hidden">
<form id="searchbar-outer" class="searchbar-outer">
<div class="search-wrapper">
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
<div class="spinner-wrapper">
<i class="fa fa-spinner fa-spin"></i>
</div>
</div>
</form>
<div id="searchresults-outer" class="searchresults-outer hidden">
<div id="searchresults-header" class="searchresults-header"></div>
<ul id="searchresults">
</ul>
</div>
</div>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script>
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
</script>
<div id="content" class="content">
<main>
<h1 id="optimized-build-of-the-compiler"><a class="header" href="#optimized-build-of-the-compiler">Optimized build of the compiler</a></h1>
<p>There are multiple additional build configuration options and techniques that can be used to compile a
build of <code>rustc</code> that is as optimized as possible (for example when building <code>rustc</code> for a Linux
distribution). The status of these configuration options for various Rust targets is tracked <a href="https://github.com/rust-lang/rust/issues/103595">here</a>.
This page describes how you can use these approaches when building <code>rustc</code> yourself.</p>
<h2 id="link-time-optimization"><a class="header" href="#link-time-optimization">Link-time optimization</a></h2>
<p>Link-time optimization is a powerful compiler technique that can increase program performance. To
enable (Thin-)LTO when building <code>rustc</code>, set the <code>rust.lto</code> config option to <code>"thin"</code>
in <code>bootstrap.toml</code>:</p>
<pre><code class="language-toml">[rust]
lto = "thin"
</code></pre>
<blockquote>
<p>Note that LTO for <code>rustc</code> is currently supported and tested only for
the <code>x86_64-unknown-linux-gnu</code> target. Other targets <em>may</em> work, but no guarantees are provided.
Notably, LTO-optimized <code>rustc</code> currently produces <a href="https://github.com/rust-lang/rust/issues/109114">miscompilations</a> on Windows.</p>
</blockquote>
<p>Enabling LTO on Linux has <a href="https://github.com/rust-lang/rust/pull/101403#issuecomment-1288190019">produced</a> speed-ups by up to 10%.</p>
<h2 id="memory-allocator"><a class="header" href="#memory-allocator">Memory allocator</a></h2>
<p>Using a different memory allocator for <code>rustc</code> can provide significant performance benefits. If you
want to enable the <code>jemalloc</code> allocator, you can set the <code>rust.jemalloc</code> option to <code>true</code>
in <code>bootstrap.toml</code>:</p>
<pre><code class="language-toml">[rust]
jemalloc = true
</code></pre>
<blockquote>
<p>Note that this option is currently only supported for Linux and macOS targets.</p>
</blockquote>
<h2 id="codegen-units"><a class="header" href="#codegen-units">Codegen units</a></h2>
<p>Reducing the amount of codegen units per <code>rustc</code> crate can produce a faster build of the compiler.
You can modify the number of codegen units for <code>rustc</code> and <code>libstd</code> in <code>bootstrap.toml</code> with the
following options:</p>
<pre><code class="language-toml">[rust]
codegen-units = 1
codegen-units-std = 1
</code></pre>
<h2 id="instruction-set"><a class="header" href="#instruction-set">Instruction set</a></h2>
<p>By default, <code>rustc</code> is compiled for a generic (and conservative) instruction set architecture
(depending on the selected target), to make it support as many CPUs as possible. If you want to
compile <code>rustc</code> for a specific instruction set architecture, you can set the <code>target_cpu</code> compiler
option in <code>RUSTFLAGS</code>:</p>
<pre><code class="language-bash">RUSTFLAGS="-C target_cpu=x86-64-v3" ./x build ...
</code></pre>
<p>If you also want to compile LLVM for a specific instruction set, you can set <code>llvm</code> flags
in <code>bootstrap.toml</code>:</p>
<pre><code class="language-toml">[llvm]
cxxflags = "-march=x86-64-v3"
cflags = "-march=x86-64-v3"
</code></pre>
<h2 id="profile-guided-optimization"><a class="header" href="#profile-guided-optimization">Profile-guided optimization</a></h2>
<p>Applying profile-guided optimizations (or more generally, feedback-directed optimizations) can
produce a large increase to <code>rustc</code> performance, by up to 15% (<a href="https://blog.rust-lang.org/inside-rust/2020/11/11/exploring-pgo-for-the-rust-compiler.html#final-numbers-and-a-benchmarking-plot-twist">1</a>, <a href="https://github.com/rust-lang/rust/pull/96978">2</a>). However, these techniques
are not simply enabled by a configuration option, but rather they require a complex build workflow
that compiles <code>rustc</code> multiple times and profiles it on selected benchmarks.</p>
<p>There is a tool called <code>opt-dist</code> that is used to optimize <code>rustc</code> with <a href="https://doc.rust-lang.org/rustc/profile-guided-optimization.html">PGO</a> (profile-guided
optimizations) and <a href="https://github.com/llvm/llvm-project/blob/main/bolt/README.md">BOLT</a> (a post-link binary optimizer) for builds distributed to end users. You
can examine the tool, which is located in <code>src/tools/opt-dist</code>, and build a custom PGO build
workflow based on it, or try to use it directly. Note that the tool is currently quite hardcoded to
the way we use it in Rust's continuous integration workflows, and it might require some custom
changes to make it work in a different environment.</p>
<p>To use the tool, you will need to provide some external dependencies:</p>
<ul>
<li>A Python3 interpreter (for executing <code>x.py</code>).</li>
<li>Compiled LLVM toolchain, with the <code>llvm-profdata</code> binary. Optionally, if you want to use BOLT,
the <code>llvm-bolt</code> and
<code>merge-fdata</code> binaries have to be available in the toolchain.</li>
</ul>
<p>These dependencies are provided to <code>opt-dist</code> by an implementation of the <a href="https://github.com/rust-lang/rust/blob/ee451f8faccf3050c76cdcd82543c917b40c7962/src/tools/opt-dist/src/environment.rs#L5"><code>Environment</code></a> struct.
It specifies directories where will the PGO/BOLT pipeline take place, and also external dependencies
like Python or LLVM.</p>
<p>Here is an example of how can <code>opt-dist</code> be used locally (outside of CI):</p>
<ol>
<li>Enable metrics in your <code>bootstrap.toml</code> file, because <code>opt-dist</code> expects it to be enabled:
<pre><code class="language-toml">[build]
metrics = true
</code></pre>
</li>
<li>Build the tool with the following command:
<pre><code class="language-bash">./x build tools/opt-dist
</code></pre>
</li>
<li>Run the tool with the <code>local</code> mode and provide necessary parameters:
<pre><code class="language-bash">./build/host/stage1-tools-bin/opt-dist local \
--target-triple &lt;target&gt; \ # select target, e.g. "x86_64-unknown-linux-gnu"
--checkout-dir &lt;path&gt; \ # path to rust checkout, e.g. "."
--llvm-dir &lt;path&gt; \ # path to built LLVM toolchain, e.g. "/foo/bar/llvm/install"
-- python3 x.py dist # pass the actual build command
</code></pre>
You can run <code>--help</code> to see further parameters that you can modify.</li>
</ol>
<blockquote>
<p>Note: if you want to run the actual CI pipeline, instead of running <code>opt-dist</code> locally,
you can execute <code>cargo run --manifest-path src/ci/citool/Cargo.toml run-local dist-x86_64-linux</code>.</p>
</blockquote>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../building/new-target.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../tests/intro.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="../building/new-target.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../tests/intro.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
</div>
<script>
window.playground_copyable = true;
</script>
<script src="../elasticlunr.min.js"></script>
<script src="../mark.min.js"></script>
<script src="../searcher.js"></script>
<script src="../clipboard.min.js"></script>
<script src="../highlight.js"></script>
<script src="../book.js"></script>
<!-- Custom JS scripts -->
<script src="../mermaid.min.js"></script>
<script src="../mermaid-init.js"></script>
<script src="../pagetoc.js"></script>
</div>
</body>
</html>