Home / Alt manpages / llvm-opt-report-18(1)

  • llvm-opt-report-18(1)
  • User command
  • linux

Turn Clang Optimisation Records into a Readable Source Report

After this guide, you will have a text report that places Clang's recorded optimisation decisions beside the source lines they affected. The examples use the llvm-opt-report-18 installed by Ubuntu's llvm-18 package, version 1:18.1.3-1ubuntu1. Allow about ten minutes if Clang and the LLVM tools are already installed.

Before you start

You need a C or C++ source file, Clang, and the matching llvm-opt-report-18 executable. The report tool does not discover optimisation decisions by itself: a compiler must first write an optimisation record. The record is normally a file ending in .opt.yaml when produced by Clang with -fsave-optimization-record.

These commands do not need elevated privileges. Do not use sudo for the report: it only reads the record and source files and writes wherever your user can write.

1. Create an optimisation record

Compile your source with optimisation enabled and ask Clang to save its record. This example uses a small program so that the generated files and the later checks are easy to recognise.

cat > example.c <<'EOF'
int add(int a, int b) {
  return a + b;
}

int main(void) {
  return add(20, 22) != 42;
}
EOF

clang -c example.c -o example.o -O2 -fsave-optimization-record

Check that the record exists before moving on:

test -s example.opt.yaml && printf '%s\n' 'record ready'
llvm-opt-report-18 --version

On the stated installation, the second command reports Ubuntu LLVM version 18.1.3. If the first command fails, fix the compilation step first. A missing record is not something llvm-opt-report-18 can repair.

Checkpoint: the input is ready

You should now have example.c, example.o, and example.opt.yaml. The object file is not the report input; pass the optimisation record to the next command.

2. Generate a report file

Give the record as the input argument and choose an output file with -o. The output is a source listing with markers in the margin, rather than YAML.

llvm-opt-report-18 example.opt.yaml -o example.lst
sed -n '1,80p' example.lst

The report starts with a source-file marker and numbered lines. With the example above, the inlined add call is marked on the corresponding line, similar to:

< example.c
1   | int add(int a, int b) {
2   |   return a + b;
3   | }
4   |
5   | int main(void) {
6 I |   return add(20, 22) != 42;
7   | }

The exact set of markers depends on compiler version, target, optimisation level, and source. Do not treat an unmarked line as an error: it means this report has no displayed optimisation for that line.

3. Read the margin markers

The installed tool uses a small set of compact symbols. I means a function was inlined. U means a loop was unrolled; the following number is the unroll factor. V means a loop was vectorised; its following numbers describe the vector length and interleave factor.

If a source line appears twice for the same kind of optimisation, the pass was applied twice and made further progress on its second iteration. That is a report detail, not duplicated source.

For a less noisy view, use -s:

llvm-opt-report-18 -s example.opt.yaml -o example-without-factors.lst
sed -n '1,80p' example-without-factors.lst

This suppresses vectorisation factors and similar detail. It does not disable the compiler optimisation, and it does not change the input record.

Checkpoint: verify the report, not just the exit code

A successful exit status is 0, but a useful check also confirms that the report contains the source file and a marker you expect:

test -s example.lst
grep -F 'example.c' example.lst
grep -E ' [IUV][0-9, ]*\|' example.lst

If the final search finds nothing, inspect the full report rather than assuming the command failed. Your source may simply have produced no reportable inline, unroll, or vectorisation marker at the selected optimisation level.

Useful input and output variations

Omit the input filename, or use -, to read the record from standard input. Omit -o, or set its value to -, to write the report to standard output:

cat example.opt.yaml | llvm-opt-report-18 - | sed -n '1,20p'
llvm-opt-report-18 example.opt.yaml -o - | sed -n '1,20p'

Use --format=yaml for ordinary YAML records. The tool also accepts yaml-strtab and bitstream; select the format that matches the record you are supplying rather than guessing from its filename. For a record whose paths are relative to a different directory, -r PATH supplies the root used for those relative input paths.

Names in reports are demangled by default. Add --no-demangle when you need the original mangled function names, for example while matching compiler or linker diagnostics.

Common traps and recovery

  • Passing the object file: example.o is compiler output, not the optimisation record. Re-run the command with example.opt.yaml.
  • Running from the wrong directory: the record can refer to source paths that are not present from the current working directory. Run from the project root or use -r with the appropriate root.
  • Overwriting a useful report: -o example.lst replaces that file. Choose a new filename when comparing runs. If you overwrote it, regenerate it from the unchanged .opt.yaml; the report command does not alter the record.
  • Expecting every pass: this report focuses on the documented margin markers. Use the compiler's optimisation remarks when you need a different diagnostic view.

No service is changed by these commands. To undo the local example, remove only the files you created in its working directory after checking that nothing else uses them:

rm -f example.c example.o example.opt.yaml example.lst example-without-factors.lst

Done means

  • The installed command reports LLVM 18.1.3.
  • Clang produced a non-empty .opt.yaml record.
  • llvm-opt-report-18 generated a readable listing without an error.
  • You can identify I, U, and V markers and know when -s hides their factors.
  • You verified the output file and kept the original record for later comparisons.