Accessing elements in LLVM arrays - llvm

I am trying to get started with LLVM in order to add just-in-time compilation for my code, but finding it very difficult find references on how to do the things I want in LLVM, despite having checked through the Kaleidoscope tutorial, the language reference manual, the programmer's manual and the doxygen documentation. Are there more references to LLVM's C++ API than these?
Now for the concrete question. I have allocated an array object with two elements (which I assume corresponds to double[2] in C++):
const llvm::Type* double_t = llvm::Type::getDoubleTy(llvm::getGlobalContext());
const llvm::Type* array_t = llvm::ArrayType::get(double_t,2)
Later in the code, I create a function, where this array is one of the arguments. Then, in my function I extract the first element in the array and return it to the user:
llvm::Function::arg_iterator AI = jit_function_->arg_begin();
llvm::Value *x = AI;
llvm::Value *x0 = Builder.CreateExtractValue(x,0);
Builder.CreateRet(x0);
The code jits fine, but when I try to run it, it doesn't work. For example:
typedef double (*GenType)(double[2]);
GenType FP = GenType(intptr_t(TheExecutionEngine->getPointerToFunction(jit_function_)));
double y[2] = {10,20};
double r = FP(y);
printf("r = %g\n", r);
The return value is just nonsense and I can't see what I'm doing wrong. If I pass the values in the array (10 and 20) as scalar arguments to the function, it works fine.

I think I am able to answer my own question. For the first part of the question, a good reference to LLVM (in addition to the ones mentioned above) is to write what you want in plain C and compile it with Clang and look at the LLVM output: clang -S -emit-llvm test.c -o -.
For the concrete question, my problem was that I assumed that I was passing an array of two doubles to the jitted function, while in fact I was passing a pointer to an array with two values. So the solution is to change:
const llvm::Type* array_t = llvm::ArrayType::get(double_t,2);
to
const llvm::Type* array_t = llvm::PointerType::getUnqual(llvm::ArrayType::get(double_t,2));
And to add an additional dereferencing by changing
llvm::Value *x0 = Builder.CreateExtractValue(x,0);
to
llvm::Value *x0 = Builder.CreateExtractValue(Builder.CreateLoad(x),0);

If you're using LLVM 3.0 or 3.1, CreateExtractValue takes an ArrayRef with the indices.

Related

Explaining C++ (C Binding Library) Function

