Detect 'and','or' instruction - llvm

I am using BasicBlock iterator to iterate over the instructions in the basic block. Does the Instruction class provide any direct methods to check whether the instruction is an 'and' or 'or' instruction. If not, is any typecasting necessary?

There is Instruction *I; I->getOpcode() method
getOpcode() returns a member of one of the enums like Instruction::Add.
Definition at line 82 of file Instruction.h.
Casting is not needed when BasicBlock is iterated. It is needed when iterator may return not an Instruction, e.g. when iterating over def-use structures.
Usage is like:
BasicBlock *b = ...;
for (BasicBlock::iterator i = b->begin(), ie = b->end(); i != ie; ++i) {
Instruction* I = &*i; // get Instr pointer from iterator.
switch (I->getOpcode()) {
case Instruction::And: // code
case Instruction::Or: // code
default: // other type
}
}
Documentation used to write this answer: http://llvm.org/docs/ProgrammersManual.html

Related

Iterate over key/value pairs in associative array in D.

I don't know why I cannot find an answer to this on the web. It seems such a simple thing.
The associative array has a byValue member and a byKey member for iterating over the values and the keys. There's also a byKeyValue member for iterating over key/value pairs. It's just not clear what type it returns for iterating using foreach, and the compiler complains that auto is not good enough here.
The language docs (https://dlang.org/spec/hash-map.html) call it an "opaque type".
Any idea how to get the commented code working? Thank you!
int main(){
int[string] contained;
contained["foo"] = 4;
contained["bar"] = 5;
contained["gooey"] = 7;
writeln("*by values*");
foreach(int i ; contained.byValue){
writeln(i);
}
writeln("*by keys*");
foreach(string i ; contained.byKey){
writeln(i);
}
// writeln("*by key/values*");
//foreach(auto i ; contained.byKeyValue){
//writeln(i.key,i.value);
//}
return 0;
}
So first, you don't even strictly need a thing:
foreach(key, value; contained) {
// use right here
}
But the .byKeyValue thing can be more efficient, so it is cool to use... just don't specify a type at all (in fact, you very rarely have to with D's foreach, and btw it is always wrong to use auto in the foreach statement - a common mistake since it is used in many other places...)
foreach(item; contained.byKeyValue()) {
writeln(item.key, " ", item.value);
}
Also btw you can use void main if you always want main to return 0 - the language will do that automatically.

Usage of Instruction* llvm::Instruction::user_back ( )

