From 631b9a3523f883cd2c018d4082a8e90ad89be941 Mon Sep 17 00:00:00 2001 From: "Vikram S. Adve" Date: Thu, 18 Oct 2001 18:16:11 +0000 Subject: [PATCH] Only print values live at BB or method exit, and insert loads at each BB exit to read and print values stored in that BB. Note that only these stored values are live at method exit!. Also, print messages at method entry and exit. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@892 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Instrumentation/TraceValues.cpp | 167 +++++++++++++----- 1 file changed, 126 insertions(+), 41 deletions(-) diff --git a/lib/Transforms/Instrumentation/TraceValues.cpp b/lib/Transforms/Instrumentation/TraceValues.cpp index de76baefaac..2d1ff3dad81 100644 --- a/lib/Transforms/Instrumentation/TraceValues.cpp +++ b/lib/Transforms/Instrumentation/TraceValues.cpp @@ -19,6 +19,7 @@ #include "llvm/Type.h" #include "llvm/DerivedTypes.h" #include "llvm/Instruction.h" +#include "llvm/iMemory.h" #include "llvm/iTerminators.h" #include "llvm/iOther.h" #include "llvm/BasicBlock.h" @@ -76,14 +77,34 @@ TraceThisOpCode(unsigned opCode) opCode != Instruction::Cast); } +// +// Check if this instruction has any uses outside its basic block +// +static inline bool +LiveAtBBExit(Instruction* I) +{ + BasicBlock* bb = I->getParent(); + bool isLive = false; + for (Value::use_const_iterator U = I->use_begin(); U != I->use_end(); ++U) + { + const Instruction* userI = dyn_cast(*U); + if (userI == NULL || userI->getParent() != bb) + isLive = true; + } + + return isLive; +} + static void -FindValuesToTraceInBB(BasicBlock* bb, vector& valuesToTraceInBB) +FindValuesToTraceInBB(BasicBlock* bb, vector& valuesToTraceInBB) { for (BasicBlock::iterator II = bb->begin(); II != bb->end(); ++II) - if ((*II)->getType()->isPrimitiveType() && - (*II)->getType() != Type::VoidTy && - TraceThisOpCode((*II)->getOpcode())) + if ((*II)->getOpcode() == Instruction::Store + || (LiveAtBBExit(*II) && + (*II)->getType()->isPrimitiveType() && + (*II)->getType() != Type::VoidTy && + TraceThisOpCode((*II)->getOpcode()))) { valuesToTraceInBB.push_back(*II); } @@ -247,13 +268,15 @@ static Value *GetPrintMethodForType(Module *Mod, const Type *VTy) { } -static void InsertPrintInsts(Value *Val, - BasicBlock::iterator &BBI, - Module *Mod, - unsigned int indent, - bool isMethodExit) { +static void +InsertPrintInsts(Value *Val, + BasicBlock* BB, + BasicBlock::iterator &BBI, + Module *Mod, + unsigned int indent, + bool isMethodExit) +{ const Type* ValTy = Val->getType(); - BasicBlock *BB = (*BBI)->getParent(); assert(ValTy->isPrimitiveType() && ValTy->getPrimitiveID() != Type::VoidTyID && @@ -294,42 +317,111 @@ static void InsertPrintInsts(Value *Val, } +static LoadInst* +InsertLoadInst(StoreInst* storeInst, + BasicBlock *bb, + BasicBlock::iterator &BBI) +{ + LoadInst* loadInst = new LoadInst(storeInst->getPtrOperand(), + storeInst->getIndexVec()); + BBI = bb->getInstList().insert(BBI, loadInst) + 1; + return loadInst; +} + // // Insert print instructions at the end of the basic block *bb -// for each value in valueVec[]. *bb must postdominate the block -// in which the value is computed; this is not checked here. +// for each value in valueVec[] that is live at the end of that basic block, +// or that is stored to memory in this basic block. +// If the value is stored to memory, we load it back before printing +// We also return all such loaded values in the vector valuesStoredInMethod +// for printing at the exit from the method. (Note that in each invocation +// of the method, this will only get the last value stored for each static +// store instruction). +// *bb must be the block in which the value is computed; +// this is not checked here. // static void -TraceValuesAtBBExit(const vector& valueVec, +TraceValuesAtBBExit(const vector& valueVec, BasicBlock* bb, Module* module, unsigned int indent, - bool isMethodExit) + bool isMethodExit, + vector* valuesStoredInMethod) { // Get an iterator to point to the insertion location // BasicBlock::InstListType& instList = bb->getInstList(); - TerminatorInst* termInst = bb->getTerminator(); BasicBlock::iterator here = instList.end()-1; assert((*here)->isTerminator()); // Insert a print instruction for each value. // for (unsigned i=0, N=valueVec.size(); i < N; i++) - InsertPrintInsts(valueVec[i], here, module, indent, isMethodExit); + { + Instruction* I = valueVec[i]; + if (I->getOpcode() == Instruction::Store) + { + assert(valuesStoredInMethod != NULL && + "Should not be printing a store instruction at method exit"); + I = InsertLoadInst((StoreInst*) I, bb, here); + valuesStoredInMethod->push_back(I); + } + InsertPrintInsts(I, bb, here, module, indent, isMethodExit); + } } -static void -InsertCodeToShowMethodEntry(BasicBlock* entryBB) + +static Instruction* +CreateMethodTraceInst( + Method* method, + unsigned int indent, + const string& msg) { + string fmtString(indent, ' '); + strstream methodNameString; + WriteAsOperand(methodNameString, method) << ends; + fmtString += msg + string(" METHOD ") + methodNameString.str(); + free(methodNameString.str()); + + GlobalVariable *fmtVal = GetStringRef(method->getParent(), fmtString); + Instruction *printInst = + new CallInst(GetPrintMethodForType(method->getParent(), fmtVal->getType()), + vector(1, fmtVal)); + + return printInst; } -static void -InsertCodeToShowMethodExit(BasicBlock* exitBB) +static inline void +InsertCodeToShowMethodEntry(Method* method, + BasicBlock* entryBB, + unsigned int indent) { + // Get an iterator to point to the insertion location + BasicBlock::InstListType& instList = entryBB->getInstList(); + BasicBlock::iterator here = instList.begin(); + + Instruction *printInst = CreateMethodTraceInst(method, indent, "ENTERING"); + + here = entryBB->getInstList().insert(here, printInst) + 1; +} + + +static inline void +InsertCodeToShowMethodExit(Method* method, + BasicBlock* exitBB, + unsigned int indent) +{ + // Get an iterator to point to the insertion location + BasicBlock::InstListType& instList = exitBB->getInstList(); + BasicBlock::iterator here = instList.end()-1; + assert((*here)->isTerminator()); + + Instruction *printInst = CreateMethodTraceInst(method, indent, "LEAVING "); + + here = exitBB->getInstList().insert(here, printInst) + 1; } @@ -341,26 +433,23 @@ InsertTraceCode::doInsertTraceCode(Method *M, bool traceBasicBlockExits, bool traceMethodExits) { - vector valuesToTraceInMethod; + vector valuesStoredInMethod; Module* module = M->getParent(); - BasicBlock* exitBB = NULL; vector exitBlocks; - + if (M->isExternal() || (! traceBasicBlockExits && ! traceMethodExits)) return false; if (traceMethodExits) - { - InsertCodeToShowMethodEntry(M->getEntryNode()); - } - + InsertCodeToShowMethodEntry(M, M->getEntryNode(), /*indent*/ 0); + for (Method::iterator BI = M->begin(); BI != M->end(); ++BI) { BasicBlock* bb = *BI; bool isExitBlock = false; + vector valuesToTraceInBB; - vector valuesToTraceInBB; FindValuesToTraceInBB(bb, valuesToTraceInBB); if (bb->succ_begin() == bb->succ_end()) @@ -369,24 +458,20 @@ InsertTraceCode::doInsertTraceCode(Method *M, isExitBlock = true; } - if (traceBasicBlockExits && (!isExitBlock || !traceMethodExits)) + if (traceBasicBlockExits) TraceValuesAtBBExit(valuesToTraceInBB, bb, module, - /*indent*/ 4, /*isMethodExit*/ false); - - if (traceMethodExits) { - valuesToTraceInMethod.insert(valuesToTraceInMethod.end(), - valuesToTraceInBB.begin(), - valuesToTraceInBB.end()); - } + /*indent*/ 4, /*isMethodExit*/ false, + &valuesStoredInMethod); } - + if (traceMethodExits) for (unsigned i=0; i < exitBlocks.size(); ++i) { - TraceValuesAtBBExit(valuesToTraceInMethod, exitBlocks[i], module, - /*indent*/ 0, /*isMethodExit*/ true); - InsertCodeToShowMethodExit(exitBB); + TraceValuesAtBBExit(valuesStoredInMethod, exitBlocks[i], module, + /*indent*/ 0, /*isMethodExit*/ true, + /*valuesStoredInMethod*/ NULL); + InsertCodeToShowMethodExit(M, exitBlocks[i], /*indent*/ 0); } - + return true; } -- 2.34.1