BasicBlock back()

Hello,

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:

  1. 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.)

  1. 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(prev_iter)) << “\n”;
}
if(last_iter){
errs() << "last_iter: " << *(dyn_cast(last_iter)) << “\n”;
}
// not related to the main question: uncomment the next line for an unusual behavior: lastlast is DIFFERENT from last. lastlast is kind of parts of the BasicBlock
// errs() << "lastlast: " << (dyn_cast(I)) << “\n”;

Instruction
prev = (dyn_cast<Instruction>(prev_iter));
errs() << “\n prev: “<<*prev<<”\n”;

The terminal prints 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 :slight_smile:

Thank you,
Alex

I believe BasicBlock::back() returns an iterator to the last instruction in the BasicBlock which should be its terminator instruction (basic blocks are required to have a TerminatorInst as their last instruction). Sometimes you have to dereference an iterator to get the thing that it’s pointing at. Try using: Instruction* prev = (dyn_cast(*prev_iter)); That might work. – John T.

Hi Alexandru,

Hello,

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:

1. I have the following sequence of code:

bool patternDC::runOnBasicBlock(BasicBlock &BB) {
...
if (BB.getTerminator())
   {
             Instruction* current = BB.getTerminator();

the terminator is the last instruction in a basic block (by definition).

             errs() << "\n LAST: "<<*current<<"\n";

             Instruction* prev = &BB.back();

"back" returns you the last instruction in the basic block, thus it is the same
as the terminator. I think you are looking for current->getPrev()

             errs() << "\n PENULTIMATE: "<<*prev<<"\n";
...

The terminal prints the SAME instruction. I don't know how back() works.
(Definition at line 199
<LLVM: include/llvm/IR/BasicBlock.h Source File; of file BasicBlock.h
<http://llvm.org/doxygen/BasicBlock_8h_source.html&gt;\.\)

2. 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 is kind of parts of the
BasicBlock
// errs() << "lastlast: " << *(dyn_cast<Instruction>(I)) << "\n";
...
Instruction* prev = *(dyn_cast<Instruction*>(prev_iter));

Probably this should be:

   const Instruction* prev = *prev_iter;

Ciao, Duncan.

Hi, thank you for your response ! Please find below my comments:

Hello,

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:

  1. 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 believe BasicBlock::back() returns an iterator to the last instruction in the BasicBlock which should be its terminator instruction (basic blocks are required to have a TerminatorInst as their last instruction).
Here is the definition of back(): return *this->getPrev(getTail()), so basically it should get the previous function of the terminator. or maybe the tail is considered the head because it is a circular list…

    

  1. 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(prev_iter)) << “\n”;
}
if(last_iter){
errs() << "last_iter: " << *(dyn_cast(last_iter)) << “\n”;
}
// not related to the main question: uncomment the next line for an unusual behavior: lastlast is DIFFERENT from last. lastlast is kind of parts of the BasicBlock
// errs() << "lastlast: " << (dyn_cast(I)) << “\n”;

Instruction
prev = (dyn_cast<Instruction>(prev_iter));
errs() << “\n prev: “<<*prev<<”\n”;

The terminal prints 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 :slight_smile:

Sometimes you have to dereference an iterator to get the thing that it’s pointing at. Try using:

Instruction* prev = (dyn_cast(*prev_iter));

error: cannot convert ‘llvm::Instruction’ to ‘llvm::Instruction*’ in initialization , and if I make dyn_cast<Instruction*> I have the previous problem…do you know other method or a pass example from the LLVM site that is passing through the instructions of a BB? And not using complicated dependencies as http://llvm.org/doxygen/EdgeBundles_8cpp_source.html#l00078 ?

PS:

I works when I use Instruction* prev = current->getPrevNode();

But then I have runtime error Stack dump that is very frequent…

PS:

I works when I use Instruction* prev = current->getPrevNode();

But then I have runtime error Stack dump that is very frequent...

This probably happens when current is the first node, so there is no previous
node.

Ciao, Duncan.