From 942457564d37cdc1c96bcc9e022e8d77628d6520 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Wed, 29 Oct 2003 21:24:22 +0000 Subject: Refactor code, initial implementation of -insert-block-profiling pass git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@9593 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Instrumentation/BlockProfiling.cpp | 170 ++++++++++++++-------- 1 file changed, 106 insertions(+), 64 deletions(-) (limited to 'lib/Transforms/Instrumentation') diff --git a/lib/Transforms/Instrumentation/BlockProfiling.cpp b/lib/Transforms/Instrumentation/BlockProfiling.cpp index 4b80d18dac..c371a9fa69 100644 --- a/lib/Transforms/Instrumentation/BlockProfiling.cpp +++ b/lib/Transforms/Instrumentation/BlockProfiling.cpp @@ -25,70 +25,8 @@ #include "llvm/Module.h" #include "llvm/Pass.h" -namespace { - class FunctionProfiler : public Pass { - bool run(Module &M); - - void insertInitializationCall(Function *MainFn, const char *FnName, - GlobalValue *Array); - }; - - RegisterOpt X("insert-function-profiling", - "Insert instrumentation for function profiling"); -} - - -bool FunctionProfiler::run(Module &M) { - Function *Main = M.getMainFunction(); - if (Main == 0) { - std::cerr << "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()) - ++NumFunctions; - - const Type *ATy = ArrayType::get(Type::UIntTy, 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); - - // 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); - } - - // Add the initialization call to main. - insertInitializationCall(Main, "llvm_start_func_profiling", Counters); - return true; -} - -void FunctionProfiler::insertInitializationCall(Function *MainFn, - const char *FnName, - GlobalValue *Array) { +static void 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(); @@ -139,3 +77,107 @@ void FunctionProfiler::insertInitializationCall(Function *MainFn, new CallInst(InitFn, Args, "", InsertPos); } + +static void IncrementCounterInBlock(BasicBlock *BB, unsigned CounterNum, + ConstantPointerRef *CounterArray) { + // Insert the increment after any alloca or PHI instructions... + BasicBlock::iterator InsertPos = BB->begin(); + while (isa(InsertPos) || isa(InsertPos)) + ++InsertPos; + + // Create the getelementptr constant expression + std::vector Indices(2); + Indices[0] = Constant::getNullValue(Type::LongTy); + Indices[1] = ConstantSInt::get(Type::LongTy, CounterNum); + Constant *ElementPtr = ConstantExpr::getGetElementPtr(CounterArray, Indices); + + // Load, increment and store the value back. + 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); +} + + +namespace { + class FunctionProfiler : public Pass { + bool run(Module &M); + }; + + RegisterOpt X("insert-function-profiling", + "Insert instrumentation for function profiling"); +} + +bool FunctionProfiler::run(Module &M) { + Function *Main = M.getMainFunction(); + if (Main == 0) { + std::cerr << "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()) + ++NumFunctions; + + const Type *ATy = ArrayType::get(Type::UIntTy, NumFunctions); + GlobalVariable *Counters = + new GlobalVariable(ATy, false, GlobalValue::InternalLinkage, + Constant::getNullValue(ATy), "FuncProfCounters", &M); + + ConstantPointerRef *CounterCPR = ConstantPointerRef::get(Counters); + + // 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 + IncrementCounterInBlock(I->begin(), i++, CounterCPR); + + // Add the initialization call to main. + insertInitializationCall(Main, "llvm_start_func_profiling", Counters); + return true; +} + + +namespace { + class BlockProfiler : public Pass { + bool run(Module &M); + }; + + RegisterOpt Y("insert-block-profiling", + "Insert instrumentation for block profiling"); +} + +bool BlockProfiler::run(Module &M) { + Function *Main = M.getMainFunction(); + if (Main == 0) { + std::cerr << "WARNING: cannot insert block profiling into a module" + << " with no main function!\n"; + return false; // No main, no instrumentation! + } + + unsigned NumBlocks = 0; + for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) + NumBlocks += I->size(); + + const Type *ATy = ArrayType::get(Type::UIntTy, NumBlocks); + GlobalVariable *Counters = + new GlobalVariable(ATy, false, GlobalValue::InternalLinkage, + Constant::getNullValue(ATy), "BlockProfCounters", &M); + + ConstantPointerRef *CounterCPR = ConstantPointerRef::get(Counters); + + // Instrument all of the blocks... + unsigned i = 0; + for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) + for (Function::iterator BB = I->begin(), E = I->end(); BB != E; ++BB) + // Insert counter at the start of the block + IncrementCounterInBlock(BB, i++, CounterCPR); + + // Add the initialization call to main. + insertInitializationCall(Main, "llvm_start_block_profiling", Counters); + return true; +} -- cgit v1.2.3