blob: 1a9a7f3a6ab7e0f06e5dff7678b343ab174bf21b [file] [log] [blame]
Chris Lattner29c14732001-12-14 16:26:05 +00001//===- TraceValues.cpp - Value Tracing for debugging -------------*- C++ -*--=//
2//
Chris Lattner649f5dd2002-04-14 06:15:24 +00003// Support for inserting LLVM code to print values at basic block and function
Chris Lattner29c14732001-12-14 16:26:05 +00004// exits.
5//
6//===----------------------------------------------------------------------===//
Vikram S. Advedf1892f2001-10-14 23:18:45 +00007
8#include "llvm/Transforms/Instrumentation/TraceValues.h"
9#include "llvm/GlobalVariable.h"
Chris Lattner31bcdb82002-04-28 19:55:58 +000010#include "llvm/Constants.h"
Vikram S. Advedf1892f2001-10-14 23:18:45 +000011#include "llvm/DerivedTypes.h"
Vikram S. Adve631b9a32001-10-18 18:16:11 +000012#include "llvm/iMemory.h"
Vikram S. Advedf1892f2001-10-14 23:18:45 +000013#include "llvm/iTerminators.h"
14#include "llvm/iOther.h"
Chris Lattner42a41272002-04-09 18:37:46 +000015#include "llvm/BasicBlock.h"
Chris Lattner79df7c02002-03-26 18:01:55 +000016#include "llvm/Function.h"
Vikram S. Advedf1892f2001-10-14 23:18:45 +000017#include "llvm/Module.h"
Chris Lattnerbd0ef772002-02-26 21:46:54 +000018#include "llvm/Pass.h"
Chris Lattner8d9e3772001-10-18 05:28:08 +000019#include "llvm/Assembly/Writer.h"
Chris Lattnercee8f9a2001-11-27 00:03:19 +000020#include "Support/StringExtras.h"
Chris Lattnerb81a0bf2001-10-18 20:06:03 +000021#include <sstream>
Chris Lattner697954c2002-01-20 22:54:45 +000022using std::vector;
23using std::string;
Vikram S. Adved8893302001-10-28 21:37:25 +000024
Chris Lattnerbd0ef772002-02-26 21:46:54 +000025namespace {
Chris Lattnerf57b8452002-04-27 06:56:12 +000026 class InsertTraceCode : public FunctionPass {
Chris Lattner79df7c02002-03-26 18:01:55 +000027 bool TraceBasicBlockExits, TraceFunctionExits;
28 Function *PrintfFunc;
Chris Lattnerbd0ef772002-02-26 21:46:54 +000029 public:
Chris Lattner79df7c02002-03-26 18:01:55 +000030 InsertTraceCode(bool traceBasicBlockExits, bool traceFunctionExits)
Chris Lattnerbd0ef772002-02-26 21:46:54 +000031 : TraceBasicBlockExits(traceBasicBlockExits),
Chris Lattner79df7c02002-03-26 18:01:55 +000032 TraceFunctionExits(traceFunctionExits) {}
Chris Lattner96c466b2002-04-29 14:57:45 +000033
34 const char *getPassName() const { return "Trace Code Insertion"; }
Chris Lattnerbd0ef772002-02-26 21:46:54 +000035
36 // Add a prototype for printf if it is not already in the program.
37 //
38 bool doInitialization(Module *M);
39
40 //--------------------------------------------------------------------------
41 // Function InsertCodeToTraceValues
42 //
Chris Lattner649f5dd2002-04-14 06:15:24 +000043 // Inserts tracing code for all live values at basic block and/or function
Chris Lattner79df7c02002-03-26 18:01:55 +000044 // exits as specified by `traceBasicBlockExits' and `traceFunctionExits'.
Chris Lattnerbd0ef772002-02-26 21:46:54 +000045 //
Chris Lattner79df7c02002-03-26 18:01:55 +000046 static bool doit(Function *M, bool traceBasicBlockExits,
47 bool traceFunctionExits, Function *Printf);
Chris Lattnerbd0ef772002-02-26 21:46:54 +000048
Chris Lattner649f5dd2002-04-14 06:15:24 +000049 // runOnFunction - This method does the work.
Chris Lattnerbd0ef772002-02-26 21:46:54 +000050 //
Chris Lattnerf57b8452002-04-27 06:56:12 +000051 bool runOnFunction(Function *F) {
Chris Lattner79df7c02002-03-26 18:01:55 +000052 return doit(F, TraceBasicBlockExits, TraceFunctionExits, PrintfFunc);
Chris Lattnerbd0ef772002-02-26 21:46:54 +000053 }
Chris Lattner97e52e42002-04-28 21:27:06 +000054
55 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
56 AU.preservesCFG();
57 }
Chris Lattnerbd0ef772002-02-26 21:46:54 +000058 };
59} // end anonymous namespace
60
61
Chris Lattnerf57b8452002-04-27 06:56:12 +000062Pass *createTraceValuesPassForFunction() { // Just trace functions
Chris Lattnerbd0ef772002-02-26 21:46:54 +000063 return new InsertTraceCode(false, true);
64}
65
Chris Lattner649f5dd2002-04-14 06:15:24 +000066Pass *createTraceValuesPassForBasicBlocks() { // Trace BB's and functions
Chris Lattnerbd0ef772002-02-26 21:46:54 +000067 return new InsertTraceCode(true, true);
68}
69
70
71
72
Chris Lattner29c14732001-12-14 16:26:05 +000073// Add a prototype for printf if it is not already in the program.
74//
Chris Lattnerf4de63f2002-01-21 07:31:50 +000075bool InsertTraceCode::doInitialization(Module *M) {
Chris Lattner29c14732001-12-14 16:26:05 +000076 const Type *SBP = PointerType::get(Type::SByteTy);
Chris Lattner2aac6bf2002-04-04 22:19:18 +000077 const FunctionType *MTy =
78 FunctionType::get(Type::IntTy, vector<const Type*>(1, SBP), true);
Vikram S. Adved8893302001-10-28 21:37:25 +000079
Chris Lattner89851072002-03-29 03:43:24 +000080 PrintfFunc = M->getOrInsertFunction("printf", MTy);
81 return false;
Vikram S. Adved8893302001-10-28 21:37:25 +000082}
83
Chris Lattner29c14732001-12-14 16:26:05 +000084
85static inline GlobalVariable *getStringRef(Module *M, const string &str) {
86 // Create a constant internal string reference...
87 Constant *Init = ConstantArray::get(str);
Vikram S. Adve524185a2002-03-18 03:40:25 +000088
89 // Create the global variable and record it in the module
90 // The GV will be renamed to a unique name if needed.
Chris Lattner29c14732001-12-14 16:26:05 +000091 GlobalVariable *GV = new GlobalVariable(Init->getType(), true, true, Init,
92 "trstr");
Chris Lattnerb81a0bf2001-10-18 20:06:03 +000093 M->getGlobalList().push_back(GV);
94 return GV;
Vikram S. Advedf1892f2001-10-14 23:18:45 +000095}
96
Vikram S. Advebedb00d2001-10-18 13:49:22 +000097
Chris Lattner29c14732001-12-14 16:26:05 +000098//
99// Check if this instruction has any uses outside its basic block,
100// or if it used by either a Call or Return instruction.
101//
102static inline bool LiveAtBBExit(const Instruction* I) {
103 const BasicBlock *BB = I->getParent();
104 for (Value::use_const_iterator U = I->use_begin(); U != I->use_end(); ++U)
105 if (const Instruction *UI = dyn_cast<Instruction>(*U))
106 if (UI->getParent() != BB || isa<ReturnInst>(UI))
107 return true;
108
109 return false;
110}
111
112
113static inline bool TraceThisOpCode(unsigned opCode) {
Vikram S. Advedf1892f2001-10-14 23:18:45 +0000114 // Explicitly test for opCodes *not* to trace so that any new opcodes will
Chris Lattner8d9e3772001-10-18 05:28:08 +0000115 // be traced by default (VoidTy's are already excluded)
Vikram S. Advedf1892f2001-10-14 23:18:45 +0000116 //
117 return (opCode < Instruction::FirstOtherOp &&
Vikram S. Advedf1892f2001-10-14 23:18:45 +0000118 opCode != Instruction::Alloca &&
Vikram S. Advedf1892f2001-10-14 23:18:45 +0000119 opCode != Instruction::PHINode &&
120 opCode != Instruction::Cast);
121}
122
Chris Lattner29c14732001-12-14 16:26:05 +0000123
124static bool ShouldTraceValue(const Instruction *I) {
125 return
126 I->getType() != Type::VoidTy && LiveAtBBExit(I) &&
127 TraceThisOpCode(I->getOpcode());
Vikram S. Adve631b9a32001-10-18 18:16:11 +0000128}
129
Chris Lattner29c14732001-12-14 16:26:05 +0000130static string getPrintfCodeFor(const Value *V) {
131 if (V == 0) return "";
Chris Lattner649f5dd2002-04-14 06:15:24 +0000132 if (V->getType()->isFloatingPoint())
133 return "%g";
134 else if (V->getType() == Type::LabelTy || isa<PointerType>(V->getType()))
135 return "0x%p";
136 else if (V->getType()->isIntegral() || V->getType() == Type::BoolTy)
Chris Lattner29c14732001-12-14 16:26:05 +0000137 return "%d";
Chris Lattnerb81a0bf2001-10-18 20:06:03 +0000138
Chris Lattner649f5dd2002-04-14 06:15:24 +0000139 assert(0 && "Illegal value to print out...");
140 return "";
Vikram S. Advebedb00d2001-10-18 13:49:22 +0000141}
Vikram S. Advebedb00d2001-10-18 13:49:22 +0000142
143
Chris Lattner29c14732001-12-14 16:26:05 +0000144static void InsertPrintInst(Value *V, BasicBlock *BB, BasicBlock::iterator &BBI,
Chris Lattner79df7c02002-03-26 18:01:55 +0000145 string Message, Function *Printf) {
Chris Lattner29c14732001-12-14 16:26:05 +0000146 // Escape Message by replacing all % characters with %% chars.
147 unsigned Offset = 0;
148 while ((Offset = Message.find('%', Offset)) != string::npos) {
Chris Lattner649f5dd2002-04-14 06:15:24 +0000149 Message.replace(Offset, 1, "%%");
Chris Lattner29c14732001-12-14 16:26:05 +0000150 Offset += 2; // Skip over the new %'s
151 }
Chris Lattner8d9e3772001-10-18 05:28:08 +0000152
Chris Lattner29c14732001-12-14 16:26:05 +0000153 Module *Mod = BB->getParent()->getParent();
Chris Lattner8d9e3772001-10-18 05:28:08 +0000154
Chris Lattner44571632001-10-18 06:03:05 +0000155 // Turn the marker string into a global variable...
Chris Lattner29c14732001-12-14 16:26:05 +0000156 GlobalVariable *fmtVal = getStringRef(Mod, Message+getPrintfCodeFor(V)+"\n");
157
158 // Turn the format string into an sbyte *
159 Instruction *GEP =
160 new GetElementPtrInst(fmtVal,
161 vector<Value*>(2,ConstantUInt::get(Type::UIntTy, 0)),
162 "trstr");
163 BBI = BB->getInstList().insert(BBI, GEP)+1;
Chris Lattner44571632001-10-18 06:03:05 +0000164
165 // Insert the first print instruction to print the string flag:
Chris Lattner29c14732001-12-14 16:26:05 +0000166 vector<Value*> PrintArgs;
167 PrintArgs.push_back(GEP);
168 if (V) PrintArgs.push_back(V);
169 Instruction *I = new CallInst(Printf, PrintArgs, "trace");
Chris Lattner44571632001-10-18 06:03:05 +0000170 BBI = BB->getInstList().insert(BBI, I)+1;
Chris Lattner29c14732001-12-14 16:26:05 +0000171}
172
Chris Lattner44571632001-10-18 06:03:05 +0000173
Chris Lattner29c14732001-12-14 16:26:05 +0000174static void InsertVerbosePrintInst(Value *V, BasicBlock *BB,
175 BasicBlock::iterator &BBI,
Chris Lattner79df7c02002-03-26 18:01:55 +0000176 const string &Message, Function *Printf) {
Chris Lattner697954c2002-01-20 22:54:45 +0000177 std::ostringstream OutStr;
Chris Lattner29c14732001-12-14 16:26:05 +0000178 if (V) WriteAsOperand(OutStr, V);
179 InsertPrintInst(V, BB, BBI, Message+OutStr.str()+" = ", Printf);
Chris Lattner8d9e3772001-10-18 05:28:08 +0000180}
181
182
Vikram S. Advedf1892f2001-10-14 23:18:45 +0000183// Insert print instructions at the end of the basic block *bb
Vikram S. Adve631b9a32001-10-18 18:16:11 +0000184// for each value in valueVec[] that is live at the end of that basic block,
185// or that is stored to memory in this basic block.
186// If the value is stored to memory, we load it back before printing
Chris Lattner79df7c02002-03-26 18:01:55 +0000187// We also return all such loaded values in the vector valuesStoredInFunction
Chris Lattner649f5dd2002-04-14 06:15:24 +0000188// for printing at the exit from the function. (Note that in each invocation
189// of the function, this will only get the last value stored for each static
Vikram S. Adve631b9a32001-10-18 18:16:11 +0000190// store instruction).
191// *bb must be the block in which the value is computed;
192// this is not checked here.
Vikram S. Advedf1892f2001-10-14 23:18:45 +0000193//
Chris Lattner79df7c02002-03-26 18:01:55 +0000194static void TraceValuesAtBBExit(BasicBlock *BB, Function *Printf,
195 vector<Instruction*> *valuesStoredInFunction) {
Vikram S. Adved8893302001-10-28 21:37:25 +0000196 // Get an iterator to point to the insertion location, which is
197 // just before the terminator instruction.
Vikram S. Advedf1892f2001-10-14 23:18:45 +0000198 //
Chris Lattner29c14732001-12-14 16:26:05 +0000199 BasicBlock::iterator InsertPos = BB->end()-1;
200 assert((*InsertPos)->isTerminator());
Vikram S. Advedf1892f2001-10-14 23:18:45 +0000201
Vikram S. Adved8893302001-10-28 21:37:25 +0000202 // If the terminator is a conditional branch, insert the trace code just
203 // before the instruction that computes the branch condition (just to
204 // avoid putting a call between the CC-setting instruction and the branch).
205 // Use laterInstrSet to mark instructions that come after the setCC instr
206 // because those cannot be traced at the location we choose.
207 //
Chris Lattner29c14732001-12-14 16:26:05 +0000208 Instruction *SetCC = 0;
209 if (BranchInst *Branch = dyn_cast<BranchInst>(BB->getTerminator()))
210 if (!Branch->isUnconditional())
211 if (Instruction *I = dyn_cast<Instruction>(Branch->getCondition()))
212 if (I->getParent() == BB) {
213 SetCC = I;
214 while (*InsertPos != SetCC)
215 --InsertPos; // Back up until we can insert before the setcc
216 }
217
218 // Copy all of the instructions into a vector to avoid problems with Setcc
219 const vector<Instruction*> Insts(BB->begin(), InsertPos);
220
Chris Lattner697954c2002-01-20 22:54:45 +0000221 std::ostringstream OutStr;
Chris Lattner29c14732001-12-14 16:26:05 +0000222 WriteAsOperand(OutStr, BB, false);
223 InsertPrintInst(0, BB, InsertPos, "LEAVING BB:" + OutStr.str(), Printf);
224
Vikram S. Advedf1892f2001-10-14 23:18:45 +0000225 // Insert a print instruction for each value.
226 //
Chris Lattner29c14732001-12-14 16:26:05 +0000227 for (vector<Instruction*>::const_iterator II = Insts.begin(),
228 IE = Insts.end(); II != IE; ++II) {
229 Instruction *I = *II;
230 if (StoreInst *SI = dyn_cast<StoreInst>(I)) {
Chris Lattner79df7c02002-03-26 18:01:55 +0000231 assert(valuesStoredInFunction &&
Chris Lattner649f5dd2002-04-14 06:15:24 +0000232 "Should not be printing a store instruction at function exit");
Chris Lattner29c14732001-12-14 16:26:05 +0000233 LoadInst *LI = new LoadInst(SI->getPointerOperand(), SI->copyIndices(),
234 "reload");
235 InsertPos = BB->getInstList().insert(InsertPos, LI) + 1;
Chris Lattner79df7c02002-03-26 18:01:55 +0000236 valuesStoredInFunction->push_back(LI);
Vikram S. Adve631b9a32001-10-18 18:16:11 +0000237 }
Chris Lattner29c14732001-12-14 16:26:05 +0000238 if (ShouldTraceValue(I))
239 InsertVerbosePrintInst(I, BB, InsertPos, " ", Printf);
240 }
Vikram S. Advedf1892f2001-10-14 23:18:45 +0000241}
242
Chris Lattner79df7c02002-03-26 18:01:55 +0000243static inline void InsertCodeToShowFunctionEntry(Function *M, Function *Printf){
Vikram S. Adve631b9a32001-10-18 18:16:11 +0000244 // Get an iterator to point to the insertion location
Chris Lattner29c14732001-12-14 16:26:05 +0000245 BasicBlock *BB = M->getEntryNode();
246 BasicBlock::iterator BBI = BB->begin();
247
Chris Lattner697954c2002-01-20 22:54:45 +0000248 std::ostringstream OutStr;
Chris Lattner29c14732001-12-14 16:26:05 +0000249 WriteAsOperand(OutStr, M, true);
Chris Lattner649f5dd2002-04-14 06:15:24 +0000250 InsertPrintInst(0, BB, BBI, "ENTERING FUNCTION: " + OutStr.str(), Printf);
Chris Lattner29c14732001-12-14 16:26:05 +0000251
Vikram S. Adve2ed5ccd2001-11-15 15:00:16 +0000252 // Now print all the incoming arguments
Chris Lattner79df7c02002-03-26 18:01:55 +0000253 const Function::ArgumentListType &argList = M->getArgumentList();
Chris Lattner29c14732001-12-14 16:26:05 +0000254 unsigned ArgNo = 0;
Chris Lattner79df7c02002-03-26 18:01:55 +0000255 for (Function::ArgumentListType::const_iterator
Chris Lattner29c14732001-12-14 16:26:05 +0000256 I = argList.begin(), E = argList.end(); I != E; ++I, ++ArgNo) {
Chris Lattner73e21422002-04-09 19:48:49 +0000257 InsertVerbosePrintInst((Value*)*I, BB, BBI,
Chris Lattner29c14732001-12-14 16:26:05 +0000258 " Arg #" + utostr(ArgNo), Printf);
259 }
Vikram S. Adve631b9a32001-10-18 18:16:11 +0000260}
261
262
Chris Lattner79df7c02002-03-26 18:01:55 +0000263static inline void InsertCodeToShowFunctionExit(BasicBlock *BB,
264 Function *Printf) {
Vikram S. Adve631b9a32001-10-18 18:16:11 +0000265 // Get an iterator to point to the insertion location
Chris Lattner29c14732001-12-14 16:26:05 +0000266 BasicBlock::iterator BBI = BB->end()-1;
267 ReturnInst *Ret = cast<ReturnInst>(*BBI);
Vikram S. Adve631b9a32001-10-18 18:16:11 +0000268
Chris Lattner697954c2002-01-20 22:54:45 +0000269 std::ostringstream OutStr;
Chris Lattner29c14732001-12-14 16:26:05 +0000270 WriteAsOperand(OutStr, BB->getParent(), true);
Chris Lattner649f5dd2002-04-14 06:15:24 +0000271 InsertPrintInst(0, BB, BBI, "LEAVING FUNCTION: " + OutStr.str(), Printf);
Vikram S. Adve631b9a32001-10-18 18:16:11 +0000272
Vikram S. Adve2ed5ccd2001-11-15 15:00:16 +0000273 // print the return value, if any
Chris Lattner29c14732001-12-14 16:26:05 +0000274 if (BB->getParent()->getReturnType() != Type::VoidTy)
275 InsertPrintInst(Ret->getReturnValue(), BB, BBI, " Returning: ", Printf);
Vikram S. Advedf1892f2001-10-14 23:18:45 +0000276}
277
278
Chris Lattner79df7c02002-03-26 18:01:55 +0000279bool InsertTraceCode::doit(Function *M, bool traceBasicBlockExits,
280 bool traceFunctionEvents, Function *Printf) {
281 if (!traceBasicBlockExits && !traceFunctionEvents)
Chris Lattner8d9e3772001-10-18 05:28:08 +0000282 return false;
Vikram S. Adve631b9a32001-10-18 18:16:11 +0000283
Chris Lattner79df7c02002-03-26 18:01:55 +0000284 vector<Instruction*> valuesStoredInFunction;
Chris Lattner29c14732001-12-14 16:26:05 +0000285 vector<BasicBlock*> exitBlocks;
286
Chris Lattner79df7c02002-03-26 18:01:55 +0000287 if (traceFunctionEvents)
288 InsertCodeToShowFunctionEntry(M, Printf);
Chris Lattner29c14732001-12-14 16:26:05 +0000289
Chris Lattner79df7c02002-03-26 18:01:55 +0000290 for (Function::iterator BI = M->begin(); BI != M->end(); ++BI) {
Chris Lattner29c14732001-12-14 16:26:05 +0000291 BasicBlock *BB = *BI;
292 if (isa<ReturnInst>(BB->getTerminator()))
293 exitBlocks.push_back(BB); // record this as an exit block
294
295 if (traceBasicBlockExits)
Chris Lattner79df7c02002-03-26 18:01:55 +0000296 TraceValuesAtBBExit(BB, Printf, &valuesStoredInFunction);
Chris Lattner29c14732001-12-14 16:26:05 +0000297 }
298
Chris Lattner79df7c02002-03-26 18:01:55 +0000299 if (traceFunctionEvents)
Chris Lattner29c14732001-12-14 16:26:05 +0000300 for (unsigned i=0; i < exitBlocks.size(); ++i) {
301#if 0
Chris Lattner79df7c02002-03-26 18:01:55 +0000302 TraceValuesAtBBExit(valuesStoredInFunction, exitBlocks[i], module,
303 /*indent*/ 0, /*isFunctionExit*/ true,
304 /*valuesStoredInFunction*/ NULL);
Chris Lattner29c14732001-12-14 16:26:05 +0000305#endif
Chris Lattner79df7c02002-03-26 18:01:55 +0000306 InsertCodeToShowFunctionExit(exitBlocks[i], Printf);
Chris Lattner29c14732001-12-14 16:26:05 +0000307 }
Vikram S. Adve631b9a32001-10-18 18:16:11 +0000308
Chris Lattner8d9e3772001-10-18 05:28:08 +0000309 return true;
Vikram S. Advedf1892f2001-10-14 23:18:45 +0000310}