X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FSupport%2FInstVisitor.h;h=e848c9b576164b5e89124740e2df01c6aa7c12eb;hb=a727d5502c8e23c090da658bf14c5ebc1169a070;hp=a4b1f8b5ee76b6e5445a4a3ae1af13b50b4b8bf3;hpb=f5428213853bae45247fe6da711ff20954d73dbd;p=oota-llvm.git diff --git a/include/llvm/Support/InstVisitor.h b/include/llvm/Support/InstVisitor.h index a4b1f8b5ee7..e848c9b5761 100644 --- a/include/llvm/Support/InstVisitor.h +++ b/include/llvm/Support/InstVisitor.h @@ -6,46 +6,7 @@ // the University of Illinois Open Source License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -// -// This template class is used to define instruction visitors in a typesafe -// manner without having to use lots of casts and a big switch statement (in -// your code that is). The win here is that if instructions are added in the -// future, they will be added to the InstVisitor class, allowing you to -// automatically support them (if you handle on of their superclasses). -// -// Note that this library is specifically designed as a template to avoid -// virtual function call overhead. Defining and using an InstVisitor is just as -// efficient as having your own switch statement over the instruction opcode. -// -// InstVisitor Usage: -// You define InstVisitors from inheriting from the InstVisitor base class -// and "overriding" functions in your class. I say "overriding" because this -// class is defined in terms of statically resolved overloading, not virtual -// functions. As an example, here is a visitor that counts the number of malloc -// instructions processed: -// -// // Declare the class. Note that we derive from InstVisitor instantiated -// // with _our new subclasses_ type. -// // -// struct CountMallocVisitor : public InstVisitor { -// unsigned Count; -// CountMallocVisitor() : Count(0) {} -// -// void visitMallocInst(MallocInst *MI) { ++Count; } -// }; -// -// And this class would be used like this: -// CountMallocVistor CMV; -// CMV.visit(function); -// NumMallocs = CMV.Count; -// -// Returning a value from the visitation function: -// The InstVisitor class takes an optional second template argument that -// specifies what type the instruction visitation functions should return. If -// you specify this, you *MUST* provide an implementation of visitInstruction -// though!. -// -//===----------------------------------------------------------------------===// + #ifndef LLVM_SUPPORT_INSTVISITOR_H #define LLVM_SUPPORT_INSTVISITOR_H @@ -71,6 +32,51 @@ class AllocationInst; visit##CLASS_TO_VISIT(static_cast(I)) +/// @brief Base class for instruction visitors +/// +/// Instruction visitors are used when you want to perform different action for +/// different kinds of instruction without without having to use lots of casts +/// and a big switch statement (in your code that is). +/// +/// To define your own visitor, inherit from this class, specifying your +/// new type for the 'SubClass' template parameter, and "override" visitXXX +/// functions in your class. I say "overriding" because this class is defined +/// in terms of statically resolved overloading, not virtual functions. +/// +/// For example, here is a visitor that counts the number of malloc +/// instructions processed: +/// +/// /// Declare the class. Note that we derive from InstVisitor instantiated +/// /// with _our new subclasses_ type. +/// /// +/// struct CountMallocVisitor : public InstVisitor { +/// unsigned Count; +/// CountMallocVisitor() : Count(0) {} +/// +/// void visitMallocInst(MallocInst &MI) { ++Count; } +/// }; +/// +/// And this class would be used like this: +/// CountMallocVistor CMV; +/// CMV.visit(function); +/// NumMallocs = CMV.Count; +/// +/// The defined has 'visit' methods for Instruction, and also for BasicBlock, +/// Function, and Module, which recursively process all conained instructions. +/// +/// Note that if you don't implement visitXXX for some instruction type, +/// the visitXXX method for instruction superclass will be invoked. So +/// if instructions are added in the future, they will be automatically +/// supported, if you handle on of their superclasses. +/// +/// The optional second template argument specifies the type that instruction +/// visitation functions should return. If you specify this, you *MUST* provide +/// an implementation of visitInstruction though!. +/// +/// Note that this class is specifically designed as a template to avoid +/// virtual function call overhead. Defining and using an InstVisitor is just +/// as efficient as having your own switch statement over the instruction +/// opcode. template class InstVisitor { //===--------------------------------------------------------------------===// @@ -137,7 +143,6 @@ public: void visitFunction (Function &F) {} void visitBasicBlock(BasicBlock &BB) {} - // Define instruction specific visitor functions that can be overridden to // handle SPECIFIC instructions. These functions automatically define // visitMul to proxy to visitBinaryOperator for instance in case the user does @@ -162,7 +167,8 @@ public: RetTy visitInvokeInst(InvokeInst &I) { DELEGATE(TerminatorInst);} RetTy visitUnwindInst(UnwindInst &I) { DELEGATE(TerminatorInst);} RetTy visitUnreachableInst(UnreachableInst &I) { DELEGATE(TerminatorInst);} - RetTy visitSetCondInst(SetCondInst &I) { DELEGATE(BinaryOperator);} + RetTy visitICmpInst(ICmpInst &I) { DELEGATE(CmpInst);} + RetTy visitFCmpInst(FCmpInst &I) { DELEGATE(CmpInst);} RetTy visitMallocInst(MallocInst &I) { DELEGATE(AllocationInst);} RetTy visitAllocaInst(AllocaInst &I) { DELEGATE(AllocationInst);} RetTy visitFreeInst(FreeInst &I) { DELEGATE(Instruction); } @@ -170,11 +176,24 @@ public: RetTy visitStoreInst(StoreInst &I) { DELEGATE(Instruction); } RetTy visitGetElementPtrInst(GetElementPtrInst &I){ DELEGATE(Instruction); } RetTy visitPHINode(PHINode &I) { DELEGATE(Instruction); } - RetTy visitCastInst(CastInst &I) { DELEGATE(Instruction); } + RetTy visitTruncInst(TruncInst &I) { DELEGATE(CastInst); } + RetTy visitZExtInst(ZExtInst &I) { DELEGATE(CastInst); } + RetTy visitSExtInst(SExtInst &I) { DELEGATE(CastInst); } + RetTy visitFPTruncInst(FPTruncInst &I) { DELEGATE(CastInst); } + RetTy visitFPExtInst(FPExtInst &I) { DELEGATE(CastInst); } + RetTy visitFPToUIInst(FPToUIInst &I) { DELEGATE(CastInst); } + RetTy visitFPToSIInst(FPToSIInst &I) { DELEGATE(CastInst); } + RetTy visitUIToFPInst(UIToFPInst &I) { DELEGATE(CastInst); } + RetTy visitSIToFPInst(SIToFPInst &I) { DELEGATE(CastInst); } + RetTy visitPtrToIntInst(PtrToIntInst &I) { DELEGATE(CastInst); } + RetTy visitIntToPtrInst(IntToPtrInst &I) { DELEGATE(CastInst); } + RetTy visitBitCastInst(BitCastInst &I) { DELEGATE(CastInst); } RetTy visitSelectInst(SelectInst &I) { DELEGATE(Instruction); } RetTy visitCallInst(CallInst &I) { DELEGATE(Instruction); } - RetTy visitShiftInst(ShiftInst &I) { DELEGATE(Instruction); } RetTy visitVAArgInst(VAArgInst &I) { DELEGATE(Instruction); } + RetTy visitExtractElementInst(ExtractElementInst &I) { DELEGATE(Instruction);} + RetTy visitInsertElementInst(InsertElementInst &I) { DELEGATE(Instruction); } + RetTy visitShuffleVectorInst(ShuffleVectorInst &I) { DELEGATE(Instruction); } // Next level propagators... if the user does not overload a specific // instruction type, they can overload one of these to get the whole class @@ -183,6 +202,8 @@ public: RetTy visitTerminatorInst(TerminatorInst &I) { DELEGATE(Instruction); } RetTy visitBinaryOperator(BinaryOperator &I) { DELEGATE(Instruction); } RetTy visitAllocationInst(AllocationInst &I) { DELEGATE(Instruction); } + RetTy visitCmpInst(CmpInst &I) { DELEGATE(Instruction); } + RetTy visitCastInst(CastInst &I) { DELEGATE(Instruction); } // If the user wants a 'default' case, they can choose to override this // function. If this function is not overloaded in the users subclass, then