File indexing completed on 2026-05-10 08:44:03
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef LLVM_IR_INSTVISITOR_H
0011 #define LLVM_IR_INSTVISITOR_H
0012
0013 #include "llvm/IR/Function.h"
0014 #include "llvm/IR/Instructions.h"
0015 #include "llvm/IR/IntrinsicInst.h"
0016 #include "llvm/IR/Intrinsics.h"
0017 #include "llvm/IR/Module.h"
0018
0019 namespace llvm {
0020
0021
0022
0023
0024 #define HANDLE_INST(NUM, OPCODE, CLASS) class CLASS;
0025 #include "llvm/IR/Instruction.def"
0026
0027 #define DELEGATE(CLASS_TO_VISIT) \
0028 return static_cast<SubClass*>(this)-> \
0029 visit##CLASS_TO_VISIT(static_cast<CLASS_TO_VISIT&>(I))
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077 template<typename SubClass, typename RetTy=void>
0078 class InstVisitor {
0079
0080
0081
0082
0083
0084 public:
0085
0086 template<class Iterator>
0087 void visit(Iterator Start, Iterator End) {
0088 while (Start != End)
0089 static_cast<SubClass*>(this)->visit(*Start++);
0090 }
0091
0092
0093
0094 void visit(Module &M) {
0095 static_cast<SubClass*>(this)->visitModule(M);
0096 visit(M.begin(), M.end());
0097 }
0098 void visit(Function &F) {
0099 static_cast<SubClass*>(this)->visitFunction(F);
0100 visit(F.begin(), F.end());
0101 }
0102 void visit(BasicBlock &BB) {
0103 static_cast<SubClass*>(this)->visitBasicBlock(BB);
0104 visit(BB.begin(), BB.end());
0105 }
0106
0107
0108 void visit(Module *M) { visit(*M); }
0109 void visit(Function *F) { visit(*F); }
0110 void visit(BasicBlock *BB) { visit(*BB); }
0111 RetTy visit(Instruction *I) { return visit(*I); }
0112
0113
0114
0115 RetTy visit(Instruction &I) {
0116 static_assert(std::is_base_of<InstVisitor, SubClass>::value,
0117 "Must pass the derived type to this template!");
0118
0119 switch (I.getOpcode()) {
0120 default: llvm_unreachable("Unknown instruction type encountered!");
0121
0122 #define HANDLE_INST(NUM, OPCODE, CLASS) \
0123 case Instruction::OPCODE: return \
0124 static_cast<SubClass*>(this)-> \
0125 visit##OPCODE(static_cast<CLASS&>(I));
0126 #include "llvm/IR/Instruction.def"
0127 }
0128 }
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141 void visitModule (Module &M) {}
0142 void visitFunction (Function &F) {}
0143 void visitBasicBlock(BasicBlock &BB) {}
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154 #define HANDLE_INST(NUM, OPCODE, CLASS) \
0155 RetTy visit##OPCODE(CLASS &I) { \
0156 if (NUM == Instruction::Call) \
0157 return delegateCallInst(I); \
0158 else \
0159 DELEGATE(CLASS); \
0160 }
0161 #include "llvm/IR/Instruction.def"
0162
0163
0164
0165
0166 RetTy visitICmpInst(ICmpInst &I) { DELEGATE(CmpInst);}
0167 RetTy visitFCmpInst(FCmpInst &I) { DELEGATE(CmpInst);}
0168 RetTy visitAllocaInst(AllocaInst &I) { DELEGATE(UnaryInstruction);}
0169 RetTy visitLoadInst(LoadInst &I) { DELEGATE(UnaryInstruction);}
0170 RetTy visitStoreInst(StoreInst &I) { DELEGATE(Instruction);}
0171 RetTy visitAtomicCmpXchgInst(AtomicCmpXchgInst &I) { DELEGATE(Instruction);}
0172 RetTy visitAtomicRMWInst(AtomicRMWInst &I) { DELEGATE(Instruction);}
0173 RetTy visitFenceInst(FenceInst &I) { DELEGATE(Instruction);}
0174 RetTy visitGetElementPtrInst(GetElementPtrInst &I){ DELEGATE(Instruction);}
0175 RetTy visitPHINode(PHINode &I) { DELEGATE(Instruction);}
0176 RetTy visitTruncInst(TruncInst &I) { DELEGATE(CastInst);}
0177 RetTy visitZExtInst(ZExtInst &I) { DELEGATE(CastInst);}
0178 RetTy visitSExtInst(SExtInst &I) { DELEGATE(CastInst);}
0179 RetTy visitFPTruncInst(FPTruncInst &I) { DELEGATE(CastInst);}
0180 RetTy visitFPExtInst(FPExtInst &I) { DELEGATE(CastInst);}
0181 RetTy visitFPToUIInst(FPToUIInst &I) { DELEGATE(CastInst);}
0182 RetTy visitFPToSIInst(FPToSIInst &I) { DELEGATE(CastInst);}
0183 RetTy visitUIToFPInst(UIToFPInst &I) { DELEGATE(CastInst);}
0184 RetTy visitSIToFPInst(SIToFPInst &I) { DELEGATE(CastInst);}
0185 RetTy visitPtrToIntInst(PtrToIntInst &I) { DELEGATE(CastInst);}
0186 RetTy visitIntToPtrInst(IntToPtrInst &I) { DELEGATE(CastInst);}
0187 RetTy visitBitCastInst(BitCastInst &I) { DELEGATE(CastInst);}
0188 RetTy visitAddrSpaceCastInst(AddrSpaceCastInst &I) { DELEGATE(CastInst);}
0189 RetTy visitSelectInst(SelectInst &I) { DELEGATE(Instruction);}
0190 RetTy visitVAArgInst(VAArgInst &I) { DELEGATE(UnaryInstruction);}
0191 RetTy visitExtractElementInst(ExtractElementInst &I) { DELEGATE(Instruction);}
0192 RetTy visitInsertElementInst(InsertElementInst &I) { DELEGATE(Instruction);}
0193 RetTy visitShuffleVectorInst(ShuffleVectorInst &I) { DELEGATE(Instruction);}
0194 RetTy visitExtractValueInst(ExtractValueInst &I){ DELEGATE(UnaryInstruction);}
0195 RetTy visitInsertValueInst(InsertValueInst &I) { DELEGATE(Instruction); }
0196 RetTy visitLandingPadInst(LandingPadInst &I) { DELEGATE(Instruction); }
0197 RetTy visitFuncletPadInst(FuncletPadInst &I) { DELEGATE(Instruction); }
0198 RetTy visitCleanupPadInst(CleanupPadInst &I) { DELEGATE(FuncletPadInst); }
0199 RetTy visitCatchPadInst(CatchPadInst &I) { DELEGATE(FuncletPadInst); }
0200 RetTy visitFreezeInst(FreezeInst &I) { DELEGATE(Instruction); }
0201
0202
0203 RetTy visitDbgDeclareInst(DbgDeclareInst &I) { DELEGATE(DbgVariableIntrinsic);}
0204 RetTy visitDbgValueInst(DbgValueInst &I) { DELEGATE(DbgVariableIntrinsic);}
0205 RetTy visitDbgVariableIntrinsic(DbgVariableIntrinsic &I)
0206 { DELEGATE(DbgInfoIntrinsic);}
0207 RetTy visitDbgLabelInst(DbgLabelInst &I) { DELEGATE(DbgInfoIntrinsic);}
0208 RetTy visitDbgInfoIntrinsic(DbgInfoIntrinsic &I){ DELEGATE(IntrinsicInst); }
0209 RetTy visitMemSetInst(MemSetInst &I) { DELEGATE(MemIntrinsic); }
0210 RetTy visitMemSetInlineInst(MemSetInlineInst &I){ DELEGATE(MemSetInst); }
0211 RetTy visitMemSetPatternInst(MemSetPatternInst &I) {
0212 DELEGATE(IntrinsicInst);
0213 }
0214 RetTy visitMemCpyInst(MemCpyInst &I) { DELEGATE(MemTransferInst); }
0215 RetTy visitMemCpyInlineInst(MemCpyInlineInst &I){ DELEGATE(MemCpyInst); }
0216 RetTy visitMemMoveInst(MemMoveInst &I) { DELEGATE(MemTransferInst); }
0217 RetTy visitMemTransferInst(MemTransferInst &I) { DELEGATE(MemIntrinsic); }
0218 RetTy visitMemIntrinsic(MemIntrinsic &I) { DELEGATE(IntrinsicInst); }
0219 RetTy visitVAStartInst(VAStartInst &I) { DELEGATE(IntrinsicInst); }
0220 RetTy visitVAEndInst(VAEndInst &I) { DELEGATE(IntrinsicInst); }
0221 RetTy visitVACopyInst(VACopyInst &I) { DELEGATE(IntrinsicInst); }
0222 RetTy visitIntrinsicInst(IntrinsicInst &I) { DELEGATE(CallInst); }
0223 RetTy visitCallInst(CallInst &I) { DELEGATE(CallBase); }
0224 RetTy visitInvokeInst(InvokeInst &I) { DELEGATE(CallBase); }
0225 RetTy visitCallBrInst(CallBrInst &I) { DELEGATE(CallBase); }
0226
0227
0228
0229 RetTy visitReturnInst(ReturnInst &I) {
0230 return static_cast<SubClass *>(this)->visitTerminator(I);
0231 }
0232 RetTy visitBranchInst(BranchInst &I) {
0233 return static_cast<SubClass *>(this)->visitTerminator(I);
0234 }
0235 RetTy visitSwitchInst(SwitchInst &I) {
0236 return static_cast<SubClass *>(this)->visitTerminator(I);
0237 }
0238 RetTy visitIndirectBrInst(IndirectBrInst &I) {
0239 return static_cast<SubClass *>(this)->visitTerminator(I);
0240 }
0241 RetTy visitResumeInst(ResumeInst &I) {
0242 return static_cast<SubClass *>(this)->visitTerminator(I);
0243 }
0244 RetTy visitUnreachableInst(UnreachableInst &I) {
0245 return static_cast<SubClass *>(this)->visitTerminator(I);
0246 }
0247 RetTy visitCleanupReturnInst(CleanupReturnInst &I) {
0248 return static_cast<SubClass *>(this)->visitTerminator(I);
0249 }
0250 RetTy visitCatchReturnInst(CatchReturnInst &I) {
0251 return static_cast<SubClass *>(this)->visitTerminator(I);
0252 }
0253 RetTy visitCatchSwitchInst(CatchSwitchInst &I) {
0254 return static_cast<SubClass *>(this)->visitTerminator(I);
0255 }
0256 RetTy visitTerminator(Instruction &I) { DELEGATE(Instruction);}
0257
0258
0259
0260
0261
0262 RetTy visitCastInst(CastInst &I) { DELEGATE(UnaryInstruction);}
0263 RetTy visitUnaryOperator(UnaryOperator &I) { DELEGATE(UnaryInstruction);}
0264 RetTy visitBinaryOperator(BinaryOperator &I) { DELEGATE(Instruction);}
0265 RetTy visitCmpInst(CmpInst &I) { DELEGATE(Instruction);}
0266 RetTy visitUnaryInstruction(UnaryInstruction &I){ DELEGATE(Instruction);}
0267
0268
0269
0270 RetTy visitCallBase(CallBase &I) {
0271 if (isa<InvokeInst>(I) || isa<CallBrInst>(I))
0272 return static_cast<SubClass *>(this)->visitTerminator(I);
0273
0274 DELEGATE(Instruction);
0275 }
0276
0277
0278
0279
0280
0281
0282
0283 void visitInstruction(Instruction &I) {}
0284
0285 private:
0286
0287 RetTy delegateCallInst(CallInst &I) {
0288 if (const Function *F = I.getCalledFunction()) {
0289 switch (F->getIntrinsicID()) {
0290 default: DELEGATE(IntrinsicInst);
0291 case Intrinsic::dbg_declare: DELEGATE(DbgDeclareInst);
0292 case Intrinsic::dbg_value: DELEGATE(DbgValueInst);
0293 case Intrinsic::dbg_label: DELEGATE(DbgLabelInst);
0294 case Intrinsic::memcpy: DELEGATE(MemCpyInst);
0295 case Intrinsic::memcpy_inline:
0296 DELEGATE(MemCpyInlineInst);
0297 case Intrinsic::memmove: DELEGATE(MemMoveInst);
0298 case Intrinsic::memset: DELEGATE(MemSetInst);
0299 case Intrinsic::memset_inline:
0300 DELEGATE(MemSetInlineInst);
0301 case Intrinsic::experimental_memset_pattern:
0302 DELEGATE(MemSetPatternInst);
0303 case Intrinsic::vastart: DELEGATE(VAStartInst);
0304 case Intrinsic::vaend: DELEGATE(VAEndInst);
0305 case Intrinsic::vacopy: DELEGATE(VACopyInst);
0306 case Intrinsic::not_intrinsic: break;
0307 }
0308 }
0309 DELEGATE(CallInst);
0310 }
0311
0312
0313
0314 RetTy delegateCallInst(Instruction &I) {
0315 llvm_unreachable("delegateCallInst called for non-CallInst");
0316 }
0317 };
0318
0319 #undef DELEGATE
0320
0321 }
0322
0323 #endif