Difference between revisions of "LDC inline IR"
m (Add category LDC to page.) |
m (Moving example from pragma page.) |
||
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 === |
Revision as of 13:56, 26 February 2014
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. Please be aware that LLVM IR is platform dependent. It is not a platform independent assembler!
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.