/// findFunctionScopedAllocas - store all allocas that are known to be valid /// to the end of their function in a set. The current algorithm does this by /// finding all the allocas in the entry block that are before the first /// llvm.stacksave call (if any). /// /// FIXME: There can also be allocas elsewhere that get deallocated at the end /// of the function but they are pessimistically ignored for now. /// void ExactCheckOpt::findFunctionScopedAllocas(Module &M) { for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) { if (F->empty()) continue; BasicBlock &BB = F->getEntryBlock(); for (BasicBlock::iterator I = BB.begin(), E = BB.end(); I != E; ++I) { if (AllocaInst *AI = dyn_cast<AllocaInst>(I)) { FunctionScopedAllocas.insert(AI); } else if(CallInst *CI = dyn_cast<CallInst>(I)) { Function *CalledFunction = CI->getCalledFunction(); if (CalledFunction && CalledFunction->getName() == "llvm.stacksave") break; } } } }
bool TraceBasicBlocks::runOnModule(Module &M) { Context =&M.getContext(); Function *Main = M.getFunction("main"); if (Main == 0) { errs() << "WARNING: cannot insert basic-block trace instrumentation" << " into a module with no main function!\n"; return false; // No main, no instrumentation! } const char* FnName="llvm_trace_basic_block"; Constant *InstrFn = M.getOrInsertFunction (FnName, Type::getVoidTy(*Context), Type::getInt64Ty(*Context), NULL); unsigned BBNumber = 0; for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) { if(F->empty()) { continue; } //We insert instrumentation calls in reverse order, because insertion puts them before previous instructions for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { dbgs() << "InsertInstrumentationCall (\"" << BB->getName () << "\", \"" << F->getName() << "\", " << BBNumber << ")\n"; //On Exit we emit the FunRet block TerminatorInst* TI=BB->getTerminator(); if(TI->getNumSuccessors()==0) { InsertRetInstrumentationCall(TI,InstrFn); } InsertInstrumentationCall (BB, InstrFn, BBNumber); if(TraceMemory) { InsertMemoryTracingCall (BB,InstrFn); } ++BBNumber; } //on Entry we emit the FunCall block. BasicBlock* EntryBlock=&F->getEntryBlock(); InsertInstrumentationCall (EntryBlock, InstrFn, BBTraceStream::FunCallID); } // Add the initialization call to main. InsertProfilingInitCall(Main, "llvm_start_basic_block_tracing"); return true; }