Open-Source Wikis

/

LLVM

/

Reference

/

Data models

llvm/llvm-project

Data models

A reference guide to the key in-memory data structures the LLVM project's components share. These are the things you'll see in printf-style debugging and on Module* and Value* parameters across most of the codebase.

LLVM IR

Hierarchy in llvm/include/llvm/IR/:

Module
└── Function
    └── BasicBlock
        └── Instruction (subclass of Value)
            └── operands: Value*

Module
└── GlobalVariable / GlobalAlias / GlobalIFunc (Value)

Constant (Value subclass)
├── ConstantInt, ConstantFP, ConstantStruct, ConstantArray, ConstantVector
├── ConstantExpr
└── GlobalValue (above)

Type (separate from Value)
├── IntegerType, FloatType, ...
├── PointerType (opaque pointers — pointee-less)
├── ArrayType, VectorType, StructType, FunctionType
└── ...

Metadata
├── MDNode
└── MDString

Key invariants:

  • IR is in SSA. Every value has exactly one definition.
  • Pointers are opaque as of recent versions — PointerType no longer carries a pointee type. The pointee is communicated through the operations themselves (e.g., the explicit type argument to load/store).
  • Memory dependences are explicit in load/store and in MemoryEffects attached to calls.
  • Instructions have a parent BasicBlock; BasicBlocks have a parent Function; Functions have a parent Module.

Pass manager

llvm/include/llvm/IR/PassManager.h:

  • PassManager<IRUnitT> — runs a pipeline over an IR unit (Module, Function, Loop, ...)
  • AnalysisManager<IRUnitT> — caches and invalidates analyses
  • PreservedAnalyses — what a pass promises not to invalidate

llvm/include/llvm/Passes/PassBuilder.h builds standard pipelines (default<O0>, default<O1>, default<O2>, default<O3>, default<Os>, default<Oz>, lto<O2>, thinlto<O2>).

MIR

Machine IR — the post-isel representation:

MachineFunction (in [llvm/include/llvm/CodeGen/MachineFunction.h](../../llvm/include/llvm/CodeGen/MachineFunction.h))
├── MachineBasicBlock (MBB)
│   ├── MachineInstr (MI)
│   │   ├── opcode (target-specific)
│   │   └── MachineOperand (register, immediate, MBB ref, MachineMemOperand, ...)
│   └── successors / predecessors / live-ins
├── MachineRegisterInfo (MRI) — virt regs, def-use, classes
├── MachineFrameInfo — stack slots, alignment
├── MachineFunctionInfo — per-function target hooks
└── MachineConstantPool, MachineJumpTableInfo

MIR is serializable as YAML for testing; see llvm/test/CodeGen/<Target>/ for .mir examples and update_mir_test_checks.py for the regenerator.

SelectionDAG

llvm/include/llvm/CodeGen/SelectionDAG/:

  • SelectionDAG — a DAG of SDNodes representing one basic block
  • SDNode — a single operation; carries an opcode (target-independent or target-specific), value types, and outgoing values
  • SDValue — a tuple of (SDNode*, result number)

MLIR

mlir/include/mlir/IR/:

Operation
├── Region (one or more)
│   └── Block
│       └── Operation
├── operands: Value
├── results: Value
├── attributes: NamedAttribute
└── successors (for terminator ops)

Type, Attribute, Dialect — all uniqued in MLIRContext

Distinctive features:

  • Operations are genericmlir::Operation is the storage; dialect-specific C++ classes are typed wrappers.
  • Regions and Blocks make MLIR a nested IR; control flow can be expressed structurally instead of as a CFG of basic blocks.
  • Types and attributes are first-class extensible objects with their own dialect membership.

Clang AST

clang/include/clang/AST/:

ASTContext (owns everything)
├── Decl hierarchy
│   ├── NamedDecl
│   │   ├── ValueDecl → VarDecl, FieldDecl, FunctionDecl
│   │   └── TypeDecl → TagDecl, TypedefNameDecl, TemplateTypeParmDecl, ...
│   └── DeclContext (mixin) — TranslationUnitDecl, NamespaceDecl, RecordDecl, FunctionDecl, ...
├── Stmt hierarchy
│   ├── Stmt → CompoundStmt, IfStmt, ForStmt, ReturnStmt, ...
│   └── Expr → BinaryOperator, CallExpr, MemberExpr, DeclRefExpr, ...
├── QualType / Type — every C/C++/ObjC type lives here
└── Source locations carried on every node via SourceLocation

Distinctive features (relative to other C++ ASTs):

  • Sugar is preserved (int declared via typedef/using keeps the alias visible until you explicitly getCanonicalType).
  • Templates are not desugared — Clang carries TemplateSpecializationType as a first-class type.
  • Macros, comments, and source locations are recoverable through the SourceManager.

Bitcode and on-disk formats

LLVM IR has two on-disk formats:

  • Textual .ll — round-trippable through llvm-as/llvm-dis. Stable across versions in nearly every case.
  • Bitcode .bc — compact binary. Subject to forward/backward compatibility within a "compatibility window" (typically several major versions).

MLIR uses bytecode (.mlirbc) for fast serialization and textual .mlir for human-readable round-trips.

Reference

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Data models – LLVM wiki | Factory