How to get the loop induction variables' name in LLVM? - llvm

I want to get the loop induction variables' name, is it right to get the name as following?
void analyze_loop(Loop* loop) {
errs() << loop->getCanonicalInductionVariable()->getName() << "\n";
}

Yes, that looks correct - assuming, of course, that a canonical induction variable could be found.

Related

Why do I get "unhandled exception" error and how can I fix it?

I am trying to write a code that uses 2 recursive functions; 'I' and 'U' and one non-recursive function 'f'. What I am tring to achive is to run the recursive function I "steps1" many times and then stop at this level to then run the recursive funtion U "steps2" many times.
After that, finally run the non-recursive function f at the level where function U's iteration ends.
For example:
Let steps1=1 and steps2=1 then,
I will iterate function 'I', 1-time(steps1) and get:
I(n)= 3*I(n/2)+7*n-3
then, I will iterate funtion U, 1-time(steps2) for n/2 value. And then, insert it instead of I(n/2), thus I will calculate:
I(n)= 3*[U(n/2)]+7*n-3= 3*[2*U(n/6)+2*(n/2)-9] = 3*2*U(n/6)+3*2*(n/2)-3*9
now insert last function f(n/6), into this equation:
3*2*U(n/6)+3*2*(n/2)-3*9=3*2*f(n/6)+3*2*(n/2)-3*9
since f is non-recursive, this will give me the result.
When I run my code I get, "unhandeled exception" error. Can someone help me find the reason for this error? Is my code wrong at somewhere? Can someone help me fix this please? I am not sure if my code does exactly what I want to do, as well?
#include<stdlib.h>
#include<bits/stdc++.h>
using namespace std;
int f(int n)
{
return (n-1)*(n-1);
}
/* step2 many iteration of the function U and then function f */
int U(int n , int steps2, int counter2=0)
{
if(counter2==steps2){
return f(n);
}
return 2*U(n/3, steps2, counter2+1)+2*n-9;
}
/* step1 many iteration of the function I and then function U*/
int I(int n , int steps1,int steps2, int counter1=0, int counter2=0)
{
if(counter1==steps1){
return U(n,steps2,counter2);
}
return 3*I(n/2, steps1, counter1+1)+7*n-3;
}
int main(){
int n, steps1,steps2;
cout<< " Enter 'n' value which is divisable by both 2 and 3"<<"\n";
cin>>n;
cout<< " Enter iteration count for I"<<"\n";
cin>>steps1;
cout<< " Enter iteration count for U"<<"\n";
cin>>steps2;
cout<< " result:" << I(n,steps1,steps2)<<"\n";
getchar();
return 0;
}
I compiled and ran your program and it looks like you're getting a stack overflow. The recursion for function I isn't correct. Namely your base case will never be reached. In each location that I is called you only pass 3 parameters, thus counter1 is always going to have a value of 0, the default value. Also, I is always called such that steps1 is always going to have the same value (from the user's input). So if(counter1==steps1){ will never be true.
Some advice for future problems, when troubleshooting a problem like this, one of the easiest things you can do is to add a cout to the beginning of each function. Print the function name and the parameter values. Another option is to hook up a debugger and set some break points. Learning how to use a debugger with C++ will come in very, very handy.

Understanding Variable Scope

I am confused about variable scope and would like to better understand it.
Moved cout oddS and cout evenS to outside for loop. Code executes properly. If moved inside for loop, code executes with improper values for oddS and evenS.
#include <iostream>
#include <vector>
#include <cmath>
int main()
{
double evenS, oddS, pH = 0;
std::vector<double> v1 = {2, 4, 3, 6, 1, 9};
for(int i = 0; i < v1.size(); i++)
{
pH = v1[i];
if(fmod(pH, 2) == 0)
{
evenS = evenS + v1[i];
}
else if(fmod(pH, 2) == 1)
{
oddS = oddS + v1[i];
}
}
std::cout << evenS << "\n";
std::cout << oddS << "\n";
}
I was expecting the oddS and evenS to not hold the proper values if incremented outside of the for loop. However, the contrary is true, which produced my confusion.
Your code has Undefined Behaviour (it contains a bug), which means it can do literally anything. It makes little sense to try to analyse why moving statements around changes output, or how [counter-]intuitive they are.
The problem is in the fact that your variables evenS and oddS are not initialised, and you're reading their values before writing to them. Reading an uninitialised value is UB.
You probably meant to write this as the definition:
double evenS = 0, oddS = 0, pH = 0;
Each variable being declared in a declaration needs its own initialiser if it is to have one.
As #Angew mentioned, you have a bug in your code and he suggested a fix. The following topic is helpful to understand uninitalized values: What happens to a declared, uninitialized variable in C? Does it have a value?
As for variable scope, if you bring std::cout << evenS << "\n"; and std::cout << oddS << "\n"; into the loop, the values of evenS and oddS would be printed more frequently.
Here's an explanation of scope from Tutorials Point (annotations in square brackets):
A scope is a region of the program and broadly speaking there are three places, where variables can be declared −
Inside a function or a block which is called local variables. [Here block means a portion of code starting and ending on these brackets {}]
In the definition of function parameters which is called formal parameters.
Outside of all functions which is called global variables.
Local Variables
Variables that are declared inside a function or block are local variables. They can be used only by statements that are inside that function or block of code. [if you try to access outside either compiler will give you an error.]
Global Variables
Global variables are defined outside of all the functions, usually on top of the program. The global variables will hold their value throughout the life-time of your program.
Now in your case as you said
Moved cout oddS and cout evenS to outside for loop. Code executes
properly. If moved inside for loop, code executes with improper values
for oddS and evenS.
If you declare variable inside for loop, its scope will remain within that block (within that loop).

Add multiple parameters to IN clause in SQLAPI c++

I am using SQLAPI to connect to a SQL-Server database from a C++ code. I need to execute a simple select statement with a IN clause, where the string values in the clause is received as a vector of strings. We want to use parameterised queries so did something like this:
std::string getSQLQuery(std::vector<std::string> ids){
std::stringstream sql;
sql << "SELECT ID, Name, DOB FROM Employees WHERE ID IN (";
unsigned int counter = 0;
for each (auto id in ids)
{
sql << ":" << counter + 1;
if (++counter < ids.size())
{
sql << ",";
}
}
sql << ")";
return sql.str();
}
And then,
int param_counter = 0;
for each (auto id in ids) {
command.Param(++param_counter).setAsString() = id.c_str();
}
Can anyone please suggest a better way of doing it?
Well, I don't want to undercut your basic question, which I take to be "What's a good way to do this?", but you have some basic syntax problems with your C++. Inferring your intention from the buggy code above, I gather that the goal is to create a command synthesizer with a common SQL select query from an arbitrary set of input id's. Cool. I don't think there's any up-side to first creating a synthesized template command with insertion points and then using their parameter replacement scheme. Might as well do the synthesis all at once. A compile-time-correct version would look something like this (with a few tweaks to make it more reusable) -
std::string getSQLQuery(
const std::string& columns
, const std::string& table
, const std::vector<std::string>& ids
){
// Check for empty strings/arrays here - leads to illegal SQL,
// so error out or except on empty ids, columns, or "table".
std::stringstream sql("SELECT ", std::ios_base::out | std::ios_base::ate);
sql << columns << " FROM " << table << " WHERE ID IN ( ";
// Trailing commas are not allowed in SQL, which makes synthesis a little trickier.
// We checked for empty inputs earlier, so we have at least one ID.
auto iter = ids.begin();
sql << *iter++; // add the first (and possibly only) ID
for (; iter != ids.end(); ++iter) { // add the rest (if any) with commas
sql << ", " << *iter;
}
sql << " )"; // <- should this be " );"? Or does SQLAPI++ deal with that?
return sql.str(); // There's a shrink-to-fit method you may want to use here.
}
Now you can just do something like -
std::vector<std::string> id_array{ "1", "50", "aardvark" };
SACommand basic_command(connection, getSQLQuery("ID, Name, DOB", "Employees", id_array));
basic_command.Execute();
This skips the second substitution phase entirely. The SQLAPI++ parameter substitution is intended for queries with a much more rigid template, but you're doing something more dynamic. You can imagine extending this further with input arrays of columns as well, to avoid syntax errors in the table list (like we do in the id list). Also, since id's are often numerical, you could make the id array std::vector<std::uint64_t> or whatever fits your specific application. In fact, you can handle both cases with the same body of code by making the signature -
template<typename T> std::string getSQLQuery(
const std::string& columns
, const std::string& table
, const std::vector<T>& ids
){
... // rest of the implementation is the same
}
I'm a new contributor, but a long-time user, so just a word about questions. When you ask a question like, "Can anyone please suggest a better way of doing it?", the answer is always "Yes.". There are a lot of smart people out there and an infinity of solutions to every high-level problem. In the future, you want to state the problem you're trying to solve (not hard to figure out in this case), and if you show a solution that was tried and failed, you should give specifics about how it failed. In the case of the code you put forth, the most obvious reason it failed is that it is syntactically wrong - the compiler would not accept it. "for each" is from some other languages. In C++, it's something like "for (auto id : ids)". But if you were just trying to show some kind of pseudo-code, it suggests that you don't really know if your existing approach works, because it hasn't been tried. And even in that case, you should say what you don't like about the presented solution (like the unnecessary second step of using the SQLAPI++ substitution scheme), and ask specifically if someone can think of a way to remove that. I'm a talker, and I would have given the same response, but for future reference, try to avoid a question that comes down to, "The following code is broken. Someone fix it for me." Just FWIW.

for_each function in c++11

I have vector of integers filled with 5 numbers and i'm curious what exactly does [&idx] do in :
int idx = 0;
for_each ( x . begin (), x . end (), [&idx] ( const int & a ) { cout << idx ++ << " " << a << endl; } );`
Why it does not work like this ? :
int idx = 0;
for_each ( x . begin (), x . end (), ( const int & a, int & idx ) { cout << idx ++ << " " << a << endl; } );
Is it better from perfomance point of view than? :
for ( vector<int>::size_type i = 0; i < x . size (); i ++ )
cout << x[i] << endl;
I'm curious what exactly does [&idx] do
That's the lambda capture. It sets the lambda to take a reference to idx. It won't work as a parameter because for_each only passes one parameter to the predicate. If you made idx a parameter instead, it wouldn't compile.
Also is it better from a performance point of view?
Possibly. If you really want to know, test each way of doing it.
what exactly does [&idx] do in
the
[](){}
structure, as of C++11, is a lambda function - that is, an anonymous function which, in this context, will be callbacked with the vector elements passed as arguments. The [&idx] denotes that the variable idx which DOES NOT NORMALLY BELONG to the lambda's environment and which is NORMALLY INACCESSIBLE by the latter, should be instead accessible (captured) in it by reference. This means that you can use idx within the body of the lambda and that whenever you do so you are using a reference to the original variable. Therefore, the idx++ part of the code increments the original idx variable and not some local copy.
Why it does not work like this ?
because () {} structures are not a valid C++ expressions or statements.
Is it better from perfomance point of view than? :
Probably, but not necessarily, you should measure to find out for sure. However, it is both advisable and idiomatic to use iterators and algorithms rather than C-style loops. Given the standard "avoid premature optimisation" guideline, I suggest that you use the first version by default and when you're done with all development you can decide if you want to dedicate some time to try-out and measure alternatives such as the second. If this is not in some critical part of your program (such as in some callback function), I don't think it deserve the fuss, the difference would be very small anyway.
Just for reference, in my system, using clang++ with -O3 flag, 1000 iterations of your std::foreach version would last 4967ms while 1000 of the for one 3861ms. That's approximately 1second for 1000 iterations, e.g. 1ms if you only run this code once..

C++ Standard Library hash code sample

I solved a problem to find duplicates in a list
I used the property of a set that it contains only unique members
set<int> s;
// insert the new item into the set
s.insert(nums[index]);
// if size does not increase there is a duplicate
if (s.size() == previousSize)
{
DuplicateFlag = true;
break;
}
Now I am trying to solve the same problem with hash functions in the Standard Library. I have sample code like this
#include <functional>
using namespace __gnu_cxx;
using namespace std;
hash<int> hash_fn2;
int x = 34567672;
size_t int_hash2 = hash_fn2(x);
cout << x << " " << int_hash2 << '\n';
x and int_hash2 are always the same
Am I missing something here ?
For std::hash<int>, it's ok to directly return the original int value. From the specification, it only needs to ensure that for two different parameters k1 and k2 that are not equal, the probability that std::hash<Key>()(k1) == std::hash<Key>()(k2) should be very small, approaching 1.0/std::numeric_limits<size_t>::max(). Clearly returning the original value satisfies the requirement for std::hash<int>.
x and int_hash2 are always the same Am I missing something here ?
Yes. You say "I am trying to solve the same problem with hash functions", but hash functions are not functional alternatives to std::set<>s, and can not - by themselves - be used to solve your poroblem. You probably want to use a std::unordered_set<>, which will internally use a hash table, using the std::hash<> function (by default) to help it map from elements to "buckets". For the purposes of a hash table, a hash function for integers that returns the input is usually good enough, and if it's not the programmer's expected to provide their preferred alternative as a template parameter.
Anyway, all you have to do to try a hash table approach is change std:set<int> s; to std::unordered_set<int> s; in your original code.