LLVM API Documentation
00001 //===- TraceBasicBlocks.cpp - Insert basic-block trace instrumentation ----===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file was developed by the LLVM research group and is distributed under 00006 // the University of Illinois Open Source License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This pass instruments the specified program with calls into a runtime 00011 // library that cause it to output a trace of basic blocks as a side effect 00012 // of normal execution. 00013 // 00014 //===----------------------------------------------------------------------===// 00015 00016 #include "llvm/Constants.h" 00017 #include "llvm/DerivedTypes.h" 00018 #include "llvm/Module.h" 00019 #include "llvm/Pass.h" 00020 #include "llvm/Transforms/Utils/BasicBlockUtils.h" 00021 #include "llvm/Transforms/Instrumentation.h" 00022 #include "llvm/Instructions.h" 00023 #include "ProfilingUtils.h" 00024 #include "llvm/Support/Debug.h" 00025 #include <set> 00026 #include <iostream> 00027 using namespace llvm; 00028 00029 namespace { 00030 class TraceBasicBlocks : public ModulePass { 00031 bool runOnModule(Module &M); 00032 }; 00033 00034 RegisterOpt<TraceBasicBlocks> X("trace-basic-blocks", 00035 "Insert instrumentation for basic block tracing"); 00036 } 00037 00038 ModulePass *llvm::createTraceBasicBlockPass() 00039 { 00040 return new TraceBasicBlocks(); 00041 } 00042 00043 static void InsertInstrumentationCall (BasicBlock *BB, 00044 const std::string FnName, 00045 unsigned BBNumber) { 00046 DEBUG (std::cerr << "InsertInstrumentationCall (\"" << BB->getName () 00047 << "\", \"" << FnName << "\", " << BBNumber << ")\n"); 00048 Module &M = *BB->getParent ()->getParent (); 00049 Function *InstrFn = M.getOrInsertFunction (FnName, Type::VoidTy, 00050 Type::UIntTy, (Type *)0); 00051 std::vector<Value*> Args (1); 00052 Args[0] = ConstantUInt::get (Type::UIntTy, BBNumber); 00053 00054 // Insert the call after any alloca or PHI instructions... 00055 BasicBlock::iterator InsertPos = BB->begin(); 00056 while (isa<AllocaInst>(InsertPos) || isa<PHINode>(InsertPos)) 00057 ++InsertPos; 00058 00059 Instruction *InstrCall = new CallInst (InstrFn, Args, "", InsertPos); 00060 } 00061 00062 bool TraceBasicBlocks::runOnModule(Module &M) { 00063 Function *Main = M.getMainFunction(); 00064 if (Main == 0) { 00065 std::cerr << "WARNING: cannot insert basic-block trace instrumentation" 00066 << " into a module with no main function!\n"; 00067 return false; // No main, no instrumentation! 00068 } 00069 00070 unsigned BBNumber = 0; 00071 for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) 00072 for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { 00073 InsertInstrumentationCall (BB, "llvm_trace_basic_block", BBNumber); 00074 ++BBNumber; 00075 } 00076 00077 // Add the initialization call to main. 00078 InsertProfilingInitCall(Main, "llvm_start_basic_block_tracing"); 00079 return true; 00080 } 00081