除了is_intrinsic
函数之外,我似乎无法在官方LLVM OCaml绑定中找到对内部函数的引用。LLVM OCaml绑定是否包含内部支持?
我正在构建一个后端,它需要执行一些特定于目标的代码生成(对于SSE,AVX和NEON),并且内在函数是C++ API中的标准路径。
除了is_intrinsic
函数之外,我似乎无法在官方LLVM OCaml绑定中找到对内部函数的引用。LLVM OCaml绑定是否包含内部支持?
我正在构建一个后端,它需要执行一些特定于目标的代码生成(对于SSE,AVX和NEON),并且内在函数是C++ API中的标准路径。
OCaml的完全相同的方式与C语言绑定绑定支持内部函数:
有一个在接口对他们没有特殊的支持(因为在完整的C++接口),但他们可以申报和其他函数一样被调用。
例如为:
open Llvm
let() =
let c = create_context() in
let f32_t = float_type c in
let f32x4_t = vector_type f32_t 4 in
let m = create_module c "test" in
(* declare void @printv(<4 x float>)
* nonce extern which forces preservation of vector results *)
let printv =
declare_function "printv"
(function_type (void_type c) [|f32x4_t|]) m in
(* declare <4 x float> @llvm.x86.sse.sqrt.ps(<4 x float>) nounwind readnone *)
let sqrtps =
declare_function "llvm.x86.sse.sqrt.ps"
(function_type f32x4_t [|f32x4_t|]) m in
(* define i32 @main() { entry: *)
let main = define_function "main" (function_type i32_t [| |]) m in
let at_entry = builder_at_end c (entry_block main) in
(*%sqrtps = call <4 x float> @llvm.x86.sse.sqrt.ps(<4 x float> <float 1.000000e+00, float 2.000000e+00, float 3.000000e+00, float 4.000000e+00>)*)
let cv1234 = const_vector [| const_float f32_t 1.0; const_float f32_t 2.0;
const_float f32_t 3.0; const_float f32_t 4.0 |] in
let sqrt = build_call sqrtps [| cv1234 |] "sqrtps" at_entry in
(* call void printv(sqrtps) *)
ignore (build_call printv [| sqrt |] "" at_entry);
(* ret void *)
ignore (build_ret (const_null i32_t) at_entry);
(* Print .ll to stderr *)
dump_module m
生产:
; ModuleID = 'test'
declare void @printv(<4 x float>)
declare <4 x float> @llvm.x86.sse.sqrt.ps(<4 x float>) nounwind readnone
define i32 @main() {
entry:
%sqrtps = call <4 x float> @llvm.x86.sse.sqrt.ps(<4 x float> <float 1.000000e+00, float 2.000000e+00, float 3.000000e+00, float 4.000000e+00>)
call void @printv(<4 x float> %sqrtps)
ret i32 0
}
其编译成86正确地调用对xmm
寄存器sqrtps
。
声明:我从来没有使用LLVM。在快速浏览绑定文档后,看起来答案是“否”。有一个内联汇编的支持,但是,这可能会或可能不适合您的需求。最后,似乎LLVM开发人员接受OCaml绑定不完整:如果你想要,你可以添加一些更多的功能(如果你不熟悉OCaml,C绑定实际上并不是最简单的部分,但LLVM绑定中充满了可以成功适应其他LLVM功能的示例代码),然后在LLVMdev列表中为其提供补丁。