#include "llvm/IR/CallSite.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/Module.h"
#include "llvm/IRReader/IRReader.h"
#include "llvm/Pass.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/raw_ostream.h" namespace llvm { // We operate on opaque instruction classes, so forward declare all instruction
// types now...
//
#define HANDLE_INST(NUM, OPCODE, CLASS) class CLASS;
#include "llvm/IR/Instruction.def" #define DELEGATE(CLASS_TO_VISIT) \
return static_cast<SubClass *>(this)->visit##CLASS_TO_VISIT( \
static_cast<CLASS_TO_VISIT &>(I)) /// @brief Base class for instruction visitors
///
/// Instruction visitors are used when you want to perform different actions
/// for different kinds of instructions 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 "override" 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 CountAllocaVisitor : public InstVisitor<CountAllocaVisitor> {
/// unsigned Count;
/// CountAllocaVisitor() : Count(0) {}
///
/// void visitAllocaInst(AllocaInst &AI) { ++Count; }
/// };
///
/// And this class would be used like this:
/// CountAllocaVisitor CAV;
/// CAV.visit(function);
/// NumAllocas = CAV.Count;
///
/// The defined has 'visit' methods for Instruction, and also for BasicBlock,
/// Function, and Module, which recursively process all contained 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 one 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 <typename SubClass, typename RetTy = void> class MyInstVisitor {
//===--------------------------------------------------------------------===//
// Interface code - This is the public interface of the InstVisitor that you
// use to visit instructions...
// public:
// Generic visit method - Allow visitation to all instructions in a range
template <class Iterator> void visit(Iterator Start, Iterator End) {
while (Start != End)
static_cast<SubClass *>(this)->visit(*Start++);
} // Define visitors for functions and basic blocks...
//
void visit(Module &M) {
static_cast<SubClass *>(this)->visitModule(M);
visit(M.begin(), M.end());
}
void visit(Function &F) {
static_cast<SubClass *>(this)->visitFunction(F);
visit(F.begin(), F.end());
}
void visit(BasicBlock &BB) {
static_cast<SubClass *>(this)->visitBasicBlock(BB);
visit(BB.begin(), BB.end());
} // Forwarding functions so that the user can visit with pointers AND refs.
void visit(Module *M) { visit(*M); }
void visit(Function *F) { visit(*F); }
void visit(BasicBlock *BB) { visit(*BB); }
RetTy visit(Instruction *I) { return visit(*I); } // visit - Finally, code to visit an instruction...
//
RetTy visit(Instruction &I) {
switch (I.getOpcode()) {
default:
llvm_unreachable("Unknown instruction type encountered!");
// Build the switch statement using the Instruction.def file...
#define HANDLE_INST(NUM, OPCODE, CLASS) \
case Instruction::OPCODE: \
return static_cast<SubClass *>(this)->visit##OPCODE( \
static_cast<CLASS &>(I));
#include "llvm/IR/Instruction.def"
}
} //===--------------------------------------------------------------------===//
// Visitation functions... these functions provide default fallbacks in case
// the user does not specify what to do for a particular instruction type.
// The default behavior is to generalize the instruction type to its subtype
// and try visiting the subtype. All of this should be inlined perfectly,
// because there are no virtual functions to get in the way.
// // When visiting a module, function or basic block directly, these methods get
// called to indicate when transitioning into a new unit.
//
void visitModule(Module &M) {}
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
// not need this generality.
//
// 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) { \
if (NUM == Instruction::Call) \
return delegateCallInst(I); \
else \
DELEGATE(CLASS); \
}
#include "llvm/IR/Instruction.def" // Specific Instruction type classes... note that all of the casts are
// necessary because we use the instruction classes as opaque types...
//
RetTy visitReturnInst(ReturnInst &I) { DELEGATE(TerminatorInst); }
RetTy visitBranchInst(BranchInst &I) { DELEGATE(TerminatorInst); }
RetTy visitSwitchInst(SwitchInst &I) { DELEGATE(TerminatorInst); }
RetTy visitIndirectBrInst(IndirectBrInst &I) { DELEGATE(TerminatorInst); }
RetTy visitResumeInst(ResumeInst &I) { DELEGATE(TerminatorInst); }
RetTy visitUnreachableInst(UnreachableInst &I) { DELEGATE(TerminatorInst); }
RetTy visitCleanupReturnInst(CleanupReturnInst &I) {
DELEGATE(TerminatorInst);
}
RetTy visitCatchReturnInst(CatchReturnInst &I) { DELEGATE(TerminatorInst); }
RetTy visitCatchSwitchInst(CatchSwitchInst &I) { DELEGATE(TerminatorInst); }
RetTy visitICmpInst(ICmpInst &I) { DELEGATE(CmpInst); }
RetTy visitFCmpInst(FCmpInst &I) { DELEGATE(CmpInst); }
RetTy visitAllocaInst(AllocaInst &I) { DELEGATE(UnaryInstruction); }
RetTy visitLoadInst(LoadInst &I) { DELEGATE(UnaryInstruction); }
RetTy visitStoreInst(StoreInst &I) { DELEGATE(Instruction); }
RetTy visitAtomicCmpXchgInst(AtomicCmpXchgInst &I) { DELEGATE(Instruction); }
RetTy visitAtomicRMWInst(AtomicRMWInst &I) { DELEGATE(Instruction); }
RetTy visitFenceInst(FenceInst &I) { DELEGATE(Instruction); }
RetTy visitGetElementPtrInst(GetElementPtrInst &I) { DELEGATE(Instruction); }
RetTy visitPHINode(PHINode &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 visitAddrSpaceCastInst(AddrSpaceCastInst &I) { DELEGATE(CastInst); }
RetTy visitSelectInst(SelectInst &I) { DELEGATE(Instruction); }
RetTy visitVAArgInst(VAArgInst &I) { DELEGATE(UnaryInstruction); }
RetTy visitExtractElementInst(ExtractElementInst &I) {
DELEGATE(Instruction);
}
RetTy visitInsertElementInst(InsertElementInst &I) { DELEGATE(Instruction); }
RetTy visitShuffleVectorInst(ShuffleVectorInst &I) { DELEGATE(Instruction); }
RetTy visitExtractValueInst(ExtractValueInst &I) {
DELEGATE(UnaryInstruction);
}
RetTy visitInsertValueInst(InsertValueInst &I) { DELEGATE(Instruction); }
RetTy visitLandingPadInst(LandingPadInst &I) { DELEGATE(Instruction); }
RetTy visitFuncletPadInst(FuncletPadInst &I) { DELEGATE(Instruction); }
RetTy visitCleanupPadInst(CleanupPadInst &I) { DELEGATE(FuncletPadInst); }
RetTy visitCatchPadInst(CatchPadInst &I) { DELEGATE(FuncletPadInst); } // 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 visitVAStartInst(VAStartInst &I) { DELEGATE(IntrinsicInst); }
RetTy visitVAEndInst(VAEndInst &I) { DELEGATE(IntrinsicInst); }
RetTy visitVACopyInst(VACopyInst &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) {
return static_cast<SubClass *>(this)->visitCallSite(&I);
}
RetTy visitInvokeInst(InvokeInst &I) {
return static_cast<SubClass *>(this)->visitCallSite(&I);
} // Next level propagators: If the user does not overload a specific
// instruction type, they can overload one of these to get the whole class
// of instructions...
//
RetTy visitCastInst(CastInst &I) { DELEGATE(UnaryInstruction); }
RetTy visitBinaryOperator(BinaryOperator &I) { DELEGATE(Instruction); }
RetTy visitCmpInst(CmpInst &I) { DELEGATE(Instruction); }
RetTy visitTerminatorInst(TerminatorInst &I) { DELEGATE(Instruction); }
RetTy visitUnaryInstruction(UnaryInstruction &I) { DELEGATE(Instruction); } // Provide a special visitor for a 'callsite' that visits both calls and
// invokes. When unimplemented, properly delegates to either the terminator or
// regular instruction visitor.
RetTy visitCallSite(CallSite CS) {
assert(CS);
Instruction &I = *CS.getInstruction();
if (CS.isCall())
DELEGATE(Instruction); assert(CS.isInvoke());
DELEGATE(TerminatorInst);
} // If the user wants a 'default' case, they can choose to override this
// function. If this function is not overloaded in the user's subclass, then
// this instruction just gets ignored.
//
// 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 (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::vastart:
DELEGATE(VAStartInst);
case Intrinsic::vaend:
DELEGATE(VAEndInst);
case Intrinsic::vacopy:
DELEGATE(VACopyInst);
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");
}
};
} using namespace llvm; int main(int argc, char **argv) {
if (argc < 2) {
errs() << "Expected an argument - IR file name\n";
exit(1);
} LLVMContext Context;
SMDiagnostic Err;
std::unique_ptr<Module> pM = parseIRFile(argv[1], Err, Context);
if (nullptr == pM) {
Err.print(argv[0], errs());
return 1;
}
Module &M = *pM.get(); errs() << M << '\n'; return 0;
}

  

