Skip to content

Commit 157b16a

Browse files
authored
Merge pull request #3524 from paschalis-mpeis/pgo-lp
Add PGO Learning Path
2 parents 0918486 + 964b428 commit 157b16a

10 files changed

Lines changed: 796 additions & 0 deletions

File tree

content/install-guides/llvm.md

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
---
2+
title: LLVM toolchain for Linux on Arm
3+
4+
additional_search_terms:
5+
- llvm
6+
- clang
7+
- compiler
8+
- lld
9+
- pgo
10+
- lto
11+
- profdata
12+
- profgen
13+
14+
minutes_to_complete: 10
15+
16+
author: Paschalis Mpeis
17+
18+
official_docs: https://releases.llvm.org/download.html
19+
description: Install the LLVM toolchain on Arm Linux to use Clang, LLD, and profiling utilities.
20+
21+
test_images:
22+
- ubuntu:latest
23+
test_maintenance: false
24+
25+
layout: installtoolsall
26+
tool_install: true
27+
multi_install: false
28+
multitool_install_part: false
29+
weight: 1
30+
---
31+
32+
The LLVM toolchain includes Clang, LLD, and other LLVM utilities for compiling, linking, and optimizing applications.
33+
34+
In this guide, you’ll learn how to download, extract, and install the LLVM toolchain from a prebuilt binary release on Arm Linux.
35+
36+
## Before you begin
37+
38+
Confirm you are using an Arm machine by running:
39+
40+
Run:
41+
42+
```bash
43+
uname -m
44+
```
45+
46+
The output is similar to:
47+
48+
```output
49+
aarch64
50+
```
51+
52+
If you see a different result, you are not using an Arm computer running 64-bit Linux.
53+
54+
Install the tools needed to download and extract the archive.
55+
For Debian-based Linux distributions, including Ubuntu, install `wget` and `xz-utils`:
56+
57+
58+
```bash { target="ubuntu:latest" }
59+
sudo apt update
60+
sudo apt install wget xz-utils -y
61+
```
62+
63+
## Install LLVM
64+
65+
You can install LLVM by downloading a prebuilt binary release from GitHub.
66+
67+
The following commands use LLVM version 22.1.8. To install a different version, replace the filename in the commands below. For the latest releases, see [LLVM Project releases](https://github.com/llvm/llvm-project/releases).
68+
69+
The commands extract LLVM to `$HOME/toolchain`. To install LLVM in a different location, adjust the extraction path and update the PATH environment variable accordingly.
70+
71+
1. Download a binary release
72+
73+
For Arm Linux, use the archive with `Linux-ARM64` in its filename:
74+
75+
76+
```bash
77+
mkdir -p $HOME/toolchain
78+
cd $HOME/toolchain
79+
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-22.1.8/LLVM-22.1.8-Linux-ARM64.tar.xz
80+
```
81+
82+
2. Extract the downloaded file
83+
84+
```bash
85+
tar -xvf LLVM-22.1.8-Linux-ARM64.tar.xz
86+
```
87+
88+
3. Add the LLVM `bin` directory to your `PATH`
89+
90+
This enables you to run LLVM tools such as `clang` and `lld` from any directory.
91+
The command updates `PATH` for your current terminal session.
92+
To make the change persistent, add the same command to your shell profile, such as `~/.bashrc`.
93+
94+
```bash
95+
export PATH="$HOME/toolchain/LLVM-22.1.8-Linux-ARM64/bin:$PATH"
96+
```
97+
## Verify LLVM is installed {#verify}
98+
99+
Run the following commands:
100+
101+
```console
102+
clang --version
103+
clang++ --version
104+
ld.lld --version
105+
```
106+
107+
The output is similar to:
108+
109+
```output
110+
clang version 22.1.8 (https://github.com/llvm/llvm-project ca7933e47d3a3451d81e72ac174dcb5aa28b59d1)
111+
Target: aarch64-unknown-linux-gnu
112+
Thread model: posix
113+
InstalledDir: /home/ubuntu/toolchain/LLVM-22.1.8-Linux-ARM64/bin
114+
115+
clang version 22.1.8 (https://github.com/llvm/llvm-project ca7933e47d3a3451d81e72ac174dcb5aa28b59d1)
116+
Target: aarch64-unknown-linux-gnu
117+
Thread model: posix
118+
InstalledDir: /home/ubuntu/toolchain/LLVM-22.1.8-Linux-ARM64/bin
119+
120+
LLD 22.1.8 (https://github.com/llvm/llvm-project ca7933e47d3a3451d81e72ac174dcb5aa28b59d1) (compatible with GNU linkers)
121+
```
122+
123+
Each command should print LLVM version information.
124+
125+
## Compile and run a C++ example
126+
127+
Use a text editor to copy and paste the following code into a file named `hello.cpp`:
128+
129+
```cpp { file_name="hello.cpp" }
130+
#include <iostream>
131+
132+
int main()
133+
{
134+
std::cout << "Hello, LLVM on Arm\n";
135+
return 0;
136+
}
137+
```
138+
139+
Compile the example with `clang++` and link it with LLD:
140+
141+
```bash
142+
clang++ -fuse-ld=lld hello.cpp -o hello
143+
```
144+
145+
Run the example:
146+
147+
```bash
148+
./hello
149+
```
150+
151+
The output is:
152+
153+
```output
154+
Hello, LLVM on Arm
155+
```
156+
157+
You are now ready to use LLVM on your Arm Linux system.
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
---
2+
title: "Optimize AArch64 code with LLVM LTO and PGO"
3+
4+
draft: true
5+
cascade:
6+
draft: true
7+
8+
description: Learn how to use LLVM Link-Time Optimization and Profile-Guided Optimization on AArch64 Linux.
9+
minutes_to_complete: 45
10+
11+
who_is_this_for: This is an introductory topic for developers who compile C or C++ applications on AArch64 Linux and want to use Link-Time Optimization (LTO) with Profile-Guided Optimization (PGO).
12+
13+
14+
learning_objectives:
15+
- Understand the basics of Link-Time Optimization (LTO) and Profile-Guided Optimization (PGO)
16+
- Build Thin-LTO and Full-LTO binaries with Clang on AArch64
17+
- Generate instrumentation-based profile data with Clang on AArch64
18+
- Generate sample-based profile data with Clang on AArch64
19+
- Use generated profile data to optimize a small example application
20+
21+
22+
prerequisites:
23+
- LLVM installed with Clang, LLD, `llvm-profdata`, and `llvm-profgen` available in your `PATH`. For setup instructions, see [LLVM toolchain for Linux on Arm](/install-guides/llvm/).
24+
- Linux kernel version 6.17 or later for the Branch Record Buffer Extension (BRBE) profile-guided optimization workflow
25+
26+
27+
author: Paschalis Mpeis
28+
29+
### Tags
30+
skilllevels: Introductory
31+
subjects: Performance and Architecture
32+
armips:
33+
- Neoverse
34+
- Cortex-A
35+
tools_software_languages:
36+
- Clang
37+
- LLVM
38+
- LTO
39+
- PGO
40+
- perf
41+
42+
operatingsystems:
43+
- Linux
44+
45+
further_reading:
46+
- resource:
47+
title: Clang profile-guided optimization
48+
link: https://clang.llvm.org/docs/UsersManual.html#profile-guided-optimization
49+
type: documentation
50+
- resource:
51+
title: llvm-profdata command guide
52+
link: https://llvm.org/docs/CommandGuide/llvm-profdata.html
53+
type: documentation
54+
- resource:
55+
title: llvm-profgen command guide
56+
link: https://llvm.org/docs/CommandGuide/llvm-profgen.html
57+
type: documentation
58+
- resource:
59+
title: LLVM LTO
60+
link: https://llvm.org/docs/LinkTimeOptimization.html
61+
type: documentation
62+
- resource:
63+
title: LLVM Thin-LTO
64+
link: https://clang.llvm.org/docs/Thin-LTO.html
65+
type: documentation
66+
67+
68+
### FIXED, DO NOT MODIFY
69+
# ================================================================================
70+
weight: 1 # _index.md always has weight of 1 to order correctly
71+
layout: "learningpathall" # All files under learning paths have this same wrapper
72+
learning_path_main_page: "yes" # This should be surfaced when looking for related content. Only set for _index.md of learning path content.
73+
---
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
# ================================================================================
3+
# FIXED, DO NOT MODIFY THIS FILE
4+
# ================================================================================
5+
weight: 21 # Set to always be larger than the content in this path to be at the end of the navigation.
6+
title: "Next Steps" # Always the same, html page title.
7+
layout: "learningpathall" # All files under learning paths have this same wrapper for Hugo processing.
8+
---
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
---
2+
title: Optimize with CSIR-PGO
3+
weight: 8
4+
5+
### FIXED, DO NOT MODIFY
6+
layout: learningpathall
7+
---
8+
9+
## What is CSIR-PGO?
10+
11+
CSIR-PGO extends IR-PGO by adding a second, context-sensitive profiling pass.
12+
The first pass is the standard IR-PGO instrumentation pass. The second pass instruments the program after inlining, which enables LLVM to distinguish execution counts from different calling contexts.
13+
The additional context can improve optimization when function behavior depends on the call site, but it does not guarantee better performance for every program.
14+
15+
Use CSIR-PGO when you want to provide LLVM with more detailed profile information and can afford an extra build and training run.
16+
17+
## Build the context-sensitive instrumented binary
18+
19+
First, generate a standard IR-PGO profile as described in the [previous section](/learning-paths/servers-and-cloud-computing/pgo/ir-pgo/).
20+
We reuse the resulting `prof/ir.profdata` profile to build a second instrumented binary with `-fcs-profile-generate`, which adds context-sensitive instrumentation after inlining.
21+
22+
```bash
23+
clang++ -O3 -flto -fuse-ld=lld \
24+
-fprofile-use=prof/ir.profdata \
25+
-fcs-profile-generate=prof/csir \
26+
bsort.cpp -o out/bsort.csirpgo.instr
27+
```
28+
29+
Run the context-sensitive instrumented binary:
30+
31+
```bash
32+
./out/bsort.csirpgo.instr
33+
```
34+
35+
After the program exits, the raw profiles are written to:
36+
37+
```bash
38+
ls prof/csir/*.profraw
39+
```
40+
41+
## Merge, Convert, and Inspect the profile
42+
43+
As with IR-PGO, the context-sensitive training run can produce one or more raw `.profraw` files. Merge those files together with the existing `prof/ir.profdata` profile using `llvm-profdata` before using the merged profile during the final optimized build.
44+
45+
46+
```bash
47+
llvm-profdata merge prof/ir.profdata prof/csir -output=prof/csir.profdata
48+
```
49+
50+
You can inspect the merged profile to see block counts. In the example below, the function `sort_array` has 6 context-sensitive counters with several recorded hits. You can inspect all functions with `--all-functions`, but the output can be extensive for large applications.
51+
52+
```bash { command_line="user@host | 2-13" }
53+
llvm-profdata show --showcs --counts --function=sort_array prof/csir.profdata
54+
Counters:
55+
ld-temp.o;_Z10sort_arrayPi:
56+
Hash: 0x18c2aba34f0cfff9
57+
Counters: 6
58+
Block counts: [24763682, 25224415, 9999, 9882, 1, 9881]
59+
Instrumentation level: IR entry_first = 0 instrument_loop_entries = 0
60+
Functions shown: 1
61+
Total functions: 12
62+
Maximum function count: 24763682
63+
Maximum internal block count: 25224415
64+
Total number of blocks: 32
65+
Total count: 75242276
66+
```
67+
68+
## Build with CSIR-PGO and LTO
69+
70+
Build the optimized binary using the merged CS-IR profile:
71+
72+
73+
```bash
74+
clang++ -O3 -flto -fuse-ld=lld -fprofile-use=prof/csir.profdata \
75+
bsort.cpp -o out/bsort.csirpgo.opt
76+
```
77+
78+
Run the optimized binary:
79+
80+
```bash { command_line="user@host | 2-3" }
81+
./out/bsort.opt.csir
82+
```
83+
84+
## What you've learned and what's next
85+
86+
You've added a second context-sensitive profiling pass on top of IR-PGO and built a CSIR-PGO optimized binary with LTO.

0 commit comments

Comments
 (0)