X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTransforms%2FInstrumentation%2FBlockProfiling.cpp;h=eb8f22585b621cdeab983f06983a6b190634cacd;hb=9e17b632ec7fdd150a2f08ed4b661011ed47dcfa;hp=5986ed9d1341ff32ad9c6d76d4fe8cf017b30c10;hpb=baa2007fae24930d9a309b74c63c1d0286fb5b76;p=oota-llvm.git diff --git a/lib/Transforms/Instrumentation/BlockProfiling.cpp b/lib/Transforms/Instrumentation/BlockProfiling.cpp index 5986ed9d134..eb8f22585b6 100644 --- a/lib/Transforms/Instrumentation/BlockProfiling.cpp +++ b/lib/Transforms/Instrumentation/BlockProfiling.cpp @@ -1,10 +1,10 @@ //===- BlockProfiling.cpp - Insert counters for block profiling -----------===// -// +// // 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 file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// //===----------------------------------------------------------------------===// // // This pass instruments the specified program with counters for basic block or @@ -19,109 +19,111 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Constants.h" #include "llvm/DerivedTypes.h" -#include "llvm/Instructions.h" #include "llvm/Module.h" #include "llvm/Pass.h" +#include "llvm/Support/Compiler.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/Transforms/Instrumentation.h" +#include "RSProfiling.h" +#include "ProfilingUtils.h" +using namespace llvm; namespace { - class FunctionProfiler : public Pass { - bool run(Module &M); - - void insertInitializationCall(Function *MainFn, const char *FnName, - GlobalValue *Array); + class VISIBILITY_HIDDEN FunctionProfiler : public RSProfilers_std { + public: + static char ID; + bool runOnModule(Module &M); }; - - RegisterOpt X("insert-function-profiling", - "Insert instrumentation for function profiling"); } +char FunctionProfiler::ID = 0; + +static RegisterPass +X("insert-function-profiling", + "Insert instrumentation for function profiling"); +static RegisterAnalysisGroup XG(X); + +ModulePass *llvm::createFunctionProfilerPass() { + return new FunctionProfiler(); +} -bool FunctionProfiler::run(Module &M) { - Function *Main = M.getMainFunction(); +bool FunctionProfiler::runOnModule(Module &M) { + Function *Main = M.getFunction("main"); if (Main == 0) { - std::cerr << "WARNING: cannot insert function profiling into a module" - << " with no main function!\n"; + errs() << "WARNING: cannot insert function profiling into a module" + << " with no main function!\n"; return false; // No main, no instrumentation! } unsigned NumFunctions = 0; - for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) - if (!I->isExternal()) + for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) + if (!I->isDeclaration()) ++NumFunctions; - const Type *ATy = ArrayType::get(Type::UIntTy, NumFunctions); + const Type *ATy = ArrayType::get(Type::getInt32Ty(M.getContext()), + NumFunctions); GlobalVariable *Counters = - new GlobalVariable(ATy, false, GlobalValue::InternalLinkage, - Constant::getNullValue(ATy), "FuncProfCounters", &M); - - ConstantPointerRef *CounterCPR = ConstantPointerRef::get(Counters); - std::vector GEPIndices; - GEPIndices.resize(2); - GEPIndices[0] = Constant::getNullValue(Type::LongTy); + new GlobalVariable(M, ATy, false, GlobalValue::InternalLinkage, + Constant::getNullValue(ATy), "FuncProfCounters"); // Instrument all of the functions... unsigned i = 0; - for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) - if (!I->isExternal()) { - // Insert counter at the start of the function, but after any allocas. - BasicBlock *Entry = I->begin(); - BasicBlock::iterator InsertPos = Entry->begin(); - while (isa(InsertPos)) ++InsertPos; - - GEPIndices[1] = ConstantSInt::get(Type::LongTy, i++); - Constant *ElementPtr = - ConstantExpr::getGetElementPtr(CounterCPR, GEPIndices); - - Value *OldVal = new LoadInst(ElementPtr, "OldFuncCounter", InsertPos); - Value *NewVal = BinaryOperator::create(Instruction::Add, OldVal, - ConstantInt::get(Type::UIntTy, 1), - "NewFuncCounter", InsertPos); - new StoreInst(NewVal, ElementPtr, InsertPos); - } + for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) + if (!I->isDeclaration()) + // Insert counter at the start of the function + IncrementCounterInBlock(&I->getEntryBlock(), i++, Counters); // Add the initialization call to main. - insertInitializationCall(Main, "llvm_start_func_profiling", Counters); + InsertProfilingInitCall(Main, "llvm_start_func_profiling", Counters); return true; } -void FunctionProfiler::insertInitializationCall(Function *MainFn, - const char *FnName, - GlobalValue *Array) { - const Type *ArgVTy = PointerType::get(PointerType::get(Type::SByteTy)); - const Type *UIntPtr = PointerType::get(Type::UIntTy); - Module &M = *MainFn->getParent(); - Function *InitFn = M.getOrInsertFunction(FnName, Type::VoidTy, Type::IntTy, - ArgVTy, UIntPtr, Type::UIntTy, 0); - - // This could force argc and argv into programs that wouldn't otherwise have - // them, but instead we just pass null values in. - std::vector Args(4); - Args[0] = Constant::getNullValue(Type::IntTy); - Args[1] = Constant::getNullValue(ArgVTy); - - /* FIXME: We should pass in the command line arguments here! */ - switch (MainFn->asize()) { - default: - case 2: - case 1: - case 0: - break; + +namespace { + class BlockProfiler : public RSProfilers_std { + bool runOnModule(Module &M); + public: + static char ID; + }; +} + +char BlockProfiler::ID = 0; +static RegisterPass +Y("insert-block-profiling", "Insert instrumentation for block profiling"); +static RegisterAnalysisGroup YG(Y); + +ModulePass *llvm::createBlockProfilerPass() { return new BlockProfiler(); } + +bool BlockProfiler::runOnModule(Module &M) { + Function *Main = M.getFunction("main"); + if (Main == 0) { + errs() << "WARNING: cannot insert block profiling into a module" + << " with no main function!\n"; + return false; // No main, no instrumentation! } - ConstantPointerRef *ArrayCPR = ConstantPointerRef::get(Array); - std::vector GEPIndices(2, Constant::getNullValue(Type::LongTy)); - Args[2] = ConstantExpr::getGetElementPtr(ArrayCPR, GEPIndices); - - unsigned NumElements = - cast(Array->getType()->getElementType())->getNumElements(); - Args[3] = ConstantUInt::get(Type::UIntTy, NumElements); - - // Skip over any allocas in the entry block. - BasicBlock *Entry = MainFn->begin(); - BasicBlock::iterator InsertPos = Entry->begin(); - while (isa(InsertPos)) ++InsertPos; - - new CallInst(InitFn, Args, "", InsertPos); + unsigned NumBlocks = 0; + for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) + if (!I->isDeclaration()) + NumBlocks += I->size(); + + const Type *ATy = ArrayType::get(Type::getInt32Ty(M.getContext()), NumBlocks); + GlobalVariable *Counters = + new GlobalVariable(M, ATy, false, GlobalValue::InternalLinkage, + Constant::getNullValue(ATy), "BlockProfCounters"); + + // Instrument all of the blocks... + unsigned i = 0; + for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { + if (I->isDeclaration()) continue; + for (Function::iterator BB = I->begin(), E = I->end(); BB != E; ++BB) + // Insert counter at the start of the block + IncrementCounterInBlock(BB, i++, Counters); + } + + // Add the initialization call to main. + InsertProfilingInitCall(Main, "llvm_start_block_profiling", Counters); + return true; } +