2017-01-18 34 views
2

我想使用parseIRFile调用来解析用clang++ -S -emit-llvm test.cpp -o test.ir创建的IR文件,稍微操作此IR,然后将IR写回文件。LLVM:如何将IR写入文件并运行?

我试过使用WriteBitcodeToFile调用,但这不能按预期方式工作。

如何将模块写回IR,然后编译并运行修改的IR?

#include <llvm/IR/Module.h> 
#include <llvm/IRReader/IRReader.h> 
#include <llvm/IR/LLVMContext.h> 
#include <llvm/Support/SourceMgr.h> 
#include <llvm/Bitcode/ReaderWriter.h> 
#include <llvm/Support/FileSystem.h> 

using namespace llvm; 
int main() 
{ 
    LLVMContext context; 
    SMDiagnostic error; 
    std::unique_ptr<Module> m = parseIRFile("test.ir", error, context); 

    std::error_code EC; 
    llvm::raw_fd_ostream OS("module", EC, llvm::sys::fs::F_None); 
    WriteBitcodeToFile(m.get(), OS); 
    OS.flush(); 

    return 0; 
} 
+0

你说的 “不能按预期工作” 是什么意思? – Steeve

+0

当我打开文件时,内容看起来是二进制的? – Shuzheng

+0

@Shuzheng这只是IR的二进制编码。您可以使用'llvm-dis'来获取文本IR,但是您应该可以直接在二进制文件上使用'llc'来创建一个目标文件。 – TartanLlama

回答

1

IR是不可读的。您可以使用llvm-dis将其转换为像@TartanLlama所说的人类可读版本。您可以使用lli命令来运行位代码。修改IR后,您将看到修改后的IR使用lli运行。

+0

IR是人类可读的吗?在我看来,x86汇编看起来像alloca,store和ret这样的语句? – Shuzheng

+0

他们在谈论bitcode,通常'IR'是用于内存表示。 – Joky

+0

这不太好,但LLVM IR甚至Assembly在习惯之后都是“人类可读的”。位码表示是另一回事。 – Silverclaw

2

一个简单的方法来做到这一点是倾倒你的模块使用到标准输出:

m->dump(); 

然后你就可以在你的C++程序的输出重定向到一个文本文件,并使用LLC编译:

llc <sample_module.ll> sample_module.s 

您还可以使用打印功能:

void print (raw_ostream &OS, AssemblyAnnotationWriter *AAW, bool ShouldPreserveUseListOrder=false, bool IsForDebug=false) const 
0

您需要的是编写一个LLVM通道,该通道允许您按功能/模块按模块进行代码功能并读取/修改/写入。您可以使用opt命令在您的字节码文件上运行此传递,它将返回可以使用的已修改的字节码文件。

这里有一些源写了一通:

1)http://llvm.org/docs/WritingAnLLVMPass.html

2)https://www.cs.cornell.edu/~asampson/blog/llvm.html

+0

opt命令是否会返回带有插入指令等的位码文件?如果我在基本块中插入指令,会自动发生吗? – Shuzheng

+0

是的,如果您编写LLVM通道,以便将指令插入LLVM字节码中,那么使用''opt''运行该通道将返回修改后的字节码。这里'''opt'''用于在字节码上运行你的传递。例如,看看这一页上的'现在让通行证做些有趣的事情'部分 - https://www.cs.cornell.edu/~asampson/blog/llvm.html。这里的例子用''''''''操作用模块代码替换''''+'''操作。 – deLta

+0

您也可以使用'''clang'''通过使用-Xclang和-load标志的组合运行传球 – deLta