I'm trying to understand a Function/Method in a Library in order to port it to Java however some parameters don't make any sense to me and reading the source code the library is based on is not helping.
Function (Note the API has few comments (We can also ignore the calc handle since it's got a supplier method))
Ssr calc_ssr(CalcHandle *calc, NoteInfo *rows, size_t num_rows, float music_rate, float score_goal) {
std::vector<NoteInfo> note_info(rows, rows + num_rows);
auto skillsets = MinaSDCalc(
note_info,
music_rate,
score_goal,
reinterpret_cast<Calc*>(calc)
);
return skillset_vector_to_ssr(skillsets);
}
NoteInfo Struct
struct NoteInfo
{
unsigned int notes;
float rowTime;
};
MinaSDCalc
// Function to generate SSR rating
auto
MinaSDCalc(const std::vector<NoteInfo>& NoteInfo,
const float musicrate,
const float goal,
Calc* calc) -> std::vector<float>
{
if (NoteInfo.size() <= 1) {
return dimples_the_all_zero_output;
}
calc->ssr = true;
calc->debugmode = false;
return calc->CalcMain(NoteInfo, musicrate, min(goal, ssr_goal_cap));
}
Calc expected input file data (Only care about the #Notes: ...)
Pastebin
Question
What is NoteInfo in calc_ssr, I don't know any C or C++ so the *rows to me just seems like a pointer to a Noteinfo instance, however the MinaSDCalc methods requires an Array/Vector which using a pointer to a single instance doesn't make sense to me (pairing this with the fact that NoteInfo needs another parameter rowTime which I think is time of Note occurrence in the file which means that value must not be constant otherwise the produced result would be inaccurate)
Github Project: https://github.com/kangalioo/minacalc-standalone (The code alone may not explain enough but it's worth a try; best to look at API.h and discern what's used from there. Though I do warn you a lot of the Code is esoteric)
Sorry if this doesn't make much sense but I've been looking into this since June/July and this API is the closest abstraction from the bare C++ code I could find.
NoteInfo * rows here is pass by pointer. So, rows actually is a pointer to an instance of type NoteInfo. This is one of the ways to pass arrays in c++ to a function. Since arrays are contiguous in memory so we can just increment the pointer by one and get the next element of the array.
for example look at these three ways to do exactly one thing, parameter to pass an array to a function :-
1. void myFunction(int *param) {}
2. void myFunction(int param[10]) {}
3. void myFunction(int param[]) {}
Look into this link for more understanding : https://www.tutorialspoint.com/cplusplus/cpp_passing_arrays_to_functions.htm
Also search for pass by pointer and pass by reference to look into different ways of passing arguments in c++.
2.however the MinaSDCalc methods requires an Array/Vector which using a pointer to a single instance doesn't make sense to me: as to this question of yours, you can now see MinaSDCalc is actually getting an array and not a single instance as passing the pointer is also one of the ways of passing an array in c++.

Matlab legacy_code Tool - Writing a wrapper functio to catch an array

currently I'm trying to use a C/C++ Code based Library in Matlab/Simulink by means of the Matlab legacy_code tool. I am very new to this, please have some patience with me.
I stumbled upon the problem, that I got class members which return an array.
What I did upon now is to follow the Matlab legacy-code examples, especially this one:
Integrate External C++ Object Methods
As far as I can see, the legacy_code tool demands a wrapper function to be wrapped around a method call, so basicaly I could, within this wrapper function manipulate the return value of the called methad any way necessary. This far no problem.
But, I'm not certain how to receive an array of information from the called method an then pass this array to Matlab/Simulink.
e.g. A method's return value is an pointer pointing at an array of information of which, let us assume, we know the length of valid information it holds.
/* Simple example */
uint8_t* BUS::answerRcvd()
{
static int r[10];
int i;
srand( (unsigned)time( NULL ) );
for ( i = 0; i < 10; ++i)
{
r[i] = rand();
}
return r;
}
Is there a way to create a wrapper function for such a method that would receive an array of information and pass it along to matlab?
Might there be a possibility to handle that array as e.g. single values of uint8_t (if way stay with the given example) and pass these like in an ordinary matlab function?
[a,b,c] = function()
I'm open to any suggestion, thank you very much in advance.
Ok, looks like I found a Solution to my problem.
As a wrapper function its possible to use the following pattern
void myfunc(double u1, double u2, double u3, double *y1, double *y2)
{
*y1=u1;
*y2=(u2+u3)/2;
}
This wrapper function the is then interfaced by the Legacy Code Tool (LCT) as followed:
def = legacy_code('initialize')
def.OutputFcnSpec = 'void myfunc(double u1, double u2, double u3, double y1[1], double y2[1])'
Simple as that. On C/C++ code use pointer nomenclature / syntax, on Matlab use array nomenclature / syntax.
I hope, this will help some people like me who need a solution to interface with legacy code which should not only accept multiple inputs, but multiple outputs as well.
In hindsight the option tuuse pointers is pretty obvious, but if you don't knoe how to teach your LCT how to interface with it, it easily becomes an tiring task.

reference to an array of size determined at run-time

I tried to find this but can't find any. I know I can create a reference to an array variable:
int x[10] = {}; int (&y)[10] = x;
However, in the case that the array size is not known at compile time, like in the following code:
const int n = atoi( string ); //the string is read from a text file at run time.
int x[n] = {}; int (&y)[n] = x; //this generates a compiling error.
Even if int n is declared const, as long as n is not known at compile time, the reference is invalid. The compiler will say something like this: reference to type 'int [n]' cannot bind to a value of unrelated type 'int [n]'. Anyone has any idea about how to fix this? Thanks in advance.
Runtime-length arrays are a C99 feature and do not exist in standard C++. They're present as an extension on some C++ compilers, but don't mix well with C++ features, like references and templates.
You should probably use a vector.
The feature of declaring arrays dynamically like shouldn't be used in C++. Not all compilers support it. Consider using the STL containers instead. Like std::vector<int>

Meaning of int (*) (int *) = 5 (or any integer value)

I cannot figure this out:
int main() {
int (*) (int *) = 5;
return 0;
}
The above assignment compiles with g++ c++11. I know that int (*) (int *) is a pointer to a function that accepts an (int *) as argument and returns an int, but I do not understand how you could equate it to 5. At first I thought it is a function that constantly returns 5 (from my recent learning in F#, probably, haha), then I thought, briefly, that the function pointer points to memory location 5, but that does not work, clearly, and neither does hex values.
Thinking that it could be because the function returns an int, and that assigning an int is ok (somehow), I also tried this:
int * (*) (int *) = my_ptr
where my_ptr is of type int *, the same type as this second function pointer, as in the first case with type int. This does not compile. Assigning 5, or any int value, instead of my_ptr, doesn't compile for this function pointer either.
So what does the assignment mean?
Update 1
We have confirmation that it is a bug, as shown in the best answer. However, it is still not known what actually happens to the value that you assign to the function pointer, or what happens with the assignment. Any (good) explanations on that would be very much appreciated! Please refer to the edits below for more clarity on the problem.
Edit 1
I am using gcc version 4.8.2 (in Ubuntu 4.8.2)
Edit 2
Actually, equating it to anything works on my compiler. Even equating it to a std::string variable, or a function name that returns a double, works.
Edit 2.1
Interestingly, making it a function pointer to any function that returns a data type that is not a pointer, will let it compile, such as
std::string (*) () = 5.6;
But as soon as the function pointer is to a function that returns some pointer, it does not compile, such as with
some_data_type ** (*) () = any_value;
It's a bug in g++.
int (*) (int *)
is a type name.
In C++ you cannot have a declaration with a type name without an identifier.
So this compiles with g++.
int (*) (int *) = 5;
and this compiles as well:
int (*) (int *);
but they are both invalid declarations.
EDIT:
T.C. mentions in the comments bugzilla bug 60680 with a similar test case but it has not yet been approved. The bug is confirmed in bugzilla.
EDIT2:
When the two declarations above are at file scope g++ correctly issues a diagnostic (it fails to issue the diagnostic at block scope).
EDIT3:
I checked and I can reproduce the issue on the latest release of g++ version 4 (4.9.2), latest pre-release version 5 (5.0.1 20150412) and latest experimental version 6 (6.0.0 20150412).
It is not valid C++. Remember that because your particular compiler happens to compile it doesn't make it valid. Compilers, like all complex software, sometimes have bugs and this appears to be one.
By contrast clang++ complains:
funnycast.cpp:3:11: error: expected expression
int (*) (int *) = 5;
^
funnycast.cpp:3:18: error: expected '(' for function-style cast or type construction
int (*) (int *) = 5;
~~~ ^
funnycast.cpp:3:19: error: expected expression
int (*) (int *) = 5;
^
3 errors generated.
This is the expected behavior because the offending line is not valid C++. It purports to be an assignment (because of the =) but contains no identifier.
As other answers have pointed out, it is a bug that
int (*) (int *) = 5;
compiles. A reasonable approximation of this statement that would be expected to have a meaning is:
int (*proc)(int*) = (int (*)(int*))(5);
Now proc is a pointer-to-function that expects the address 5 to be the base address of a function that takes an int* and returns an int.
On some microcontrollers/microprocessors 5 might be a valid code address, and it might be possible to locate such a function there.
On most general-purpose computers, the first page of memory (addresses 0-1023 for 4K pages) are purposely invalid (unmapped) in order to catch null pointer accesses.
Thus, while behavior depends on the platform, one can reasonably expect a page fault to occur when *proc is invoked (e.g., (*proc)(&v)). Before the time at which *proc is invoked, nothing unusual happens.
Unless you are writing a dynamic linker, you almost certainly shouldn't be numerically calculating addresses and assigning them to pointer-to-function variables.
/usr/lib/gcc/x86_64-pc-cygwin/4.9.2/cc1plus.exe -da so.cpp
This command line generates a lot of intermediate files. The first of them, so.cpp.170r.expand, says:
...
int main() ()
{
int D.2229;
int _1;
;; basic block 2, loop depth 0
;; pred: ENTRY
_1 = 0;
;; succ: 3
;; basic block 3, loop depth 0
;; pred: 2
<L0>:
return _1;
;; succ: EXIT
}
...
This still doesn’t answer what happens exactly, but it should be a step in the right direction.

D language function call with argument

I am learning D and have mostly experience in C#. Specifically I am trying to use the Derelict3 Binding to SDL2. I have been able to get some basic functionality working just fine but I have become stumped on how to create an array argument for a specific call.
The library contains a call
SDL_RenderDrawLines(SDL_Renderer*, const(SDL_Point)*, int) //Derelict3 Binding
And I have been unable to correctly form the argument for
const(SDL_Point)*
The SDL Documentation for this function states that this argument is an array of SDL_Point, but I am unclear how to create an appropriate array to pass to this function.
Here is an example of what I have at the moment:
void DrawShape(SDL_Renderer* renderer)
{
SDL_Point a = { x:10, y:10};
SDL_Point b = { x:500, y:500};
const(SDL_Point[2]) points = [a,b];
Uint8 q = 255;
SDL_SetRenderDrawColor(renderer,q,q,q,q);
SDL_RenderDrawLines(renderer,points,1);
}
And the compiler complains that I am not passing the correct type of argument for const(SDL_Point)* in points.
Error: function pointer SDL_RenderDrawLines (SDL_Renderer*, const(SDL_Point)*, int)
is not callable using argument types (SDL_Renderer*, const(SDL_Point[2u]), int)
I suspect this is a fundamental misunderstanding on my part so any help would be appreciated.
Arrays aren't implicitly castable to pointers in D. Instead, each array (both static and dynamic) has an intrinsic .ptr property that is a pointer to its first element.
Change your code to:
SDL_RenderDrawLines(renderer,points.ptr,1);
given that the call asks for a pointer and length, I feel it is safer to define you own wrapper:
SDL_RenderDrawLines(SDL_Renderer* rend, const SDL_Point[] points){
SDL_RenderDrawLines(rend,points.ptr,points.length);
}
(why it isn't defined I don't know, any performance hit from the extra function call is just a -inline away from being resolved)