summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2012-07-30 23:45:06 +0000
committerChandler Carruth <chandlerc@gmail.com>2012-07-30 23:45:06 +0000
commit5eb301740c4ee5d978535caa917cc004733a7fca (patch)
tree2f676d93fd277fd5b1a189b2ee2b57bfcd123310 /include
parent2f6b62b09f07d63b7f3ee2de50735dd8c83c0f0f (diff)
downloadllvm-5eb301740c4ee5d978535caa917cc004733a7fca.tar.gz
llvm-5eb301740c4ee5d978535caa917cc004733a7fca.tar.bz2
llvm-5eb301740c4ee5d978535caa917cc004733a7fca.tar.xz
Extend the InstVisitor to visit the specialized classes wrapping
CallInst for intrinsics. This allows users of the InstVisitor that would like to special case certain very common intrinsics to do so naturally in keeping with the type hierarchy's utility classes. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@161006 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include')
-rw-r--r--include/llvm/Support/InstVisitor.h53
1 files changed, 46 insertions, 7 deletions
diff --git a/include/llvm/Support/InstVisitor.h b/include/llvm/Support/InstVisitor.h
index 52de8f660d..109b3cff85 100644
--- a/include/llvm/Support/InstVisitor.h
+++ b/include/llvm/Support/InstVisitor.h
@@ -13,6 +13,8 @@
#include "llvm/Function.h"
#include "llvm/Instructions.h"
+#include "llvm/Intrinsics.h"
+#include "llvm/IntrinsicInst.h"
#include "llvm/Module.h"
#include "llvm/Support/CallSite.h"
#include "llvm/Support/ErrorHandling.h"
@@ -145,14 +147,17 @@ public:
// visitMul to proxy to visitBinaryOperator for instance in case the user does
// not need this generality.
//
- // The one problem case we have to handle here though is that the PHINode
- // class and opcode name are the exact same. Because of this, we cannot
- // define visitPHINode (the inst version) to forward to visitPHINode (the
- // generic version) without multiply defined symbols and recursion. To handle
- // this, we do not autoexpand "Other" instructions, we do it manually.
- //
+ // These functions can also implement fan-out, when a single opcode and
+ // instruction have multiple more specific Instruction subclasses. The Call
+ // instruction currently supports this. We implement that by redirecting that
+ // instruction to a special delegation helper.
#define HANDLE_INST(NUM, OPCODE, CLASS) \
- RetTy visit##OPCODE(CLASS &I) { DELEGATE(CLASS); }
+ RetTy visit##OPCODE(CLASS &I) { \
+ if (NUM == Instruction::Call) \
+ return delegateCallInst(I); \
+ else \
+ DELEGATE(CLASS); \
+ }
#include "llvm/Instruction.def"
// Specific Instruction type classes... note that all of the casts are
@@ -195,6 +200,17 @@ public:
RetTy visitInsertValueInst(InsertValueInst &I) { DELEGATE(Instruction); }
RetTy visitLandingPadInst(LandingPadInst &I) { DELEGATE(Instruction); }
+ // Handle the special instrinsic instruction classes.
+ RetTy visitDbgDeclareInst(DbgDeclareInst &I) { DELEGATE(DbgInfoIntrinsic);}
+ RetTy visitDbgValueInst(DbgValueInst &I) { DELEGATE(DbgInfoIntrinsic);}
+ RetTy visitDbgInfoIntrinsic(DbgInfoIntrinsic &I) { DELEGATE(IntrinsicInst); }
+ RetTy visitMemSetInst(MemSetInst &I) { DELEGATE(MemIntrinsic); }
+ RetTy visitMemCpyInst(MemCpyInst &I) { DELEGATE(MemTransferInst); }
+ RetTy visitMemMoveInst(MemMoveInst &I) { DELEGATE(MemTransferInst); }
+ RetTy visitMemTransferInst(MemTransferInst &I) { DELEGATE(MemIntrinsic); }
+ RetTy visitMemIntrinsic(MemIntrinsic &I) { DELEGATE(IntrinsicInst); }
+ RetTy visitIntrinsicInst(IntrinsicInst &I) { DELEGATE(CallInst); }
+
// Call and Invoke are slightly different as they delegate first through
// a generic CallSite visitor.
RetTy visitCallInst(CallInst &I) {
@@ -234,6 +250,29 @@ public:
// Note that you MUST override this function if your return type is not void.
//
void visitInstruction(Instruction &I) {} // Ignore unhandled instructions
+
+private:
+ // Special helper function to delegate to CallInst subclass visitors.
+ RetTy delegateCallInst(CallInst &I) {
+ if (const Function *F = I.getCalledFunction()) {
+ switch ((Intrinsic::ID)F->getIntrinsicID()) {
+ default: DELEGATE(IntrinsicInst);
+ case Intrinsic::dbg_declare: DELEGATE(DbgDeclareInst);
+ case Intrinsic::dbg_value: DELEGATE(DbgValueInst);
+ case Intrinsic::memcpy: DELEGATE(MemCpyInst);
+ case Intrinsic::memmove: DELEGATE(MemMoveInst);
+ case Intrinsic::memset: DELEGATE(MemSetInst);
+ case Intrinsic::not_intrinsic: break;
+ }
+ }
+ DELEGATE(CallInst);
+ }
+
+ // An overload that will never actually be called, it is used only from dead
+ // code in the dispatching from opcodes to instruction subclasses.
+ RetTy delegateCallInst(Instruction &I) {
+ llvm_unreachable("delegateCallInst called for non-CallInst");
+ }
};
#undef DELEGATE