You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

LLVM中不同BasicBlock共享相同对象ID?程序是否存在Bug?

为什么llvmlite中不同BasicBlock会共享相同的对象ID?

你用llvmlite代码打印LLVM模块中BasicBlock的对象ID时,发现不同BasicBlock的ID重复,比如main函数的BasicBlock和foo的第一个BasicBlock ID相同,foo内部也有重复ID。输出如下:

foo
Block ID: 140516957688448
Block ID: 140516957688544
Block ID: 140516957688448
Block ID: 140516957688544
Block ID: 140516957688448
Block ID: 140516957688544
printf
main
Block ID: 140516957688448

你的代码如下:

from llvmlite import binding as llvm

# Initialize the LLVM system
llvm.initialize()
llvm.initialize_native_target()
llvm.initialize_native_asmprinter()
    
def find_basic_block_ids(ir):
    # Parse the LLVM IR
    llvm_module = llvm.parse_assembly(ir)
    llvm_module.verify()


    for function in llvm_module.functions:
        print (function.name)
        for block in function.blocks:   
            block_id = id(block)
            print(f"Block ID: {block_id}")


if __name__ == "__main__":
    with open("mycode.ll", "r") as f:
        llvm_ir = f.read()

    find_basic_block_ids(llvm_ir)

原因分析

这不是你的程序Bug,是llvmlite的对象包装机制导致的:

  • llvmlite在访问LLVM底层对象(比如BasicBlock)时,不会为每个底层对象持续创建新的Python包装器。当遍历完一个BasicBlock后,对应的Python包装器会被Python的垃圾回收机制回收,其占用的内存地址会被重新分配给后续新创建的包装器。
  • 你看到的重复ID,其实是不同Python包装器复用了同一块内存地址,它们对应的是LLVM底层不同的BasicBlock实例,但Python层面的包装对象被回收后复用了ID。

正确的标识方式

如果需要区分不同的BasicBlock,不要用Python的id(),应该用:

  • BasicBlock的名称:如果IR中给块命名了,可以用block.name获取
  • LLVM内部的唯一标识:通过block.as_pointer()获取底层LLVM对象的指针值,这个值是唯一的,不会重复

修改后的代码示例:

from llvmlite import binding as llvm

# Initialize the LLVM system
llvm.initialize()
llvm.initialize_native_target()
llvm.initialize_native_asmprinter()
    
def find_basic_block_ids(ir):
    llvm_module = llvm.parse_assembly(ir)
    llvm_module.verify()

    for function in llvm_module.functions:
        print(function.name)
        for block in function.blocks:   
            # 使用底层指针值作为唯一标识
            block_ptr = block.as_pointer()
            # 或者使用块名称(如果有命名)
            block_name = block.name if block.name else "unnamed"
            print(f"Block Name: {block_name}, LLVM Pointer: {block_ptr}")


if __name__ == "__main__":
    with open("mycode.ll", "r") as f:
        llvm_ir = f.read()

    find_basic_block_ids(llvm_ir)

内容的提问来源于stack exchange,提问作者zell

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 14:05:01