ProfilingUtils.cpp revision 467dd2ec6192fca6fe1d2a4b339fbc9b45ca3b17
1//===- ProfilingUtils.cpp - Helper functions shared by profilers ----------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file was developed by the LLVM research group and is distributed under 6// the University of Illinois Open Source License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This files implements a few helper functions which are used by profile 11// instrumentation code to instrument the code. This allows the profiler pass 12// to worry about *what* to insert, and these functions take care of *how* to do 13// it. 14// 15//===----------------------------------------------------------------------===// 16 17#include "ProfilingUtils.h" 18#include "llvm/Constants.h" 19#include "llvm/DerivedTypes.h" 20#include "llvm/Instructions.h" 21#include "llvm/Module.h" 22 23void llvm::InsertProfilingInitCall(Function *MainFn, const char *FnName, 24 GlobalValue *Array) { 25 const Type *ArgVTy = PointerType::get(PointerType::get(Type::SByteTy)); 26 const Type *UIntPtr = PointerType::get(Type::UIntTy); 27 Module &M = *MainFn->getParent(); 28 Function *InitFn = M.getOrInsertFunction(FnName, Type::IntTy, Type::IntTy, 29 ArgVTy, UIntPtr, Type::UIntTy, 0); 30 31 // This could force argc and argv into programs that wouldn't otherwise have 32 // them, but instead we just pass null values in. 33 std::vector<Value*> Args(4); 34 Args[0] = Constant::getNullValue(Type::IntTy); 35 Args[1] = Constant::getNullValue(ArgVTy); 36 37 // Skip over any allocas in the entry block. 38 BasicBlock *Entry = MainFn->begin(); 39 BasicBlock::iterator InsertPos = Entry->begin(); 40 while (isa<AllocaInst>(InsertPos)) ++InsertPos; 41 42 ConstantPointerRef *ArrayCPR = ConstantPointerRef::get(Array); 43 std::vector<Constant*> GEPIndices(2, Constant::getNullValue(Type::LongTy)); 44 Args[2] = ConstantExpr::getGetElementPtr(ArrayCPR, GEPIndices); 45 46 unsigned NumElements = 47 cast<ArrayType>(Array->getType()->getElementType())->getNumElements(); 48 Args[3] = ConstantUInt::get(Type::UIntTy, NumElements); 49 50 Instruction *InitCall = new CallInst(InitFn, Args, "newargc", InsertPos); 51 52 // If argc or argv are not available in main, just pass null values in. 53 Function::aiterator AI; 54 switch (MainFn->asize()) { 55 default: 56 case 2: 57 AI = MainFn->abegin(); ++AI; 58 if (AI->getType() != ArgVTy) { 59 InitCall->setOperand(2, new CastInst(AI, ArgVTy, "argv.cast", InitCall)); 60 } else { 61 InitCall->setOperand(2, AI); 62 } 63 64 case 1: 65 AI = MainFn->abegin(); 66 // If the program looked at argc, have it look at the return value of the 67 // init call instead. 68 if (AI->getType() != Type::IntTy) { 69 if (!AI->use_empty()) 70 AI->replaceAllUsesWith(new CastInst(InitCall, AI->getType(), "", 71 InsertPos)); 72 InitCall->setOperand(1, new CastInst(AI, Type::IntTy, "argc.cast", 73 InitCall)); 74 } else { 75 AI->replaceAllUsesWith(InitCall); 76 InitCall->setOperand(1, AI); 77 } 78 79 case 0: break; 80 } 81} 82 83void llvm::IncrementCounterInBlock(BasicBlock *BB, unsigned CounterNum, 84 ConstantPointerRef *CounterArray) { 85 // Insert the increment after any alloca or PHI instructions... 86 BasicBlock::iterator InsertPos = BB->begin(); 87 while (isa<AllocaInst>(InsertPos) || isa<PHINode>(InsertPos)) 88 ++InsertPos; 89 90 // Create the getelementptr constant expression 91 std::vector<Constant*> Indices(2); 92 Indices[0] = Constant::getNullValue(Type::LongTy); 93 Indices[1] = ConstantSInt::get(Type::LongTy, CounterNum); 94 Constant *ElementPtr = ConstantExpr::getGetElementPtr(CounterArray, Indices); 95 96 // Load, increment and store the value back. 97 Value *OldVal = new LoadInst(ElementPtr, "OldFuncCounter", InsertPos); 98 Value *NewVal = BinaryOperator::create(Instruction::Add, OldVal, 99 ConstantInt::get(Type::UIntTy, 1), 100 "NewFuncCounter", InsertPos); 101 new StoreInst(NewVal, ElementPtr, InsertPos); 102} 103