g++ inst_visitor.cpp  -L/usr/local/lib  -g -Wall -Wextra -std=c++14 `llvm-config --cxxflags --ldflags --libs --libfiles --system-libs  all` -lLLVMSupport && ./a.out a.ll

LLVM example for main的更多相关文章

  1. [llvm] Call the LLVM Jit from c program

    stackoverflow: http://stackoverflow.com/questions/1838304/call-the-llvm-jit-from-c-program Another t ...

  2. LLVM 初探<一>

    一.安装LLVM LLVM是一个低级虚拟机,全称为Low Level Virtual Machine.LLVM也是一个新型的编译器框架,相关的介绍Wikipedia. 现在LLVM的版本已经有很多,根 ...

  3. LLVM language 参考手册(译)(1)

    LLVM Language Reference Manual 摘要 这个文档是一个LLVM汇编语言的参考手册.LLVM是一个基于Static Single Assignment(SSA - 静态单赋值 ...

  4. Debian/Ubuntu Linux 下安装LLVM/Clang 编译器

    第一步,首先编辑 /etc/apt/sources.list,增加下面源: (加入源后务必执行apt-get update,假设有错误提示,先执行第二步,然后apt-get update) Debia ...

  5. LLVM小结

    随笔- 5  文章- 0  评论- 10  LLVM小结   如果说gcc是FSF的传奇,llvm就是Chris Lattner的小清新.当然啦,想具体看看这位四处游山玩水还GPA 4.0的大神和他的 ...

  6. 关于llvm kaleidoscope: 记一次Debug血泪之路

    简而言之,慎(bu)用(yong)全局变量! 这次debug基本上花了我一周的时间,我基本上是晚上9点30下自习回然后调试到11点30,如此反复一周直到今天周五终于解决了,,以前都听说前辈们 说尽量不 ...

  7. 手写token解析器、语法解析器、LLVM IR生成器(GO语言)

    最近开始尝试用go写点东西,正好在看LLVM的资料,就写了点相关的内容 - 前端解析器+中间代码生成(本地代码的汇编.执行则靠LLVM工具链完成) https://github.com/daibinh ...

  8. 在windows上构建LLVM 7.0.1

    关于在windows上构建LLVM,网上有不少文章,但都是互相抄来的,写作时极不认真,不是少这个,就是少那个,没有一篇是可以完整照着做下来的,实在气人. 本文的安装和配置过程,我亲自操作过好几遍,不惜 ...

  9. 开发和调试第一个 LLVM Pass

    1. 下载和编译 LLVM LLVM 下载地址 http://releases.llvm.org/download.html,目前最新版是 6.0.0,下载完成之后,执行 tar 解压 llvm 包: ...

随机推荐

  1. 批量删除wps文档里的回车符的方法!WPS使用技巧分享!

    有时候整理文档的时候,如果是从网上复制的文字,可能会因为复制而产生很多的回车符.怎样能批量去掉这些个回车符呢,下面马上告诉你批量删除wps文档里的回车符的方法!WPS使用技巧分享! 想要批量删除批量删 ...

  2. bonext.js学习笔记

    bonext.js是个什么鬼? 首先这是一个前端开发框架,建立在Backbone.js的基础上,使用Jquery操作Dom,Bootstrap负责布局,Art-Template渲染模板,再加上自定义一 ...

  3. php-fpm 在centos 7下的安装配置

    安装php: sudo yum install php php-fpm php-mysql php-mbstring php-mcrypt php-sockets php-curl php-commo ...

  4. Leetcode5:Longest Palindromic Substring@Python

    Given a string s, find the longest palindromic substring in s. You may assume that the maximum lengt ...

  5. Unity已经学会的

    1.以MonoBehaviour为脚本的开发模式. 2.MonoBehaviour的大多数API. 3.动画系统大多数了解. 4.UI了解一些,能写UI. 5.Editor了解一些,能写Editor. ...

  6. vs2013密钥

    Visual Studio Ultimate 2013 KEY(密钥):BWG7X-J98B3-W34RT-33B3R-JVYW9 Visual Studio Premium 2013 KEY(密钥) ...

  7. matplotlib 显示中文 与 latex冲突

    如果在使用中文之前包含了使用latex的语法: mpl.rcParams['text.usetex'] = True 将不能正确显示含有中文的图片. 附 显示中文的方法: from matplotli ...

  8. XP局域网内专用消息队列

    网上能找到DELPHI消息队列的方法,在XP下试了总是不成功,后来在2003上试就行了,对比发现消息队列属性->安全 2003中多了个用户ANONYMOUS_LOGON. 然后在XP下消息队列属 ...

  9. 关于iOS开发证书的一些总结(很有用)

    今天出了个问题,具体是这样的,我把本地的钥匙传里面的各种东西全部清空了,结果出现了各种不可预料到问题.花了一下午的时间反复的测试,终于把证书的一些问题理顺,然后在这里做一些总结. 先看张图片: 其中, ...

  10. linux 目录下文件批量植入和删除,按日期打包

    linux目录下文件批量植入 [root@greymouster http2]# find /usr/local/http2/htdocs/ -type f|xargs sed -i "   ...