Access variable Element of Array in llvm - llvm

I want to get the Value of an array at an variable index. The Index is computed by the program and not known at parse time. So it is stored in an Value and converted to an Int like this:
Value *IndexV = Index->Codegen();
Value *IntV = Builder.CreateFPToUI( IndexV, Type::getInt32Ty( getGlobalContext() ) );
If I know the index, I can use:
Value *VV = Builder.CreateExtractValue( Builder.CreateLoad( V ), 0 );
This gives me the first element of the array. And works correctly. But how can I use IntV as the index? CreateExtractValue only takes an ArrayRef and there is no way of casting the IntV to an ArrayRef, or am I wrong? How would one do such a thing?
Thanks!

First of all, whenever an ArrayRef is expected, you can always pass just a single item, as there's an implicit conversion between any T and ArrayRef<T>.
Specifically here, though, extractvalue requires constant indices, and cannot accept general values, which is why it wants unsigned values. If you want to access an element in an unknown index in an array, use a getelementptr instruction instead: invoke it on the address of the array with indices 0 and IntV, and you should get a pointer to the array at location IntV.

Related

How to retrieve the size of this array?

I'm using IMidiQueue to queue/add IMidiMsg objects to my IMidiQueue mMIDICreated;
At some times, I'd like to retrieve the number of items I've added on it. I've tried this:
char buffer[50];
sprintf(buffer, "size %d\n", sizeof(mMIDICreated) / sizeof(IMidiMsg));
OutputDebugString(buffer);
but after adding 8 items:
for (int i = 0; i < 4; i++) {
IMidiMsg* one = new IMidiMsg;
// ...
mMIDICreated.Add(one);
IMidiMsg* two = new IMidiMsg;
// ...
mMIDICreated.Add(two);
}
it returns 2, not 8. Where am I wrong?
sizeof will return the size of the object or type itself, it's a constant and is evaluated at compile-time, has nothing to do with the number of items which could be known only at run-time.
You should use IMidiQueue::ToDo:
Returns the number of MIDI messages in the queue.
Assuming that mMIDICreated is a pointer, doing sizeof on a pointer returns the size of the actual pointer and not what it points to. Also note that when passing an array to a function, it decays to a pointer to its first element.
If a function needs the number of elements in an array, you need to pass that along to the function as an argument.
An alternate solution, and one that I recommend over using plain arrays/pointers, is to use std::array (for arrays that are known at time of compilation) and std::vector for "run-time" or dynamic arrays.
Looking at your link:
class IMidiQueue
{
...
IMidiMsg* mBuf;
}
The buffer that stores the elements is not taken into the size returned by sizeof(). Only the size of the pointer itself.
However, there is also a method int GetSize() that could be useful to you.

passing a function a specific array index value

Ive been coding in c and I have an array which is just a char array[22],
I can successfully populate the array with data. there are a few numeric values in the array and i want to check if they fall within a certain range i.e greater than 0 and less than 10 etc.
I have a function, void array_check(testarray[]) declare before the main.
the function is being called inside the main i.e. array_check(testarray[9])
So this should pass the function index number 9, and the function should check if the value of index 9 is between a range etc.
I can't get the program to compile properly. in the function declaration I would have thought the it would be something like this void array_check(testarray[i]) where when I call the function in the main the I would denote the index to check. The compiler tells me that the function decaration and the function itself should have a constant value. It wont allow me to leave the [i] value in the square brackets. any ideas?
thanks guys
If you call check(array[9]), you're just passing the char stored at index 9 in the array, and your function should be declared as
void check(char);
Once you've indexed an array of any type to get the element at that index, there's nothing magically arrayish about the element - it's just a normal object of that type (in this case a char).

Cuda thrust::device_vector get pointer from specific range

