使用 C++ API 生成 LLVM 代码:如何处理 OpenMP 调用

LLVM code generation with C++ API: How to handle OpenMP calls

我正在为一种小型语言开发编译器。在编译器内部,我使用 LLVM C++ API 生成 llvm 代码,类似于 LLVM Kaleidoscope tutorial。所以我正在使用 TheModule、TheContext、BasicBlocks, 并调用 Builder.Create...().

我目前可以为算术、控制流和方法生成有效的 llvm 代码。但是,我也希望我的小语言能够支持非常简单的 OpenMP pragma。例如,

#pragma omp parallel
{
  print "Hello World"
}

我试过用 C++ 编写类似的程序,

#include <iostream>
int main() {
  #pragma omp parallel
  {
    std::cout << "Hi";
  }
}

并使用 clang++ -S -emit-llvm file.cpp -fopenmp 生成 llvm。连同其余代码,这会生成以下似乎实现 OpenMP 功能的行:

declare void @__kmpc_fork_call(%ident_t*, i32, void (i32*, i32*, ...)*, ...)
define internal void @.omp_outlined.(...)

通过研究这些语句,我发现 Clang OpenMP API 包含像

这样的调用
OMPParallelDirective * OMPParallelDirective::Create(...)

我猜这就是 Clang 编译器用来生成上述语句的原因。但是,它似乎与 LLVM C++ API 是分开的,因为它不引用 TheContext、TheModule 等...

所以我的问题是:有什么方法可以利用 Clang OpenMP API 调用和我的 LLVM C++ API 调用来生成所需的 kmpc__fork_call@.omp_outlined IR用于并行计算?

我确实尝试使用 llc -march=cpp file.bc ... 将 C++ 代码生成的 llvm 反编译回 LLVM C++ API 代码,但没有成功。

您发现的 API 在 clang AST 上运行并且在 clang 之外几乎不可用。事实上,在 LLVM IR 级别没有 OpenMP 构造 - 一切都已经降低到运行时调用等。

因此,您确实需要自己为 OpenMP 实现代码生成,根据需要(根据您的语言语义)发出运行时调用。