From: Chris Lattner Date: Tue, 23 Jul 2002 18:04:15 +0000 (+0000) Subject: * Cleanup the pass a bit more, making it more object oriented. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=11982667780c40f0640408e78da1ba06a35c183e;p=oota-llvm.git * Cleanup the pass a bit more, making it more object oriented. * Split the two behaviors of the InsertTraceCode class into two subclasses * Register Passes git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@3014 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Transforms/Instrumentation/TraceValues.cpp b/lib/Transforms/Instrumentation/TraceValues.cpp index 3e0cb4b7f48..52c7c0aa649 100644 --- a/lib/Transforms/Instrumentation/TraceValues.cpp +++ b/lib/Transforms/Instrumentation/TraceValues.cpp @@ -30,17 +30,20 @@ static cl::list TraceFuncName("tracefunc", cl::desc("trace only specific functions"), cl::value_desc("function"), cl::Hidden); +static void TraceValuesAtBBExit(BasicBlock *BB, + Function *Printf, Function* HashPtrToSeqNum, + vector *valuesStoredInFunction); // We trace a particular function if no functions to trace were specified // or if the function is in the specified list. // -inline bool -TraceThisFunction(Function* func) +inline static bool +TraceThisFunction(Function &func) { if (TraceFuncName.size() == 0) return true; - return std::find(TraceFuncName.begin(), TraceFuncName.end(), func->getName()) + return std::find(TraceFuncName.begin(), TraceFuncName.end(), func.getName()) != TraceFuncName.end(); } @@ -53,14 +56,9 @@ namespace { }; class InsertTraceCode : public FunctionPass { - bool TraceBasicBlockExits, TraceFunctionExits; + protected: ExternalFuncs externalFuncs; public: - InsertTraceCode(bool traceBasicBlockExits, bool traceFunctionExits) - : TraceBasicBlockExits(traceBasicBlockExits), - TraceFunctionExits(traceFunctionExits) {} - - const char *getPassName() const { return "Trace Code Insertion"; } // Add a prototype for runtime functions not already in the program. // @@ -72,30 +70,47 @@ namespace { // Inserts tracing code for all live values at basic block and/or function // exits as specified by `traceBasicBlockExits' and `traceFunctionExits'. // - static bool doit(Function *M, bool traceBasicBlockExits, - bool traceFunctionExits, ExternalFuncs& externalFuncs); + bool doit(Function *M); + + virtual void handleBasicBlock(BasicBlock *BB, vector &VI) = 0; // runOnFunction - This method does the work. // - bool runOnFunction(Function &F) { - return doit(&F, TraceBasicBlockExits, TraceFunctionExits, externalFuncs); - } + bool runOnFunction(Function &F); virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.preservesCFG(); } }; + + struct FunctionTracer : public InsertTraceCode { + // Ignore basic blocks here... + virtual void handleBasicBlock(BasicBlock *BB, vector &VI) {} + }; + + struct BasicBlockTracer : public InsertTraceCode { + // Trace basic blocks here... + virtual void handleBasicBlock(BasicBlock *BB, vector &VI) { + TraceValuesAtBBExit(BB, externalFuncs.PrintfFunc, + externalFuncs.HashPtrFunc, &VI); + } + }; + + // Register the passes... + RegisterPass X("tracem","Insert Function trace code only"); + RegisterPass Y("trace","Insert BB and Function trace code"); } // end anonymous namespace Pass *createTraceValuesPassForFunction() { // Just trace functions - return new InsertTraceCode(false, true); + return new FunctionTracer(); } Pass *createTraceValuesPassForBasicBlocks() { // Trace BB's and functions - return new InsertTraceCode(true, true); + return new BasicBlockTracer(); } + // Add a prototype for external functions used by the tracing code. // void ExternalFuncs::doInitialization(Module &M) { @@ -336,30 +351,6 @@ static void TraceValuesAtBBExit(BasicBlock *BB, BasicBlock::iterator InsertPos = --BB->end(); assert(InsertPos->isTerminator()); -#undef CANNOT_SAVE_CCR_ACROSS_CALLS -#ifdef CANNOT_SAVE_CCR_ACROSS_CALLS - // - // *** DISABLING THIS BECAUSE SAVING %CCR ACROSS CALLS WORKS NOW. - // *** DELETE THIS CODE AFTER SOME TESTING. - // *** NOTE: THIS CODE IS BROKEN ANYWAY WHEN THE SETCC IS NOT JUST - // *** BEFORE THE BRANCH. - // -- Vikram Adve, 7/7/02. - // - // If the terminator is a conditional branch, insert the trace code just - // before the instruction that computes the branch condition (just to - // avoid putting a call between the CC-setting instruction and the branch). - // Use laterInstrSet to mark instructions that come after the setCC instr - // because those cannot be traced at the location we choose. - // - Instruction *SetCC = 0; - if (BranchInst *Branch = dyn_cast(BB->getTerminator())) - if (!Branch->isUnconditional()) - if (Instruction *I = dyn_cast(Branch->getCondition())) - if (I->getParent() == BB) { - InsertPos = SetCC = I; // Back up until we can insert before the setcc - } -#endif CANNOT_SAVE_CCR_ACROSS_CALLS - std::ostringstream OutStr; WriteAsOperand(OutStr, BB, false); InsertPrintInst(0, BB, InsertPos, "LEAVING BB:" + OutStr.str(), @@ -387,20 +378,20 @@ static void TraceValuesAtBBExit(BasicBlock *BB, } } -static inline void InsertCodeToShowFunctionEntry(Function *M, Function *Printf, +static inline void InsertCodeToShowFunctionEntry(Function &F, Function *Printf, Function* HashPtrToSeqNum){ // Get an iterator to point to the insertion location - BasicBlock &BB = M->getEntryNode(); + BasicBlock &BB = F.getEntryNode(); BasicBlock::iterator BBI = BB.begin(); std::ostringstream OutStr; - WriteAsOperand(OutStr, M, true); + WriteAsOperand(OutStr, &F, true); InsertPrintInst(0, &BB, BBI, "ENTERING FUNCTION: " + OutStr.str(), Printf, HashPtrToSeqNum); // Now print all the incoming arguments unsigned ArgNo = 0; - for (Function::aiterator I = M->abegin(), E = M->aend(); I != E; ++I,++ArgNo){ + for (Function::aiterator I = F.abegin(), E = F.aend(); I != E; ++I, ++ArgNo){ InsertVerbosePrintInst(I, &BB, BBI, " Arg #" + utostr(ArgNo) + ": ", Printf, HashPtrToSeqNum); @@ -427,45 +418,37 @@ static inline void InsertCodeToShowFunctionExit(BasicBlock *BB, } -bool InsertTraceCode::doit(Function *M, bool traceBasicBlockExits, - bool traceFunctionEvents, - ExternalFuncs& externalFuncs) { - if (!traceBasicBlockExits && !traceFunctionEvents) - return false; - - if (!TraceThisFunction(M)) +bool InsertTraceCode::runOnFunction(Function &F) { + if (!TraceThisFunction(F)) return false; vector valuesStoredInFunction; vector exitBlocks; // Insert code to trace values at function entry - if (traceFunctionEvents) - InsertCodeToShowFunctionEntry(M, externalFuncs.PrintfFunc, - externalFuncs.HashPtrFunc); + InsertCodeToShowFunctionEntry(F, externalFuncs.PrintfFunc, + externalFuncs.HashPtrFunc); // Push a pointer set for recording alloca'd pointers at entry. if (!DisablePtrHashing) - InsertPushOnEntryFunc(M, externalFuncs.PushOnEntryFunc); + InsertPushOnEntryFunc(&F, externalFuncs.PushOnEntryFunc); - for (Function::iterator BB = M->begin(); BB != M->end(); ++BB) { + for (Function::iterator BB = F.begin(); BB != F.end(); ++BB) { if (isa(BB->getTerminator())) exitBlocks.push_back(BB); // record this as an exit block - - if (traceBasicBlockExits) - TraceValuesAtBBExit(BB, externalFuncs.PrintfFunc, - externalFuncs.HashPtrFunc, &valuesStoredInFunction); - + + // Insert trace code if this basic block is interesting... + handleBasicBlock(BB, valuesStoredInFunction); + if (!DisablePtrHashing) // release seq. numbers on free/ret ReleasePtrSeqNumbers(BB, externalFuncs); } - for (unsigned i=0; i < exitBlocks.size(); ++i) + for (unsigned i=0; i != exitBlocks.size(); ++i) { // Insert code to trace values at function exit - if (traceFunctionEvents) - InsertCodeToShowFunctionExit(exitBlocks[i], externalFuncs.PrintfFunc, - externalFuncs.HashPtrFunc); + InsertCodeToShowFunctionExit(exitBlocks[i], externalFuncs.PrintfFunc, + externalFuncs.HashPtrFunc); // Release all recorded pointers before RETURN. Do this LAST! if (!DisablePtrHashing)