LLVM和clang的工作流程
我只是LLVM和()网页以及堆栈溢出的初学者,我的研究员同事帮了我很多。 首先,我想说明我试图解决的问题,然后我将描述我解决问题所采取的方法。 那么,如果我遗漏了什么,我需要你的建议和指导 工作问题 我的输入是一个C程序,输出是输出文件中打印的前缀表示形式的SSA形式。 例如,如果C代码段为:LLVM和clang的工作流程,llvm,llvm-clang,llvm-ir,Llvm,Llvm Clang,Llvm Ir,我只是LLVM和()网页以及堆栈溢出的初学者,我的研究员同事帮了我很多。 首先,我想说明我试图解决的问题,然后我将描述我解决问题所采取的方法。 那么,如果我遗漏了什么,我需要你的建议和指导 工作问题 我的输入是一个C程序,输出是输出文件中打印的前缀表示形式的SSA形式。 例如,如果C代码段为: x=4; x++; z=x+7; 前缀表示中的输出SSA形式为: ( = x0 4) ( = x1 (+ x0 1) ) ( = z (x1 + 7) ) 现在请忽略实际的IR指令,只需假设我能够阅
x=4;
x++;
z=x+7;
前缀表示中的输出SSA形式为:
( = x0 4)
( = x1 (+ x0 1) )
( = z (x1 + 7) )
现在请忽略实际的IR指令,只需假设我能够阅读IR并将其转换为这种形式,还有一些额外的语句(我在这里不是为了可读性)
我使用LLVM的无知方法(请在下面找到完整的程序)
我的期望
我假设(根据我的理解)上述两个命令执行以下操作。
First clang接受程序someProgram.c并生成IR作为输出文件“test.bc”。
下一个命令opt,获取文件“test.bc”,然后一个接一个地应用所有上述过程,直到最后一个过程“-unroll allow partial”,它还链接我的库libTestPass.so(这个.so文件是在编译上面的ModulePass程序时生成的),然后,最后一个过程“-testPass”,我认为这就是我正在进行处理的过程(用于转换为SSA前缀表示)
你的建议和评论
我不确定LLVM是否真的按照我假设的顺序运行(我的预期)。如果我遗漏了什么或我的假设不正确,请发表评论。如有必要,请随时询问更多细节
当前面临的问题
我能够成功地转换大多数C程序,但在一个特定的程序上,我遇到了一些错误。调试这个错误使我认为我缺少了一些想法,或者我关于LLVM在clang和opt调用顺序方面的工作的假设是不正确的
非常感谢您的帮助。“我能够成功地转换大多数C程序,但在某个特定的程序中,我遇到了一些错误。”-什么错误?请将其全部粘贴。@schaiba:谢谢您对查询的回复。这里的问题不是什么大问题,因为我知道convertFunctionToSSA()函数出现问题的原因。我的主要查询是我如何运行“clang and opt”的顺序命令应该按照这个顺序运行。顺便说一句,我已经修复了我的错误。我刚刚将opt命令一个接一个地拆分为两个命令,如下所示:opt-O1-instnamer-mem2reg-simplifycfg-loops-lcssa-loop simplify-loop rotate-loop unroll-unroll count=15-unroll allow partial-o test1.bc太长了,读不下去了,01个负载SRC/LIbTestPas.SO TestPosits Test1.BC-O有一个TL,DR版本吗?我不确定我理解了所有文本杂乱的问题。
using namespace llvm;
namespace {
struct TestPass: public ModulePass {
IRssa::ptr ir_ssa = IRssa::ptr(new IRssa());
static char ID;
typedef std::list<std::pair<std::string, std::list<Instruction *> > > funcDump;
TestPass() : ModulePass(ID) { }
std::map<std::string, funcDump> workingList;
bool runOnModule(Module &M) {
std::string funcName, bkName;
for (Function &F : M) { //Found a new Function
if (isa<Function>(F) && !(F.getName().startswith("llvm."))) {
funcName = F.getName();
std::pair<std::string, std::list<Instruction *> > funcBlockList;
std::list<std::pair<std::string, std::list<Instruction *> > > wholeFuncBlocks;
for (BasicBlock &B : F) { //Blocks of the Function
if (isa<BasicBlock>(B)) {
bkName = B.getName();
}
std::list<Instruction *> listInst;
for (auto &I : B) {
Instruction *ins;
ins = &I;
listInst.push_back(ins);
}
funcBlockList.first = bkName;
funcBlockList.second = listInst;
wholeFuncBlocks.push_back(funcBlockList);
}
workingList[funcName] = wholeFuncBlocks;//Mapping of the functions
}
}
ir_ssa->setFunctionDump(workingList);
funcDump funcData;
funcData = workingList["start_program"]; //Starting from the start_program function
convertFunctionToSSA(funcData, ir_ssa);
std::ofstream outFile;
outFile.open("Out.ssa");
printSSA_toFile(outFile, ir_ssa);
return false;
}
};
}
char TestPass::ID = 0;
static RegisterPass<TestPass> X("testPass", "Testing A Pass");
static void registerTestPass(const PassManagerBuilder &, legacy::PassManagerBase &PM) {
PM.add(new TestPass());
}
static RegisterStandardPasses RegisterMyPass(PassManagerBuilder::EP_ModuleOptimizerEarly, registerTestPass);
static RegisterStandardPasses RegisterMyPass0(PassManagerBuilder::EP_EnabledOnOptLevel0, registerTestPass);
//Automatically enable the pass (http://adriansampson.net/blog/clangpass.html)
clang -O1 -g -Xclang -emit-llvm -c someProgram.c -o test.bc
opt -O1 -instnamer -mem2reg -simplifycfg -loops -lcssa -loop-simplify -loop-rotate -loop-unroll -unroll-count=15 -unroll-allow-partial -load src/libTestPass.so -testPass test.bc -o test