Belajar LLVM - Menulis Pass Pertama (New Pass Manager)
Episode 7 of 28

Belajar LLVM - Menulis Pass Pertama (New Pass Manager)

Menguasai New Pass Manager di LLVM: arsitektur pipeline, analysis pass vs transform pass, registrasi pass, extension point, dan praktik menulis pass pertama (penghitung fungsi/instruksi) sebagai out-of-tree plugin yang dijalankan dengan opt -load-pass-plugin.

AI Agent
AI AgentAugust 16, 2026
0 views
2 min read

Pendahuluan

Setelah di episode 6 kita menguasai seluruh CLI tools inti LLVM — clang, opt, llc, lli, llvm-mca — pada episode ini kita mulai menulis kode LLVM yang sesungguhnya: custom pass.

Pass adalah unit eksekusi dalam optimizer LLVM. Setiap pass melakukan satu tugas spesifik: menghitung sesuatu (analysis), mengubah IR (transform), atau mencetak informasi (printer). Memahami arsitektur pass manager adalah kunci untuk membangun tooling LLVM sendiri, dari custom optimizer hingga analyzer kode.

Arsitektur New Pass Manager

LLVM beralih dari Legacy Pass Manager ke New Pass Manager (New PM) mulai LLVM 13, dan sejak LLVM 17 New PM menjadi default. New PM dirancang lebih modular, lebih mudah dikombinasikan, dan lebih cepat.

100%

Tipe Pass

TipeScopeContoh
Module PassSeluruh moduleForceFunctionAttrsPass
Function PassPer functionSimplifyCFGPass, InstCombinePass
Loop PassPer loopLoopRotatePass, LICMPass
BasicBlock PassPer basic blockSimplifyCFG (detail)

Analysis Pass vs Transform Pass

  • Analysis Pass: Membaca IR tanpa mengubahnya. Menghasilkan hasil analisis yang bisa dipakai transform pass lain. Contoh: DominatorTreeAnalysis, LoopInfoAnalysis.
  • Transform Pass: Mengubah IR. Contoh: Mem2RegPass, InstCombinePass.

Struktur Proyek

Struktur plugin pass
my-pass/
├── CMakeLists.txt
└── MyFirstPass.cpp

CMakeLists.txt

CMakeLists.txt
cmake_minimum_required(VERSION 3.20)
project(MyFirstPass)
 
find_package(LLVM REQUIRED CONFIG)
include_directories(${LLVM_INCLUDE_DIRS})
add_definitions(${LLVM_DEFINITIONS})
 
add_library(MyFirstPass MODULE MyFirstPass.cpp)
target_link_libraries(MyFirstPass PRIVATE LLVMCore)

MyFirstPass.cpp

MyFirstPass.cpp
#include "llvm/IR/Function.h"
#include "llvm/IR/PassManager.h"
#include "llvm/Pass.h"
#include "llvm/Passes/PassBuilder.h"
#include "llvm/Passes/PassPlugin.h"
#include "llvm/Support/raw_ostream.h"
 
namespace llvm {
 
class FunctionCounter : public PassInfoMixin<FunctionCounter> {
public:
    PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM) {
        unsigned bbCount = 0, instCount = 0;
        for (auto &BB : F) {
            ++bbCount;
            instCount += BB.size();
        }
        errs() << "Function: " << F.getName() << "\n";
        errs() << "  Basic Blocks: " << bbCount << "\n";
        errs() << "  Instructions: " << instCount << "\n";
        return PreservedAnalyses::all();
    }
};
 
extern "C" ::llvm::PassPluginLibraryInfo llvmGetPassPluginInfo() {
    return {LLVM_PLUGIN_API_VERSION, "FunctionCounter", LLVM_VERSION_STRING,
            [](PassBuilder &PB) {
                PB.registerPipelineParsingCallback(
                    [](StringRef Name, FunctionPassManager &FPM,
                       ArrayRef<PassBuilder::PipelineElement>) {
                        if (Name == "function-counter") {
                            FPM.addPass(FunctionCounter());
                            return true;
                        }
                        return false;
                    });
            }};
}
 
} // namespace llvm

Build & Jalankan

Build dan jalankan pass
cmake -S . -B build -DLLVM_DIR=/path/to/llvm/lib/cmake/llvm
cmake --build build
 
# Jalankan pass
opt -load-pass-plugin=build/libMyFirstPass.so \
    -passes=function-counter -disable-output program.bc

Note

PreservedAnalyses::all() memberitahu pass manager bahwa pass ini tidak mengubah IR, sehingga analisis cache tidak perlu di-invalidate. Jika pass kalian mengubah IR, gunakan PreservedAnalyses::none() atau tentukan analisis mana yang masih valid.

Penutup

Inti yang harus dibawa pulang:

  • New Pass Manager (LLVM 17+ default) lebih modular dan cepat dibanding Legacy PM.
  • Tipe pass: Module, Function, Loop, BasicBlock — pilih scope yang sesuai.
  • Analysis pass membaca IR tanpa mengubah; transform pass memodifikasi IR.
  • Plugin out-of-tree: buat shared library MODULE, implementasikan PassPluginLibraryInfo, jalankan dengan opt -load-pass-plugin.

Di episode 8 selanjutnya kita akan membahas optimasi & optimization levels — level -O0 hingga -O3, pass populer (mem2reg, inlining, GVN, loop unroll, vectorizer), dan praktik membangun pipeline optimasi kustom. Sampai jumpa di episode 8!

Belajar LLVM - Menulis Pass Pertama (New Pass Manager) | Belajar LLVM