ProfilingUtils.cpp revision 508955156a25a9abc470a29e1760aa176d341cf9
1//===- ProfilingUtils.cpp - Helper functions shared by profilers ----------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file 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/LLVMContext.h" 22#include "llvm/Module.h" 23 24void llvm::InsertProfilingInitCall(Function *MainFn, const char *FnName, 25 GlobalValue *Array) { 26 LLVMContext* Context = MainFn->getContext(); 27 const Type *ArgVTy = 28 Context->getPointerTypeUnqual(Context->getPointerTypeUnqual(Type::Int8Ty)); 29 const PointerType *UIntPtr = Context->getPointerTypeUnqual(Type::Int32Ty); 30 Module &M = *MainFn->getParent(); 31 Constant *InitFn = M.getOrInsertFunction(FnName, Type::Int32Ty, Type::Int32Ty, 32 ArgVTy, UIntPtr, Type::Int32Ty, 33 (Type *)0); 34 35 // This could force argc and argv into programs that wouldn't otherwise have 36 // them, but instead we just pass null values in. 37 std::vector<Value*> Args(4); 38 Args[0] = Context->getNullValue(Type::Int32Ty); 39 Args[1] = Context->getNullValue(ArgVTy); 40 41 // Skip over any allocas in the entry block. 42 BasicBlock *Entry = MainFn->begin(); 43 BasicBlock::iterator InsertPos = Entry->begin(); 44 while (isa<AllocaInst>(InsertPos)) ++InsertPos; 45 46 std::vector<Constant*> GEPIndices(2, Context->getNullValue(Type::Int32Ty)); 47 unsigned NumElements = 0; 48 if (Array) { 49 Args[2] = Context->getConstantExprGetElementPtr(Array, &GEPIndices[0], 50 GEPIndices.size()); 51 NumElements = 52 cast<ArrayType>(Array->getType()->getElementType())->getNumElements(); 53 } else { 54 // If this profiling instrumentation doesn't have a constant array, just 55 // pass null. 56 Args[2] = Context->getConstantPointerNull(UIntPtr); 57 } 58 Args[3] = Context->getConstantInt(Type::Int32Ty, NumElements); 59 60 Instruction *InitCall = CallInst::Create(InitFn, Args.begin(), Args.end(), 61 "newargc", InsertPos); 62 63 // If argc or argv are not available in main, just pass null values in. 64 Function::arg_iterator AI; 65 switch (MainFn->arg_size()) { 66 default: 67 case 2: 68 AI = MainFn->arg_begin(); ++AI; 69 if (AI->getType() != ArgVTy) { 70 Instruction::CastOps opcode = CastInst::getCastOpcode(AI, false, ArgVTy, 71 false); 72 InitCall->setOperand(2, 73 CastInst::Create(opcode, AI, ArgVTy, "argv.cast", InitCall)); 74 } else { 75 InitCall->setOperand(2, AI); 76 } 77 /* FALL THROUGH */ 78 79 case 1: 80 AI = MainFn->arg_begin(); 81 // If the program looked at argc, have it look at the return value of the 82 // init call instead. 83 if (AI->getType() != Type::Int32Ty) { 84 Instruction::CastOps opcode; 85 if (!AI->use_empty()) { 86 opcode = CastInst::getCastOpcode(InitCall, true, AI->getType(), true); 87 AI->replaceAllUsesWith( 88 CastInst::Create(opcode, InitCall, AI->getType(), "", InsertPos)); 89 } 90 opcode = CastInst::getCastOpcode(AI, true, Type::Int32Ty, true); 91 InitCall->setOperand(1, 92 CastInst::Create(opcode, AI, Type::Int32Ty, "argc.cast", InitCall)); 93 } else { 94 AI->replaceAllUsesWith(InitCall); 95 InitCall->setOperand(1, AI); 96 } 97 98 case 0: break; 99 } 100} 101 102void llvm::IncrementCounterInBlock(BasicBlock *BB, unsigned CounterNum, 103 GlobalValue *CounterArray) { 104 LLVMContext* Context = BB->getContext(); 105 106 // Insert the increment after any alloca or PHI instructions... 107 BasicBlock::iterator InsertPos = BB->getFirstNonPHI(); 108 while (isa<AllocaInst>(InsertPos)) 109 ++InsertPos; 110 111 // Create the getelementptr constant expression 112 std::vector<Constant*> Indices(2); 113 Indices[0] = Context->getNullValue(Type::Int32Ty); 114 Indices[1] = Context->getConstantInt(Type::Int32Ty, CounterNum); 115 Constant *ElementPtr = 116 Context->getConstantExprGetElementPtr(CounterArray, &Indices[0], 117 Indices.size()); 118 119 // Load, increment and store the value back. 120 Value *OldVal = new LoadInst(ElementPtr, "OldFuncCounter", InsertPos); 121 Value *NewVal = BinaryOperator::Create(Instruction::Add, OldVal, 122 Context->getConstantInt(Type::Int32Ty, 1), 123 "NewFuncCounter", InsertPos); 124 new StoreInst(NewVal, ElementPtr, InsertPos); 125} 126