欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

llvm常用工具的使用详解

程序员文章站 2022-03-25 17:27:37
...

llvm常用工具的使用详解

  1. 使用clang将C源码转换为LLVM IR:

    clang -emit-llvm -S test.c -o test.ll
    
  2. 使用llvm-as工具将LLVM IR转换为LLVM字节码:

    llvm-as test.ll -o test.bc
    

    LLVM IR的字节码形式可能是结构体被简单封装后的形式。字节码文件结构包含一个指示字节码文件偏移和大小的头文件。

  3. 将LLVM字节码转换为机器汇编码

    llc test.bc -o test.s
    clang -S test.bc -o test.s -fomit-frame-pointer
    

    使用llc命令可以在特定的机器上,将LLVM字节码转换为机器汇编码。如果llc命令中未指定任何机器架构的选项( -march=architecture ),默认以当前主机为目标机器架构。使用 -mcpu=cpu 选项指定关于cpu架构的信息。使用-regalloc=basic/greedy/fast/pbqp选项,可以指定寄存器分配的类型。

    此外,使用-fomit-frame-pointer选项,开启消除函数栈帧顶指针功能。clang默认是关闭此选项的,而llc默认是开启的。

    -fomit-frame-pointer

    ​ Omit the frame pointer in functions that don’t need one. This avoids the instructions to save, set up and restore the frame pointer; on many targets it also makes an extra register available.

    ​ On some targets this flag has no effect because the standard calling sequence always uses a frame pointer, so it cannot be omitted.

    ​ Note that -fno-omit-frame-pointer doesn’t guarantee the frame pointer is used in all functions. Several targets always omit the frame pointer in leaf functions.

    Note:

    ​ When stack frame sizes can differ, such as between different functions of between invocations of a particular function, popping a frame off the stack does no constitute a fixed decrement of the stack pointer. At function return, the stack pointer is instead restored to the frame pointer, the value of the stack pointer just before the function was called. Each stack frame contains a stack pointer to the top of the frame immediately below. The stack pointer is a mutable register shared between all invocations. A frame pointer of a give invocation of a function is a copy of the stack pointer as it was before the function was invoked.
    llvm常用工具的使用详解
    ​ The locations of all other fields in the frame can be defined relative either to the top of the frame, as negative offsets to the stack pointer, or relative to the top of the frame below, as positive offsets of the frame pointer. The location of the frame pointer itself must inherently be defined as a negative offset of the stack pointer. For more detail of call-stack , See:https://en.wikipedia.org/wiki/Call_stack

  4. 将LLVM字节码转换为LLVM IR

    llvm-dis test.bc -o test.ll
    
  5. 使用优化器opt,优化LLVM IR

    opt --passname input.ll -o output.ll
    

    opt是LLVM的优化器和分析工具。当使用-analyze选项时,opt将会对输入LLVM IR执行各种各样的分析,然后将结果输出到标准输出流或标准错误流。如果没有使用-analyze选项,opt会对输入文件做优化。更多关于优化器、优化选项、分析选项的信息,参考:http://llvm.org/docs/Passes.html

  6. 链接LLVM字节码文件

    clang -emit-llvm -S test1.c -o test1.ll
    clang -emit-llvm -S test2.c -o test2.ll
    llvm-as test1.ll -o test1.bc
    llvm-as test2.ll -o test2.bc
    llvm-link test1.bc test2.bc -o output.bc
    

    提供多个需要链接的字节码文件给llvm-link工具,它会将这些字节码文件链接生成一个新的字节码文件。上面的例子中,output.bc为llvm-link工具链接生成的文件。

    llvm-link 不是传统的链接器,链接各种对象文件以生成二进制文件。 llvm-link工具仅链接字节码文件。 链接了字节码文件后,我们可以通过llvm-link工具加上-S选项来将输出生成为IR文件。

  7. 执行LLVM字节码

    lli output.bc
    

    lli 使用JIT解释器执行字节码

  8. 使用Clang作为C语言前端

    clang -cc1 test.c -ast-dump
    

    -cc1选项保证,clang仅运行编译器前端,而不是clang-driver,然后输出语法分析树(AST)。

    clang test.c -S -emit-llvm -o -
    

    使用-S-emit-llvm 选项为test.c生成LLVM IR。-o - 使用这个选项可以将结果直接输出到屏幕。clang命令单独使用-S选项可以生成汇编码。

  9. 使用GO前端

    llgo是仅针对GO语言的编译器,使用该编译器前端生成LLVM IR的命令如下:

    llgo -dump test.go
    

    更多关于llgo信息,参考: https://github.com/go-llvm/llgo

  10. 使用DragonEgg

    ​ DragonEgg是gcc的一个插件,它允许gcc编译器使用LLVM优化器和代码生成。该插件必须在gcc 4.5及其以上的版本,并且在x86-32/x86-64和ARM处理器架构下运行。其次,还需要实现准备好dragonegg.so 文件。使用的命令如下:

    gcc test.c -S -O1 -o - -fplugin=./dragonegg.so
    

    更多关于DragonEgg的信息,参考:http://dragonegg.llvm.org/

相关标签: llvm 编译器