Converting from GenericValue to Value* in setOperand - llvm

I'm using interpreter. I need to convert GenericValue to Value * in function setOperand. For example,
GenericValue newV;
I.setOperand(0, (Value*)newV);
I'm inserting some results in newV, then I need to insert it to a certain instruction as example.

Related

Can't modify the value of a reference in Range based loop

I'm working on a school project of boolean minimization, and here I want to delete some elements of a set of my user defined class.
This is where the error occurs:
(dc and PI are both sets of my class Term, passed to this function by reference. std::set<Term>& dc, PI)
for (const auto& n : dc) {
for (const auto& i : n.getMinterm()) {
m[i] = 0;
for (auto &x : PI) {
x.delMinterm(i);
}
}
}
The error message is:
Error (active) E1086 the object has type qualifiers that are not compatible with the member function "Term::delMinterm"
Error C2662 'void Term::delMinterm(int)': cannot convert 'this' pointer from 'const Term' to 'Term &'
This is the content of my class:
class Term {
private:
int group = 0;
int literal = 0;
std::string term;
std::set<int>minterm;
bool isDontCare;
bool merged;
};
Function delMintern(int) just erases the selected element from the set minterm.
Though I didn't use "const auto&" but "auto&", it still shown as a const object.
I've tried taking off the '&' but it just create a local duplicate, however, I want to directly modify the original one.
I also tried something like:
for (auto x : PI) {
PI.erase(x);
x.delMinterm(i);
PI.insert(x);
}
but it caused a "read access violation" error.
You can't modify a reference to x because it is const. It is const because iterating a std::set through loop gives only const values.
See solution with const_cast example code at the end of my answer.
It is known that std::set stores all entries in a sorted tree.
Now imagine if you can modify a variable when iterating a loop, it means that after modification sorted order of std::set might be changed. But std::set should always keep invariant of its tree, hence it can't allow to make any modifications thus gives only const values when iterating.
If you need to really modify set entry then you have to take it from set, delete from set and that add again to set. Even if sorted order is not changed after your modification, still you need to reinsert into set.
But there is a hacky workaround - you can make your method delMinentry as having const modifier. Then all fields that it modifies should be marked as mutable. Mutable fields allow modifications from const methods. And std::set allows to call const methods when iterating.
There is one more workaround - you make delMinterm() as const method, but inside this method do const_cast<Term &>(*this).delMintermNonConst(), in other words from const method you can call non-const method if you do const_cast. Also you can do const cast directly on loop variable if you're sure what you do, in other words if you modify Term in such a way that std::set sorted order is not changed:
for (auto &x : PI) {
const_cast<Term &>(x).delMinterm(i);
}
If delMinterm() results in such modification of a Term after which order of std::set may change then you can't do const_cast in code above. In other words if after delMinterm your operator < may give a different result between terms, then you can't do this const cast and you have to reinsert into set (delete Term and add again).
Also don't forget that after reinserting into set you have to redo set iteration loop again from start, because after change to inner structure you can't keep iterating loop running further, iterators are invalidated.
If set's order changes (hence you can't do const_cast) then you have to re-insert values of set, do this by copying values to vector, modifying them through delMinterm(), copying back to set, like this:
std::vector<Term> scopy(PI.cbegin(), PI.cend());
for (auto & x: scopy)
x.delMinterm(i);
PI = std::set<Term>(scopy.cbegin(), scopy.cend());

pushing a big float inside a tuple Julia

I am trying to "push" a big float into a Tuple. But get following error:
# where test() is a function with big floats as values
store = Tuple{Any, Any}][]
for i in 1:10
push!(store, test(i))
end
store
The error message mentions convert() as a solution, but I am not sure how to convert test().
You cannot push BigFloat into a container that accepts only Tuples. Your container has to accept BigFloats instead, so initialize it with:
store = BigFloat[]
Also note that you could have just written:
store = test.(1:10)

Passing an array of structure elements

I am doing some vector computations using the NE10 library. The library has a type for a complex number which is a struct like this:
typedef struct
{
ne10_float32_t r;
ne10_float32_t i;
} ne10_fft_cpx_float32_t;
I would like to have a function, which takes an array of these structs (1D array of complex numbers) as an argument and performs a vector computation for only the r or i elements of the array. Here is an example of such function to get an idea:
void multiple_real_part_by_two(ne10_fft_cpx_float32_t* output,
ne10_fft_cpx_float32_t* input, ne10_uint32_t array_length)
{
ne10_mulc_float_c (&output->r, &input->r, 2.0, array_length)
}
So I would like the output array to be like the input array, but each of the r elements should be multiplied by two. The problem is, the way the function is written above does not work, and leads to a segmentation fault. I think the problem is in how I am trying to pass an array of the r elements to the ne10_mulc_float_c() function.
The ne10_mulc_float_c() function takes as arguments pointers to two arrays of type ne10_float32_t of size array_length. The elements of the input array are multiplied by the number passed as the third argument, and the result is stored in the output array. The documentation can be found here.
Is there a way I could do this? I know I could just do this in a for loop
for (int i = 0; i < array_length; i++) {
output[i].r = input[i].r * 2.0
}
but I don't want to do this since performance is critical, which is why I am trying to use the vector operations provided by NE10 in the first place.
The problem is that you give ne10_mulc_float_c() arguments of the right type, but which do not match the assumptions.
According to the library's documentation page, the function is defined as:
ne10_result_t ne10_mulc_float_c (ne10_float32_t *dst, ne10_float32_t *src,
const ne10_float32_t cst, ne10_uint32_t count)
with the following arguments:
[out] dst Pointer to the destination array
[in] src Pointer to the source array
[in] cst The constant to multiply by
[in] count The number of scalar values to be processed
This means that the function assumes that dst and src are are pointers to arrays of count CONSECUTIVE floating point numbers.
Unfortunately, the is is not the case with the arguments that you pass:
&output->r and &input->r are both pointers to one single float. So as soon at this function tries to access the second item in the array it expects, it code goes beyond the array's real bounds and this is UB. This is why it doesn't work and you get the segmentation fault.
Your for-loop is just fine. Don't forget:
Premature optimization is the root of all evil.
-- Donald Knuth