I have a vector of vectors:
thrust::device_vector weights_;
which is a continuous amount of memory, where every w items,
represent a vector.
In one of my functions, I pass as parameters the begin and end of that range, like so:
__host__ ann::d_vector ann::prop_layer (
unsigned int weights_begin,
unsigned int weights_end,
ann::d_vector & input
) const
and then, I go and copy into a new vector that range,
and then get a raw pointer which I can use in a kernel:
thrust::device_vector<float> weights ( weights_.begin() + weights_begin,
weights_.begin() + weights_end );
float * weight_ptr = thrust::raw_pointer_cast( weights.data() );
some_kernel<<<numBlocks,numThreads>>>( weight_ptr, weight.size() );
Can I get a pointer from that range, without first copying it to a new vector? That seems like a waste of copy-realloc to me.
In case I can't get a pointer from that range, can I at least assign a vector to that range, without copying the actual values?
Can I get a pointer from that range, without first copying it to a new vector? That seems like a waste of copy-realloc to me.
Yes, you can get a pointer to that range.
float * weight_ptr = thrust::raw_pointer_cast( weights_.data() ) + weights_begin;
In case I can't get a pointer from that range, can I at least assign a vector to that range, without copying the actual values?
No, a thrust vector cannot be instantiated "on top" of existing data.

Misunderstanding of C++ array structure

I'm new to C++ and I learned with different tutorials, in one of them I found an example of code:
I have pointed by numbers of lines, that I completely do not understand;
Does this array in array or something like that?
I can understand the second call, but what is the first doing? There is already
"coordinates[blocks[num]]", aren't there? Why need again blocks(i) ?
How do you make this part of the code easier? Did struct with this arrays
don't make easier getting value from arrays?
Thanks in advance!
// Global vars
Struct Rect {
float left;
}
Rectangle *coordinates;
int *blocks;
coordinates = new Rect[25];
blocks = new int[25];
// in method storing values
const int currentBlock = 0; //var in cycle
coordinates[currentBlock].left = column;
blocks[currentBlock] = currentBlock;
//get element method
const Rect& classA::Coords(int num) const
{
return coordinates[blocks[num]]; //(2)
}
//and calling this method like
Coords(blocks[i]); //(3)
Coords(i); //(3)
// (4)
No, not really. Lots of people will think of them as arrays and even describe them as arrays, but they're actually not. coordinates and blocks are both pointers. They just store a single address of a Rect and an int respectively.
However, when you do coordinates = new Rect[25];, for example, you are allocating an array of 25 Rects and setting the pointer coordinates to point at the first element in that array. So, while coordinates itself is a pointer, it's pointing at the first element in an array.
You can index coordinates and blocks like you would an array. For example, coordinates[3] will access the 4th element of the array of Rects you allocated. The reason why this behaves the same as arrays is because it actually is the same. When you have an actual array arr, for example, and you do arr[4], the array first gets converted to a pointer to its first element and then the indexing occurs.
No, this is not an array of arrays. What it is doing is looking up a value in one array (blocks[num]) and using that to index the next array (coordinates[blocks[num]]). So one array is storing indices into the other array.
I'll ignore that this won't compile, but in both cases you are passing an int to the Coords function. The first case looks incorrect, but might not be. It is taking the value at blocks[i], passing that to the function then using that value to index blocks to get another value, then using that other value to index coordinates. In the second case, you are just passing i, which is being used to index blocks to give you a value with which you index coordinates.
That's a broad question that I don't think I can answer without knowing exactly what you want to simplify and without seeing some real valid code.

C++ conversion from array to pointer

I am bit struggling with kinda easy task. I need to convert array to pointer.
GLfloat serieLine[8][80];
GLfloat *points = &serieLine[0][0];
this gives me just first value, but how can I get all values in the array?
If you want pointer to an array, you can do it like this:
GLfloat (*points)[80] = serieLine;
points will point to the first row of serieLine. If you increment points, it will point to the next row.
Increment the pointer, and it'll point at the next value in the array (so once you've incremented it 8*80 times you'll have seen all of the values)