I'm trying to figure out how to use the trampoline intrinsics in LLVM. The documentation makes mention of some amount of storage that's needed to store the trampoline in, which is platform dependent. My question is, how do I figure out how much is needed?
I found this example, that picks 32 bytes for apparently no reason. How does one choose a good value?
declare void #llvm.init.trampoline(i8*, i8*, i8*);
declare i8* #llvm.adjust.trampoline(i8*);
define i32 #foo(i32* nest %ptr, i32 %val)
{
%x = load i32* %ptr
%sum = add i32 %x, %val
ret i32 %sum
}
define i32 #main(i32, i8**)
{
%closure = alloca i32
store i32 13, i32* %closure
%closure_ptr = bitcast i32* %closure to i8*
%tramp_buf = alloca [32 x i8], align 4
%tramp_ptr = getelementptr [32 x i8]* %tramp_buf, i32 0, i32 0
call void #llvm.init.trampoline(
i8* %tramp_ptr,
i8* bitcast (i32 (i32*, i32)* #foo to i8*),
i8* %closure_ptr)
%ptr = call i8* #llvm.adjust.trampoline(i8* %tramp_ptr)
%fp = bitcast i8* %ptr to i32(i32)*
%val2 = call i32 %fp (i32 13)
; %val = call i32 #foo(i32* %closure, i32 42);
ret i32 %val2
}
Yes, trampolines are used to generate some code "on fly". It's unclear why do you need these intrinsics at all, because they are used to implement GCC's nested functions extension (in particular, when the address of the nested function is captured and the function access the stuff inside the enclosing function).
The best way to figure out the necessary size and alignment of trampoline buffer is to grep gcc sources for "TRAMPOLINE_SIZE" and "TRAMPOLINE_ALIGNMENT".
As far as I can see, at the time of this writing, the buffer of 72 bytes and alignment of 16 bytes will be enough for all the platforms gcc / LLVM supports.
Related
I am trying to understand the LLVM IR generated from a C++ program
int add(int *x);
int func()
{
int T;
T=25;
return add(&T);
}
The generated IR is:
define i32 #_Z4funcv() local_unnamed_addr #0 {
entry:
%T = alloca i32, align 4
%0 = bitcast i32* %T to i8*
call void #llvm.lifetime.start.p0i8(i64 4, i8* nonnull %0) #3
store i32 25, i32* %T, align 4, !tbaa !2
%call = call i32 #_Z3addPi(i32* nonnull %T)
call void #llvm.lifetime.end.p0i8(i64 4, i8* nonnull %0) #3
ret i32 %call
}
I do not understand this line %0 = bitcast i32* %T to i8*. What is the purpose of converting %T from i32 to i8?
Assuming you know about intrinsics
llvm.lifetime.start / llvm.lifetime.end
and its uses as memory uses marker for MemoryDependenceAnalysis.
About the choice of pointer(address of variable) as i8 was made to make it more generic as byte addressable memory region with first arguments as number of bytes same as we use in malloc.
so to generate the intrinsic call we need a memory byte address and the number of bytes that is sizeof(T). that is why we need to convert i32* to i8*.
by the way the signature if lifetime intrinsics used in your examples are
declare void #llvm.lifetime.start(i64 , i8* nocapture )
declare void #llvm.lifetime.end(i64 , i8* nocapture )
go through Lang ref for more info.
LLVM is typed and monomorphical. Thus, you need to cast values to the right type before you can use them. As the other answer explained, the llvm intrinsics operate on i8* which is kind of the translation of a void* in C.
Assume a simple partial evaluation scenario:
#include <vector>
/* may be known at runtime */
int someConstant();
/* can be partially evaluated */
double foo(std::vector<double> args) {
return args[someConstant()] * someConstant();
}
Let's say that someConstant() is known and does not change at runtime (e.g. given by the user once) and can be replaced by the corresponding int literal. If foo is part of the hot path, I expect a significant performance improvement:
/* partially evaluated, someConstant() == 2 */
double foo(std::vector<double> args) {
return args[2] * 2;
}
My current take on that problem would be to generate LLVM IR at runtime, because I know the structure of the partially evaluated code (so I would not need a general purpose partial evaluator).
So I want to write a function foo_ir that generates IR code that does the same thing as foo, but not calling someConstant(), because it is known at runtime.
Simple enough, isn't it? Yet, when I look at the generated IR for the code above:
; Function Attrs: uwtable
define double #_Z3fooSt6vectorIdSaIdEE(%"class.std::vector"* %args) #0 {
%1 = call i32 #_Z12someConstantv()
%2 = sext i32 %1 to i64
%3 = call double* #_ZNSt6vectorIdSaIdEEixEm(%"class.std::vector"* %args, i64 %2)
%4 = load double* %3
%5 = call i32 #_Z12someConstantv()
%6 = sitofp i32 %5 to double
%7 = fmul double %4, %6
ret double %7
}
; Function Attrs: nounwind uwtable
define linkonce_odr double* #_ZNSt6vectorIdSaIdEEixEm(%"class.std::vector"* %this, i64 %__n) #1 align 2 {
%1 = alloca %"class.std::vector"*, align 8
%2 = alloca i64, align 8
store %"class.std::vector"* %this, %"class.std::vector"** %1, align 8
store i64 %__n, i64* %2, align 8
%3 = load %"class.std::vector"** %1
%4 = bitcast %"class.std::vector"* %3 to %"struct.std::_Vector_base"*
%5 = getelementptr inbounds %"struct.std::_Vector_base"* %4, i32 0, i32 0
%6 = getelementptr inbounds %"struct.std::_Vector_base<double, std::allocator<double> >::_Vector_impl"* %5, i32 0, i32 0
%7 = load double** %6, align 8
%8 = load i64* %2, align 8
%9 = getelementptr inbounds double* %7, i64 %8
ret double* %9
}
I see, that the [] was included from the STL definition (function #_ZNSt6vectorIdSaIdEEixEm) - fair enough. The problem is: It could as well be some member function, or even a direct data access, I simply cannot assume the data layout to be the same everywhere, so at development-time, I do not know the concrete std::vector layout of the host machine.
Is there some way to use C++ metaprogramming to get the required information at compile time? i.e. is there some way to ask llvm to provide IR for std::vector's [] method?
As a bonus: I would prefer to not enforce the compilation of the library with clang, instead, LLVM shall be a runtime-dependency, so just invoking clang at compile time (even if I do not know how to do this) is a second-best solution.
Answering my own question:
While I still have no solution for the general case (e.g. std::map), there exists a simple solution for std::vector:
According to the C++ standard, the following holds for the member function data()
Returns a direct pointer to the memory array used internally by the
vector to store its owned elements.
Because elements in the vector are guaranteed to be stored in
contiguous storage locations in the same order as represented by the
vector, the pointer retrieved can be offset to access any element in
the array.
So in fact, the object-level layout of std::vector is fixed by the standard.
I am trying to use GEP to get a pointer of i32 from an array.
But the problem is: I don't know the size of the array.
The IR document on llvm.org said GEP just adds the offsets to the base address with silently-wrapping two’s complement arithmetic.
So, I want to ask for some advice.
Is it safe like this:
%v1 = alloca i32
store i32 5, i32* %v1
%6 = load i32* %v1
%7 = bitcast i32* %v0 to [1 x i32]*
%8 = getelementptr [1 x i32]* %7, i32 0, i32 %6
%9 = load i32* %8
store i32 %9, i32* %v0
Type of %v0 is i32*, and I know %v0 is pointing to an array in mem, but the size is 9, not 1.
Then I "GEP" from %7 which I treat it as a [1 x i32], not [9 x i32] , but the "offset" is 5(%6).
So, is there any problem? Not safe, or just not good but basically OK?
First of all, the entire code you wrote is equivalent to:
%x = getelementptr i32* %v0, i32 5
%y = load i32* %x
store i32* %y, %v0
There's no reason to bitcast the pointer to [1 x i32]*, just use it as-is.
Regarding your question - using a gep to get the pointer is always safe (in the sense that it's well-defined and will never crash), however there's nothing stopping it from evaluating to a pointer beyond the bounds of the array; and in such a case, accessing the memory (as you do in the subsequent load instruction) is undefined.
Also, this link might be of interest: http://llvm.org/docs/GetElementPtr.html#what-happens-if-an-array-index-is-out-of-bounds
From an llvm pass, I need to print an llvm instruction (Type llvm::Instruction) on the screen, just like as it appears in the llvm bitcode file. Actually my compilation is crashing, and does not reach the point where bitcode file is generated. So for debugging I want to print some instructions to know what is going wrong.
Assuming I is your instruction
I.print(errs());
By simply using the print method.
For a simple Hello World program, using C++'s range-based loops, you can do something like this:
for(auto& B: F){
for(auto& I: B){
errs() << I << "\n";
}
}
This gives the output:
%3 = alloca i32, align 4
%4 = alloca i8**, align 8
store i32 %0, i32* %3, align 4
store i8** %1, i8*** %4, align 8
%5 = call i32 (i8*, ...) #printf(i8* getelementptr inbounds ([15 x i8], [15 x i8]* #.str, i64 0, i64 0))
ret i32 0
I wish I could have tested it myself, but unfortunately it's impossible to do so in the current situation I'm in. Could anyone care to shed some light on this?
It returns the address of the value it is referencing.
Unlike a pointer, a reference isn't actually an object. It doesn't have an address itself, it's easier to think of it as an alias to an object that the compiler will then interpret.
Anyway, you can always test code online with IdeOne
#include <stdio.h>
void func(int &z)
{
printf("&z: %p", &z);
}
int main(int argc, char **argv)
{
int x = 0;
int &y = x;
printf("&x: %p\n", &x);
printf("&y: %p\n", &y);
func(x);
return 0;
}
Executed online, with results.
Address of the value.
(There is no such thing as address of reference)
You can always check on codepad : http://codepad.org/I1aBfWAQ
A further experiment: there are online compilers that allow inspection of intermediate results!
Taking Mahmoud's example on the Try out LLVM and Clang page, we get the following LLVM IR (truncated).
define i32 #main() nounwind uwtable {
%x = alloca i32, align 4
store i32 0, i32* %x, align 4, !tbaa !0
%1 = call i32 (i8*, ...)* #printf(i8* getelementptr inbounds ([8 x i8]* #.str, i64 0, i64 0), i32* %x)
%2 = call i32 (i8*, ...)* #printf(i8* getelementptr inbounds ([8 x i8]* #.str1, i64 0, i64 0), i32* %x)
%3 = call i32 (i8*, ...)* #printf(i8* getelementptr inbounds ([7 x i8]* #.str2, i64 0, i64 0), i32* %x) nounwind
ret i32 0
}
... the syntax is not too important, what is important is to note that a single variable has been declared: %x (whose name is suspiciously similar to that of the C function).
This means that the compiler has elided the y and z variable, no storage is ever allocated for them.
I will spare you the assembly listing ;)