我正在尝试进行活跃度分析,为了做到这一点,我需要获取所有节点的def
和use
集,其定义如下:
def[n] = set of all variables defined at node n
use[n] = set of all variables used at node n
例如在行中:
a = b + c
def[n] = {a}
use[n] = {b,c}
我该怎么做?
答案 0 :(得分:2)
http://llvm.org/docs/ProgrammersManual.html#iterating-over-def-use-use-def-chains
我希望这个页面可以帮到你。访问Value对象中的user_begin(),user_end()和users()方法的用户对象是使用Value对象的用户对象。 Instruction类是User类的子类。
我可能错了,但要获得IR级别的def-use设置,集合的元素应该是Value对象,每个节点应该是一个Instruction对象。
因此,每个节点的 def设置将是指令返回的Value对象(有可能情况下指令不返回。这种情况下,def set为空集。),并且使用集将是通过指令的user_iterator访问的用户对象。
答案 1 :(得分:0)
基本上,当我们在LLVM中定义局部变量时,它使用import groovy.transform.AutoClone
@AutoClone
class TestClass {
String getName() {
return "Jake"
}
}
def tc1 = new TestClass()
def tc2 = tc1.clone()
tc1.metaClass.getName = {'Fatman'}
tc2.metaClass.getName = {'Joe'}
assert tc1.getName() == 'Fatman'
assert tc2.getName() == 'Joe'
assert new TestClass().getName() == 'Jake'
。以下是您提出的示例:
AllocaInst
C代码中的:
a=b+c
在使用int a;
int b=10;
int c=10;
a=b+c;
编译的LLVM IR中(调试模式):
-g
让我们看看如何使用LLVM API收集def-use链。这很容易,因为LLVM在功能级别上有一个内部内置API:
%a = alloca i32, align 4
%b = alloca i32, align 4
%c = alloca i32, align 4
call void @llvm.dbg.declare(metadata i32* %a, metadata !14, metadata !16),
... !dbg !17
call void @llvm.dbg.declare(metadata i32* %b, metadata !18, metadata !16),
... !dbg !19
store i32 10, i32* %b, align 4, !dbg !19
call void @llvm.dbg.declare(metadata i32* %c, metadata !20, metadata !16),
... !dbg !21
store i32 10, i32* %c, align 4, !dbg !21
%0 = load i32, i32* %b, align 4, !dbg !22
%1 = load i32, i32* %c, align 4, !dbg !23
%add = add nsw i32 %0, %1, !dbg !24
store i32 %add, i32* %a, align 4, !dbg !25
对于def-use链,简单的渠道分配和用户。
这将生成一个PDG。
代码取自https://github.com/DengMinghua/LLVM-Program-Dependency-Graph-Generator
希望这有帮助。