llc
Compile LLVM IR to assembly language
TLDR
Compile a bitcode or IR file to an assembly file with the same base name
Enable all optimizations
Output assembly to a specific file
Emit fully relocatable, position independent code
SYNOPSIS
llc [options] <input LLVM IR file>
PARAMETERS
-o <filename>
Specifies the output file name for the generated assembly or object code.
-march=<architecture>
Sets the target architecture (e.g., x86, arm, aarch64) for code generation.
-mcpu=<cpu>
Specifies the target CPU within the chosen architecture (e.g., haswell, cortex-a7), allowing for CPU-specific optimizations.
-filetype=<type>
Determines the type of output file. Common types are asm (assembly code), obj (object file), and null (discards output).
-O<level>
Applies optimization passes to the IR before code generation. Levels include 0 (no optimizations), 1, 2, 3 (increasing aggression), s (optimize for size), and z (optimize for even smaller size).
-mtriple=<triple>
Specifies the target triple, a string that uniquely identifies the target platform (e.g., x86_64-unknown-linux-gnu).
-help
Displays a comprehensive list of all available command-line options and their descriptions.
-version
Prints the version of the llc compiler.
DESCRIPTION
The llc command, part of the LLVM (Low Level Virtual Machine) project, is the LLVM static compiler. Its primary function is to transform LLVM Intermediate Representation (IR) into target-specific assembly code or object files. LLVM IR can be in text format (.ll files) or bitcode format (.bc files). llc is a crucial component in the LLVM compilation toolchain, typically invoked after front-ends like clang have converted source code (e.g., C, C++, Objective-C) into LLVM IR.
llc supports various target architectures and CPUs, allowing for cross-compilation. It can apply a wide range of optimizations specified by different optimization levels (e.g., -O0 for no optimizations, -O3 for aggressive optimizations). The output can be raw assembly code (.s files), which can then be assembled by a native assembler, or directly object files (.o files) suitable for linking. This modular design makes LLVM highly flexible and enables extensive analysis and transformation of the code at the IR level before final code generation. llc is essential for developers working with LLVM, compilers, or needing to generate highly optimized machine code for specific platforms.
CAVEATS
llc is part of the LLVM toolchain and requires LLVM to be installed on the system. It processes LLVM Intermediate Representation (IR), not direct high-level source code like C/C++ (that's handled by front-ends like clang). Therefore, input files must be valid LLVM IR (.ll or .bc format). Its capabilities for a specific target depend on how LLVM was compiled and what back-ends are enabled.
LLVM INTERMEDIATE REPRESENTATION (IR)
LLVM IR is a low-level, assembly-like language with strong type safety and explicit data flow, serving as the common intermediate representation for all LLVM front-ends and back-ends. It exists in three forms: human-readable assembly (.ll files), an in-memory representation, and a compact binary bitcode format (.bc files). llc consumes this IR to generate machine code.
COMPILATION WORKFLOW WITH LLVM
In a typical LLVM-based compilation, a front-end like clang first parses high-level source code (e.g., C/C++) and translates it into LLVM IR. This IR can then be optimized by tools like opt. Finally, llc takes this (potentially optimized) LLVM IR and generates the target-specific assembly code or object files, which are then linked to create an executable program. This modularity allows for powerful cross-language and cross-platform optimizations.
HISTORY
The llc command is an integral part of the LLVM compiler infrastructure, which originated in 2000 as a research project at the University of Illinois at Urbana-Champaign under the guidance of Chris Lattner. Its design emphasizes modularity and optimization, aiming to provide a universal, reusable compiler framework. llc was developed as the core component responsible for the final stage of code generation, translating the architecture-independent LLVM IR into machine-specific assembly or object code, enabling LLVM's widespread adoption for diverse platforms and languages.