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