我通过llvm pass将调试信息添加到基本块的第一条和最后一条指令中,然后成功地在程序集代码中找到添加的信息。但是,第一指令和最后指令的信息量是不同的。
我想知道结果是否正确,如果是正确的,为什么数字是不同的,以及如何正确地在装配代码中得到块的边界?
我通行证的密码
bool runOnFunction(Function &F) override {
unsigned start = 2333;
unsigned end = 23333;
MDNode *N = F.getMetadata("dbg");
for (BasicBlock &B : F) {
errs() << "Hello: ";
Instruction *I = B.getFirstNonPHI();
DebugLoc loc = DebugLoc::get(start, 0, N);
if (loc && I!=NULL) {
I->setDebugLoc(loc);
} else {
errs() << "start error";
}
I = B.getTerminator();
loc = DebugLoc::get(end, 1, N);
if (loc && I!= NULL) {
I->setDebugLoc(loc);
} else {
errs() << "end error";
}
errs() << "\n";
}
return true;
}
};
} 它运行时没有任何错误。其中一些结果是:
# %bb.2: # %for.body
# in Loop: Header=BB0_1 Depth=1
.loc 1 2333 0 # myls.c:2333:0
movl -4(%ebp), %eax
.Ltmp4:
.loc 1 71 14 # myls.c:71:14
movl %eax, -8(%ebp)
.Ltmp5:
.LBB0_3: # %for.cond1
# Parent Loop BB0_1 Depth=1
# => This Inner Loop Header: Depth=2
.loc 1 2333 0 # myls.c:2333:0
movl -8(%ebp), %eax
.Ltmp6:
.loc 1 71 18 # myls.c:71:18
cmpl n, %eax
.Ltmp7:
.loc 1 23333 1 # myls.c:23333:1
jge .LBB0_13
......
LBB2_10: # %sw.epilog
.loc 1 23333 1 # myls.c:23333:1
jmp .LBB2_11
.LBB2_11: # %while.cond
# =>This Inner Loop Header: Depth=1
.loc 1 162 13 # myls.c:162:13
cmpl $0, -164(%ebp)
.loc 1 23333 1 # myls.c:23333:1
jl .LBB2_20
# %bb.12: # %while.body
# in Loop: Header=BB2_11 Depth=1
.Ltmp75:
.loc 1 164 14 # myls.c:164:14
movl -136(%ebp), %eax
.loc 1 164 28 is_stmt 0 # myls.c:164:28
movl -164(%ebp), %ecx
# kill: def $cl killed $ecx
.loc 1 164 25 # myls.c:164:25
movl $1, %edx
shll %cl, %edx
.loc 1 164 22 # myls.c:164:22
andl %edx, %eax
cmpl $0, %eax
.Ltmp76:
.loc 1 23333 1 is_stmt 1 # myls.c:23333:1
je .LBB2_18我发现2333和23333不匹配,并且在不同的体系结构的装配代码中,2333和23333的数量是不同的。我使用opt运行我的pass和llc来获取组装代码。
我很感激每一个帮助。
发布于 2019-10-29 15:23:15
我认为问题在于优化。在您通过之后,IR会进行其他几轮的优化,这些优化更改了基本块并消除了一些指令。
您可能有一个寄存器函数,类似于LLVM页面中的以下内容
static llvm::RegisterStandardPasses Y(
llvm::PassManagerBuilder::EP_EarlyAsPossible,
[](const llvm::PassManagerBuilder &Builder,
llvm::legacy::PassManagerBase &PM) { PM.add(new Hello()); });尝试使用EP_OptimizerLast而不是EP_EarlyAsPossible。它将作为最后一个优化器运行您的pass。
另一种选择是使用EP_EnabledOnOptLevel0和与-O0一起使用opt。
您可以在这个页面中查找这些标志
使用-emit-llvm在*.ll中生成LLVM可能会有所帮助。更明显的是,您的代码对IR所做的事情
https://stackoverflow.com/questions/58545770
复制相似问题