1 //===- InstVisitor.h - Instruction visitor templates ------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 10 #ifndef LLVM_IR_INSTVISITOR_H 11 #define LLVM_IR_INSTVISITOR_H 12 13 #include "llvm/IR/Function.h" 14 #include "llvm/IR/Instructions.h" 15 #include "llvm/IR/IntrinsicInst.h" 16 #include "llvm/IR/Intrinsics.h" 17 #include "llvm/IR/Module.h" 18 #include "llvm/Support/ErrorHandling.h" 19 20 namespace llvm { 21 22 // We operate on opaque instruction classes, so forward declare all instruction 23 // types now... 24 // 25 #define HANDLE_INST(NUM, OPCODE, CLASS) class CLASS; 26 #include "llvm/IR/Instruction.def" 27 28 #define DELEGATE(CLASS_TO_VISIT) \ 29 return static_cast<SubClass*>(this)-> \ 30 visit##CLASS_TO_VISIT(static_cast<CLASS_TO_VISIT&>(I)) 31 32 33 /// Base class for instruction visitors 34 /// 35 /// Instruction visitors are used when you want to perform different actions 36 /// for different kinds of instructions without having to use lots of casts 37 /// and a big switch statement (in your code, that is). 38 /// 39 /// To define your own visitor, inherit from this class, specifying your 40 /// new type for the 'SubClass' template parameter, and "override" visitXXX 41 /// functions in your class. I say "override" because this class is defined 42 /// in terms of statically resolved overloading, not virtual functions. 43 /// 44 /// For example, here is a visitor that counts the number of malloc 45 /// instructions processed: 46 /// 47 /// /// Declare the class. Note that we derive from InstVisitor instantiated 48 /// /// with _our new subclasses_ type. 49 /// /// 50 /// struct CountAllocaVisitor : public InstVisitor<CountAllocaVisitor> { 51 /// unsigned Count; 52 /// CountAllocaVisitor() : Count(0) {} 53 /// 54 /// void visitAllocaInst(AllocaInst &AI) { ++Count; } 55 /// }; 56 /// 57 /// And this class would be used like this: 58 /// CountAllocaVisitor CAV; 59 /// CAV.visit(function); 60 /// NumAllocas = CAV.Count; 61 /// 62 /// The defined has 'visit' methods for Instruction, and also for BasicBlock, 63 /// Function, and Module, which recursively process all contained instructions. 64 /// 65 /// Note that if you don't implement visitXXX for some instruction type, 66 /// the visitXXX method for instruction superclass will be invoked. So 67 /// if instructions are added in the future, they will be automatically 68 /// supported, if you handle one of their superclasses. 69 /// 70 /// The optional second template argument specifies the type that instruction 71 /// visitation functions should return. If you specify this, you *MUST* provide 72 /// an implementation of visitInstruction though!. 73 /// 74 /// Note that this class is specifically designed as a template to avoid 75 /// virtual function call overhead. Defining and using an InstVisitor is just 76 /// as efficient as having your own switch statement over the instruction 77 /// opcode. 78 template<typename SubClass, typename RetTy=void> 79 class InstVisitor { 80 //===--------------------------------------------------------------------===// 81 // Interface code - This is the public interface of the InstVisitor that you 82 // use to visit instructions... 83 // 84 85 public: 86 // Generic visit method - Allow visitation to all instructions in a range 87 template<class Iterator> visit(Iterator Start,Iterator End)88 void visit(Iterator Start, Iterator End) { 89 while (Start != End) 90 static_cast<SubClass*>(this)->visit(*Start++); 91 } 92 93 // Define visitors for functions and basic blocks... 94 // visit(Module & M)95 void visit(Module &M) { 96 static_cast<SubClass*>(this)->visitModule(M); 97 visit(M.begin(), M.end()); 98 } visit(Function & F)99 void visit(Function &F) { 100 static_cast<SubClass*>(this)->visitFunction(F); 101 visit(F.begin(), F.end()); 102 } visit(BasicBlock & BB)103 void visit(BasicBlock &BB) { 104 static_cast<SubClass*>(this)->visitBasicBlock(BB); 105 visit(BB.begin(), BB.end()); 106 } 107 108 // Forwarding functions so that the user can visit with pointers AND refs. visit(Module * M)109 void visit(Module *M) { visit(*M); } visit(Function * F)110 void visit(Function *F) { visit(*F); } visit(BasicBlock * BB)111 void visit(BasicBlock *BB) { visit(*BB); } visit(Instruction * I)112 RetTy visit(Instruction *I) { return visit(*I); } 113 114 // visit - Finally, code to visit an instruction... 115 // visit(Instruction & I)116 RetTy visit(Instruction &I) { 117 static_assert(std::is_base_of<InstVisitor, SubClass>::value, 118 "Must pass the derived type to this template!"); 119 120 switch (I.getOpcode()) { 121 default: llvm_unreachable("Unknown instruction type encountered!"); 122 // Build the switch statement using the Instruction.def file... 123 #define HANDLE_INST(NUM, OPCODE, CLASS) \ 124 case Instruction::OPCODE: return \ 125 static_cast<SubClass*>(this)-> \ 126 visit##OPCODE(static_cast<CLASS&>(I)); 127 #include "llvm/IR/Instruction.def" 128 } 129 } 130 131 //===--------------------------------------------------------------------===// 132 // Visitation functions... these functions provide default fallbacks in case 133 // the user does not specify what to do for a particular instruction type. 134 // The default behavior is to generalize the instruction type to its subtype 135 // and try visiting the subtype. All of this should be inlined perfectly, 136 // because there are no virtual functions to get in the way. 137 // 138 139 // When visiting a module, function or basic block directly, these methods get 140 // called to indicate when transitioning into a new unit. 141 // visitModule(Module & M)142 void visitModule (Module &M) {} visitFunction(Function & F)143 void visitFunction (Function &F) {} visitBasicBlock(BasicBlock & BB)144 void visitBasicBlock(BasicBlock &BB) {} 145 146 // Define instruction specific visitor functions that can be overridden to 147 // handle SPECIFIC instructions. These functions automatically define 148 // visitMul to proxy to visitBinaryOperator for instance in case the user does 149 // not need this generality. 150 // 151 // These functions can also implement fan-out, when a single opcode and 152 // instruction have multiple more specific Instruction subclasses. The Call 153 // instruction currently supports this. We implement that by redirecting that 154 // instruction to a special delegation helper. 155 #define HANDLE_INST(NUM, OPCODE, CLASS) \ 156 RetTy visit##OPCODE(CLASS &I) { \ 157 if (NUM == Instruction::Call) \ 158 return delegateCallInst(I); \ 159 else \ 160 DELEGATE(CLASS); \ 161 } 162 #include "llvm/IR/Instruction.def" 163 164 // Specific Instruction type classes... note that all of the casts are 165 // necessary because we use the instruction classes as opaque types... 166 // visitICmpInst(ICmpInst & I)167 RetTy visitICmpInst(ICmpInst &I) { DELEGATE(CmpInst);} visitFCmpInst(FCmpInst & I)168 RetTy visitFCmpInst(FCmpInst &I) { DELEGATE(CmpInst);} visitAllocaInst(AllocaInst & I)169 RetTy visitAllocaInst(AllocaInst &I) { DELEGATE(UnaryInstruction);} visitLoadInst(LoadInst & I)170 RetTy visitLoadInst(LoadInst &I) { DELEGATE(UnaryInstruction);} visitStoreInst(StoreInst & I)171 RetTy visitStoreInst(StoreInst &I) { DELEGATE(Instruction);} visitAtomicCmpXchgInst(AtomicCmpXchgInst & I)172 RetTy visitAtomicCmpXchgInst(AtomicCmpXchgInst &I) { DELEGATE(Instruction);} visitAtomicRMWInst(AtomicRMWInst & I)173 RetTy visitAtomicRMWInst(AtomicRMWInst &I) { DELEGATE(Instruction);} visitFenceInst(FenceInst & I)174 RetTy visitFenceInst(FenceInst &I) { DELEGATE(Instruction);} visitGetElementPtrInst(GetElementPtrInst & I)175 RetTy visitGetElementPtrInst(GetElementPtrInst &I){ DELEGATE(Instruction);} visitPHINode(PHINode & I)176 RetTy visitPHINode(PHINode &I) { DELEGATE(Instruction);} visitTruncInst(TruncInst & I)177 RetTy visitTruncInst(TruncInst &I) { DELEGATE(CastInst);} visitZExtInst(ZExtInst & I)178 RetTy visitZExtInst(ZExtInst &I) { DELEGATE(CastInst);} visitSExtInst(SExtInst & I)179 RetTy visitSExtInst(SExtInst &I) { DELEGATE(CastInst);} visitFPTruncInst(FPTruncInst & I)180 RetTy visitFPTruncInst(FPTruncInst &I) { DELEGATE(CastInst);} visitFPExtInst(FPExtInst & I)181 RetTy visitFPExtInst(FPExtInst &I) { DELEGATE(CastInst);} visitFPToUIInst(FPToUIInst & I)182 RetTy visitFPToUIInst(FPToUIInst &I) { DELEGATE(CastInst);} visitFPToSIInst(FPToSIInst & I)183 RetTy visitFPToSIInst(FPToSIInst &I) { DELEGATE(CastInst);} visitUIToFPInst(UIToFPInst & I)184 RetTy visitUIToFPInst(UIToFPInst &I) { DELEGATE(CastInst);} visitSIToFPInst(SIToFPInst & I)185 RetTy visitSIToFPInst(SIToFPInst &I) { DELEGATE(CastInst);} visitPtrToIntInst(PtrToIntInst & I)186 RetTy visitPtrToIntInst(PtrToIntInst &I) { DELEGATE(CastInst);} visitIntToPtrInst(IntToPtrInst & I)187 RetTy visitIntToPtrInst(IntToPtrInst &I) { DELEGATE(CastInst);} visitBitCastInst(BitCastInst & I)188 RetTy visitBitCastInst(BitCastInst &I) { DELEGATE(CastInst);} visitAddrSpaceCastInst(AddrSpaceCastInst & I)189 RetTy visitAddrSpaceCastInst(AddrSpaceCastInst &I) { DELEGATE(CastInst);} visitSelectInst(SelectInst & I)190 RetTy visitSelectInst(SelectInst &I) { DELEGATE(Instruction);} visitVAArgInst(VAArgInst & I)191 RetTy visitVAArgInst(VAArgInst &I) { DELEGATE(UnaryInstruction);} visitExtractElementInst(ExtractElementInst & I)192 RetTy visitExtractElementInst(ExtractElementInst &I) { DELEGATE(Instruction);} visitInsertElementInst(InsertElementInst & I)193 RetTy visitInsertElementInst(InsertElementInst &I) { DELEGATE(Instruction);} visitShuffleVectorInst(ShuffleVectorInst & I)194 RetTy visitShuffleVectorInst(ShuffleVectorInst &I) { DELEGATE(Instruction);} visitExtractValueInst(ExtractValueInst & I)195 RetTy visitExtractValueInst(ExtractValueInst &I){ DELEGATE(UnaryInstruction);} visitInsertValueInst(InsertValueInst & I)196 RetTy visitInsertValueInst(InsertValueInst &I) { DELEGATE(Instruction); } visitLandingPadInst(LandingPadInst & I)197 RetTy visitLandingPadInst(LandingPadInst &I) { DELEGATE(Instruction); } visitFuncletPadInst(FuncletPadInst & I)198 RetTy visitFuncletPadInst(FuncletPadInst &I) { DELEGATE(Instruction); } visitCleanupPadInst(CleanupPadInst & I)199 RetTy visitCleanupPadInst(CleanupPadInst &I) { DELEGATE(FuncletPadInst); } visitCatchPadInst(CatchPadInst & I)200 RetTy visitCatchPadInst(CatchPadInst &I) { DELEGATE(FuncletPadInst); } visitFreezeInst(FreezeInst & I)201 RetTy visitFreezeInst(FreezeInst &I) { DELEGATE(Instruction); } 202 203 // Handle the special instrinsic instruction classes. visitDbgDeclareInst(DbgDeclareInst & I)204 RetTy visitDbgDeclareInst(DbgDeclareInst &I) { DELEGATE(DbgVariableIntrinsic);} visitDbgValueInst(DbgValueInst & I)205 RetTy visitDbgValueInst(DbgValueInst &I) { DELEGATE(DbgVariableIntrinsic);} visitDbgVariableIntrinsic(DbgVariableIntrinsic & I)206 RetTy visitDbgVariableIntrinsic(DbgVariableIntrinsic &I) 207 { DELEGATE(DbgInfoIntrinsic);} visitDbgLabelInst(DbgLabelInst & I)208 RetTy visitDbgLabelInst(DbgLabelInst &I) { DELEGATE(DbgInfoIntrinsic);} visitDbgInfoIntrinsic(DbgInfoIntrinsic & I)209 RetTy visitDbgInfoIntrinsic(DbgInfoIntrinsic &I){ DELEGATE(IntrinsicInst); } visitMemSetInst(MemSetInst & I)210 RetTy visitMemSetInst(MemSetInst &I) { DELEGATE(MemIntrinsic); } visitMemCpyInst(MemCpyInst & I)211 RetTy visitMemCpyInst(MemCpyInst &I) { DELEGATE(MemTransferInst); } visitMemMoveInst(MemMoveInst & I)212 RetTy visitMemMoveInst(MemMoveInst &I) { DELEGATE(MemTransferInst); } visitMemTransferInst(MemTransferInst & I)213 RetTy visitMemTransferInst(MemTransferInst &I) { DELEGATE(MemIntrinsic); } visitMemIntrinsic(MemIntrinsic & I)214 RetTy visitMemIntrinsic(MemIntrinsic &I) { DELEGATE(IntrinsicInst); } visitVAStartInst(VAStartInst & I)215 RetTy visitVAStartInst(VAStartInst &I) { DELEGATE(IntrinsicInst); } visitVAEndInst(VAEndInst & I)216 RetTy visitVAEndInst(VAEndInst &I) { DELEGATE(IntrinsicInst); } visitVACopyInst(VACopyInst & I)217 RetTy visitVACopyInst(VACopyInst &I) { DELEGATE(IntrinsicInst); } visitIntrinsicInst(IntrinsicInst & I)218 RetTy visitIntrinsicInst(IntrinsicInst &I) { DELEGATE(CallInst); } visitCallInst(CallInst & I)219 RetTy visitCallInst(CallInst &I) { DELEGATE(CallBase); } visitInvokeInst(InvokeInst & I)220 RetTy visitInvokeInst(InvokeInst &I) { DELEGATE(CallBase); } visitCallBrInst(CallBrInst & I)221 RetTy visitCallBrInst(CallBrInst &I) { DELEGATE(CallBase); } 222 223 // While terminators don't have a distinct type modeling them, we support 224 // intercepting them with dedicated a visitor callback. visitReturnInst(ReturnInst & I)225 RetTy visitReturnInst(ReturnInst &I) { 226 return static_cast<SubClass *>(this)->visitTerminator(I); 227 } visitBranchInst(BranchInst & I)228 RetTy visitBranchInst(BranchInst &I) { 229 return static_cast<SubClass *>(this)->visitTerminator(I); 230 } visitSwitchInst(SwitchInst & I)231 RetTy visitSwitchInst(SwitchInst &I) { 232 return static_cast<SubClass *>(this)->visitTerminator(I); 233 } visitIndirectBrInst(IndirectBrInst & I)234 RetTy visitIndirectBrInst(IndirectBrInst &I) { 235 return static_cast<SubClass *>(this)->visitTerminator(I); 236 } visitResumeInst(ResumeInst & I)237 RetTy visitResumeInst(ResumeInst &I) { 238 return static_cast<SubClass *>(this)->visitTerminator(I); 239 } visitUnreachableInst(UnreachableInst & I)240 RetTy visitUnreachableInst(UnreachableInst &I) { 241 return static_cast<SubClass *>(this)->visitTerminator(I); 242 } visitCleanupReturnInst(CleanupReturnInst & I)243 RetTy visitCleanupReturnInst(CleanupReturnInst &I) { 244 return static_cast<SubClass *>(this)->visitTerminator(I); 245 } visitCatchReturnInst(CatchReturnInst & I)246 RetTy visitCatchReturnInst(CatchReturnInst &I) { 247 return static_cast<SubClass *>(this)->visitTerminator(I); 248 } visitCatchSwitchInst(CatchSwitchInst & I)249 RetTy visitCatchSwitchInst(CatchSwitchInst &I) { 250 return static_cast<SubClass *>(this)->visitTerminator(I); 251 } visitTerminator(Instruction & I)252 RetTy visitTerminator(Instruction &I) { DELEGATE(Instruction);} 253 254 // Next level propagators: If the user does not overload a specific 255 // instruction type, they can overload one of these to get the whole class 256 // of instructions... 257 // visitCastInst(CastInst & I)258 RetTy visitCastInst(CastInst &I) { DELEGATE(UnaryInstruction);} visitUnaryOperator(UnaryOperator & I)259 RetTy visitUnaryOperator(UnaryOperator &I) { DELEGATE(UnaryInstruction);} visitBinaryOperator(BinaryOperator & I)260 RetTy visitBinaryOperator(BinaryOperator &I) { DELEGATE(Instruction);} visitCmpInst(CmpInst & I)261 RetTy visitCmpInst(CmpInst &I) { DELEGATE(Instruction);} visitUnaryInstruction(UnaryInstruction & I)262 RetTy visitUnaryInstruction(UnaryInstruction &I){ DELEGATE(Instruction);} 263 264 // The next level delegation for `CallBase` is slightly more complex in order 265 // to support visiting cases where the call is also a terminator. visitCallBase(CallBase & I)266 RetTy visitCallBase(CallBase &I) { 267 if (isa<InvokeInst>(I) || isa<CallBrInst>(I)) 268 return static_cast<SubClass *>(this)->visitTerminator(I); 269 270 DELEGATE(Instruction); 271 } 272 273 // If the user wants a 'default' case, they can choose to override this 274 // function. If this function is not overloaded in the user's subclass, then 275 // this instruction just gets ignored. 276 // 277 // Note that you MUST override this function if your return type is not void. 278 // visitInstruction(Instruction & I)279 void visitInstruction(Instruction &I) {} // Ignore unhandled instructions 280 281 private: 282 // Special helper function to delegate to CallInst subclass visitors. delegateCallInst(CallInst & I)283 RetTy delegateCallInst(CallInst &I) { 284 if (const Function *F = I.getCalledFunction()) { 285 switch (F->getIntrinsicID()) { 286 default: DELEGATE(IntrinsicInst); 287 case Intrinsic::dbg_declare: DELEGATE(DbgDeclareInst); 288 case Intrinsic::dbg_value: DELEGATE(DbgValueInst); 289 case Intrinsic::dbg_label: DELEGATE(DbgLabelInst); 290 case Intrinsic::memcpy: DELEGATE(MemCpyInst); 291 case Intrinsic::memmove: DELEGATE(MemMoveInst); 292 case Intrinsic::memset: DELEGATE(MemSetInst); 293 case Intrinsic::vastart: DELEGATE(VAStartInst); 294 case Intrinsic::vaend: DELEGATE(VAEndInst); 295 case Intrinsic::vacopy: DELEGATE(VACopyInst); 296 case Intrinsic::not_intrinsic: break; 297 } 298 } 299 DELEGATE(CallInst); 300 } 301 302 // An overload that will never actually be called, it is used only from dead 303 // code in the dispatching from opcodes to instruction subclasses. delegateCallInst(Instruction & I)304 RetTy delegateCallInst(Instruction &I) { 305 llvm_unreachable("delegateCallInst called for non-CallInst"); 306 } 307 }; 308 309 #undef DELEGATE 310 311 } // End llvm namespace 312 313 #endif 314