llvm pass is very slow


I write a LLVM function pass. The pass will loop the basicblock in the function, check the instruction’s type with dyn_cast, print the instruction and the basicblock’s successors. I think it is not very complex.

My bitcode file is about 30M. My CPU is i7-7700(3.6GHz). It has been running for 60 hours but it is still running. I am not sure whether this is a normal behavior. If so, any options or suggestions to help me speed up the analysis. Many Thanks


The first thing you should check is whether you’ve written the loop properly. It’s possible that you’ve somehow written an infinite loop. If your pass is adding instructions, be careful that you’re not invalidating the iterator that you’re using to loop over the instructions. That might cause a non-obvious error. The second thing to consider is to use the InstVisitor class instead of writing a loop. Look at InstVisitor.h in the LLVM source code; it has comments that show you how to use it. In a nutshell, your FunctionPass will be a subclass of InstVisitor. You then implement the visitSwitchInst() method and call visit() on the function in runOnFunction, and you’re done. Regards, John Criswell

Hi John

Thanks for your suggestions. I forget to send the last response to llvm community.

I will try your idea and it would be great if you can give me some comments on the code below, many thanks

namespace {
// Hello - The first implementation, without getAnalysisUsage.
struct Hello : public FunctionPass {
static char ID; // Pass identification, replacement for typeid
Hello() : FunctionPass(ID) {}
std::error_code error;
enum sys::fs::OpenFlags of;
bool runOnFunction(Function &F) override {

raw_fd_ostream file(StringRef(F.getName().str()+".info"), error, of);
for (BasicBlock &BB : F){
std::string bb_name = BB.getName().str();
BlockAddress* bb_addr = BlockAddress::get(&BB);
file <<“This is the Block Node”<< bb_addr<<"\n";
for(Instruction &I: BB){
int split = 0;
int indirect_call = 0;
std:: string split_func = “”;
if(const SwitchInst* switchinst = dyn_cast(&I)){
DILocation* Loc = I.getDebugLoc().get();
unsigned Line = Loc->getLine();
unsigned Column = Loc->getColumn();
StringRef File = Loc->getFilename();
StringRef Dir = Loc->getDirectory();
if (indirect_call){file<<"|IndirectCall";}
file <<"|Instruction:|Source Line:"<< Line<<"|Column:"<<Column<<"|File:"<<File;
file <<"|IR:"<<I<<"\n";
for (BasicBlock * SuccBB : successors(&BB)){
BlockAddress * succBB_addr = BlockAddress::get(SuccBB);
file <<bb_addr<<"–>"<<succBB_addr<<"\n";
return false;

char Hello::ID = 0;
static RegisterPass X(“hello”, “Hello World Pass”);

I run it using the command “opt -load /path/to/LLVMHello.so -hello target.bc”.

If you need the bitcode file that takes me so much time, please tell me.



John Criswell <jtcriswel@gmail.com>于2018年7月16日 周一下午11:30写道: