Difference between revisions of "LDC inline IR"
(New page decribing the inline IR feature of LDC.) |
Klickverbot (talk | contribs) (Downgrade warning) |
||
(4 intermediate revisions by one other user not shown) | |||
Line 1: | Line 1: | ||
− | LDC has an interface to LLVM IR. This can be useful if you want to exploit special LLVM features like vector instructions or address space operations. | + | LDC has an interface to the [http://llvm.org/docs/LangRef.html LLVM assembly language (IR)]. This can be useful if you want to exploit special LLVM features like vector instructions or address space operations. |
− | Please be aware that LLVM IR is platform dependent. It is not a platform independent assembler! | + | Please be aware that LLVM IR is platform dependent. It is not a platform independent assembler! This pragma is intrinsically very brittle in nature, and should only be used if other facilities (e.g. the ldc.simd module) are not sufficient. |
== Interface == | == Interface == | ||
Line 9: | Line 9: | ||
R inlineIR(string s, R, P...)(P); | R inlineIR(string s, R, P...)(P); | ||
</source> | </source> | ||
− | The first type parameter | + | The symbol declared with pragma LDC_inline_ir must be a function template with three template parameters. The first template parameter must be string in LLVM assembly language. The second template parameter must be the return type, and the third template parmeter must be a tuple of function parameter types. |
+ | When the function template is instantiated, an LLVM function is created. The string passed as the first template parameter is used as the function's body. If the return type is void, "void" is appended to it. The function's return type is determined from the second template parameter and the parameter list is generated from the third template parameter. This function will be inlined if possible. If all the calls to the function are inlined, the function will not appear in the object file. | ||
Inside the IR you refer to the parameters with the special names %0, %1 and so on. | Inside the IR you refer to the parameters with the special names %0, %1 and so on. | ||
== Examples == | == Examples == | ||
+ | |||
+ | === Adding 2 integers === | ||
+ | |||
+ | A simple usage is here: | ||
+ | <source lang="d"> | ||
+ | int add(int a, int b) | ||
+ | { | ||
+ | return inlineIR!(` | ||
+ | %r = add i32 %0, %1 | ||
+ | ret i32 %r`, int)(a, b); | ||
+ | } | ||
+ | </source> | ||
=== Using another address space === | === Using another address space === | ||
Line 32: | Line 45: | ||
=== Using vector instructions === | === Using vector instructions === | ||
− | The file | + | The file [https://github.com/ldc-developers/druntime/blob/ldc/src/ldc/simd.di ldc.simd] contains the source for the LLVM vector instructions. |
+ | |||
+ | [[Category:LDC]] |
Latest revision as of 23:38, 7 April 2017
LDC has an interface to the LLVM assembly language (IR). This can be useful if you want to exploit special LLVM features like vector instructions or address space operations. Please be aware that LLVM IR is platform dependent. It is not a platform independent assembler! This pragma is intrinsically very brittle in nature, and should only be used if other facilities (e.g. the ldc.simd module) are not sufficient.
Contents
Interface
To use the inline IR feature you have to declare the following magic template:
pragma(LDC_inline_ir)
R inlineIR(string s, R, P...)(P);
The symbol declared with pragma LDC_inline_ir must be a function template with three template parameters. The first template parameter must be string in LLVM assembly language. The second template parameter must be the return type, and the third template parmeter must be a tuple of function parameter types. When the function template is instantiated, an LLVM function is created. The string passed as the first template parameter is used as the function's body. If the return type is void, "void" is appended to it. The function's return type is determined from the second template parameter and the parameter list is generated from the third template parameter. This function will be inlined if possible. If all the calls to the function are inlined, the function will not appear in the object file.
Inside the IR you refer to the parameters with the special names %0, %1 and so on.
Examples
Adding 2 integers
A simple usage is here:
int add(int a, int b)
{
return inlineIR!(`
%r = add i32 %0, %1
ret i32 %r`, int)(a, b);
}
Using another address space
On Windows 64bit, the bottom of stack is stored at gs:8. Instead of using inline assembler you can use this IR:
void* getStackBottom(){
return inlineIR!(`
%ptr = inttoptr i64 %0 to i64 addrspace(256)*
%val = load i64 addrspace(256)* %ptr, align 1
%tmp = inttoptr i64 %val to i8*
ret i8* %tmp`,
void*, ulong)(8);
}
LLVM uses different address spaces to model the segment registers on x86/x86_64. The address space 256 is the gs segment register and address space 257 is the fs segment register.
Using vector instructions
The file ldc.simd contains the source for the LLVM vector instructions.