This is an old revision of the document!


LLVM Passes

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ă).

Crearea unui Pass

LLVM Passes pot fi rulate cu ajutorul tool-ului opt.

Pass-uri existente

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
[...]

Hello World

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:

ex.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

Integrarea unui pas în LLVM

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
    • se şterge: LOADABLE_MODULE = 1
    • și se adaugă: BUILD_ARCHIVE = 1
  • tools/opt/CMakeLists.txt
    • se înlocuiește
      • set(LLVM_LINK_COMPONENTS bitreader asmparser bitwriter instrumentation scalaropts ipo vectorize) cu
      • set(LLVM_LINK_COMPONENTS bitreader asmparser bitwriter instrumentation scalaropts ipo vectorize hello)
  • tools/bugpoint/CMakeLists.txt
    • se înlocuiește
      • set(LLVM_LINK_COMPONENTS asmparser instrumentation scalaropts ipo linker bitreader bitwriter irreader vectorize objcarcopts) cu
      • set(LLVM_LINK_COMPONENTS asmparser instrumentation scalaropts ipo linker bitreader bitwriter irreader vectorize objcarcopts hello)
  • se crează fişierul 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/CMakeLists.txt
    • se şterge add_llvm_loadable_module( LLVMHello Hello.cpp )
    • și se adaugă
      • add_llvm_library( LLVMHello Hello.cpp )
      • target_link_libraries (LLVMHello LLVMSupport)
  • lib/Transforms/Hello/Hello.cpp
    • se include
      • llvm/Transforms/Hello.h
      • llvm/Support/Debug.h
    • se adaugă
      • FunctionPass* llvm::createHelloPass()
        {
           return new Hello();
        }
  • include/llvm/LinkAllPasses.h
    • se include llvm/Transforms/Hello.h
    • și se adaugă
      • (void) llvm::createHelloPass();
  • se creeaza un director nou în care vor fi compilate sursele. De exemplu dacă sursele se află în directorul llvm-3.3.src și am creat pe același nivel directorul llvm, executăm din interiorul directorului nou creat comanda
    • cmake -G "Unix Makefiles" ../llvm-3.3.src
    • urmată de comanda
       make 
cpl/labs/llvm-pass.1449525941.txt.gz · Last modified: 2015/12/08 00:05 by irina.presa
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0