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