LLVM API Documentation
00001 //===- ProfilingUtils.cpp - Helper functions shared by profilers ----------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements a few helper functions which are used by profile 00011 // instrumentation code to instrument the code. This allows the profiler pass 00012 // to worry about *what* to insert, and these functions take care of *how* to do 00013 // it. 00014 // 00015 //===----------------------------------------------------------------------===// 00016 00017 #include "ProfilingUtils.h" 00018 #include "llvm/Constants.h" 00019 #include "llvm/DerivedTypes.h" 00020 #include "llvm/Instructions.h" 00021 #include "llvm/Module.h" 00022 00023 void llvm::InsertProfilingInitCall(Function *MainFn, const char *FnName, 00024 GlobalValue *Array) { 00025 const Type *ArgVTy = 00026 PointerType::getUnqual(PointerType::getUnqual(Type::Int8Ty)); 00027 const PointerType *UIntPtr = PointerType::getUnqual(Type::Int32Ty); 00028 Module &M = *MainFn->getParent(); 00029 Constant *InitFn = M.getOrInsertFunction(FnName, Type::Int32Ty, Type::Int32Ty, 00030 ArgVTy, UIntPtr, Type::Int32Ty, 00031 (Type *)0); 00032 00033 // This could force argc and argv into programs that wouldn't otherwise have 00034 // them, but instead we just pass null values in. 00035 std::vector<Value*> Args(4); 00036 Args[0] = Constant::getNullValue(Type::Int32Ty); 00037 Args[1] = Constant::getNullValue(ArgVTy); 00038 00039 // Skip over any allocas in the entry block. 00040 BasicBlock *Entry = MainFn->begin(); 00041 BasicBlock::iterator InsertPos = Entry->begin(); 00042 while (isa<AllocaInst>(InsertPos)) ++InsertPos; 00043 00044 std::vector<Constant*> GEPIndices(2, Constant::getNullValue(Type::Int32Ty)); 00045 unsigned NumElements = 0; 00046 if (Array) { 00047 Args[2] = ConstantExpr::getGetElementPtr(Array, &GEPIndices[0], 00048 GEPIndices.size()); 00049 NumElements = 00050 cast<ArrayType>(Array->getType()->getElementType())->getNumElements(); 00051 } else { 00052 // If this profiling instrumentation doesn't have a constant array, just 00053 // pass null. 00054 Args[2] = ConstantPointerNull::get(UIntPtr); 00055 } 00056 Args[3] = ConstantInt::get(Type::Int32Ty, NumElements); 00057 00058 Instruction *InitCall = CallInst::Create(InitFn, Args.begin(), Args.end(), 00059 "newargc", InsertPos); 00060 00061 // If argc or argv are not available in main, just pass null values in. 00062 Function::arg_iterator AI; 00063 switch (MainFn->arg_size()) { 00064 default: 00065 case 2: 00066 AI = MainFn->arg_begin(); ++AI; 00067 if (AI->getType() != ArgVTy) { 00068 Instruction::CastOps opcode = CastInst::getCastOpcode(AI, false, ArgVTy, 00069 false); 00070 InitCall->setOperand(2, 00071 CastInst::Create(opcode, AI, ArgVTy, "argv.cast", InitCall)); 00072 } else { 00073 InitCall->setOperand(2, AI); 00074 } 00075 /* FALL THROUGH */ 00076 00077 case 1: 00078 AI = MainFn->arg_begin(); 00079 // If the program looked at argc, have it look at the return value of the 00080 // init call instead. 00081 if (AI->getType() != Type::Int32Ty) { 00082 Instruction::CastOps opcode; 00083 if (!AI->use_empty()) { 00084 opcode = CastInst::getCastOpcode(InitCall, true, AI->getType(), true); 00085 AI->replaceAllUsesWith( 00086 CastInst::Create(opcode, InitCall, AI->getType(), "", InsertPos)); 00087 } 00088 opcode = CastInst::getCastOpcode(AI, true, Type::Int32Ty, true); 00089 InitCall->setOperand(1, 00090 CastInst::Create(opcode, AI, Type::Int32Ty, "argc.cast", InitCall)); 00091 } else { 00092 AI->replaceAllUsesWith(InitCall); 00093 InitCall->setOperand(1, AI); 00094 } 00095 00096 case 0: break; 00097 } 00098 } 00099 00100 void llvm::IncrementCounterInBlock(BasicBlock *BB, unsigned CounterNum, 00101 GlobalValue *CounterArray) { 00102 // Insert the increment after any alloca or PHI instructions... 00103 BasicBlock::iterator InsertPos = BB->getFirstNonPHI(); 00104 while (isa<AllocaInst>(InsertPos)) 00105 ++InsertPos; 00106 00107 // Create the getelementptr constant expression 00108 std::vector<Constant*> Indices(2); 00109 Indices[0] = Constant::getNullValue(Type::Int32Ty); 00110 Indices[1] = ConstantInt::get(Type::Int32Ty, CounterNum); 00111 Constant *ElementPtr = 00112 ConstantExpr::getGetElementPtr(CounterArray, &Indices[0], Indices.size()); 00113 00114 // Load, increment and store the value back. 00115 Value *OldVal = new LoadInst(ElementPtr, "OldFuncCounter", InsertPos); 00116 Value *NewVal = BinaryOperator::Create(Instruction::Add, OldVal, 00117 ConstantInt::get(Type::Int32Ty, 1), 00118 "NewFuncCounter", InsertPos); 00119 new StoreInst(NewVal, ElementPtr, InsertPos); 00120 }
This web site is hosted by the Computer Science Department at the University of Illinois at Urbana-Champaign.