blob: 7948266c25cb35bdbf41dec5309eb6f9cd2c6158 [file] [log] [blame]
Chris Lattnerf1197b02001-12-14 16:26:05 +00001//===- TraceValues.cpp - Value Tracing for debugging -------------*- C++ -*--=//
2//
3// Support for inserting LLVM code to print values at basic block and method
4// exits.
5//
6//===----------------------------------------------------------------------===//
Vikram S. Advea200a6c2001-10-14 23:18:45 +00007
8#include "llvm/Transforms/Instrumentation/TraceValues.h"
9#include "llvm/GlobalVariable.h"
Chris Lattner3462ae32001-12-03 22:26:30 +000010#include "llvm/ConstantVals.h"
Vikram S. Advea200a6c2001-10-14 23:18:45 +000011#include "llvm/DerivedTypes.h"
Vikram S. Advea0db1c92001-10-18 18:16:11 +000012#include "llvm/iMemory.h"
Vikram S. Advea200a6c2001-10-14 23:18:45 +000013#include "llvm/iTerminators.h"
14#include "llvm/iOther.h"
Vikram S. Advea200a6c2001-10-14 23:18:45 +000015#include "llvm/Method.h"
16#include "llvm/Module.h"
17#include "llvm/SymbolTable.h"
Chris Lattnera0a8b5b2001-10-18 05:28:08 +000018#include "llvm/Assembly/Writer.h"
Chris Lattner5de22042001-11-27 00:03:19 +000019#include "Support/StringExtras.h"
Chris Lattnere2c61262001-10-18 20:06:03 +000020#include <sstream>
Vikram S. Adve7ac553a2001-10-18 13:49:22 +000021
Vikram S. Adve96f6ac92001-10-28 21:37:25 +000022
Chris Lattnerf1197b02001-12-14 16:26:05 +000023// Add a prototype for printf if it is not already in the program.
24//
25bool InsertTraceCode::doPassInitialization(Module *M) {
26 SymbolTable *ST = M->getSymbolTable();
27 const Type *SBP = PointerType::get(Type::SByteTy);
28 const MethodType *MTy =
29 MethodType::get(Type::IntTy, vector<const Type*>(1, SBP), true);
Vikram S. Adve96f6ac92001-10-28 21:37:25 +000030
Chris Lattnerf1197b02001-12-14 16:26:05 +000031 if (Value *Meth = ST->lookup(PointerType::get(MTy), "printf")) {
32 PrintfMeth = cast<Method>(Meth);
33 return false;
34 }
35
36 // Create a new method and add it to the module
37 PrintfMeth = new Method(MTy, false, "printf");
38 M->getMethodList().push_back(PrintfMeth);
39 return true;
Vikram S. Adve96f6ac92001-10-28 21:37:25 +000040}
41
Chris Lattnerf1197b02001-12-14 16:26:05 +000042
43static inline GlobalVariable *getStringRef(Module *M, const string &str) {
44 // Create a constant internal string reference...
45 Constant *Init = ConstantArray::get(str);
46 GlobalVariable *GV = new GlobalVariable(Init->getType(), true, true, Init,
47 "trstr");
Chris Lattnere2c61262001-10-18 20:06:03 +000048 M->getGlobalList().push_back(GV);
49 return GV;
Vikram S. Advea200a6c2001-10-14 23:18:45 +000050}
51
Vikram S. Adve7ac553a2001-10-18 13:49:22 +000052
Chris Lattnerf1197b02001-12-14 16:26:05 +000053//
54// Check if this instruction has any uses outside its basic block,
55// or if it used by either a Call or Return instruction.
56//
57static inline bool LiveAtBBExit(const Instruction* I) {
58 const BasicBlock *BB = I->getParent();
59 for (Value::use_const_iterator U = I->use_begin(); U != I->use_end(); ++U)
60 if (const Instruction *UI = dyn_cast<Instruction>(*U))
61 if (UI->getParent() != BB || isa<ReturnInst>(UI))
62 return true;
63
64 return false;
65}
66
67
68static inline bool TraceThisOpCode(unsigned opCode) {
Vikram S. Advea200a6c2001-10-14 23:18:45 +000069 // Explicitly test for opCodes *not* to trace so that any new opcodes will
Chris Lattnera0a8b5b2001-10-18 05:28:08 +000070 // be traced by default (VoidTy's are already excluded)
Vikram S. Advea200a6c2001-10-14 23:18:45 +000071 //
72 return (opCode < Instruction::FirstOtherOp &&
Vikram S. Advea200a6c2001-10-14 23:18:45 +000073 opCode != Instruction::Alloca &&
Vikram S. Advea200a6c2001-10-14 23:18:45 +000074 opCode != Instruction::PHINode &&
75 opCode != Instruction::Cast);
76}
77
Chris Lattnerf1197b02001-12-14 16:26:05 +000078
79static bool ShouldTraceValue(const Instruction *I) {
80 return
81 I->getType() != Type::VoidTy && LiveAtBBExit(I) &&
82 TraceThisOpCode(I->getOpcode());
Vikram S. Advea0db1c92001-10-18 18:16:11 +000083}
84
Chris Lattnerf1197b02001-12-14 16:26:05 +000085static string getPrintfCodeFor(const Value *V) {
86 if (V == 0) return "";
87 switch (V->getType()->getPrimitiveID()) {
88 case Type::BoolTyID:
89 case Type::UByteTyID: case Type::UShortTyID:
90 case Type::UIntTyID: case Type::ULongTyID:
91 case Type::SByteTyID: case Type::ShortTyID:
92 case Type::IntTyID: case Type::LongTyID:
93 return "%d";
Chris Lattnere2c61262001-10-18 20:06:03 +000094
Chris Lattnerf1197b02001-12-14 16:26:05 +000095 case Type::FloatTyID: case Type::DoubleTyID:
96 return "%g";
Chris Lattnere2c61262001-10-18 20:06:03 +000097
Chris Lattnerf1197b02001-12-14 16:26:05 +000098 case Type::LabelTyID: case Type::PointerTyID:
99 return "%p";
Vikram S. Adve7ac553a2001-10-18 13:49:22 +0000100
Chris Lattnerf1197b02001-12-14 16:26:05 +0000101 default:
102 assert(0 && "Illegal value to print out...");
103 return "";
104 }
Vikram S. Adve7ac553a2001-10-18 13:49:22 +0000105}
Vikram S. Adve7ac553a2001-10-18 13:49:22 +0000106
107
Chris Lattnerf1197b02001-12-14 16:26:05 +0000108static void InsertPrintInst(Value *V, BasicBlock *BB, BasicBlock::iterator &BBI,
109 string Message, Method *Printf) {
110 // Escape Message by replacing all % characters with %% chars.
111 unsigned Offset = 0;
112 while ((Offset = Message.find('%', Offset)) != string::npos) {
113 string::iterator Offs = Message.begin()+Offset;
114 //Message.replace(Offs, Offs+1, "%%");
115 Message.replace(Offset, 2, "%%");
116 Offset += 2; // Skip over the new %'s
117 }
Chris Lattnera0a8b5b2001-10-18 05:28:08 +0000118
Chris Lattnerf1197b02001-12-14 16:26:05 +0000119 Module *Mod = BB->getParent()->getParent();
Chris Lattnera0a8b5b2001-10-18 05:28:08 +0000120
Chris Lattner5309e102001-10-18 06:03:05 +0000121 // Turn the marker string into a global variable...
Chris Lattnerf1197b02001-12-14 16:26:05 +0000122 GlobalVariable *fmtVal = getStringRef(Mod, Message+getPrintfCodeFor(V)+"\n");
123
124 // Turn the format string into an sbyte *
125 Instruction *GEP =
126 new GetElementPtrInst(fmtVal,
127 vector<Value*>(2,ConstantUInt::get(Type::UIntTy, 0)),
128 "trstr");
129 BBI = BB->getInstList().insert(BBI, GEP)+1;
Chris Lattner5309e102001-10-18 06:03:05 +0000130
131 // Insert the first print instruction to print the string flag:
Chris Lattnerf1197b02001-12-14 16:26:05 +0000132 vector<Value*> PrintArgs;
133 PrintArgs.push_back(GEP);
134 if (V) PrintArgs.push_back(V);
135 Instruction *I = new CallInst(Printf, PrintArgs, "trace");
Chris Lattner5309e102001-10-18 06:03:05 +0000136 BBI = BB->getInstList().insert(BBI, I)+1;
Chris Lattnerf1197b02001-12-14 16:26:05 +0000137}
138
Chris Lattner5309e102001-10-18 06:03:05 +0000139
Chris Lattnerf1197b02001-12-14 16:26:05 +0000140static void InsertVerbosePrintInst(Value *V, BasicBlock *BB,
141 BasicBlock::iterator &BBI,
142 const string &Message, Method *Printf) {
143 ostringstream OutStr;
144 if (V) WriteAsOperand(OutStr, V);
145 InsertPrintInst(V, BB, BBI, Message+OutStr.str()+" = ", Printf);
Chris Lattnera0a8b5b2001-10-18 05:28:08 +0000146}
147
148
Vikram S. Advea200a6c2001-10-14 23:18:45 +0000149// Insert print instructions at the end of the basic block *bb
Vikram S. Advea0db1c92001-10-18 18:16:11 +0000150// for each value in valueVec[] that is live at the end of that basic block,
151// or that is stored to memory in this basic block.
152// If the value is stored to memory, we load it back before printing
153// We also return all such loaded values in the vector valuesStoredInMethod
154// for printing at the exit from the method. (Note that in each invocation
155// of the method, this will only get the last value stored for each static
156// store instruction).
157// *bb must be the block in which the value is computed;
158// this is not checked here.
Vikram S. Advea200a6c2001-10-14 23:18:45 +0000159//
Chris Lattnerf1197b02001-12-14 16:26:05 +0000160static void TraceValuesAtBBExit(BasicBlock *BB, Method *Printf,
161 vector<Instruction*> *valuesStoredInMethod) {
Vikram S. Adve96f6ac92001-10-28 21:37:25 +0000162 // Get an iterator to point to the insertion location, which is
163 // just before the terminator instruction.
Vikram S. Advea200a6c2001-10-14 23:18:45 +0000164 //
Chris Lattnerf1197b02001-12-14 16:26:05 +0000165 BasicBlock::iterator InsertPos = BB->end()-1;
166 assert((*InsertPos)->isTerminator());
Vikram S. Advea200a6c2001-10-14 23:18:45 +0000167
Vikram S. Adve96f6ac92001-10-28 21:37:25 +0000168 // If the terminator is a conditional branch, insert the trace code just
169 // before the instruction that computes the branch condition (just to
170 // avoid putting a call between the CC-setting instruction and the branch).
171 // Use laterInstrSet to mark instructions that come after the setCC instr
172 // because those cannot be traced at the location we choose.
173 //
Chris Lattnerf1197b02001-12-14 16:26:05 +0000174 Instruction *SetCC = 0;
175 if (BranchInst *Branch = dyn_cast<BranchInst>(BB->getTerminator()))
176 if (!Branch->isUnconditional())
177 if (Instruction *I = dyn_cast<Instruction>(Branch->getCondition()))
178 if (I->getParent() == BB) {
179 SetCC = I;
180 while (*InsertPos != SetCC)
181 --InsertPos; // Back up until we can insert before the setcc
182 }
183
184 // Copy all of the instructions into a vector to avoid problems with Setcc
185 const vector<Instruction*> Insts(BB->begin(), InsertPos);
186
187 ostringstream OutStr;
188 WriteAsOperand(OutStr, BB, false);
189 InsertPrintInst(0, BB, InsertPos, "LEAVING BB:" + OutStr.str(), Printf);
190
Vikram S. Advea200a6c2001-10-14 23:18:45 +0000191 // Insert a print instruction for each value.
192 //
Chris Lattnerf1197b02001-12-14 16:26:05 +0000193 for (vector<Instruction*>::const_iterator II = Insts.begin(),
194 IE = Insts.end(); II != IE; ++II) {
195 Instruction *I = *II;
196 if (StoreInst *SI = dyn_cast<StoreInst>(I)) {
197 assert(valuesStoredInMethod &&
198 "Should not be printing a store instruction at method exit");
199 LoadInst *LI = new LoadInst(SI->getPointerOperand(), SI->copyIndices(),
200 "reload");
201 InsertPos = BB->getInstList().insert(InsertPos, LI) + 1;
202 valuesStoredInMethod->push_back(LI);
Vikram S. Advea0db1c92001-10-18 18:16:11 +0000203 }
Chris Lattnerf1197b02001-12-14 16:26:05 +0000204 if (ShouldTraceValue(I))
205 InsertVerbosePrintInst(I, BB, InsertPos, " ", Printf);
206 }
Vikram S. Advea200a6c2001-10-14 23:18:45 +0000207}
208
Chris Lattnerf1197b02001-12-14 16:26:05 +0000209static inline void InsertCodeToShowMethodEntry(Method *M, Method *Printf) {
Vikram S. Advea0db1c92001-10-18 18:16:11 +0000210 // Get an iterator to point to the insertion location
Chris Lattnerf1197b02001-12-14 16:26:05 +0000211 BasicBlock *BB = M->getEntryNode();
212 BasicBlock::iterator BBI = BB->begin();
213
214 ostringstream OutStr;
215 WriteAsOperand(OutStr, M, true);
216 InsertPrintInst(0, BB, BBI, "ENTERING METHOD: " + OutStr.str(), Printf);
217
Vikram S. Adveb601fda2001-11-15 15:00:16 +0000218 // Now print all the incoming arguments
Chris Lattnerf1197b02001-12-14 16:26:05 +0000219 const Method::ArgumentListType &argList = M->getArgumentList();
220 unsigned ArgNo = 0;
Vikram S. Adveb601fda2001-11-15 15:00:16 +0000221 for (Method::ArgumentListType::const_iterator
Chris Lattnerf1197b02001-12-14 16:26:05 +0000222 I = argList.begin(), E = argList.end(); I != E; ++I, ++ArgNo) {
223 InsertVerbosePrintInst(*I, BB, BBI,
224 " Arg #" + utostr(ArgNo), Printf);
225 }
Vikram S. Advea0db1c92001-10-18 18:16:11 +0000226}
227
228
Chris Lattnerf1197b02001-12-14 16:26:05 +0000229static inline void InsertCodeToShowMethodExit(BasicBlock *BB, Method *Printf) {
Vikram S. Advea0db1c92001-10-18 18:16:11 +0000230 // Get an iterator to point to the insertion location
Chris Lattnerf1197b02001-12-14 16:26:05 +0000231 BasicBlock::iterator BBI = BB->end()-1;
232 ReturnInst *Ret = cast<ReturnInst>(*BBI);
Vikram S. Advea0db1c92001-10-18 18:16:11 +0000233
Chris Lattnerf1197b02001-12-14 16:26:05 +0000234 ostringstream OutStr;
235 WriteAsOperand(OutStr, BB->getParent(), true);
236 InsertPrintInst(0, BB, BBI, "LEAVING METHOD: " + OutStr.str(), Printf);
Vikram S. Advea0db1c92001-10-18 18:16:11 +0000237
Vikram S. Adveb601fda2001-11-15 15:00:16 +0000238 // print the return value, if any
Chris Lattnerf1197b02001-12-14 16:26:05 +0000239 if (BB->getParent()->getReturnType() != Type::VoidTy)
240 InsertPrintInst(Ret->getReturnValue(), BB, BBI, " Returning: ", Printf);
Vikram S. Advea200a6c2001-10-14 23:18:45 +0000241}
242
243
Chris Lattnerf1197b02001-12-14 16:26:05 +0000244bool InsertTraceCode::doit(Method *M, bool traceBasicBlockExits,
245 bool traceMethodEvents, Method *Printf) {
246 if (M->isExternal() || (!traceBasicBlockExits && !traceMethodEvents))
Chris Lattnera0a8b5b2001-10-18 05:28:08 +0000247 return false;
Vikram S. Advea0db1c92001-10-18 18:16:11 +0000248
Chris Lattnerf1197b02001-12-14 16:26:05 +0000249 vector<Instruction*> valuesStoredInMethod;
250 vector<BasicBlock*> exitBlocks;
251
252 Module *module = M->getParent();
253
254 if (traceMethodEvents)
255 InsertCodeToShowMethodEntry(M, Printf);
256
257 for (Method::iterator BI = M->begin(); BI != M->end(); ++BI) {
258 BasicBlock *BB = *BI;
259 if (isa<ReturnInst>(BB->getTerminator()))
260 exitBlocks.push_back(BB); // record this as an exit block
261
262 if (traceBasicBlockExits)
263 TraceValuesAtBBExit(BB, Printf, &valuesStoredInMethod);
264 }
265
266 if (traceMethodEvents)
267 for (unsigned i=0; i < exitBlocks.size(); ++i) {
268#if 0
269 TraceValuesAtBBExit(valuesStoredInMethod, exitBlocks[i], module,
270 /*indent*/ 0, /*isMethodExit*/ true,
271 /*valuesStoredInMethod*/ NULL);
272#endif
273 InsertCodeToShowMethodExit(exitBlocks[i], Printf);
274 }
Vikram S. Advea0db1c92001-10-18 18:16:11 +0000275
Chris Lattnera0a8b5b2001-10-18 05:28:08 +0000276 return true;
Vikram S. Advea200a6c2001-10-14 23:18:45 +0000277}