Identify an object in a container using object name?

If there is the following vector1:
vector<string*> cont; // cont[0] == "0"
where pointers to strings are named either l or r; are sequentially added like so:
string r* = new string("1");
cont.emplace_back(r);
or:
string l* = new string("-1");
cont.emplace_back(l);
For example: if there is a direction to a node given like: "lrlrrr".
Is there a way to search through the vector using the string names, l and r, as "element id" rather than string content2?
Note: I've researched finding a vector element by native property, however, I'm interested if there is alternative way.
1. The vector stores sequentially (level by level) the nodes of a binary tree, where each left node's,l, value is: parent value - 1 and each right node's, r, value is: parent value + 1.
2. Comparing current and previous node values determines if current node left or right.
It is generally weird to use pointers to string in C++, since string internally contains a pointer to char giving a double indexation. But in this use case, it could make sense, if you store pointers to the same constant objects:
static string _r = "1";
static string _l = "-1";
const string * r = &_r;
const string * l = &_l;
then you could do
cont.emplace_back(r);
or
cont.emplace_back(l);
Because when iterating the vector of pointers you can do if (cont[i] == r) ...
If you really build new different objects on each step, storing pointers would only make sense if you need polymorphism, but it would be hard to test as identity if you do not have a know set of possible objects.
Is there a way to search through the vector using the string names?
No, because the names, l or r, are local variables1 that get destroyed after the string is stored in the vector. Once stored, the vector indexes become "names" of the stored strings.
1. l and r are rvalues and their addresses can not be obtained after the execution of the function that contains them.

Passing a pointer to an array of arrays to a function

I have a main function which sets up the following variables:
double matrix[numVectors][size] = {
{0.183963, 0.933146, 0.476773, 0.086125, 0.566566, 0.728107, 0.837345, 0.885175, 0.600559, 0.142238},
{0.086523, 0.025236, 0.252289, 0.089437, 0.382081, 0.420934, 0.038498, 0.626125, 0.468158, 0.247754},
{0.969345, 0.127753, 0.736213, 0.264992, 0.518971, 0.216767, 0.390992, 0.242241, 0.516135, 0.990155}
};
double result1[size], result2[size];
double *ptr_matrix = &matrix[0];
double *ptr_result1 = &result1[0];
double *ptr_result2 = &result2[0];
What the above is trying to do is:
Create an array with three rows of 10 doubles
Create two empty arrays of 10 doubles
Create a pointer to the matrix
Create pointers to the two empty arrays
Then, I'm trying to pass all three pointers to another function. This other function will iterate over the matrix rows (only the rows, it doesn't visit the whole matrix space), perform a computation using the row (as an array). The end result is the two empty arrays declared at the beginning end up each becoming one row from the matrix.
Here is the prototype of the second function:
void smallestSum(double (*mat)[size], int num, double *first, double *second)
This function goes through each combination of the matrix rows (0/1, 0/2, 1/2) and checks the sums of their values. The two arrays producing the smallest sum eventually become result1 and result2 from above.
Seeing as this is the first time I'm really delving into pointer/array/matrix territory, I have a few questions:
Am I correctly "getting" a pointer to the matrix? Or do I need to get a pointer to the first value of the matrix instead?
In smallestSum(), can I iterate over the array as I would normally (using for (int i = 0; i < num; i++)?
You need to change the definition of ptr_matrix, as it's not a pointer to a single double, but to the whole row:
double (*ptr_matrix)[size] = &matrix[0];
Then, you can call the function as follows:
smallestSum(ptr_matrix, numVectors, ptr_result1, ptr_result_2);
Inside smallestSum, you can iterate both over rows and over columns.
Note that size must be known at compilation time.
If the function doesn't modify the matrix, consider adding const to the type of its first argument.
The answer abacabadabacaba gave is mostly correct except that size does not need to be known at compile time. If you include size as a parameter to the function you can use it as part of the type for other parameters to that function:
void smallestSum(int size, double (*mat)[size], int num, double *first, double *second)