LLVM BasicBlock pass - llvm

I am a beginner of LLVM. I am trying to move among the instructions of a BasicBlock and I cannot. In this particular example, I try to get the previous instruction of the end instruction. I am trying 2 methods:
I have the following sequence of code:
bool patternDC::runOnBasicBlock(BasicBlock &BB) {
...
if (BB.getTerminator())
{
Instruction* current = BB.getTerminator();
errs() << "\n LAST: "<<*current<<"\n";
Instruction* prev = &BB.back();
errs() << "\n PENULTIMATE: "<<*prev<<"\n";
...
The terminal prints the SAME instruction. I don't know how back() works. (Definition at line 199 of file BasicBlock.h.)
I also tried :
bool patternDC::runOnBasicBlock(BasicBlock &BB) {
...
BasicBlock::const_iterator I = BB.begin();
BasicBlock::const_iterator E = BB.end();
BasicBlock::const_iterator prev_iter,last_iter;
prev_iter = NULL; last_iter = NULL;
for(;I!=E;I++){
prev_iter = last_iter;
last_iter = I;
}
if(prev_iter){
errs() << "prev_iter: " << *(dyn_cast<Instruction>(prev_iter)) << "\n";
}
if(last_iter){
errs() << "last_iter: " << *(dyn_cast<Instruction>(last_iter)) << "\n";
}
// not related to the main question: uncomment the next line for an unusual
//behavior: lastlast is DIFFERENT from last.lastlast=section(BasicBlock)
// errs() << "lastlast: " << *(dyn_cast<Instruction>(I)) << "\n";
...
Instruction* prev = *(dyn_cast<Instruction*>(prev_iter));
errs() << "\n prev: "<<*prev<<"\n";
The terminal prints out well prev and last, but I have compilation errors when trying to assign to Instruction* prev
The Clang error is:
".....
/home/alex/llvm/include/llvm/Support/Casting.h:51:28: error: ‘classof’ is not a member of ‘llvm::Instruction*’"
If someone knows a better way to use any element from the basic block or knows why these are not working, please let me know :)
Thank you,
Alex

All LLVM Instruction classes are also ilist_node, which means you can query them for the next/previous instruction in the list that holds them (in this case the basic block). More concretely to your question:
Instruction* last = BB.getTerminator();
Instruction* prev = last->getPrevNode();
See the definition of ilist_node in LLVM's source to see the relevant APIs.

I solved by checking if(BB->size()>1) for a basic block with only an element

Related

Iterating of a simple hello world program with llvm

I am new to llvm framework and I am starting very basic. What's more basic than a hello world?
I want to iterate over my main function in main.c. It looks like the section
"Iterating over the BasicBlock in a Function" would be a good place to start"
Function &Func = ...
for (BasicBlock &BB : Func)
// Print out the name of the basic block if it has one, and then the
// number of instructions that it contains
errs() << "Basic block (name=" << BB.getName() << ") has "
<< BB.size() << " instructions.\n";
What do I set Function &Func =
to?
I want to look at the main function in my main.c file.
While we're on this topic. What would I set BasicBlock& BB = ... to?
My code.
bool Prereqs::runOnModule(Module &M) {
/* Add your code here */
errs() << "Hi: ";
errs().write_escaped(M.getName()) << '\n';
NumOfFunctions +=10;
outs()<<"get opcode yields: getOpcode()" <<"\n";
Function &Func = main.c;
for (BasicBlock &BB : Func)
// Print out the name of the basic block if it has one, and then the
// // number of instructions that it contains
// errs() << "Basic block (name=" << BB.getName() << ") has "
// << BB.size() << " instructions.\n";
print(M);
return false;
}
documentation
https://releases.llvm.org/8.0.0/docs/ProgrammersManual.html#basic-inspection-and-traversal-routines
You'll probably want to set Func to the return value of Module::getFunction() and if you don't know what a Module is or how to make one, there is a tutorial.

Simplify Do While Loop Checking for Null Pointer

I have a really basic problem that I can't figure out. I'm using chaining with hash tables to store nodes that collide with each other. I used a do while loop to print the first node at least once, and continue to print the chained nodes if they exist. However, in order to traverse the chained list, I need to change the address of the node for the next loop. Any way I try writing this, I find myself repeating code, which I was trying to avoid by using this loop. Please help
do {
cout << "Bid id: " << table.at(i)->bidId << " title: " << table.at(i)->title <<
" fund: " << table.at(i)->fund << " amount: " << table.at(i)->amount << endl;
if (table.at(i)->next!=nullptr){//check if first node has next node
table.at(i) = table.at(i)->next; //change address to the next pointer
}// how do I avoid repeating my condition below?
}
while (table.at(i)->next!=nullptr);
This code will replicate the functionality in your loop without duplicating the check against NULL.
while(true)
{
cout << /* stuff */ endl;
auto next = table.at(i)->next;
if(next)
table.at(i) = next;
else
break;
}
From the description though, are you sure you want to reassign the values inside your hash map while looping over them? I suspect that this code may suit your intent/needs better:
auto current = table.at(i);
while(current)
{
cout << /* stuff */ endl;
current = current->next;
}
When you find yourself in a situation like this one, it's a good idea to question your premise. In this case, I am talking about your assumption that you need a do while loop.
If there is a chance that your data won't be there or that your container is empty, then a do while won't do the job because it will loop at least once.
Generally, for iterating through a collection of data you'll want to use a for or while loop.
If I understand the code correctly, you need a precondition loop and not a postcondition one, as you have right now. For example:
while (table.at(i)) {
cout << "Bunch of stuff";
table.at(i) = table.at(i)->next;
}
You could try doing:
for(auto node = table.at(i)->next;node!=nullptr;node=node->next)
cout << "Bid id: " << node->bidId << " title: " << node->title;
Where you may need to replace node = table.at(i)->next with an appropriate way of getting a link to the first entry.
You can use C++11's range based for loop here. All you want to know is that value->next is not a nullptr before doing the assignment. Rest all is taken care by the simple and modern range based for loop
for(auto const& value: table) {
if (value->next != nullptr) {
value = value->next;
}
}
Its even faster and safer this way
If really you want to be able to get last element after the loop, you may do:
do {
cout << "Bid id: " << table.at(i)->bidId
<< " title: " << table.at(i)->title
<< " fund: " << table.at(i)->fund
<< " amount: " << table.at(i)->amount << endl;
if (table.at(i)->next == nullptr){
break;
}
table.at(i) = table.at(i)->next;
} while (true);
// table.at(i) != nullptr && table.at(i)->next == nullptr

c++ - Linked List - program break when i use -> in print function

I wrote a linked list and everything works fine but when I tried to use a particular function and print it I get an error I will be happy to help Why do I get an error and how to fix it.
The error occurs only when I call the ReverseNew-> print ();
function reverseList(in main.cpp):
List * reverseList(List &listToReverse){
List newList;
Node* currentPtr = listToReverse.getFirstNode();
while (currentPtr != 0){
newList.AddElement(currentPtr->getdata());
currentPtr = currentPtr->getNextPtr();
}
Node* currentNode = newList.getFirstNode();
int size = newList.size();
while (currentNode != 0){
currentNode->setId(size);
size--;
currentNode = currentNode->getNextPtr();
}
return &newList;
}
main:
int main(){
List l1;
l1.AddElement(1);
l1.AddElement(2);
l1.AddElement(3);
**l1.print(); >> Here he prints the list and works fine**
List* reverseNew = reverseList(l1);
**reverseNew->print(); >> here the program break**
system("pause");
return 0;
}
print function: (in List.cpp)
void List::print(){
Node* currentNode = firstPtr;
if (isEmpty())
std::cout << "List is empty" << std::endl;
else{
while (currentNode != 0){
std::cout << " < " << currentNode->data << " , " << currentNode->ID
<< " > " << std::endl;
currentNode = currentNode->nextPtr;
}}}
When the program comes out she takes me to this line: (in print function)
std::cout << " < " << currentNode->data << " , " << currentNode->ID
<< " > " << std::endl;
thabk's.
Inside reverseList(List &listToReverse) function body, you create a variable newList which goes out of scope and gets destroyed after the function ends its execution. When you try to reference that variable later in your code, that causes undefined behaviour, because you try to reference something that had already been deleted. Make newList a pointer instead to fix this (or, better, a smart pointer).
Once you remove part of the function it should be easier to see the issue:
List * reverseList(List &listToReverse){
List newList;
// ...
return &newList;
}
You return the address of a local variable. It's an Undefined Behaviour (UB).
To fix this you have two solution: return a copy of the object (beware of shallow copy issues), or use dynamic allocation in the function (check out the standard library smart pointer std::unique_ptr and std::shared_ptr/std::weak_ptr)

Creating a linked list using a while loop

I need to create a linked list of a class member (Binary), and I'm running into an infinite loop problem. The Binary class only contains the degree (int) and a next node pointer.
Within the Binary Class, the implementation for the Binary linked list is being performed inside the set_bit method. The set_bit method takes in two ints, and they are either a 1/0 int (bit) and a degree int. The bit is not needed at this point though.
The set_bit method is below:
void Binary::set_bit(int b, int d){
BinaryNode* current = firstTerm;
BinaryNode* toSet;
if (current == NULL) {
firstTerm = new BinaryNode(d, NULL);
current = firstTerm;
cout << "\nd: " << d << " <--> current degree: " << current->degree << endl;
system("pause");
} else {
while (current != NULL){
firstTerm = new BinaryNode(d, current);
cout << "\nd: " << d << " <--> current degree: " << current->degree << endl;
cout << "first term: " << firstTerm->degree << endl;
system("pause");
}
}
}
on the main.cpp file, I am trying to set the following bits:
b1.set_bit(1, 2);
b1.set_bit(1, 5);
b1.set_bit(1, 0);
b1.set_bit(0, 2);
The method is setting the first bit (2), and gets to the next (5), then begins an infinite loop trying to set the bit.
Where am I going wrong on this?
I've asked my lab instructor for help and he provided me the following code:
Why did the code that the lab instructor not work either?
void Binary ::set_bit( int b , int d ){
BinaryNode * current = firstTerm;
if (current == NULL ){
firstTerm = new BinaryNode(d,NULL); // Corrected Line
}
while (current != NULL ){
firstTerm = new BinaryNode(d,firstTerm); // Corrected Line
}
}
Thanks
Of course you would end up with infinite loop, because when u try inserting the second node, current != NULL is always true, which means the else section is called. Unfortunately, the there is a while loop inside whose condition is always true.

Comparing One Link List to Another Blacklist versus Word Frequency List C++

I have created a program that will read a text file and put the words as strings into a linked list, along with their frequency count throughout the text file. It only prints one occurrence of each word with the total times it appeared.
My program also loads a blacklist, in which it is supposed to compare the blacklist linked list to the word cloud (or word frequency) linked list, and then remove the blacklisted words from the word frequency list.
I have tried doing this several ways. The following is my 3rd version. What I am wanting to do is add a Boolean value to each node, and when one node is equal to a word in the blacklist, the Boolean value will be true. However, I am not getting it to print right with the following code. I have searched, and I can't seem to find the correct syntax to add a Boolean value to a node in linked list.
EDIT #3:
void wordCloud::compareWith(wordCloud& wordList, wordCloud& badList){
wordNode *wordListTemp, *blacklistTemp, *temp = NULL;
unsigned int counter = 0;
for (blacklistTemp = badList.head; blacklistTemp; blacklistTemp = blacklistTemp->next){
cout << blacklistTemp->myWord << "\n";
for (wordListTemp = wordList.head; wordListTemp; wordListTemp = wordListTemp->next){
if (wordListTemp->myWord != blacklistTemp->myWord){
wordListTemp->blacklist = false;
if (wordListTemp->blacklist = false){
cout << wordListTemp->myWord << " <"
<< wordListTemp->freq_count << ">\n";
}
}
else if (wordListTemp->myWord == blacklistTemp->myWord){
cout << blacklistTemp->myWord << " " << wordListTemp->myWord << "\n";
wordListTemp->blacklist = true;
if (wordListTemp->blacklist = true)
cout << wordListTemp->myWord << "\n";
}
}
//counter++;
cout << blacklistTemp->myWord << " " << wordListTemp->myWord << "\n";
}
system("pause");
}
This is not complete, but it is as far as I have gotten. The problem is it only prints the true if, and will not print any false if. Even if I switch the values, it will still only print the true if's. So I am assuming that I am going about this wrong. What would be the correct way to "flag" a node true and "flag" a node false? All the cout's are for debugging purposes. I will remove or comment those out later.
First of all, you could always debug step-by-step to see just which portion of the code freezes up your comp. The better way to detect memory leaks would be to use Valgrind.
On a side note, I would implement that comparison function as a comparison operator, and implement a comparison operator for their Nodes as well (for convenience). Doing so divides the code a bit and helps, later on, understand where your problem is. It is also a better way to do it (more readable, OOP-y, etc).
Finally!!
With a lot of old fashion debugging and cout statements, I finally got what I wanted. I know this might have been easy for some, but with not being very familiar with linked lists, this was quite the process for me.
Before I was trying to delete words that were seen in the blacklist linked list out of the wordList linked list. I decided later to just try to add a boolean value of true to the nodes in wordList, and then adjust my print function to not print nodes with the value of true. I also had to tweak a few things in insertWord(), and my freqSort() functions, but all that really consisted of was adding a pointer to the boolean value when a new node was being created.
My member function is void wordCloud::compareWith(wordCloud& wordList, wordCloud& badList), and is part of my wordCloud class. Here is the following definition:
void wordCloud::compareWith(const wordCloud& wordList, const wordCloud& badList){
wordNode *wordListTemp, *blacklistTemp;
unsigned int counter = 0;
//loop that advances wordListTemp
for (wordListTemp = wordList.head; wordListTemp; wordListTemp = wordListTemp->next){
blacklistTemp = badList.head;
//loop advances blacklistTemp - compares links in wordList to badList(blacklist)
//and sets the node to true if myWord equals any word in the blacklist
while (blacklistTemp){
if (wordListTemp->myWord == blacklistTemp->myWord){
wordListTemp->blacklist = true;
counter++;
}
blacklistTemp = blacklistTemp->next;
}
//for debugging
//cout << blacklistTemp->myWord << " " << wordListTemp->myWord << "\n";
}
/********************* All for debugging ***************************************
cout << "True:\n\n";
wordListTemp = wordList.head; //reset wordListTemp to head
while (wordListTemp){ //print blacklisted words from wordList
if (wordListTemp->blacklist == true){
cout << wordListTemp->myWord << " <"
<< wordListTemp->freq_count << ">\n";
}
wordListTemp = wordListTemp->next;
}
//prints total words blacklisted
cout << "There are " << counter << " blacklisted words.";
cout << "\n\nFalse:\n\n";
wordListTemp = wordList.head; //reset wordListTemp to head
counter = 0;
while (wordListTemp){ //print non-blacklisted words from wordList
if (wordListTemp->blacklist == false){
cout << wordListTemp->myWord << " <"
<< wordListTemp->freq_count << ">\n";
counter++;
}
wordListTemp = wordListTemp->next;
}
//prints total words not blacklisted
cout << "There are " << counter << " words that are not blacklisted.\n";
system("pause");
******************** End debugging *******************************************/
}
So basically this is a comparison function that flags nodes that are found in another list. Works well and tested with all other options.