您的位置:首页 > 其它

llvm學習(一)————朦胧的感觉

2013-12-06 18:10 696 查看

做个开始标记:

在上大学的时候,就想拥有一个自己的博客,想要写出一些有质量的博文。现在回过头来,感到很失望,博文数量少,质量差。在这里将记录我的llvm学习之路,希望和朋友交流学习。

以前多多少少接触过一点llvm的东东,现在想要全面系统的学习一下。下面是我收集到的一些资料,提供链接。

下面两个链接,自认为可以让我们知道究竟什么是llvm,对llvm的框架做了概括的介绍,可以是我们对llvm有个整体把握。

使用 LLVM 框架创建一个工作编译器,第 1 部分 (在此附编译方法:test$ clang++ IRBuilder.cpp `llvm-config --cppflags --ldflags --libs core` -o IRBuilder)

使用 LLVM 框架创建有效的编译器,第 2 部分

下面两个链接是我学习写第一个pass所找的资料,希望对大家有帮助:

llvm官方提供的写pass的方法

一位台湾同胞写的第一个pass(自认为更适合llvm初学者) PS:众所周知的原因,该博文无法正常访问,我将其附在我的博文后面,如果可以访问,请尽量访问原作者博文。

官方llvm-programmer-s-manual文档的中文翻译

附录一 :LLVM 寫一個 pass - 教學入門篇

注意!! 這篇文章並非官方的 Writing an LLVM
Pass 的中文翻譯版本!!

而是精簡版, 採用建置方式是將 pass 的程式碼獨立於 LLVM 的 Source tree 外

這樣的好處是可避免與整串 LLVM 搞在一起, 並且對於整體建置流程會較為清楚

這篇文章對於讀者有些假設 :

已經會建置 LLVM (不會? 建置與安裝
LLVM + Clang)
對於 Makefile 有一點基礎知識 (沒有? 快來惡補)

1. 先從 LLVM 抄一個 Hello Pass

?
將上列程式碼儲存成 Hello.cpp 或著任何你喜歡的檔名

原程式碼上面有一些授權宣告跟註解, 基於文章版面配置將那部份移除, 其詳細授權見LLVM Developer Policy

說明?能建置成功前先把細節拋一邊吧

2. 建置 Makefile

?
把上面內容抄到與 Hello.cpp 同目錄下的 Makefile 中

注意一下 Makefile 建置動作前面的是 Tab 字元不是空白字元, 相當重要

這邊唯一要注意的是 LLVM_CONFIG 要設定為 你安裝的 llvm 路徑裡面的那個 llvm-config

例如 LLVM 裝在家目錄底下, 那麼 LLVM_CONFIG 就設定為 /home/kito/bin/llvm-config

3. 建置與測試
接著執行 make,

?
應該會吐出下面兩行

?
然後目錄下應該會出現 Hello.so 才對

?
接著寫個 Hello World 的小程式

?
將以上簡單內容存檔成 HelloWorld.c 接著把 Hello World 產生 .bc 檔, 加上 -emit-llvm 告訴 llvm 你要產生 bitcode

?
最後步驟就是把你的 HelloWorld.bc 丟到前面寫的 Hello Pass !

?
後面 -o /dev/null 的意思是叫 opt 把經過最佳化或分析的結果直接丟掉

執行完後 LLVM 就會跟你說 Hello 了!

?
main 是你 Hello World 中的 Function 名稱

4. 回頭看一下 Hello Pass
DEBUG_TYPE 是 LLVM 拿來統計該 pass 被呼叫幾次或著是使用 DEBUG 輸出除錯訊息的時候用的

?
include 要用到的 LLVM 的

?
把 llvm namespace 的東西都弄進來, 雖然這是不好的習慣, 不過由於方便起見直接 using 下去吧XD

?
匿名 namespace, 避免 export 裡面的 symbol,

聽無上一句在講啥就先跳過就可以了

?
Hello 繼承 FunctionPass, 代表 Hello Pass 的輸入是以 Function 為單位

?
現階段下面這行就照抄吧

給 LLVM 用來識別這個 Pass 的 id

?
Constructor

?
這邊則是整個 pass 的精華所在, LLVM 會以一次一個 Function 為單位, 餵進來給你玩

大致上裡面的行為就是將餵進來的 Function 的名稱印出來而已

其中 return false 是告訴 LLVM 你沒有修改任何東西

?
class 跟 namespace 的結束, 沒啥好說的

?
定義下一下 Hello::ID 的實體

?
跟 LLVM 註冊你的這個 Pass, 第一個參數是 pass name, 第二個則是說明用的文字

?
5. 解析 Makefile
先指定 llvm-config 執行檔的所在位置, 如果 llvm-config 已經加到 PATH 中的話那就填 llvm-config 就好

?
llvm-config 這隻程式可以幫你產生出大部分你所需的 flag

用 --help 可以檢視所有可用選項

?
指定編譯器使用 clang, 單純個人喜好XD

?
指定編譯的參數, 大部分從 llvm-config --cppflags 即可,

但由於我們現在是要編譯的是 Shared Library 所以要加 -fPIC

不知道 Shared Library 是啥? 快去弄一本程式設計師的自我修養來 K 阿~~

-fno-rtti 則是指定不產生 Run-time Typeinfo 的資訊,加了此選項後 typeid 及 dynamic_cast 會無法使用,基於實作成本 LLVM 在這方面有實作自己一套的 RTTI 機制

?
指定 Link 的參數, 大部分從 llvm-config --ldflags 即可,

現在是要編譯的是 Shared Library 所以加 -shared

?
我們總共要建置 hello.so

?
hello.so 怎麼生勒?, 生之前要先生出 Hello.o

然後下面一行則是建置規則

?
Hello.o 的建置規則, 以及其相依 Hello.cpp

?
寫 Makefile 時寫個 clean 的 rule 是個好習慣 :)

?
參考
[1] Writing an LLVM Pass

[2] 程式設計師的自我修養-連結、載入、程式庫

Update Note

(11/16) 在較新版的 llvm-config 無提供 -fno-rtti 選項,必須自行在 CXXFLAGS 那邊自行添加
(11/22) 上面提到那個項目目前不確定是 bug 還是怎樣,cmake 出來的 llvm-config 不會有 -fno-rtti,但 configure 建置出來的 llvm-config 則會有

張貼者: KITO's Lab 於 上午4:43
標籤: compiler, llvm, 教學
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: