1 //===- ProfilingUtils.cpp - Helper functions shared by profilers ----------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
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
15 //===----------------------------------------------------------------------===//
17 #include "ProfilingUtils.h"
18 #include "llvm/Constants.h"
19 #include "llvm/DerivedTypes.h"
20 #include "llvm/Instructions.h"
21 #include "llvm/Module.h"
23 void llvm::InsertProfilingInitCall(Function
*MainFn
, const char *FnName
,
26 PointerType::getUnqual(PointerType::getUnqual(Type::Int8Ty
));
27 const PointerType
*UIntPtr
= PointerType::getUnqual(Type::Int32Ty
);
28 Module
&M
= *MainFn
->getParent();
29 Constant
*InitFn
= M
.getOrInsertFunction(FnName
, Type::Int32Ty
, Type::Int32Ty
,
30 ArgVTy
, UIntPtr
, Type::Int32Ty
,
33 // This could force argc and argv into programs that wouldn't otherwise have
34 // them, but instead we just pass null values in.
35 std::vector
<Value
*> Args(4);
36 Args
[0] = Constant::getNullValue(Type::Int32Ty
);
37 Args
[1] = Constant::getNullValue(ArgVTy
);
39 // Skip over any allocas in the entry block.
40 BasicBlock
*Entry
= MainFn
->begin();
41 BasicBlock::iterator InsertPos
= Entry
->begin();
42 while (isa
<AllocaInst
>(InsertPos
)) ++InsertPos
;
44 std::vector
<Constant
*> GEPIndices(2, Constant::getNullValue(Type::Int32Ty
));
45 unsigned NumElements
= 0;
47 Args
[2] = ConstantExpr::getGetElementPtr(Array
, &GEPIndices
[0],
50 cast
<ArrayType
>(Array
->getType()->getElementType())->getNumElements();
52 // If this profiling instrumentation doesn't have a constant array, just
54 Args
[2] = ConstantPointerNull::get(UIntPtr
);
56 Args
[3] = ConstantInt::get(Type::Int32Ty
, NumElements
);
58 Instruction
*InitCall
= CallInst::Create(InitFn
, Args
.begin(), Args
.end(),
59 "newargc", InsertPos
);
61 // If argc or argv are not available in main, just pass null values in.
62 Function::arg_iterator AI
;
63 switch (MainFn
->arg_size()) {
66 AI
= MainFn
->arg_begin(); ++AI
;
67 if (AI
->getType() != ArgVTy
) {
68 Instruction::CastOps opcode
= CastInst::getCastOpcode(AI
, false, ArgVTy
,
70 InitCall
->setOperand(2,
71 CastInst::Create(opcode
, AI
, ArgVTy
, "argv.cast", InitCall
));
73 InitCall
->setOperand(2, AI
);
78 AI
= MainFn
->arg_begin();
79 // If the program looked at argc, have it look at the return value of the
81 if (AI
->getType() != Type::Int32Ty
) {
82 Instruction::CastOps opcode
;
83 if (!AI
->use_empty()) {
84 opcode
= CastInst::getCastOpcode(InitCall
, true, AI
->getType(), true);
85 AI
->replaceAllUsesWith(
86 CastInst::Create(opcode
, InitCall
, AI
->getType(), "", InsertPos
));
88 opcode
= CastInst::getCastOpcode(AI
, true, Type::Int32Ty
, true);
89 InitCall
->setOperand(1,
90 CastInst::Create(opcode
, AI
, Type::Int32Ty
, "argc.cast", InitCall
));
92 AI
->replaceAllUsesWith(InitCall
);
93 InitCall
->setOperand(1, AI
);
100 void llvm::IncrementCounterInBlock(BasicBlock
*BB
, unsigned CounterNum
,
101 GlobalValue
*CounterArray
) {
102 // Insert the increment after any alloca or PHI instructions...
103 BasicBlock::iterator InsertPos
= BB
->getFirstNonPHI();
104 while (isa
<AllocaInst
>(InsertPos
))
107 // Create the getelementptr constant expression
108 std::vector
<Constant
*> Indices(2);
109 Indices
[0] = Constant::getNullValue(Type::Int32Ty
);
110 Indices
[1] = ConstantInt::get(Type::Int32Ty
, CounterNum
);
111 Constant
*ElementPtr
=
112 ConstantExpr::getGetElementPtr(CounterArray
, &Indices
[0], Indices
.size());
114 // Load, increment and store the value back.
115 Value
*OldVal
= new LoadInst(ElementPtr
, "OldFuncCounter", InsertPos
);
116 Value
*NewVal
= BinaryOperator::Create(Instruction::Add
, OldVal
,
117 ConstantInt::get(Type::Int32Ty
, 1),
118 "NewFuncCounter", InsertPos
);
119 new StoreInst(NewVal
, ElementPtr
, InsertPos
);