xref: /freebsd/contrib/llvm-project/llvm/include/llvm/IR/InstVisitor.h (revision bdd1243df58e60e85101c09001d9812a789b6bc4)
10b57cec5SDimitry Andric //===- InstVisitor.h - Instruction visitor templates ------------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric 
100b57cec5SDimitry Andric #ifndef LLVM_IR_INSTVISITOR_H
110b57cec5SDimitry Andric #define LLVM_IR_INSTVISITOR_H
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "llvm/IR/Function.h"
140b57cec5SDimitry Andric #include "llvm/IR/Instructions.h"
150b57cec5SDimitry Andric #include "llvm/IR/IntrinsicInst.h"
160b57cec5SDimitry Andric #include "llvm/IR/Intrinsics.h"
170b57cec5SDimitry Andric #include "llvm/IR/Module.h"
180b57cec5SDimitry Andric 
190b57cec5SDimitry Andric namespace llvm {
200b57cec5SDimitry Andric 
210b57cec5SDimitry Andric // We operate on opaque instruction classes, so forward declare all instruction
220b57cec5SDimitry Andric // types now...
230b57cec5SDimitry Andric //
240b57cec5SDimitry Andric #define HANDLE_INST(NUM, OPCODE, CLASS)   class CLASS;
250b57cec5SDimitry Andric #include "llvm/IR/Instruction.def"
260b57cec5SDimitry Andric 
270b57cec5SDimitry Andric #define DELEGATE(CLASS_TO_VISIT) \
280b57cec5SDimitry Andric   return static_cast<SubClass*>(this)-> \
290b57cec5SDimitry Andric                visit##CLASS_TO_VISIT(static_cast<CLASS_TO_VISIT&>(I))
300b57cec5SDimitry Andric 
310b57cec5SDimitry Andric 
320b57cec5SDimitry Andric /// Base class for instruction visitors
330b57cec5SDimitry Andric ///
340b57cec5SDimitry Andric /// Instruction visitors are used when you want to perform different actions
350b57cec5SDimitry Andric /// for different kinds of instructions without having to use lots of casts
360b57cec5SDimitry Andric /// and a big switch statement (in your code, that is).
370b57cec5SDimitry Andric ///
380b57cec5SDimitry Andric /// To define your own visitor, inherit from this class, specifying your
390b57cec5SDimitry Andric /// new type for the 'SubClass' template parameter, and "override" visitXXX
400b57cec5SDimitry Andric /// functions in your class. I say "override" because this class is defined
410b57cec5SDimitry Andric /// in terms of statically resolved overloading, not virtual functions.
420b57cec5SDimitry Andric ///
430b57cec5SDimitry Andric /// For example, here is a visitor that counts the number of malloc
440b57cec5SDimitry Andric /// instructions processed:
450b57cec5SDimitry Andric ///
460b57cec5SDimitry Andric ///  /// Declare the class.  Note that we derive from InstVisitor instantiated
470b57cec5SDimitry Andric ///  /// with _our new subclasses_ type.
480b57cec5SDimitry Andric ///  ///
490b57cec5SDimitry Andric ///  struct CountAllocaVisitor : public InstVisitor<CountAllocaVisitor> {
500b57cec5SDimitry Andric ///    unsigned Count;
510b57cec5SDimitry Andric ///    CountAllocaVisitor() : Count(0) {}
520b57cec5SDimitry Andric ///
530b57cec5SDimitry Andric ///    void visitAllocaInst(AllocaInst &AI) { ++Count; }
540b57cec5SDimitry Andric ///  };
550b57cec5SDimitry Andric ///
560b57cec5SDimitry Andric ///  And this class would be used like this:
570b57cec5SDimitry Andric ///    CountAllocaVisitor CAV;
580b57cec5SDimitry Andric ///    CAV.visit(function);
590b57cec5SDimitry Andric ///    NumAllocas = CAV.Count;
600b57cec5SDimitry Andric ///
610b57cec5SDimitry Andric /// The defined has 'visit' methods for Instruction, and also for BasicBlock,
620b57cec5SDimitry Andric /// Function, and Module, which recursively process all contained instructions.
630b57cec5SDimitry Andric ///
640b57cec5SDimitry Andric /// Note that if you don't implement visitXXX for some instruction type,
650b57cec5SDimitry Andric /// the visitXXX method for instruction superclass will be invoked. So
660b57cec5SDimitry Andric /// if instructions are added in the future, they will be automatically
670b57cec5SDimitry Andric /// supported, if you handle one of their superclasses.
680b57cec5SDimitry Andric ///
690b57cec5SDimitry Andric /// The optional second template argument specifies the type that instruction
700b57cec5SDimitry Andric /// visitation functions should return. If you specify this, you *MUST* provide
710b57cec5SDimitry Andric /// an implementation of visitInstruction though!.
720b57cec5SDimitry Andric ///
730b57cec5SDimitry Andric /// Note that this class is specifically designed as a template to avoid
740b57cec5SDimitry Andric /// virtual function call overhead.  Defining and using an InstVisitor is just
750b57cec5SDimitry Andric /// as efficient as having your own switch statement over the instruction
760b57cec5SDimitry Andric /// opcode.
770b57cec5SDimitry Andric template<typename SubClass, typename RetTy=void>
780b57cec5SDimitry Andric class InstVisitor {
790b57cec5SDimitry Andric   //===--------------------------------------------------------------------===//
800b57cec5SDimitry Andric   // Interface code - This is the public interface of the InstVisitor that you
810b57cec5SDimitry Andric   // use to visit instructions...
820b57cec5SDimitry Andric   //
830b57cec5SDimitry Andric 
840b57cec5SDimitry Andric public:
850b57cec5SDimitry Andric   // Generic visit method - Allow visitation to all instructions in a range
860b57cec5SDimitry Andric   template<class Iterator>
visit(Iterator Start,Iterator End)870b57cec5SDimitry Andric   void visit(Iterator Start, Iterator End) {
880b57cec5SDimitry Andric     while (Start != End)
890b57cec5SDimitry Andric       static_cast<SubClass*>(this)->visit(*Start++);
900b57cec5SDimitry Andric   }
910b57cec5SDimitry Andric 
920b57cec5SDimitry Andric   // Define visitors for functions and basic blocks...
930b57cec5SDimitry Andric   //
visit(Module & M)940b57cec5SDimitry Andric   void visit(Module &M) {
950b57cec5SDimitry Andric     static_cast<SubClass*>(this)->visitModule(M);
960b57cec5SDimitry Andric     visit(M.begin(), M.end());
970b57cec5SDimitry Andric   }
visit(Function & F)980b57cec5SDimitry Andric   void visit(Function &F) {
990b57cec5SDimitry Andric     static_cast<SubClass*>(this)->visitFunction(F);
1000b57cec5SDimitry Andric     visit(F.begin(), F.end());
1010b57cec5SDimitry Andric   }
visit(BasicBlock & BB)1020b57cec5SDimitry Andric   void visit(BasicBlock &BB) {
1030b57cec5SDimitry Andric     static_cast<SubClass*>(this)->visitBasicBlock(BB);
1040b57cec5SDimitry Andric     visit(BB.begin(), BB.end());
1050b57cec5SDimitry Andric   }
1060b57cec5SDimitry Andric 
1070b57cec5SDimitry Andric   // Forwarding functions so that the user can visit with pointers AND refs.
visit(Module * M)1080b57cec5SDimitry Andric   void visit(Module       *M)  { visit(*M); }
visit(Function * F)1090b57cec5SDimitry Andric   void visit(Function     *F)  { visit(*F); }
visit(BasicBlock * BB)1100b57cec5SDimitry Andric   void visit(BasicBlock   *BB) { visit(*BB); }
visit(Instruction * I)1110b57cec5SDimitry Andric   RetTy visit(Instruction *I)  { return visit(*I); }
1120b57cec5SDimitry Andric 
1130b57cec5SDimitry Andric   // visit - Finally, code to visit an instruction...
1140b57cec5SDimitry Andric   //
visit(Instruction & I)1150b57cec5SDimitry Andric   RetTy visit(Instruction &I) {
1160b57cec5SDimitry Andric     static_assert(std::is_base_of<InstVisitor, SubClass>::value,
1170b57cec5SDimitry Andric                   "Must pass the derived type to this template!");
1180b57cec5SDimitry Andric 
1190b57cec5SDimitry Andric     switch (I.getOpcode()) {
1200b57cec5SDimitry Andric     default: llvm_unreachable("Unknown instruction type encountered!");
1210b57cec5SDimitry Andric       // Build the switch statement using the Instruction.def file...
1220b57cec5SDimitry Andric #define HANDLE_INST(NUM, OPCODE, CLASS) \
1230b57cec5SDimitry Andric     case Instruction::OPCODE: return \
1240b57cec5SDimitry Andric            static_cast<SubClass*>(this)-> \
1250b57cec5SDimitry Andric                       visit##OPCODE(static_cast<CLASS&>(I));
1260b57cec5SDimitry Andric #include "llvm/IR/Instruction.def"
1270b57cec5SDimitry Andric     }
1280b57cec5SDimitry Andric   }
1290b57cec5SDimitry Andric 
1300b57cec5SDimitry Andric   //===--------------------------------------------------------------------===//
1310b57cec5SDimitry Andric   // Visitation functions... these functions provide default fallbacks in case
1320b57cec5SDimitry Andric   // the user does not specify what to do for a particular instruction type.
1330b57cec5SDimitry Andric   // The default behavior is to generalize the instruction type to its subtype
1340b57cec5SDimitry Andric   // and try visiting the subtype.  All of this should be inlined perfectly,
1350b57cec5SDimitry Andric   // because there are no virtual functions to get in the way.
1360b57cec5SDimitry Andric   //
1370b57cec5SDimitry Andric 
1380b57cec5SDimitry Andric   // When visiting a module, function or basic block directly, these methods get
1390b57cec5SDimitry Andric   // called to indicate when transitioning into a new unit.
1400b57cec5SDimitry Andric   //
visitModule(Module & M)1410b57cec5SDimitry Andric   void visitModule    (Module &M) {}
visitFunction(Function & F)1420b57cec5SDimitry Andric   void visitFunction  (Function &F) {}
visitBasicBlock(BasicBlock & BB)1430b57cec5SDimitry Andric   void visitBasicBlock(BasicBlock &BB) {}
1440b57cec5SDimitry Andric 
1450b57cec5SDimitry Andric   // Define instruction specific visitor functions that can be overridden to
1460b57cec5SDimitry Andric   // handle SPECIFIC instructions.  These functions automatically define
1470b57cec5SDimitry Andric   // visitMul to proxy to visitBinaryOperator for instance in case the user does
1480b57cec5SDimitry Andric   // not need this generality.
1490b57cec5SDimitry Andric   //
1500b57cec5SDimitry Andric   // These functions can also implement fan-out, when a single opcode and
1510b57cec5SDimitry Andric   // instruction have multiple more specific Instruction subclasses. The Call
1520b57cec5SDimitry Andric   // instruction currently supports this. We implement that by redirecting that
1530b57cec5SDimitry Andric   // instruction to a special delegation helper.
1540b57cec5SDimitry Andric #define HANDLE_INST(NUM, OPCODE, CLASS) \
1550b57cec5SDimitry Andric     RetTy visit##OPCODE(CLASS &I) { \
1560b57cec5SDimitry Andric       if (NUM == Instruction::Call) \
1570b57cec5SDimitry Andric         return delegateCallInst(I); \
1580b57cec5SDimitry Andric       else \
1590b57cec5SDimitry Andric         DELEGATE(CLASS); \
1600b57cec5SDimitry Andric     }
1610b57cec5SDimitry Andric #include "llvm/IR/Instruction.def"
1620b57cec5SDimitry Andric 
1630b57cec5SDimitry Andric   // Specific Instruction type classes... note that all of the casts are
1640b57cec5SDimitry Andric   // necessary because we use the instruction classes as opaque types...
1650b57cec5SDimitry Andric   //
visitICmpInst(ICmpInst & I)1660b57cec5SDimitry Andric   RetTy visitICmpInst(ICmpInst &I)                { DELEGATE(CmpInst);}
visitFCmpInst(FCmpInst & I)1670b57cec5SDimitry Andric   RetTy visitFCmpInst(FCmpInst &I)                { DELEGATE(CmpInst);}
visitAllocaInst(AllocaInst & I)1680b57cec5SDimitry Andric   RetTy visitAllocaInst(AllocaInst &I)            { DELEGATE(UnaryInstruction);}
visitLoadInst(LoadInst & I)1690b57cec5SDimitry Andric   RetTy visitLoadInst(LoadInst     &I)            { DELEGATE(UnaryInstruction);}
visitStoreInst(StoreInst & I)1700b57cec5SDimitry Andric   RetTy visitStoreInst(StoreInst   &I)            { DELEGATE(Instruction);}
visitAtomicCmpXchgInst(AtomicCmpXchgInst & I)1710b57cec5SDimitry Andric   RetTy visitAtomicCmpXchgInst(AtomicCmpXchgInst &I) { DELEGATE(Instruction);}
visitAtomicRMWInst(AtomicRMWInst & I)1720b57cec5SDimitry Andric   RetTy visitAtomicRMWInst(AtomicRMWInst &I)      { DELEGATE(Instruction);}
visitFenceInst(FenceInst & I)1730b57cec5SDimitry Andric   RetTy visitFenceInst(FenceInst   &I)            { DELEGATE(Instruction);}
visitGetElementPtrInst(GetElementPtrInst & I)1740b57cec5SDimitry Andric   RetTy visitGetElementPtrInst(GetElementPtrInst &I){ DELEGATE(Instruction);}
visitPHINode(PHINode & I)1750b57cec5SDimitry Andric   RetTy visitPHINode(PHINode       &I)            { DELEGATE(Instruction);}
visitTruncInst(TruncInst & I)1760b57cec5SDimitry Andric   RetTy visitTruncInst(TruncInst &I)              { DELEGATE(CastInst);}
visitZExtInst(ZExtInst & I)1770b57cec5SDimitry Andric   RetTy visitZExtInst(ZExtInst &I)                { DELEGATE(CastInst);}
visitSExtInst(SExtInst & I)1780b57cec5SDimitry Andric   RetTy visitSExtInst(SExtInst &I)                { DELEGATE(CastInst);}
visitFPTruncInst(FPTruncInst & I)1790b57cec5SDimitry Andric   RetTy visitFPTruncInst(FPTruncInst &I)          { DELEGATE(CastInst);}
visitFPExtInst(FPExtInst & I)1800b57cec5SDimitry Andric   RetTy visitFPExtInst(FPExtInst &I)              { DELEGATE(CastInst);}
visitFPToUIInst(FPToUIInst & I)1810b57cec5SDimitry Andric   RetTy visitFPToUIInst(FPToUIInst &I)            { DELEGATE(CastInst);}
visitFPToSIInst(FPToSIInst & I)1820b57cec5SDimitry Andric   RetTy visitFPToSIInst(FPToSIInst &I)            { DELEGATE(CastInst);}
visitUIToFPInst(UIToFPInst & I)1830b57cec5SDimitry Andric   RetTy visitUIToFPInst(UIToFPInst &I)            { DELEGATE(CastInst);}
visitSIToFPInst(SIToFPInst & I)1840b57cec5SDimitry Andric   RetTy visitSIToFPInst(SIToFPInst &I)            { DELEGATE(CastInst);}
visitPtrToIntInst(PtrToIntInst & I)1850b57cec5SDimitry Andric   RetTy visitPtrToIntInst(PtrToIntInst &I)        { DELEGATE(CastInst);}
visitIntToPtrInst(IntToPtrInst & I)1860b57cec5SDimitry Andric   RetTy visitIntToPtrInst(IntToPtrInst &I)        { DELEGATE(CastInst);}
visitBitCastInst(BitCastInst & I)1870b57cec5SDimitry Andric   RetTy visitBitCastInst(BitCastInst &I)          { DELEGATE(CastInst);}
visitAddrSpaceCastInst(AddrSpaceCastInst & I)1880b57cec5SDimitry Andric   RetTy visitAddrSpaceCastInst(AddrSpaceCastInst &I) { DELEGATE(CastInst);}
visitSelectInst(SelectInst & I)1890b57cec5SDimitry Andric   RetTy visitSelectInst(SelectInst &I)            { DELEGATE(Instruction);}
visitVAArgInst(VAArgInst & I)1900b57cec5SDimitry Andric   RetTy visitVAArgInst(VAArgInst   &I)            { DELEGATE(UnaryInstruction);}
visitExtractElementInst(ExtractElementInst & I)1910b57cec5SDimitry Andric   RetTy visitExtractElementInst(ExtractElementInst &I) { DELEGATE(Instruction);}
visitInsertElementInst(InsertElementInst & I)1920b57cec5SDimitry Andric   RetTy visitInsertElementInst(InsertElementInst &I) { DELEGATE(Instruction);}
visitShuffleVectorInst(ShuffleVectorInst & I)1930b57cec5SDimitry Andric   RetTy visitShuffleVectorInst(ShuffleVectorInst &I) { DELEGATE(Instruction);}
visitExtractValueInst(ExtractValueInst & I)1940b57cec5SDimitry Andric   RetTy visitExtractValueInst(ExtractValueInst &I){ DELEGATE(UnaryInstruction);}
visitInsertValueInst(InsertValueInst & I)1950b57cec5SDimitry Andric   RetTy visitInsertValueInst(InsertValueInst &I)  { DELEGATE(Instruction); }
visitLandingPadInst(LandingPadInst & I)1960b57cec5SDimitry Andric   RetTy visitLandingPadInst(LandingPadInst &I)    { DELEGATE(Instruction); }
visitFuncletPadInst(FuncletPadInst & I)1970b57cec5SDimitry Andric   RetTy visitFuncletPadInst(FuncletPadInst &I) { DELEGATE(Instruction); }
visitCleanupPadInst(CleanupPadInst & I)1980b57cec5SDimitry Andric   RetTy visitCleanupPadInst(CleanupPadInst &I) { DELEGATE(FuncletPadInst); }
visitCatchPadInst(CatchPadInst & I)1990b57cec5SDimitry Andric   RetTy visitCatchPadInst(CatchPadInst &I)     { DELEGATE(FuncletPadInst); }
visitFreezeInst(FreezeInst & I)200480093f4SDimitry Andric   RetTy visitFreezeInst(FreezeInst &I)         { DELEGATE(Instruction); }
2010b57cec5SDimitry Andric 
20281ad6265SDimitry Andric   // Handle the special intrinsic instruction classes.
visitDbgDeclareInst(DbgDeclareInst & I)2030b57cec5SDimitry Andric   RetTy visitDbgDeclareInst(DbgDeclareInst &I)    { DELEGATE(DbgVariableIntrinsic);}
visitDbgValueInst(DbgValueInst & I)2040b57cec5SDimitry Andric   RetTy visitDbgValueInst(DbgValueInst &I)        { DELEGATE(DbgVariableIntrinsic);}
visitDbgVariableIntrinsic(DbgVariableIntrinsic & I)2050b57cec5SDimitry Andric   RetTy visitDbgVariableIntrinsic(DbgVariableIntrinsic &I)
2060b57cec5SDimitry Andric                                                   { DELEGATE(DbgInfoIntrinsic);}
visitDbgLabelInst(DbgLabelInst & I)2070b57cec5SDimitry Andric   RetTy visitDbgLabelInst(DbgLabelInst &I)        { DELEGATE(DbgInfoIntrinsic);}
visitDbgInfoIntrinsic(DbgInfoIntrinsic & I)2080b57cec5SDimitry Andric   RetTy visitDbgInfoIntrinsic(DbgInfoIntrinsic &I){ DELEGATE(IntrinsicInst); }
visitMemSetInst(MemSetInst & I)2090b57cec5SDimitry Andric   RetTy visitMemSetInst(MemSetInst &I)            { DELEGATE(MemIntrinsic); }
visitMemSetInlineInst(MemSetInlineInst & I)210*bdd1243dSDimitry Andric   RetTy visitMemSetInlineInst(MemSetInlineInst &I){ DELEGATE(MemSetInst); }
visitMemCpyInst(MemCpyInst & I)2110b57cec5SDimitry Andric   RetTy visitMemCpyInst(MemCpyInst &I)            { DELEGATE(MemTransferInst); }
visitMemCpyInlineInst(MemCpyInlineInst & I)212*bdd1243dSDimitry Andric   RetTy visitMemCpyInlineInst(MemCpyInlineInst &I){ DELEGATE(MemCpyInst); }
visitMemMoveInst(MemMoveInst & I)2130b57cec5SDimitry Andric   RetTy visitMemMoveInst(MemMoveInst &I)          { DELEGATE(MemTransferInst); }
visitMemTransferInst(MemTransferInst & I)2140b57cec5SDimitry Andric   RetTy visitMemTransferInst(MemTransferInst &I)  { DELEGATE(MemIntrinsic); }
visitMemIntrinsic(MemIntrinsic & I)2150b57cec5SDimitry Andric   RetTy visitMemIntrinsic(MemIntrinsic &I)        { DELEGATE(IntrinsicInst); }
visitVAStartInst(VAStartInst & I)2160b57cec5SDimitry Andric   RetTy visitVAStartInst(VAStartInst &I)          { DELEGATE(IntrinsicInst); }
visitVAEndInst(VAEndInst & I)2170b57cec5SDimitry Andric   RetTy visitVAEndInst(VAEndInst &I)              { DELEGATE(IntrinsicInst); }
visitVACopyInst(VACopyInst & I)2180b57cec5SDimitry Andric   RetTy visitVACopyInst(VACopyInst &I)            { DELEGATE(IntrinsicInst); }
visitIntrinsicInst(IntrinsicInst & I)2190b57cec5SDimitry Andric   RetTy visitIntrinsicInst(IntrinsicInst &I)      { DELEGATE(CallInst); }
visitCallInst(CallInst & I)2205ffd83dbSDimitry Andric   RetTy visitCallInst(CallInst &I)                { DELEGATE(CallBase); }
visitInvokeInst(InvokeInst & I)2215ffd83dbSDimitry Andric   RetTy visitInvokeInst(InvokeInst &I)            { DELEGATE(CallBase); }
visitCallBrInst(CallBrInst & I)2225ffd83dbSDimitry Andric   RetTy visitCallBrInst(CallBrInst &I)            { DELEGATE(CallBase); }
2230b57cec5SDimitry Andric 
2240b57cec5SDimitry Andric   // While terminators don't have a distinct type modeling them, we support
2250b57cec5SDimitry Andric   // intercepting them with dedicated a visitor callback.
visitReturnInst(ReturnInst & I)2260b57cec5SDimitry Andric   RetTy visitReturnInst(ReturnInst &I) {
2270b57cec5SDimitry Andric     return static_cast<SubClass *>(this)->visitTerminator(I);
2280b57cec5SDimitry Andric   }
visitBranchInst(BranchInst & I)2290b57cec5SDimitry Andric   RetTy visitBranchInst(BranchInst &I) {
2300b57cec5SDimitry Andric     return static_cast<SubClass *>(this)->visitTerminator(I);
2310b57cec5SDimitry Andric   }
visitSwitchInst(SwitchInst & I)2320b57cec5SDimitry Andric   RetTy visitSwitchInst(SwitchInst &I) {
2330b57cec5SDimitry Andric     return static_cast<SubClass *>(this)->visitTerminator(I);
2340b57cec5SDimitry Andric   }
visitIndirectBrInst(IndirectBrInst & I)2350b57cec5SDimitry Andric   RetTy visitIndirectBrInst(IndirectBrInst &I) {
2360b57cec5SDimitry Andric     return static_cast<SubClass *>(this)->visitTerminator(I);
2370b57cec5SDimitry Andric   }
visitResumeInst(ResumeInst & I)2380b57cec5SDimitry Andric   RetTy visitResumeInst(ResumeInst &I) {
2390b57cec5SDimitry Andric     return static_cast<SubClass *>(this)->visitTerminator(I);
2400b57cec5SDimitry Andric   }
visitUnreachableInst(UnreachableInst & I)2410b57cec5SDimitry Andric   RetTy visitUnreachableInst(UnreachableInst &I) {
2420b57cec5SDimitry Andric     return static_cast<SubClass *>(this)->visitTerminator(I);
2430b57cec5SDimitry Andric   }
visitCleanupReturnInst(CleanupReturnInst & I)2440b57cec5SDimitry Andric   RetTy visitCleanupReturnInst(CleanupReturnInst &I) {
2450b57cec5SDimitry Andric     return static_cast<SubClass *>(this)->visitTerminator(I);
2460b57cec5SDimitry Andric   }
visitCatchReturnInst(CatchReturnInst & I)2470b57cec5SDimitry Andric   RetTy visitCatchReturnInst(CatchReturnInst &I) {
2480b57cec5SDimitry Andric     return static_cast<SubClass *>(this)->visitTerminator(I);
2490b57cec5SDimitry Andric   }
visitCatchSwitchInst(CatchSwitchInst & I)2500b57cec5SDimitry Andric   RetTy visitCatchSwitchInst(CatchSwitchInst &I) {
2510b57cec5SDimitry Andric     return static_cast<SubClass *>(this)->visitTerminator(I);
2520b57cec5SDimitry Andric   }
visitTerminator(Instruction & I)2530b57cec5SDimitry Andric   RetTy visitTerminator(Instruction &I)    { DELEGATE(Instruction);}
2540b57cec5SDimitry Andric 
2550b57cec5SDimitry Andric   // Next level propagators: If the user does not overload a specific
2560b57cec5SDimitry Andric   // instruction type, they can overload one of these to get the whole class
2570b57cec5SDimitry Andric   // of instructions...
2580b57cec5SDimitry Andric   //
visitCastInst(CastInst & I)2590b57cec5SDimitry Andric   RetTy visitCastInst(CastInst &I)                { DELEGATE(UnaryInstruction);}
visitUnaryOperator(UnaryOperator & I)2600b57cec5SDimitry Andric   RetTy visitUnaryOperator(UnaryOperator &I)      { DELEGATE(UnaryInstruction);}
visitBinaryOperator(BinaryOperator & I)2610b57cec5SDimitry Andric   RetTy visitBinaryOperator(BinaryOperator &I)    { DELEGATE(Instruction);}
visitCmpInst(CmpInst & I)2620b57cec5SDimitry Andric   RetTy visitCmpInst(CmpInst &I)                  { DELEGATE(Instruction);}
visitUnaryInstruction(UnaryInstruction & I)2630b57cec5SDimitry Andric   RetTy visitUnaryInstruction(UnaryInstruction &I){ DELEGATE(Instruction);}
2640b57cec5SDimitry Andric 
2650b57cec5SDimitry Andric   // The next level delegation for `CallBase` is slightly more complex in order
2660b57cec5SDimitry Andric   // to support visiting cases where the call is also a terminator.
visitCallBase(CallBase & I)2670b57cec5SDimitry Andric   RetTy visitCallBase(CallBase &I) {
2680b57cec5SDimitry Andric     if (isa<InvokeInst>(I) || isa<CallBrInst>(I))
2690b57cec5SDimitry Andric       return static_cast<SubClass *>(this)->visitTerminator(I);
2700b57cec5SDimitry Andric 
2710b57cec5SDimitry Andric     DELEGATE(Instruction);
2720b57cec5SDimitry Andric   }
2730b57cec5SDimitry Andric 
2740b57cec5SDimitry Andric   // If the user wants a 'default' case, they can choose to override this
2750b57cec5SDimitry Andric   // function.  If this function is not overloaded in the user's subclass, then
2760b57cec5SDimitry Andric   // this instruction just gets ignored.
2770b57cec5SDimitry Andric   //
2780b57cec5SDimitry Andric   // Note that you MUST override this function if your return type is not void.
2790b57cec5SDimitry Andric   //
visitInstruction(Instruction & I)2800b57cec5SDimitry Andric   void visitInstruction(Instruction &I) {}  // Ignore unhandled instructions
2810b57cec5SDimitry Andric 
2820b57cec5SDimitry Andric private:
2830b57cec5SDimitry Andric   // Special helper function to delegate to CallInst subclass visitors.
delegateCallInst(CallInst & I)2840b57cec5SDimitry Andric   RetTy delegateCallInst(CallInst &I) {
2850b57cec5SDimitry Andric     if (const Function *F = I.getCalledFunction()) {
2860b57cec5SDimitry Andric       switch (F->getIntrinsicID()) {
2870b57cec5SDimitry Andric       default:                     DELEGATE(IntrinsicInst);
2880b57cec5SDimitry Andric       case Intrinsic::dbg_declare: DELEGATE(DbgDeclareInst);
2890b57cec5SDimitry Andric       case Intrinsic::dbg_value:   DELEGATE(DbgValueInst);
2900b57cec5SDimitry Andric       case Intrinsic::dbg_label:   DELEGATE(DbgLabelInst);
2910b57cec5SDimitry Andric       case Intrinsic::memcpy:      DELEGATE(MemCpyInst);
292*bdd1243dSDimitry Andric       case Intrinsic::memcpy_inline:
293*bdd1243dSDimitry Andric         DELEGATE(MemCpyInlineInst);
2940b57cec5SDimitry Andric       case Intrinsic::memmove:     DELEGATE(MemMoveInst);
2950b57cec5SDimitry Andric       case Intrinsic::memset:      DELEGATE(MemSetInst);
296*bdd1243dSDimitry Andric       case Intrinsic::memset_inline:
297*bdd1243dSDimitry Andric         DELEGATE(MemSetInlineInst);
2980b57cec5SDimitry Andric       case Intrinsic::vastart:     DELEGATE(VAStartInst);
2990b57cec5SDimitry Andric       case Intrinsic::vaend:       DELEGATE(VAEndInst);
3000b57cec5SDimitry Andric       case Intrinsic::vacopy:      DELEGATE(VACopyInst);
3010b57cec5SDimitry Andric       case Intrinsic::not_intrinsic: break;
3020b57cec5SDimitry Andric       }
3030b57cec5SDimitry Andric     }
3040b57cec5SDimitry Andric     DELEGATE(CallInst);
3050b57cec5SDimitry Andric   }
3060b57cec5SDimitry Andric 
3070b57cec5SDimitry Andric   // An overload that will never actually be called, it is used only from dead
3080b57cec5SDimitry Andric   // code in the dispatching from opcodes to instruction subclasses.
delegateCallInst(Instruction & I)3090b57cec5SDimitry Andric   RetTy delegateCallInst(Instruction &I) {
3100b57cec5SDimitry Andric     llvm_unreachable("delegateCallInst called for non-CallInst");
3110b57cec5SDimitry Andric   }
3120b57cec5SDimitry Andric };
3130b57cec5SDimitry Andric 
3140b57cec5SDimitry Andric #undef DELEGATE
3150b57cec5SDimitry Andric 
3160b57cec5SDimitry Andric } // End llvm namespace
3170b57cec5SDimitry Andric 
3180b57cec5SDimitry Andric #endif
319