"symbol lookup error" while running a Simple Loop Pass

Hello;

I wrote this simple loop pass to collect the number of instructions in each loop of the program. The code is as follows-

#define DEBUG_TYPE “loopinst”
#include “llvm/Pass.h”
#include “llvm/Analysis/LoopPass.h”
#include “llvm/Support/raw_ostream.h”
#include “llvm/ADT/Statistic.h”
#include “llvm/Instructions.h”
#include “llvm/Analysis/LoopInfo.h”

using namespace llvm;

STATISTIC(LoopInstNum, “Counts number of instructions in a loop”);

namespace {
struct LoopInst : public LoopPass {
static char ID; // Pass identification, replacement for typeid
LoopInst() : LoopPass(ID) {}

virtual bool runOnLoop(Loop *L, LPPassManager &LPM) {
LoopInfo *LI = &getAnalysis();
for (Loop::block_iterator b = L->block_begin(), be = L->block_end();b != be; ++b)
{
for (BasicBlock::iterator i = (*b)->begin(), ie = (*b)->end(); i != ie; ++i)
{
++LoopInstNum;
errs() << "Hello: ";
}
}

return false;
}

// We don’t modify the program, so we preserve all analyses
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired();
AU.addPreserved();
}
};
}

char LoopInst::ID = 0;
static RegisterPass X(“loop-inst”, “loop instruction Pass”);

I put it under llvm-src/lib/Transforms directory and ran a “make” from there to create the .so file. But when I run opt with the library, I get the following error -

opt -load=/home/arnie/llvm-development/llvm/Debug+Asserts/lib/LoopInst.so -loops -loop-inst a.s

opt: symbol lookup error: /home/arnie/llvm-development/llvm/Debug+Asserts/lib/LoopInst.so: undefined symbol: _ZNK4llvm8LoopBaseINS_10BasicBlockENS_4LoopEE11block_beginEv

Can anyone tell me what I am doing wrong?

Also what’s the difference between declaring a pass as a struct vs declaring it as a class. In the “writing a pass” tutorial the “Hello” pass has been declared as a struct but most (if not all) the LLVM passes are written as classes.

Thanks a lot;

Hi,

this is probably related to the reported bug:

http://llvm.org/bugs/show_bug.cgi?id=13144

You have two possible solutions:
1) add KEEP_SYMBOLS := 1 to opt Makefile and recompile OR
2) used a shared build of LLVM

BR

Carlos

PD: If you are uing OSX, the problem might be slightly more complex.
Look at my mail which is linked at the end of the bug report.

Problem solved. I was building llvm in a separate llvm-build directory. I built it within the llvm-src directory (which kept all the llvm .so and my pass’ .so in the llvm-src/Release+Asserts/lib directory) to solve the problem.

Can anyone tell me what’s the difference between writing a pass as a “struct” (as in the tutorial) and as a “class” (as most developers do)?

Thanks again;

Hi,

Problem solved. I was building llvm in a separate llvm-build directory. I
built it within the llvm-src directory (which kept all the llvm .so and my
pass' .so in the llvm-src/Release+Asserts/lib directory) to solve the
problem.

I do not fully understand what you mean, there should be no difference
on building out of source AFAIK.

Can anyone tell me what's the difference between writing a pass as a
"struct" (as in the tutorial) and as a "class" (as most developers do)?

In C++, "class" is just an struct where members have private
visibility by default. So defining a pass (or any class) with "struct"
is 100% equivalent to defining it with "class" and then placing all
members with "public:" visibility. From LLVM point of view,
functionality of your pass is not going to change at all by using
"class" or "struct" to define it.

BR

Carlos

Hi,

Problem solved. I was building llvm in a separate llvm-build directory. I
built it within the llvm-src directory (which kept all the llvm .so and my
pass’ .so in the llvm-src/Release+Asserts/lib directory) to solve the
problem.

I do not fully understand what you mean, there should be no difference
on building out of source AFAIK.

What I meant to say was previously I built llvm and installed it in different directories than the source directory, e.g if the source was downloaded into , and I wanted to build it in and install it into , I would do the following -

  1. Run …/llvm-src/cofigure from within the directory [–prefix=]
  2. Run make and make install from within the build directory.

In that manner, I would have all the llvm .so files in the /Release+Asserts/lib directory. So when I kept my pass inside the llvm-src/lib/Transforms directory and run a make from there (after running a configure from the source directory), my .so will be created in the /Release+Asserts/lib directory. When I tried to use this .so with the opt created inside directory, I was getting errors.

Then I did the following -

  1. Run ./cofigure from within the directory [–prefix=]
  2. Run make and make install from within the src directory.

In that manner, I would have all the llvm .so files and my pass’ .so in the /Release+Asserts/lib directory. Then I was able to use the .so with opt from the /bin directory.

May be your and mine reason for the error was different. Sorry I was not clear in my last email.