LLVM Passes este un subsistem al framework-ului LLVM ce permite crearea de module simple pentru transformarea, prelucrarea și analiza codului intermediar LLVM IR
.
Există numeroase pass-uri deja implementate în versiunea oficială LLVM. Acestea primesc ca input cod LLVM IR
și oferă ca output fie LLVM IR
(în cazul în care este un pass de transformare), fie un text cu diverse statistici (în cazul în care este un pass de analiză).
LLVM Passes
pot fi rulate cu ajutorul tool-ului opt
.
student@cpl-vm ~ $ opt --help OVERVIEW: llvm .bc -> .bc modular optimizer and analysis printer USAGE: opt [options] <input bitcode file> OPTIONS: -O1 - Optimization level 1. Similar to clang -O1 -O2 - Optimization level 2. Similar to clang -O2 -O3 - Optimization level 3. Similar to clang -O3 -Os - Like -O2 with extra optimizations for size. Similar to clang -Os -Oz - Like -Os but reduces code size further. Similar to clang -Oz -S - Write output as LLVM assembly -analyze - Only perform analysis, no optimization -asm-instrumentation - Instrumentation of inline assembly and assembly source files =none - no instrumentation at all =address - instrument instructions with memory arguments -asm-show-inst - Emit internal instruction representation to assembly file Optimizations available: [...] -bb-vectorize - Basic-Block Vectorization -constprop - Simple constant propagation -da - Dependence Analysis -dce - Dead Code Elimination -domtree - Dominator Tree Construction -dot-callgraph - Print call graph to 'dot' file -dot-cfg - Print CFG of function to 'dot' file -dot-cfg-only - Print CFG of function to 'dot' file (with no function bodies) -dot-dom - Print dominance tree of function to 'dot' file -dot-dom-only - Print dominance tree of function to 'dot' file (with no function bodies) -dot-postdom - Print postdominance tree of function to 'dot' file -dot-postdom-only - Print postdominance tree of function to 'dot' file (with no function bodies) -instcount - Counts the various types of Instructions -loop-deletion - Delete dead loops -loop-reroll - Reroll loops -loop-rotate - Rotate Loops -loop-unroll - Unroll loops -loop-vectorize - Loop Vectorization -loops - Natural Loop Information -mem2reg - Promote Memory to Register -memdep - Memory Dependence Analysis -print-callgraph - Print a call graph -reg2mem - Demote all values to stack slots -sample-profile - Sample Profile loader -simplifycfg - Simplify the CFG -verify - Module Verifier -view-callgraph - View call graph -view-cfg - View CFG of function -view-cfg-only - View CFG of function (with no function bodies) -view-dom - View dominance tree of function -view-dom-only - View dominance tree of function (with no function bodies) -view-postdom - View postdominance tree of function -view-postdom-only - View postdominance tree of function (with no function bodies) -p - Print module after each transformation -stats - Enable statistics output from program (available with Asserts) -time-passes - Time each pass, printing elapsed time for each on exit [...]
Vom rula pass-ul default hello pe un cod simplu.
Codul sursă al pass-ului Hello din LLVM se găsește în directorul $LLVM_SRC/lib/Transforms/Hello
. Vizualizați codul sursă și makefile-ul. Pentru detalii suplimentare consultați pagina de manual.
După cum ați observat anterior, acesta nu este găsit by default de către tool-ul opt
. Va trebui să îi specificăm calea către biblioteca dinamică compilată.
student@cpl-vm ~/llvm-3.6.2 $ opt -load llvm-3.6.2/install/lib/LLVMHello.so --help OVERVIEW: llvm .bc -> .bc modular optimizer and analysis printer USAGE: opt [options] <input bitcode file> [...] -hello - Hello World Pass -hello2 - Hello World Pass (with getAnalysisUsage implemented) [...]
Fie următorul cod sursă C:
#include <stdio.h> int compute(int x) { return 10 + 4 * x; } int main(void) { int x = 10 * 12; printf("Printing something: %d\n", compute(x)); return 0; }
Vom genera fișierul .bc
corespunzător:
student@cpl-vm ~ $ clang -emit-llvm ex.c -c -o ex.bc
Vom rula pass-ul Hello
peste bitcode-ul obținut:
student@cpl-vm ~ $ opt -load llvm-3.6.2/install/lib/LLVMHello.so --hello < ex.bc WARNING: You're attempting to print out a bitcode file. This is inadvisable as it may cause display problems. If you REALLY want to taste LLVM bitcode first-hand, you can force output with the `-f' option. Hello: compute Hello: main
Pentru a nu mai fi nevoiți să specificăm biblioteca dinamică la runtime, aceasta trebuie să fie integrată în codul utilitarelor opt
și bugpoint
. Pentru a realiza acest lucru, trebuie să modificăm exemplul dat în sursele de LLVM astfel:
lib/Transforms/Hello/Makefile
tools/opt/CMakeLists.txt
tools/bugpoint/CMakeLists.txt
include/llvm/Transforms/Hello.h
cu conţinutul #ifndef LLVM_TRANSFORMS_HELLO_H #define LLVM_TRANSFORMS_HELLO_H namespace llvm { class FunctionPass; FunctionPass *createHelloPass(); } #endif
lib/Transforms/Hello/LLVMBuild.txt
după formatul din sistemul de build llvm.[component_0] type = Library name = Hello parent = Transforms library_name = hello required_libraries = Analysis Support
Hello
. lib/Transforms/Hello/CMakeLists.txt
lib/Transforms/Hello/Hello.cpp
FunctionPass* llvm::createHelloPass() { return new Hello(); }
include/llvm/LinkAllPasses.h
(void) llvm::createHelloPass();
cmake -G "Unix Makefiles" ../llvm-3.3.src
make