示例#1
0
/// 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;
}