如何从给定 LLVM IR 的源代码中获取变量的所有行号?
Posted
技术标签:
【中文标题】如何从给定 LLVM IR 的源代码中获取变量的所有行号?【英文标题】:How to get all the line number of a variable from source code given LLVM IR? 【发布时间】:2019-09-25 10:21:03 【问题描述】:我完全是 LLVM 的新手。我想知道如何从给定 LLVM IR 的源代码中获取特定变量的所有行号?
例如(显示 LLVM IR 的 sn-p)
store i32 0, i32* %i, align 4, !dbg !12
!12 = !DILocation(line: 2, column: 6, scope: !7)
%4 = load i32*, i32** %ip, align 8, !dbg !30
!30 = !DILocation(line: 7, column: 4, scope: !25)
我相信,通过检查 LLVM IR,获取任何变量的行号详细信息与在指令结束时访问 !dbg
有关。但我不知道如何访问这些信息。
另一个疑问是,如果使用指针存储变量的地址,我们如何知道它存储的是哪个变量的地址?
【问题讨论】:
【参考方案1】:我相信,通过检查 LLVM IR,获取行号详细信息 对于任何变量都与在末尾访问 !dbg 有关 操作说明。但我不知道如何访问这些信息。
我相信你的假设是正确的。据我所知,所有信息都在那里:
第一条指令以!dbg !12
(store i32 0, i32* %i, align 4, !dbg !12
) 结尾。
然后你应该找到以!12
开头的行。提示,调试信息通常位于模块的 LLVM IR 的底部。
在您的情况下是:!12 = !DILocation(line: 2, column: 6, scope: !7)
!12 的指令来自生成此 LLVM IR 的源文件中的第 2 行第 6 列。源文件的名称也应该可用(通常位于 LLVM IR 的顶部)。
另一个疑问是指针是否用于存储变量的地址, 我们怎么知道它存储的是哪个变量的地址?
您需要自己推断该信息,例如通过数据流分析。不过,它在概念上相当简单,因为 LLVM IR is in SSA form 已经存在。
【讨论】:
答案是正确的,但可能会提到Instruction::getDebugLoc()。顺便说一句,以 !7 开头的行将具有文件名。或者可以从 DebugLoc 对象中获取它,这就是 IR 打印机所做的。 感谢 Morten 和 arnt 的回答,我看到通过 I->getDebugLoc() 我们可以获得有关变量行号的详细信息,但我关心的是如何获取所有行访问了吗?【参考方案2】:LLVM 中的所有内容都是一个值,其中一些值会跟踪其用户。 42(一个常量 int)不会,但您感兴趣的 Values 会跟踪他们的用户。我有一些代码可以处理使用特定值的 phi 节点;以下是找到这些 phi 节点的三行代码:
for(auto u : someValue->users())
PHINode * phi = dyn_cast<PHINode>(u);
if(phi)
…
请注意,这仅适用于模块内。如果您有一个全局值(例如许多函数),则不会跟踪模块外部的使用(例如大多数函数调用)。
【讨论】:
以上是关于如何从给定 LLVM IR 的源代码中获取变量的所有行号?的主要内容,如果未能解决你的问题,请参考以下文章