将 SPIR 二进制反汇编为 LLVM IR

Disassemble SPIR binary to LLVM IR

我的理解是 SPIR 二进制文件应该是 LLVM 位码,而 SPIR IR 是 LLVM IR 的子集。此外,SPIR 与设备无关。我已经尝试对从 clGetProgramInfo 获得的二进制文件使用 llvm-dis 命令,并将 CL_PROGRAM_BINARIES 作为参数,但它告诉我 "Invalid bitcode signature"。 llvm-bcanalyzer returns "Invalid record at top-level".

我可以反其道而行之,使用 Clang 将我的 OpenCL 内核转换为 LLVM IR 或 LLVM 位码。但是,位码文件大小大约小 10 倍,所以我很确定它与我的 SPIR 二进制文件不同。

为了完整起见,我的 GPU 确实有 cl_khr_spir 扩展名。

  1. 我将 SPIR 二进制文件理解为 LLVN 位码是否正确?
  2. 有没有办法将 SPIR 二进制文件反汇编为 LLVM IR?

你说得对,SPIR 1.2 是 LLVM IR(特别是 LLVM 3.2)的一个子集。请注意,最新版本的 SPIR(称为 SPIR-V)不是从 LLVM IR 派生的,并且是一个独立的、从头开始的中间表示。

使用llvm-dis 是反汇编基于 LLVM 的 SPIR 二进制文件的正确方法。由于 SPIR 1.2 是从 LLVM 3.2 派生的,所以这只能真正保证适用于 llvm-dis 的 LLVM 3.2 版本。在实践中,我发现这对于较新版本的 LLVM 仍然可以正常工作,但不能保证总是如此。

虽然您的设备支持 cl_khr_spir 扩展,但当您从 clGetProgramInfo 查询 CL_PROGRAM_BINARIES 时,并不需要它实际 return 一个 SPIR 二进制文件。许多平台将取而代之 return 本机二进制文件(例如 x86 或本机 GPU ISA)或其他一些中间表示(这可能是 LLVM 无法将您的二进制文件识别为基于 LLVM 的原因)。没有用于通过 OpenCL 运行时检索 SPIR 二进制文件的标准化机制 API.

使用 clang 将 OpenCL C 内核编译成 LLVM IR/SPIR 1.2 是获得 LLVM 位码文件的最佳方法,然后可以使用 llvm-dis 对其进行反汇编。一些供应商(例如 Intel)还提供离线编译器及其 OpenCL SDK,这些 SDK 提供专用 commands/tools 来执行此操作。