llvm學習(三)————如何編譯自己的第一個Pass

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ningxialieri/article/details/18265209

本文由博主原创,转载请注明出处(保證文章完整性,保留此处和链接):

 IT 人生http://blog.csdn.net/robinblog/article/details/18265209



 

        對llvm的pass研究有一段時間了,第一個pass的編寫比較簡單,可以直接從官網獲取(第一個pass) ,我獲取去的pass如下test.cpp,pass的意義在此不作過多解釋:

test$ cat test.cpp 

#include "llvm/Pass.h"
#include "llvm/Function.h"
#include "llvm/Support/raw_ostream.h"

using namespace llvm;

namespace {
    struct Test : public FunctionPass {
        static char ID;
        Test() : FunctionPass(ID) {}
        
        virtual bool runOnFunction(Function &F) {
            errs() << "Test: ";
            errs() << F.getName() << "\n";
            return false;
        }
    };
}

char  Test::ID = 0;
static RegisterPass<Test> X("test", "First test Pass");

         這裡的重點是說下編譯環境的構建,官網上給的編譯方法是在llvm源碼之中,lib/Transforms/Test下構建的,採用了一個Makefile。每次編譯pass就要整體編譯一下llvm源碼,博主感覺餓很煩。博主提供一句話編譯自己Pass的方法,如下

test$ `llvm-config --bindir`/clang  -shared  -fPIC `llvm-config --cxxflags`  `llvm-config --ldflags`  test.cpp -o libtest.so 


其中,

·llvm-config --bindir·/clang 表示clang的位置。

`llvm-config --cxxflags` 能夠列出llvm中的編譯選項。

`llvm-config --ldflags`    能夠列出llvm中的連接選項。

-shared 和 -fPIC 是爲了生成so文件。

llvm-config 官方介紹

        接著來測試一下我們的pass,測試文件如下HelloWorld.ll:

test$ cat HelloWorld.ll 
; ModuleID = 'HelloWorld.c'
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S128"
target triple = "i386-pc-linux-gnu"

@.str = private unnamed_addr constant [13 x i8] c"Hello LLVM!\0A\00", align 1

define void @p() nounwind {
entry:
  %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([13 x i8]* @.str, i32 0, i32 0))
  ret void
}

declare i32 @printf(i8*, ...)

define void @f() nounwind {
entry:
  call void @p()
  ret void
}

define i32 @main(i32 %argc, i8** %argv, i8** %envp) nounwind {
entry:
  %retval = alloca i32, align 4
  %argc.addr = alloca i32, align 4
  %argv.addr = alloca i8**, align 4
  %envp.addr = alloca i8**, align 4
  store i32 0, i32* %retval
  store i32 %argc, i32* %argc.addr, align 4
  store i8** %argv, i8*** %argv.addr, align 4
  store i8** %envp, i8*** %envp.addr, align 4
  call void @f()
  ret i32 0
}



 

        最後,來測試一下我們的pass,測試pass的方法如下:

test$ opt -load ./libtest.so -test < HelloWorld.ll > /dev/null 
Test: p
Test: f
Test: main







猜你喜欢

转载自blog.csdn.net/ningxialieri/article/details/18265209
今日推荐