mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-04-08 09:43:20 +00:00
* 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
This commit is contained in:
parent
e9754ef595
commit
1198266778
@ -30,17 +30,20 @@ static cl::list<string>
|
||||
TraceFuncName("tracefunc", cl::desc("trace only specific functions"),
|
||||
cl::value_desc("function"), cl::Hidden);
|
||||
|
||||
static void TraceValuesAtBBExit(BasicBlock *BB,
|
||||
Function *Printf, Function* HashPtrToSeqNum,
|
||||
vector<Instruction*> *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<Instruction*> &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<Instruction*> &VI) {}
|
||||
};
|
||||
|
||||
struct BasicBlockTracer : public InsertTraceCode {
|
||||
// Trace basic blocks here...
|
||||
virtual void handleBasicBlock(BasicBlock *BB, vector<Instruction*> &VI) {
|
||||
TraceValuesAtBBExit(BB, externalFuncs.PrintfFunc,
|
||||
externalFuncs.HashPtrFunc, &VI);
|
||||
}
|
||||
};
|
||||
|
||||
// Register the passes...
|
||||
RegisterPass<FunctionTracer> X("tracem","Insert Function trace code only");
|
||||
RegisterPass<BasicBlockTracer> 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<BranchInst>(BB->getTerminator()))
|
||||
if (!Branch->isUnconditional())
|
||||
if (Instruction *I = dyn_cast<Instruction>(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<Instruction*> valuesStoredInFunction;
|
||||
vector<BasicBlock*> 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<ReturnInst>(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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user