DragonEgg示例分析

DragonEgg示例分析

以下是使用gcc-4.5编译一个简单的“hello-world”程序的结果:

$ gcc hello.c -S -O1 -o -

       .file  "hello.c"

       .section  .rodata.str1.1,"aMS",@progbits,1

.LC0:

       .string     "Hello world!"

       .text

.globl main

       .type       main, @function

main:

       subq       $8, %rsp

       movl       $.LC0, %edi

       call  puts

       movl       $0, %eax

       addq      $8, %rsp

       ret

       .size main, .-main

       .ident     "GCC: (GNU) 4.5.0 20090928 (experimental)"

       .section  .note.GNU-stack,"",@progbits

在gcc命令行中添加-fplugin=path/dragonegg.so会导致程序被LLVM优化和编码:

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

        .file          "hello.c"

# Start of file scope inline assembly

        .ident       "GCC: (GNU) 4.5.0 20090928 (experimental) LLVM: 82450:82981"

# End of file scope inline assembly

        .text

        .align       16

        .globl       main

        .type        main,@function

main:

        subq        $8, %rsp

        movl        $.L.str, %edi

        call          puts

        xorl          %eax, %eax

        addq        $8, %rsp

        ret

        .size         main, .-main

        .type        .L.str,@object

        .section    .rodata.str1.1,"aMS",@progbits,1

.L.str:

        .asciz       "Hello world!"

        .size         .L.str, 13

        .section    .note.GNU-stack,"",@progbits

添加-fplugin arg dragonegg emit ir或-flto会导致输出LLVM ir(需要请求汇编程序输出-S,而不是对象代码输出-c,因为否则gcc会将LLVM ir传递给系统汇编程序,而系统汇编程序无疑无法对其进行汇编):

$ gcc hello.c -S -O1 -o - -fplugin=./dragonegg.so -fplugin-arg-dragonegg-emit-ir

; ModuleID = 'hello.c'

target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"

target triple = "x86_64-unknown-linux-gnu"

module asm "\09.ident\09\22GCC: (GNU) 4.5.0 20090928 (experimental) LLVM: 82450:82981\22"

@.str = private constant [13 x i8] c"Hello world!\00", align 1 ; <[13 x i8]*> [#uses=1]

define i32 @main() nounwind {

entry:

  %0 = tail call i32 @puts(i8* getelementptr inbounds ([13 x i8]* @.str, i64 0, i64 0)) nounwind ; <i32> [#uses=0]

  ret i32 0

}

declare i32 @puts(i8* nocapture) nounwind

获取DragonEgg-3.3源代码:

wget http://llvm.org/releases/3.3/dragonegg-3.3.src.tar.gz

打开包装:

tar xzf dragonegg--3.3.src.tar.gz

安装LLVM的3.3版,例如下载并安装适用于现有平台的LLVM-3.3二进制文件(称为clang二进制文件)。

确保安装了gcc-4.5、gcc-4.6、gcc-4.7或gcc-4.8(不需要构建自己的副本);gcc-4.6效果最好。在Debian和Ubuntu上,需要安装相应的插件开发包(gcc-4.5-plugin-dev、gcc-4.6-plugin-dev等)。

执行

       GCC=gcc-4.6 make

(如果使用gcc-4.6;否则用目前现存的gcc版本替换gcc-4.6)在dragonegg--3.3.src目录中应该构建dragonegg.so。如果LLVM二进制文件不在目前路径中,那么可以使用

GCC=gcc-4.6 LLVM_CONFIG=directory_where_llvm_installed/bin/llvm-config make

如果只构建了LLVM而没有安装它,那么仍然可以通过将LLVM_CONFIG设置为指向构建树中LLVM配置的副本来构建dragonegg。

要使用dragonegg.so,请使用gcc-4.6或使用的任何版本的gcc编译一些内容,在命令行中添加-fplugin=path_To_dragonegg/dragoneggso。

获取开发版本

获取DragonEgg开发版本的源代码:

svn http://llvm.org/svn/llvm-project/dragonegg/trunk

获取LLVM开发版本的源代码:

svn http://llvm.org/svn/llvm-project/llvm/trunkllvm

以通常的方式构建LLVM。

安装gcc-4.5、gcc-4.6、gcc-4.7或gcc-4.8(不需要构建自己的副本)。在Debian和Ubuntu上,需要安装相应的插件开发包(gcc-4.5-plugin-dev、gcc-4.6-plugin-dev等)。

执行

       GCC=place_you_installed_gcc/bin/gcc make

然后,在dragonegg目录中构建dragonegg.so。

要使用dragonegg.so,请使用刚安装的gcc版本编译一些组件,在命令行中添加-fplugin=path_to_dragonegg/dragonegg.so。
posted @ 2023-06-08 04:17  吴建明wujianming  阅读(26)  评论(0编辑  收藏  举报