[英]Parsing and Modifying LLVM IR code
我想讀取(解析)LLVM IR代碼(保存在文本文件中)並添加一些我自己的代碼。 我需要一些這樣做的例子,也就是說,如何通過使用LLVM提供的庫來實現這一目的。 基本上我想要的是將IR代碼從文本文件讀入內存(也許LLVM庫以AST形式表示它,我不知道),進行修改,比如在AST中添加更多節點然后最后寫在IR文本文件中備份AST。
雖然我需要閱讀和修改IR代碼,但如果有人能夠提供或推薦我剛剛讀取(解析)它的一些示例,我將非常感激。
首先,要解決一個明顯的誤解:LLVM是一個用於處理IR格式代碼的框架。 看不到AST(*) - 您讀取IR,轉換/操作/分析它,然后寫回IR。
閱讀IR非常簡單:
int main(int argc, char** argv)
{
if (argc < 2) {
errs() << "Expected an argument - IR file name\n";
exit(1);
}
LLVMContext &Context = getGlobalContext();
SMDiagnostic Err;
Module *Mod = ParseIRFile(argv[1], Err, Context);
if (!Mod) {
Err.print(argv[0], errs());
return 1;
}
[...]
}
此代碼接受文件名。 這應該是LLVM IR文件(文本)。 然后它繼續將其解析為一個Module
,該模塊代表LLVM內部內存格式的IR模塊。 然后可以使用LLVM具有的各種傳遞來操作它,或者您自己添加。 查看LLVM代碼庫中的一些示例(例如lib/Transforms/Hello/Hello.cpp
)並閱讀此內容 - http://llvm.org/docs/WritingAnLLVMPass.html 。
將IR吐回文件更加容易。 Module
類只是將自己寫入流:
some_stream << *Mod;
而已。
現在,如果您對要對IR代碼進行的具體修改有任何具體問題,那么您應該提出更具針對性的問題。 我希望這個答案向您展示如何解析IR並將其寫回。
(*) IR在LLVM中沒有AST表示,因為它是一種簡單的匯編語言。 如果你向上一步,使用C或C ++,你可以使用Clang將其解析為AST,然后在AST級別進行操作。 然后Clang知道如何從AST生成LLVM IR。 但是,您必須從這里開始使用C / C ++,而不是LLVM IR。 如果你關心的是LLVM IR,那就忘了AST。
這通常通過實現LLVM傳遞/轉換來完成。 這樣你根本不需要解析IR,因為LLVM會為你做這件事,你將在面向對象的內存中表示IR。
這是編寫LLVM傳遞的入口點。 然后,您可以查看與LLVM捆綁在一起的任何已實現的標准傳遞(查看lib / Transforms )。
最簡單的方法是查看其中一個現有工具並從中竊取代碼。 在這種情況下,您可能希望查看llc的源代碼。 它可以采用bitcode或.ll文件作為輸入。 您可以以任何方式修改輸入文件,然后使用與llvm-dis中的代碼類似的內容寫出文件(如果需要文本文件)。
Opt工具采用llvm IR代碼,對其進行傳遞,然后在另一側吐出轉換后的llvm IR。
最容易開始的黑客攻擊是lib \\ Transforms \\ Hello \\ Hello.cpp。 破解它,以源文件作為輸入運行opt,檢查輸出。
除此之外,寫通行證的文件非常好。
如上所述,寫一個通行證的最佳方式。 但是如果你想簡單地遍歷指令並使用LLVM做一些提供InstVisitor類的東西。 它是一個實現指令的訪問者模式的類。 這對用戶來說非常簡單,所以如果你想避免學習如何實現一個傳遞,你可以訴諸於此。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.