diff options
author | Chris Lattner <sabre@nondot.org> | 2003-10-29 21:24:22 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2003-10-29 21:24:22 +0000 |
commit | 942457564d37cdc1c96bcc9e022e8d77628d6520 (patch) | |
tree | 8944a8415608c777ebbe7bc40a55d6c31dd015cf /lib/Transforms/Instrumentation/BlockProfiling.cpp | |
parent | 05b958d3631de6b531766d364170afff1cd8a836 (diff) |
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
Diffstat (limited to 'lib/Transforms/Instrumentation/BlockProfiling.cpp')
-rw-r--r-- | lib/Transforms/Instrumentation/BlockProfiling.cpp | 170 |
1 files changed, 106 insertions, 64 deletions
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<FunctionProfiler> 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<Constant*> 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<AllocaInst>(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<AllocaInst>(InsertPos) || isa<PHINode>(InsertPos)) + ++InsertPos; + + // Create the getelementptr constant expression + std::vector<Constant*> 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<FunctionProfiler> 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<BlockProfiler> 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; +} |