From c03eb7b923d4ba40a647ffd364cd2e89fc22301d Mon Sep 17 00:00:00 2001 From: Brian Gaeke Date: Mon, 3 May 2004 22:06:32 +0000 Subject: Add initial implementation of basic-block tracing instrumentation pass. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@13335 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Instrumentation/TraceBasicBlocks.cpp | 76 ++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 lib/Transforms/Instrumentation/TraceBasicBlocks.cpp (limited to 'lib/Transforms/Instrumentation') diff --git a/lib/Transforms/Instrumentation/TraceBasicBlocks.cpp b/lib/Transforms/Instrumentation/TraceBasicBlocks.cpp new file mode 100644 index 0000000000..9b8ee8e2d0 --- /dev/null +++ b/lib/Transforms/Instrumentation/TraceBasicBlocks.cpp @@ -0,0 +1,76 @@ +//===- TraceBasicBlocks.cpp - Insert basic-block trace instrumentation ----===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by the LLVM research group and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This pass instruments the specified program with calls into a runtime +// library that cause it to output a trace of basic blocks as a side effect +// of normal execution. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Constants.h" +#include "llvm/DerivedTypes.h" +#include "llvm/Module.h" +#include "llvm/Pass.h" +#include "llvm/Transforms/Utils/BasicBlockUtils.h" +#include "llvm/iOther.h" +#include "llvm/iMemory.h" +#include "llvm/iPHINode.h" +#include "ProfilingUtils.h" +#include "Support/Debug.h" +#include +using namespace llvm; + +namespace { + class TraceBasicBlocks : public Pass { + bool run(Module &M); + }; + + RegisterOpt X("trace-basic-blocks", + "Insert instrumentation for basic block tracing"); +} + +static void InsertInstrumentationCall (BasicBlock *BB, + const std::string FnName, + unsigned BBNumber) { + DEBUG (std::cerr << "InsertInstrumentationCall (\"" << BB->getName () + << "\", \"" << FnName << "\", " << BBNumber << ")\n"); + Module &M = *BB->getParent ()->getParent (); + Function *InstrFn = M.getOrInsertFunction (FnName, Type::VoidTy, + Type::UIntTy, 0); + std::vector Args (1); + Args[0] = ConstantUInt::get (Type::UIntTy, BBNumber); + + // Insert the call after any alloca or PHI instructions... + BasicBlock::iterator InsertPos = BB->begin(); + while (isa(InsertPos) || isa(InsertPos)) + ++InsertPos; + + Instruction *InstrCall = new CallInst (InstrFn, Args, "", InsertPos); +} + +bool TraceBasicBlocks::run(Module &M) { + Function *Main = M.getMainFunction(); + if (Main == 0) { + std::cerr << "WARNING: cannot insert basic-block trace instrumentation" + << " into a module with no main function!\n"; + return false; // No main, no instrumentation! + } + + unsigned BBNumber = 0; + for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) + for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { + InsertInstrumentationCall (BB, "llvm_basic_block_trace", BBNumber); + ++BBNumber; + } + + // Add the initialization call to main. + InsertProfilingInitCall(Main, "llvm_start_basic_block_tracing"); + return true; +} + -- cgit v1.2.3