I am learning llvm now. I am confused with Instruction::user_back().
The docs said "user_back - Specialize the methods defined in Value, as we know that an instruction can only be used by other instructions. " But I still don't know what it returns.
I couldn't find more information about it. I guess for an instruction u, if u is in i->users(), u->user_back() will return i. When I tried to check my guess, I encountered with the following runtime error:
opt: /usr/local/include/llvm/IR/Value.h:144: UseT& llvm::Value::use_iterator_impl<UseT>::operator*() const [with UseT = llvm::Use]: Assertion `U && "Cannot dereference end iterator!"' failed.
My pass is like this:
for (auto &B : F) {
for (auto &I : B) {
if (auto *target = dyn_cast<AllocaInst>(&I)) {
for(auto it : target->users()){
if (Instruction *I = dyn_cast<Instruction>(it)){
Instruction *temp = I->user_back();
errs() << "user_back"<< *temp <<"\n";
//Aborted (core dumped)
}
}
}
}
}
My first question is whether I misunderstood the usage of Instruction* llvm::Instruction::user_back(), what's the correct meaning of it?
My second question is for an Instruction U, if U is in Instruction I->users(), is there a method to obtain whose user U is? In this case, is there a method for me to obtain I from U please? Could U->user_back() return I please?
Many thanks in advance :)
Your understanding of user_back is exactly backward.
Each Value V has a set of users -- other Values that use V. So user_back is the last such user in the list. You're getting the assert because your instruction u apparently doesn't have any users. Check user_empty first.
You want the opposite relationship: given instruction U, find instructions used by U. To get that you have to iterate over U's operands. Each operand O is a Use and O.get() will retrieve the Value used, which could be a Constant, Instruction or any kind of Value. Since LLVM IR is in SSA there will be only once such Value for each operand.
In short, the answer to your second question is, "Iterate over U's operands and one of those will be I."

Is there a NULL equivalent for pairs in C++?

What would I want to use instead of NULL if I have an unassigned pair in C++?
As an example, suppose I have (pseudo)code like the following:
pair<int,int> bestPair; //Global variable
updateBestPair(vector<int> a, vector<int> b) {
bestPair = NULL;
for (/* loop through a and b */) {
if (/* pair(a,b) is better than bestPair and better than some baseline */)
bestPair = make_pair(a,b);
}
if (bestPair != NULL) //Found an acceptable best pair
function(bestPair);
else
cout<<"No acceptable pairs found"<<endl;
}
Is there a NULL equivalent for pairs in C++?
No.
What would I want to use instead of NULL if I have an unassigned pair in C++?
Here are a few options:
you can use a pointer to a pair, which can be set to NULL; This is probably not the best solution (since you are clearly not requiring a pointer)
you can use a boost::optional<std::pair<int,int>>;
you can (and probably should) rewrite your code not to use a global variable.
you can restructure your control flow to avoid checking for a valid pair as a separate step:
pair<int,int> bestPair; //Global variable
updateBestPair(vector<int> a, vector<int> b) {
// not needed
// bestPair = NULL;
//loop through a and b
if (/* pair(a,b) is better than bestPair and ... */)
{
bestPair = make_pair(a,b);
function(bestPair);
}
else
cout<<"No acceptable pairs found"<<endl;
}
you can choose an artificial value to represent "invalid pair value":
// use as constant, wherever you used NULL before
const auto invalid_pair = std::make_pair(
std::numeric_limits<int>::max(),
std::numeric_limits<int>::max());
you can use a boolean flag:
pair<int,int> bestPair; //Global variable
updateBestPair(vector<int> a, vector<int> b) {
bool initialized = false;
//loop through a and b
if (/* pair(a,b) is better than bestPair and ... */)
{
bestPair = make_pair(a,b);
initialized = true;
}
if(initialized)
function(bestPair);
else
cout<<"No acceptable pairs found"<<endl;
}
you can use a custom solution (similar to boost::optional wrapper or not)
No. C++ objects cannot be "NULLed".
(Even pointers, which are objects, cannot be "NULLed"! This is confusing because their value may be set to a null pointer value, which we sometimes in the past obtained with a macro named NULL; however, this has never been the same as "NULLing" the pointer itself. Er, anyway…)
I recommend either boost::optional, or rethink the idea of having a global variable that can be "has a useful value" or "does not have a useful value". What's the point in it existing if it has no useful value?
No, that is not possible. You could use an additional variable to indicate the validity of the pair (that you have a pair).

How can I check if the key exists in a std::map and get the map::iterator in if condition?

I'd like to define the variable in condition expression so that the variable scope would be within the if clause. This works fine,
if (int* x = new int(123)) { }
When I was trying to do a similar thing with map::iterator,
if ((map<string, Property>::iterator it = props.find(PROP_NAME)) != props.end()) { it->do_something(); }
I got error: expected primary-expression before ‘it’
What makes the difference between int* and map::iterator?
There's no difference between int * and map::iterator in that regard. There's a difference in the surrounding semantic constructs that you are using with int * and map::iterator, which is why one compiles and other doesn't.
With if you have a choice of either
if (declaration)
or
if (expression)
Declaration is not an expression. You can't use a declaration as a subexpression in a larger expression. You cannot use a declaration as a part of explicit comparison, which is exactly what you attempt to do.
For example, if you attempted to do the same thing with int *, like this
if ((int* x = new int(123)) != NULL)
the code would not not compile for exactly the same reasons your map::iterator code does not compile.
You have to use
if (int* x = new int(123))
or
int* x = new int(123);
if (x != NULL)
or
int* x;
if ((x = new int(123)) != NULL)
As you can see above, int * exhibits exactly the same behavior as map::iterator.
In your example, it is impossible to declare it and perform its comparison with props.end() in ifs condition. You will have to use one of the above variants instead, i.e. either
map<string, Property>::iterator it = props.find(PROP_NAME);
if (it != props.end())
or
map<string, Property>::iterator it;
if ((it = props.find(PROP_NAME)) != props.end())
Choose whichever you like more.
P.S. Of course, formally you can also write
if (map<string, Property>::iterator it = props.find(PROP_NAME))
but it does not do what you want it to do (does not compare the iterator value to props.end()) and might not compile at all, since the iterator type is probably not convertible to bool.
Here is one way to limit it to a scope:
{
auto it = props.find(PROP_NAME);
if (it != props.end()) {
it->do_something();
}
}
Granted, this scope is not technically the "if scope", but should serve just as well for all practical intents and purposes.
As AndreyT already explained (+1), declaration can't transcend ( and ), which you did not use for int but you did for the iterator.
Map iterators contain first and second, which point to the key and value, respectively.
To access a member of the value, use it->second.do_Something()

How should I pass this std::array<> to a function?

std::array<LINE,10> currentPaths=PossibleStrtPaths();
LINE s=shortestLine(currentPaths); //ERROR
LINE CShortestPathFinderView::shortestLine(std::array<LINE,10> *currentPaths)
{
std::array<LINE,10>::iterator iter;
LINE s=*(currentPaths+1); //ERROR
for(iter=currentPaths->begin()+1;iter<=currentPaths->end();iter++)
{
if(s.cost>iter->cost)
s=*iter;
}
std::remove(currentPaths->begin(),currentPaths->end(),s);
//now s contains the shortest partial path
return s;
}
At both those statements I'm getting the same error: no suitable conversion from std::array<LINE,10U>*currentPaths to LINE . Why is this so? Should I pass the array another way? I've also tried passing currentPaths as a reference, but it tells me that a reference of the type cannot be initialized.
You said you tried a reference and it failed. I don't know why, because that was the correct thing to do.
LINE CShortestPathFinderView::shortestLine(std::array<LINE,10> &currentPaths);
From the sounds of it, you also used a reference for the temporary variable. That's wrong.
std::array<LINE,10>& currentPaths = PossibleStrtPaths(); // WRONG
std::array<LINE,10> currentPaths = PossibleStrtPaths(); // RIGHT
LINE s = shortestLine(currentPaths);
And finally, the first element is number zero. The subscripting operator [] is preferred when you are doing array access. So:
LINE s = currentPaths[0];
But you also can easily get the first item from the iterator.
Final code:
/* precondition: currentPaths is not empty */
LINE CShortestPathFinderView::shortestLine(std::array<LINE,10>& currentPaths)
{
std::array<LINE,10>::iterator iter = currentPaths.begin();
LINE s = *(iter++);
for(; iter != currentPaths->end(); ++iter) {
if(s.cost>iter->cost)
s=*iter;
}
std::remove(currentPaths.begin(), currentPaths.end(), s);
//now s contains the shortest partial path
return s;
}
You are dereferencing (currentPaths+1) which is of type std::array* (more precisely: you are incrementing the pointer and then accessing its pointed data) while you probably want to retrieve the first element of currentPaths, that is: currentPaths[0] (the first index in an array is 0).