Patrick Martin
Patrick Martin

Reputation: 229

How do I correclty implement an LLVM InstVisitor?

To learn LLVM I made a ModulePass that runs through the functions, basic blocks, and finally instructions. At some point I want to dig into the instructions and perform analysis. While reading the documentation I came across http://llvm.org/docs/doxygen/html/classllvm_1_1InstVisitor.html and the documentation recommends using these structures to efficiently traverse IR rather than do a lot of if(auto* I = dyn_cast<>()) lines.

I tried making a variation of the documentation example, but for BranchInst:

struct BranchInstVisitor : public InstVisitor<BranchInst> {                                               
    unsigned Count;                                                                                       
    BranchInstVisitor() : Count(0) {}                                                                     

    void visitBranchInst(BranchInst &BI){                                                                 
        Count++;                                                                                          
        errs() << "BI found! " << Count << "\n";                                                          
    }                                                                                                     

}; // End of BranchInstVisitor

Within my ModulePass, I created the visitor:

for(Module::iterator F = M.begin(), modEnd = M.end(); F != modEnd; ++F){
    BranchInstVisitor BIV; 
    BIV.visit(F);
    ...

Unfortunately, my call to visit(F) fails when I compile:

error: invalid static_cast from type ‘llvm::InstVisitor<llvm::BranchInst>* const’ to type ‘llvm::BranchInst*’ static_cast<SubClass*>(this)->visitFunction(F);

How do I correctly implement an LLVM InstVisitor? Are InstVisitors supposed to be run outside of passes? If I missed documentation, please let me know where to go.

Upvotes: 4

Views: 2390

Answers (1)

Ismail Badawi
Ismail Badawi

Reputation: 37167

The template parameter should be the type you're declaring, not a type of instruction, like this:

struct BranchInstVisitor : public InstVisitor<BranchInstVisitor>

Each visitor can override as many visit* methods as you want -- it's not like each visitor is tied to one type of instruction. That wouldn't be very useful.

Upvotes: 7

Related Questions