InstVisitor.h revision b4c5f83eacbdb7643f9efada8fd281ef77a662c3
1b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner//===- llvm/Support/InstVisitor.h - Define instruction visitors --*- C++ -*--=// 2b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner// 3b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner// This template class is used to define instruction visitors in a typesafe 4b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner// manner without having to use lots of casts and a big switch statement (in 5b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner// your code that is). The win here is that if instructions are added in the 6b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner// future, they will be added to the InstVisitor<T> class, allowing you to 7b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner// automatically support them (if you handle on of their superclasses). 8b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner// 9b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner// Note that this library is specifically designed as a template to avoid 10b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner// virtual function call overhead. Defining and using an InstVisitor is just as 11b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner// efficient as having your own switch statement over the instruction opcode. 12b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner// 13b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner// InstVisitor Usage: 14b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner// You define InstVisitors from inheriting from the InstVisitor base class 15b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner// and "overriding" functions in your class. I say "overriding" because this 16b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner// class is defined in terms of statically resolved overloading, not virtual 17b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner// functions. As an example, here is a visitor that counts the number of malloc 18b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner// instructions processed: 19b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner// 20b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner// // Declare the class. Note that we derive from InstVisitor instantiated 21b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner// // with _our new subclasses_ type. 22b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner// // 23b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner// struct CountMallocVisitor : public InstVisitor<CountMallocVisitor> { 24b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner// unsigned Count; 25b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner// CountMallocVisitor() : Count(0) {} 26b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner// 27b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner// void visitMallocInst(MallocInst *MI) { ++Count; } 28b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner// }; 29b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner// 30b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner// And this class would be used like this: 31b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner// CountMallocVistor CMV; 32b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner// CMV.visit(method); 33b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner// NumMallocs = CMV.Count; 34b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner// 35b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner//===----------------------------------------------------------------------===// 36b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner 37b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner#ifndef LLVM_SUPPORT_INSTVISITOR_H 38b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner#define LLVM_SUPPORT_INSTVISITOR_H 39b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner 40b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner#include "llvm/Instruction.h" 41b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner 42b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner// We operate on opaque instruction classes, so forward declare all instruction 43b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner// types now... 44b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner// 45b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner#define HANDLE_INST(NUM, OPCODE, CLASS) class CLASS; 46b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner#include "llvm/Instruction.def" 47b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner 48b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner// Forward declare the intermediate types... 49b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattnerclass TerminatorInst; class UnaryOperator; class BinaryOperator; 50b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattnerclass AllocationInst; class MemAccessInst; 51b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner 52b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattnertemplate<typename SubClass> 53b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattnerstruct InstVisitor { 54b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner ~InstVisitor() {} // We are meant to be derived from 55b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner 56b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner //===--------------------------------------------------------------------===// 57b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner // Interface code - This is the public interface of the InstVisitor that you 58b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner // use to visit instructions... 59b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner // 60b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner 61b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner // Generic visit method - Allow visitation to all instructions in a range 62b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner template<class Iterator> 63b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner void visit(Iterator Start, Iterator End) { 64b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner while (Start != End) 65b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner visit(*Start++); 66b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner } 67b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner 68b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner // Define visitors for modules, methods and basic blocks... 69b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner // 70b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner void visit(Module *M) { visit(M->begin(), M->end()); } 71b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner void visit(Method *M) { visit(M->begin(), M->end()); } 72b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner void visit(BasicBlock *BB) { visit(BB->begin(), BB->end()); } 73b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner 74b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner // visit - Finally, code to visit an instruction... 75b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner // 76b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner void visit(Instruction *I) { 77b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner switch (I->getOpcode()) { 78b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner // Build the switch statement using the Instruction.def file... 79b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner#define HANDLE_INST(NUM, OPCODE, CLASS) \ 80b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner case Instruction::OPCODE: ((SubClass*)this)->visit##CLASS((CLASS*)I); return; 81b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner#include "llvm/Instruction.def" 82b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner 83b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner default: assert(0 && "Unknown instruction type encountered!"); 84b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner } 85b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner } 86b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner 87b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner //===--------------------------------------------------------------------===// 88b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner // Visitation functions... these functions provide default fallbacks in case 89b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner // the user does not specify what to do for a particular instruction type. 90b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner // The default behavior is to generalize the instruction type to its subtype 91b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner // and try visiting the subtype. All of this should be inlined perfectly, 92b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner // because there are no virtual functions to get in the way. 93b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner // 94b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner 95b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner // Specific Instruction type classes... note that all of the casts are 96b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner // neccesary because we use the instruction classes as opaque types... 97b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner // 98b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner void visitReturnInst(ReturnInst *I) { ((SubClass*)this)->visitTerminatorInst((TerminatorInst*)I); } 99b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner void visitBranchInst(BranchInst *I) { ((SubClass*)this)->visitTerminatorInst((TerminatorInst*)I); } 100b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner void visitSwitchInst(SwitchInst *I) { ((SubClass*)this)->visitTerminatorInst((TerminatorInst*)I); } 101b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner void visitInvokeInst(InvokeInst *I) { ((SubClass*)this)->visitTerminatorInst((TerminatorInst*)I); } 102b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner void visitGenericUnaryInst(GenericUnaryInst *I) { ((SubClass*)this)->visitUnaryOperator((UnaryOperator*)I); } 103b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner void visitGenericBinaryInst(GenericBinaryInst *I) { ((SubClass*)this)->visitBinaryOperator((BinaryOperator*)I); } 104b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner void visitSetCondInst(SetCondInst *I) { ((SubClass*)this)->visitBinaryOperator((BinaryOperator *)I); } 105b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner void visitMallocInst(MallocInst *I) { ((SubClass*)this)->visitAllocationInst((AllocationInst *)I); } 106b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner void visitAllocaInst(AllocaInst *I) { ((SubClass*)this)->visitAllocationInst((AllocationInst *)I); } 107b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner void visitFreeInst(FreeInst *I) { ((SubClass*)this)->visitInstruction((Instruction *)I); } 108b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner void visitLoadInst(LoadInst *I) { ((SubClass*)this)->visitMemAccessInst((MemAccessInst *)I); } 109b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner void visitStoreInst(StoreInst *I) { ((SubClass*)this)->visitMemAccessInst((MemAccessInst *)I); } 110b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner void visitGetElementPtrInst(GetElementPtrInst *I) { ((SubClass*)this)->visitMemAccessInst((MemAccessInst *)I); } 111b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner void visitPHINode(PHINode *I) { ((SubClass*)this)->visitInstruction((Instruction *)I); } 112b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner void visitCastInst(CastInst *I) { ((SubClass*)this)->visitInstruction((Instruction *)I); } 113b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner void visitCallInst(CallInst *I) { ((SubClass*)this)->visitInstruction((Instruction *)I); } 114b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner void visitShiftInst(ShiftInst *I) { ((SubClass*)this)->visitInstruction((Instruction *)I); } 115b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner 116b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner // Next level propogators... if the user does not overload a specific 117b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner // instruction type, they can overload one of these to get the whole class 118b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner // of instructions... 119b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner // 120b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner void visitTerminatorInst(TerminatorInst *I) { ((SubClass*)this)->visitInstruction((Instruction*)I); } 121b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner void visitUnaryOperator (UnaryOperator *I) { ((SubClass*)this)->visitInstruction((Instruction*)I); } 122b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner void visitBinaryOperator(BinaryOperator *I) { ((SubClass*)this)->visitInstruction((Instruction*)I); } 123b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner void visitAllocationInst(AllocationInst *I) { ((SubClass*)this)->visitInstruction((Instruction*)I); } 124b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner void visitMemAccessInst (MemAccessInst *I) { ((SubClass*)this)->visitInstruction((Instruction*)I); } 125b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner 126b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner // If the user wants a 'default' case, they can choose to override this 127b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner // function. If this function is not overloaded in the users subclass, then 128b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner // this instruction just gets ignored. 129b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner // 130b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner void visitInstruction(Instruction *I) {} // Ignore unhandled instructions 131b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner}; 132b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner 133b4c5f83eacbdb7643f9efada8fd281ef77a662c3Chris Lattner#endif 134