LLVM CallGraph调用图输出中#uses字段的含义是什么
LLVM CallGraph 中
#uses 字段的准确定义 你一开始的猜测是错的,这个值根本不是当前节点发起的直接调用次数。
#uses统计的是当前调用图节点对应的函数,作为被调用方,在整个模块里被多少个编译期可见的直接调用点(CallSite)调用的总次数,也就是指向这个节点的调用入边总数。
你用来生成调用图的代码如下:
virtual bool runOnModule(Module &M) { CallGraph CG = CallGraph(M); CG.dump(); }
对应你贴出的function1节点输出:
Call graph node for function: 'function1'<<0x563f43b334e0>> #uses=2 CS<0x563f442ea418> calls function 'function2' CS<0x563f442ea888> calls function 'function3' CS<0x563f442eabf8> calls function 'function3' CS<0x563f442eb1e0> calls function 'function4' CS<0x563f442ebcf0> calls function 'function5' CS<0x563f442ebdb0> calls function 'function6' CS<0x563f442ec080> calls function 'function7' CS<0x563f442ec110> calls function 'function6' CS<0x563f442ecb10> calls function 'function4' CS<0x563f442ecbd0> calls function 'function6' CS<0x563f442ecde0> calls function 'function7' CS<0x563f442ece70> calls function 'function4'
这里function1的#uses=2,意思是整个模块里一共有2处直接调用function1的代码。节点下面缩进列的12条CS<xxx>记录,才是function1作为调用方往外发起的直接调用,这部分的计数和#uses完全没关系——光数这部分就有12次调用,和2的数值差得远,刚好能推翻你最初的猜测。
你可以自己翻完整的调用图输出验证:比如上面的列表里function3被function1调了2次,如果整个模块里没有其他地方调用function3,那function3对应节点的#uses就正好是2;function4被function1调了3次,没有其他调用点的话它的#uses就是3;完全没被任何代码调用的函数,#uses值就是0。
补充两个注意点:
- 这个计数只算编译期能识别的直接函数调用,通过函数指针发起的间接调用不会被统计进去
- 调用图里代表整个模块外部入口的虚拟根节点的
#uses不适用这个规则,不用硬套
内容的提问来源于stack exchange,提问作者Rubujubi
相关产品推荐
相关产品推荐

