在llvmlite中,需要
TargetData
的实例来获取对象的ABI大小。这是有道理的,因为对象的大小取决于字的大小和对齐方式。如果我想立即编译并使用当前进程中的代码,那么除了当前进程的目标数据之外,我不需要任何其他东西。文档似乎表明这将可靠地获取当前进程的目标数据。
import llvmlite.binding as llvm
# Initialize the LLVM
# https://llvmlite.readthedocs.io/en/latest/user-guide/binding/examples.html
llvm.initialize()
llvm.initialize_native_target()
llvm.initialize_native_asmprinter()
target_string = llvm.get_process_triple()
target_data = llvm.create_target_data(target_string)
但是,最后一行中止了 Python 进程并出现错误:
LLVM ERROR: Unknown specifier in datalayout string
Aborted (core dumped)
大概,这与我的进程三重相关是
x86_64-unknown-linux-gnu
我在 Lenovo P53 上安装了 Ubuntu 20.04,所以应该不会那么奇怪。
如何获得当前进程的工作默认值
TargetData
?
你遇到的错误是由于 LLVM 无法识别
llvm.get_process_triple()
返回的三元组字符串中的某些组件造成的。虽然你的三元组字符串
x86_64-unknown-linux-gnu
看起来很标准,但在某些情况下,LLVM 可能无法完全解析它。
以下是两种解决这个问题来获取当前进程的工作
TargetData
的替代方法:
方法 1:从
TargetMachine
获取
TargetData
这个方法更可靠,因为它不依赖于解析三元组字符串。你可以创建一个
TargetMachine
并从中获取
TargetData
:
import llvmlite.binding as llvm
llvm.initialize()
llvm.initialize_native_target()
llvm.initialize_native_asmprinter()
# 获取默认目标机器
target = llvm.Target.from_default_triple()
target_machine = target.create_target_machine()
# 从目标机器获取目标数据
target_data = target_machine.target_data
方法 2:指定数据布局字符串
如果由于某种原因你必须使用
create_target_data
,你可以手动指定一个数据布局字符串,而不是依赖于解析的三元组:
import llvmlite.binding as llvm
llvm.initialize()
llvm.initialize_native_target()
llvm.initialize_native_asmprinter()
# 为 x86_64-unknown-linux-gnu 指定数据布局字符串
data_layout_str = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target_data = llvm.create_target_data(data_layout_str)
这个方法需要你知道你的目标架构和环境的正确数据布局字符串。你可以通过在你的系统上运行
llc -march=native -print-data-layout
命令来找到它。
这两种方法都应该能让你在不依赖于可能导致问题的 LLVM 三元组解析的情况下,为你的进程获取有效的
TargetData
对象。