示例#1
0
bool PrintCgTree::runOnModule(Module &M)
{
#if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR == 4
   CallGraph CG;
   CG.runOnModule(M);
   CallGraphNode* root = CG.getRoot();
#else
   CallGraph CG(M);
   Function* Main = M.getFunction("main");
   CallGraphNode* root = Main?CG[Main]:CG.getExternalCallingNode();
   
#endif
   Assert(root->getFunction()==Main, "");
   errs()<<root->getFunction()->getName()<<"\n";
   print_cg(root);
   return false;
}
示例#2
0
/// removeDeadFunctions - Remove dead functions that are not included in
/// DNR (Do Not Remove) list.
bool Inliner::removeDeadFunctions(CallGraph &CG, bool AlwaysInlineOnly) {
  SmallVector<CallGraphNode*, 16> FunctionsToRemove;

  // Scan for all of the functions, looking for ones that should now be removed
  // from the program.  Insert the dead ones in the FunctionsToRemove set.
  for (CallGraph::iterator I = CG.begin(), E = CG.end(); I != E; ++I) {
    CallGraphNode *CGN = I->second;
    Function *F = CGN->getFunction();
    if (!F || F->isDeclaration())
      continue;

    // Handle the case when this function is called and we only want to care
    // about always-inline functions. This is a bit of a hack to share code
    // between here and the InlineAlways pass.
    if (AlwaysInlineOnly &&
        !F->getFnAttributes().hasAttribute(Attributes::AlwaysInline))
      continue;

    // If the only remaining users of the function are dead constants, remove
    // them.
    F->removeDeadConstantUsers();

    if (!F->isDefTriviallyDead())
      continue;
    
    // Remove any call graph edges from the function to its callees.
    CGN->removeAllCalledFunctions();

    // Remove any edges from the external node to the function's call graph
    // node.  These edges might have been made irrelegant due to
    // optimization of the program.
    CG.getExternalCallingNode()->removeAnyCallEdgeTo(CGN);

    // Removing the node for callee from the call graph and delete it.
    FunctionsToRemove.push_back(CGN);
  }
  if (FunctionsToRemove.empty())
    return false;

  // Now that we know which functions to delete, do so.  We didn't want to do
  // this inline, because that would invalidate our CallGraph::iterator
  // objects. :(
  //
  // Note that it doesn't matter that we are iterating over a non-stable order
  // here to do this, it doesn't matter which order the functions are deleted
  // in.
  array_pod_sort(FunctionsToRemove.begin(), FunctionsToRemove.end());
  FunctionsToRemove.erase(std::unique(FunctionsToRemove.begin(),
                                      FunctionsToRemove.end()),
                          FunctionsToRemove.end());
  for (SmallVectorImpl<CallGraphNode *>::iterator I = FunctionsToRemove.begin(),
                                                  E = FunctionsToRemove.end();
       I != E; ++I) {
    delete CG.removeFunctionFromModule(*I);
    ++NumDeleted;
  }
  return true;
}
示例#3
0
文件: Laser.cpp 项目: xuzb/laser
bool AnalysisEngine::runOnSCC(CallGraphSCC &scc) {
  for (CallGraphSCC::iterator i = scc.begin(),
                              e = scc.end(); i != e; ++i) {
    CallGraphNode *cgnode = *i;
    Function *f = cgnode->getFunction();
    FunctionSimulator fsimulator(f);
    fsimulator.simulate();
  }
}
示例#4
0
文件: Inliner.cpp 项目: aosm/clang
  /// removeDeadFunctions - Remove dead functions that are not included in
  /// DNR (Do Not Remove) list.
bool Inliner::removeDeadFunctions(CallGraph &CG, 
                                 SmallPtrSet<const Function *, 16> *DNR) {
  std::set<CallGraphNode*> FunctionsToRemove;

  // Scan for all of the functions, looking for ones that should now be removed
  // from the program.  Insert the dead ones in the FunctionsToRemove set.
  for (CallGraph::iterator I = CG.begin(), E = CG.end(); I != E; ++I) {
    CallGraphNode *CGN = I->second;
    if (Function *F = CGN ? CGN->getFunction() : 0) {
      // If the only remaining users of the function are dead constants, remove
      // them.
      F->removeDeadConstantUsers();

      if (DNR && DNR->count(F))
        continue;

      if ((F->hasLinkOnceLinkage() || F->hasLocalLinkage()) &&
          F->use_empty()) {

        // Remove any call graph edges from the function to its callees.
        CGN->removeAllCalledFunctions();

        // Remove any edges from the external node to the function's call graph
        // node.  These edges might have been made irrelegant due to
        // optimization of the program.
        CG.getExternalCallingNode()->removeAnyCallEdgeTo(CGN);

        // Removing the node for callee from the call graph and delete it.
        FunctionsToRemove.insert(CGN);
      }
    }
  }

  // Now that we know which functions to delete, do so.  We didn't want to do
  // this inline, because that would invalidate our CallGraph::iterator
  // objects. :(
  bool Changed = false;
  for (std::set<CallGraphNode*>::iterator I = FunctionsToRemove.begin(),
         E = FunctionsToRemove.end(); I != E; ++I) {
    resetCachedCostInfo((*I)->getFunction());
    delete CG.removeFunctionFromModule(*I);
    ++NumDeleted;
    Changed = true;
  }

  return Changed;
}
示例#5
0
void CallGraph::verify() const {
#ifndef NDEBUG
  // For every function in the module, add it to our SILFunction set.
  llvm::DenseSet<SILFunction *> Functions;
  for (auto &F : M)
    Functions.insert(&F);

  // For every pair (SILFunction, CallGraphNode) in the
  // function-to-node map, verify:
  //
  //    a. The function is in the current module.
  //    b. The call graph node is for that same function.
  //
  // In addition, call the verify method for the function.
  unsigned numEdges = 0;
  for (auto &P : FunctionToNodeMap) {
    SILFunction *F = P.first;
    CallGraphNode *Node = P.second;
    assert(Functions.count(F) &&
           "Function in call graph but not in module!?");
    assert(Node->getFunction() == F &&
           "Func mapped to node, but node has different Function inside?!");
    verify(F);
    numEdges += Node->getCalleeEdges().size();
  }

  assert(InstToEdgeMap.size() == numEdges &&
         "Some edges in InstToEdgeMap are not contained in any node");

  // Verify the callee sets.
  for (auto Iter : CalleeSetCache) {
    auto *CalleeSet = Iter.second.getPointer();
    for (CallGraphNode *Node : *CalleeSet) {
      SILFunction *F = Node->getFunction();
      assert(tryGetCallGraphNode(F) &&
             "Callee set contains dangling node poiners");
    }
  }
#endif
}
bool CallGraphCFG::findBBPath(CallGraphNode *n, std::vector<BasicBlock*> &path, std::string srcFile, int srcLine)
{
    if (n == NULL) return false;

    Function *F = n->getFunction();

    std::cerr << "Processing " << F->getNameStr() << "\n";

    // Are we on a leaf?
    if (n->size() == 0) {
        BasicBlock *bb=NULL;
        if (findLineInFunction(F,&bb,srcFile,srcLine)) {
            path.push_back(bb);
            return true;
        }
    }

    for (CallGraphNode::iterator it = n->begin(); it != n->end(); ++it) {
        CallSite cs = it->first;
        CallGraphNode *tCGN = it->second;
        Instruction *tI = cs.getInstruction();
        if (tI == NULL) return false;
        BasicBlock *bb = tI->getParent();
        Function *tF = tCGN->getFunction();

        path.push_back(bb);
        if (findLineInBB(bb,srcFile,srcLine))
            return true;

        if (tF != F) {    // Dont get stuck in recursion
            if (findBBPath(tCGN,path,srcFile,srcLine))
                return true;
        }

        std::cerr << " Dead end, reverting...\n";  // FIX: This is misleading, not really correct.
        path.pop_back();
    }
    return false;
}
示例#7
0
文件: Inliner.cpp 项目: 8l/SPIRV-LLVM
/// Remove dead functions that are not included in DNR (Do Not Remove) list.
bool Inliner::removeDeadFunctions(CallGraph &CG, bool AlwaysInlineOnly) {
  SmallVector<CallGraphNode*, 16> FunctionsToRemove;
  SmallVector<CallGraphNode *, 16> DeadFunctionsInComdats;
  SmallDenseMap<const Comdat *, int, 16> ComdatEntriesAlive;

  auto RemoveCGN = [&](CallGraphNode *CGN) {
    // Remove any call graph edges from the function to its callees.
    CGN->removeAllCalledFunctions();

    // Remove any edges from the external node to the function's call graph
    // node.  These edges might have been made irrelegant due to
    // optimization of the program.
    CG.getExternalCallingNode()->removeAnyCallEdgeTo(CGN);

    // Removing the node for callee from the call graph and delete it.
    FunctionsToRemove.push_back(CGN);
  };

  // Scan for all of the functions, looking for ones that should now be removed
  // from the program.  Insert the dead ones in the FunctionsToRemove set.
  for (CallGraph::iterator I = CG.begin(), E = CG.end(); I != E; ++I) {
    CallGraphNode *CGN = I->second;
    Function *F = CGN->getFunction();
    if (!F || F->isDeclaration())
      continue;

    // Handle the case when this function is called and we only want to care
    // about always-inline functions. This is a bit of a hack to share code
    // between here and the InlineAlways pass.
    if (AlwaysInlineOnly && !F->hasFnAttribute(Attribute::AlwaysInline))
      continue;

    // If the only remaining users of the function are dead constants, remove
    // them.
    F->removeDeadConstantUsers();

    if (!F->isDefTriviallyDead())
      continue;

    // It is unsafe to drop a function with discardable linkage from a COMDAT
    // without also dropping the other members of the COMDAT.
    // The inliner doesn't visit non-function entities which are in COMDAT
    // groups so it is unsafe to do so *unless* the linkage is local.
    if (!F->hasLocalLinkage()) {
      if (const Comdat *C = F->getComdat()) {
        --ComdatEntriesAlive[C];
        DeadFunctionsInComdats.push_back(CGN);
        continue;
      }
    }

    RemoveCGN(CGN);
  }
  if (!DeadFunctionsInComdats.empty()) {
    // Count up all the entities in COMDAT groups
    auto ComdatGroupReferenced = [&](const Comdat *C) {
      auto I = ComdatEntriesAlive.find(C);
      if (I != ComdatEntriesAlive.end())
        ++(I->getSecond());
    };
    for (const Function &F : CG.getModule())
      if (const Comdat *C = F.getComdat())
        ComdatGroupReferenced(C);
    for (const GlobalVariable &GV : CG.getModule().globals())
      if (const Comdat *C = GV.getComdat())
        ComdatGroupReferenced(C);
    for (const GlobalAlias &GA : CG.getModule().aliases())
      if (const Comdat *C = GA.getComdat())
        ComdatGroupReferenced(C);
    for (CallGraphNode *CGN : DeadFunctionsInComdats) {
      Function *F = CGN->getFunction();
      const Comdat *C = F->getComdat();
      int NumAlive = ComdatEntriesAlive[C];
      // We can remove functions in a COMDAT group if the entire group is dead.
      assert(NumAlive >= 0);
      if (NumAlive > 0)
        continue;

      RemoveCGN(CGN);
    }
  }

  if (FunctionsToRemove.empty())
    return false;

  // Now that we know which functions to delete, do so.  We didn't want to do
  // this inline, because that would invalidate our CallGraph::iterator
  // objects. :(
  //
  // Note that it doesn't matter that we are iterating over a non-stable order
  // here to do this, it doesn't matter which order the functions are deleted
  // in.
  array_pod_sort(FunctionsToRemove.begin(), FunctionsToRemove.end());
  FunctionsToRemove.erase(std::unique(FunctionsToRemove.begin(),
                                      FunctionsToRemove.end()),
                          FunctionsToRemove.end());
  for (SmallVectorImpl<CallGraphNode *>::iterator I = FunctionsToRemove.begin(),
                                                  E = FunctionsToRemove.end();
       I != E; ++I) {
    delete CG.removeFunctionFromModule(*I);
    ++NumDeleted;
  }
  return true;
}
示例#8
0
bool Strator::runOnModule(Module &m) {
	errs() << "Strator started!\n";
	/// Get previous analysis results
	// multithreadedFunctionMap = &(getAnalysis<MultithreadFinder>().multithreadedFunctionMap);
//	if(UseLocalValueInfo)
//		localValueInfo = &(getAnalysis<LocalIdentifier>().localValueInfo);
	if(UseAliasAnalysis || DebugAliasAnalysis)
		aa = &getAnalysis<AliasAnalysis>();
		//aa = getAnalysis<LocalIdentifier>().aa;
	//useDefMap = &(getAnalysis<UseDefBuilder>().useDefMap);
	CallGraph& callGraph = getAnalysis<CallGraph>();

	GEPFactory = new GEPValueFactory(&m);

	if(PrintPrevPasses){
		printLocalModificationInfo();
	}

	CallGraphNode* externalNode = callGraph.getExternalCallingNode();

	if (DirectedRaceDetection){
		/// This is the first and default race detection strategy
		/// that only tracks a main function (like the
		/// unit test case). We call this directed race detection
		/// There is no thread pool in this case but a single worker
		threadPoolSize = 0;

		/// We use this simply to mark all the external entry point functions as initially not analyzed
		CallGraphNode::iterator it;
		for(it = externalNode->begin(); it != externalNode->end(); ++it){
			Function* f = 0;
			if((f = it->second->getFunction()))
				if(f->size() > 0){
					functionMap[f->getName().str()] = false;
					++functionCount;
				}
		}

		// cerr << "Total entry point count: " << functionCount << endl;

		CallGraphNode* root = callGraph.getRoot();
		assert(root->size() && "Size of the call graph root is 0! Something is wrong");
		cerr << "Root calls: " << root->size() << " functions"<< endl;

		if(!root->getFunction()){
			cerr << "The root represents an external node" << endl;
			assert(false && "You need to switch to global race detection!");
		}
		// cerr << root->getFunction()->getName().str() << endl;
		/// Initialize all functions to not-multithreaded
		workers.push_back(new StratorWorker(this));
		for(it = root->begin(); it != root->end(); ++it){
			Function* f = 0;
			if((f = it->second->getFunction())){
				if(f->size() > 0){
					workers[0]->multithreadedFunctionMap[it->second->getFunction()->getName().str()] = false;
				}
			}
		}
		Strator::StratorWorker::LockSet* lockSet = new Strator::StratorWorker::LockSet();
		workers[0]->traverseFunction(*(root->getFunction()), *lockSet);
	} else {
		/// This is the second variant of race detection. Here all the external
		/// functions with definitions are considered as root and race detection
		/// is performed over all their childeren. this variant is called global
		/// race detection
		pthread_t tids[50];
		threadPoolSize = 50;

		if(externalNode){
			/// TODO: We should investigate the following: Some static functions (thus
			/// having internal linkage) are considered as external nodes as they are
			/// used as parameters to some functions (like pthread_create). We should
			/// understand if it is necessary to add such functions as external nodes.
			CallGraphNode::iterator it;
			for(it = externalNode->begin(); it != externalNode->end(); ++it){
				Function* f = 0;
				if((f = it->second->getFunction()))
					if(f->size() > 0){
						cerr << "adding function \"" << it->second->getFunction()->getName().str() << "\" to task list" << endl;
						tasks.push_back(f);
						++functionCount;
					}
			}
			/// Create the thread pool
			threadPoolSize = (threadPoolSize < functionCount) ? threadPoolSize : functionCount;
			/// Create as many workers as the pool size
			// threadPoolSize = 1;
			cerr << "Thread pool size:" << threadPoolSize << endl;
			for(unsigned i=0; i<threadPoolSize; ++i)
				workers.push_back(new StratorWorker(this));
			/// trigger the
			for(unsigned i=0; i<threadPoolSize; ++i){
				int retVal = pthread_create(&tids[i], 0, stratorWorkerHelper, workers[i]);
				assert(retVal == 0 && "Problem with creating the threads");
			}

			/// Synchronize the threads
			for(unsigned i=0; i<threadPoolSize; ++i){
				int retVal = pthread_join(tids[i], 0);
				assert(retVal == 0 && "Problem with joining the threads");
			}
		}
	}

	if(ReportUnprocessed){
		/// list all the unprocessed entry point functions
		cerr << "Following entry point functions were not processed: " << endl;
		FunctionMap::iterator fMIt;
		for(fMIt = functionMap.begin(); fMIt != functionMap.end(); ++fMIt){
			if(!fMIt->second)
				cerr << fMIt->first << endl;
		}
	}

	/// We have gathered race detection data, now report
	reportRaces();
	/// We did not modify the module, return false
	return false;
}
示例#9
0
/// Remove dead functions that are not included in DNR (Do Not Remove) list.
bool LegacyInlinerBase::removeDeadFunctions(CallGraph &CG,
                                            bool AlwaysInlineOnly) {
  SmallVector<CallGraphNode *, 16> FunctionsToRemove;
  SmallVector<Function *, 16> DeadFunctionsInComdats;

  auto RemoveCGN = [&](CallGraphNode *CGN) {
    // Remove any call graph edges from the function to its callees.
    CGN->removeAllCalledFunctions();

    // Remove any edges from the external node to the function's call graph
    // node.  These edges might have been made irrelegant due to
    // optimization of the program.
    CG.getExternalCallingNode()->removeAnyCallEdgeTo(CGN);

    // Removing the node for callee from the call graph and delete it.
    FunctionsToRemove.push_back(CGN);
  };

  // Scan for all of the functions, looking for ones that should now be removed
  // from the program.  Insert the dead ones in the FunctionsToRemove set.
  for (const auto &I : CG) {
    CallGraphNode *CGN = I.second.get();
    Function *F = CGN->getFunction();
    if (!F || F->isDeclaration())
      continue;

    // Handle the case when this function is called and we only want to care
    // about always-inline functions. This is a bit of a hack to share code
    // between here and the InlineAlways pass.
    if (AlwaysInlineOnly && !F->hasFnAttribute(Attribute::AlwaysInline))
      continue;

    // If the only remaining users of the function are dead constants, remove
    // them.
    F->removeDeadConstantUsers();

    if (!F->isDefTriviallyDead())
      continue;

    // It is unsafe to drop a function with discardable linkage from a COMDAT
    // without also dropping the other members of the COMDAT.
    // The inliner doesn't visit non-function entities which are in COMDAT
    // groups so it is unsafe to do so *unless* the linkage is local.
    if (!F->hasLocalLinkage()) {
      if (F->hasComdat()) {
        DeadFunctionsInComdats.push_back(F);
        continue;
      }
    }

    RemoveCGN(CGN);
  }
  if (!DeadFunctionsInComdats.empty()) {
    // Filter out the functions whose comdats remain alive.
    filterDeadComdatFunctions(CG.getModule(), DeadFunctionsInComdats);
    // Remove the rest.
    for (Function *F : DeadFunctionsInComdats)
      RemoveCGN(CG[F]);
  }

  if (FunctionsToRemove.empty())
    return false;

  // Now that we know which functions to delete, do so.  We didn't want to do
  // this inline, because that would invalidate our CallGraph::iterator
  // objects. :(
  //
  // Note that it doesn't matter that we are iterating over a non-stable order
  // here to do this, it doesn't matter which order the functions are deleted
  // in.
  array_pod_sort(FunctionsToRemove.begin(), FunctionsToRemove.end());
  FunctionsToRemove.erase(
      std::unique(FunctionsToRemove.begin(), FunctionsToRemove.end()),
      FunctionsToRemove.end());
  for (CallGraphNode *CGN : FunctionsToRemove) {
    delete CG.removeFunctionFromModule(CGN);
    ++NumDeleted;
  }
  return true;
}
示例#10
0
bool InlineModule::runOnModule( Module & M ) {
  
  std::vector<std::string> leafNames;
  //File *file = fopen("inline_info.txt", "r");
  //if (!file) {
  //  errs() << "Error: Could not open inline_info file.\n";
  //  retrun true;
  //}
  std::string line;
  std::ifstream file ("inline_info.txt");
  if(file.is_open()) {
    while(std::getline(file, line))
      leafNames.push_back(line);
    file.close();
  }
  else
    errs() << "Error: Could not open inline_info file.\n";

  //makeLeaf.push_back(M.getFunction("ORACLE_0"));
  //makeLeaf.push_back(M.getFunction("ORACLE_1"));
  //makeLeaf.push_back(M.getFunction("ORACLE_2"));
  //makeLeaf.push_back(M.getFunction("ORACLE_3"));

  for (std::vector<std::string>::iterator i = leafNames.begin(), e = leafNames.end();
      i!=e; ++i) {
    if (debugInlining)
      errs() << "inline_info: " << *i << "\n";
    makeLeaf.push_back(M.getFunction(*i));
  }
  

  // First, get a pointer to previous analysis results
  CallGraph & CG = getAnalysis<CallGraph>();

  CallGraphNode * entry = CG.getRoot();
  if( entry && entry->getFunction() && debugInlining)
    errs() << "Entry is function: " << entry->getFunction()->getName() << "\n";

  // Iterate over all SCCs in the module in bottom-up order
  for( scc_iterator<CallGraph*>
   si=scc_begin( &CG ), se=scc_end( &CG ); si != se; ++si ) {
    runOnSCC( *si );
  }

  //reverse the vector for preorder
  std::reverse(vectPostOrder.begin(),vectPostOrder.end());

  for(std::vector<Function*>::iterator vit = vectPostOrder.begin(), vitE = vectPostOrder.end();
      vit!=vitE; ++vit) { 
    Function *f = *vit;      
    runOnFunction(*f);    
  }

  
  // now we have all the call sites which need to be inlined
  // inline from the leaves all the way up
  const TargetData *TD = getAnalysisIfAvailable<TargetData>();
  InlineFunctionInfo InlineInfo(&CG, TD);  

  std::reverse(inlineCallInsts.begin(),inlineCallInsts.end());
  for (std::vector<CallInst*>::iterator i = inlineCallInsts.begin(), e = inlineCallInsts.end();
      i!=e; ++i) {
    CallInst* CI = *i;
    bool success = InlineFunction(CI, InlineInfo, false);
    if(!success) {
      if (debugInlining)
        errs() << "Error: Could not inline callee function " << CI->getCalledFunction()->getName()
                 << " into caller function " << "\n";
      continue;
    }
    if (debugInlining)    
      errs() << "Successfully inlined callee function " << CI->getCalledFunction()->getName()
                 << "into caller function " << "\n";
  }  
  
  return false;
}
示例#11
0
bool PathList::runOnModule(Module &M) {
	module = &M;
	
	llvm::dbgs() << "[runOnModule]: Moduel M has " << M.getFunctionList().size() << " Functions in all.\n";
	
	// for test
	Function *f1 = M.getFunction("fprintf");
	if (!f1)
		dbgs() << "[Test]: can not find function fprintf.\n";
	else
		dbgs() << "[Test]: find function fprintf.\n";
	  
	CallGraph &CG = getAnalysis<CallGraph>();
//	CG.dump();
	
	CallGraphNode *cgNode = CG.getRoot();
	cgNode->dump();
//	errs()<<node->getFunction()->getName()<<'\n';
	
	Function *startFunc;
	Function *endFunc;
	startFunc = M.getFunction("__user_main");
	
	//std::string fileName("/home/xqx/data/xqx/projects/benckmarks-klee/texinfo-4.8/build-shit/makeinfo/../../makeinfo/insertion.c");
	//int lineNo = 407;
	
	BB = getBB(fileName, lineNo);
	*targetBbpp = getBB(fileName, lineNo);
	if (BB) {
		endFunc = BB->getParent();
		if (!endFunc) {
			errs()<<"Error: get endFunc failed.\n";
			return false;
		}
		if (!startFunc) {
		  	errs()<<"Error: get startFunc failed.\n";
			return false;
		}
		errs()<<startFunc->getName()<<'\n';
	}
	else {
		errs()<<"Error: get BB failed.\n";
		return false;
	}
	
	
	
	//read start and end from xml files
//	defectList enStart, enEnd;
//	getEntryList("/tmp/entrys.xml", &enStart, "start");
//	getEntryList("/tmp/entrys.xml", &enEnd, "end");
//	getEntryList("/tmp/entrys.xml", &dl, "end");
//	dumpEntryList(&enStart);
//	dumpEntryList(&enEnd);
//	dumpEntryList(&dl);
	
	//read bug information from xml file
/*	for (defectList::iterator dit = dl.begin(); dit != dl.end(); dit++) {
		StringRef file(dit->first.c_str());
		std::vector<int> lines = dit->second;
		BasicBlock *BB = getBB(file, *(lines.begin()));
		if (BB) {
			endFunc = BB->getParent();
		}
	}
*/	
	//to store temporary path
	std::vector<BasicBlock*> p;
	// a counter
	int map_count = 0;
	
	for (Module::iterator i = M.begin(), e = M.end(); i != e; ++i) {
		Function *F = i;
		if (!F) {
			llvm::errs() << "***NULL Function***\n";
			continue;
		}
		cgNode = CG.getOrInsertFunction(F);
		F = cgNode->getFunction();
//		
		for (CallGraphNode::iterator I = cgNode->begin(), E = cgNode->end();
				I != E; ++I){
			CallGraphNode::CallRecord *cr = &*I;
//			llvm::errs() << "\tCS<" << cr->first << "> calls";
			// check if the CallInst is existed
			if(cr->first){
				Instruction *TmpIns = dyn_cast<Instruction>(cr->first);
				if(TmpIns) {
//					errs() << "\t" << *TmpIns << "\n";
					//unsigned int l, c;
					//std::string cfi_path = getInstPath(TmpIns, l, c);
					//if (!cfi_path.empty()) {
					//	if (cfi_path.find("uclibc") != std::string::npos) {
					//		dbgs() << "[Filter Uclib]: find an instruction from uclibc.\n";
					//		continue;
					//	} else if (cfi_path.find("POSIX") != std::string::npos) {
					//		dbgs() << "[Filter Uclib]: find an instruction from POSIX.\n";
					//		continue;
					//	}
					//}
				} else
					continue;
			}
			// get the funciton pointer which is called by current CallRecord cr
			Function *FI = cr->second->getFunction();
			if (!FI)
				continue;
			
			// create a new CalledFunctions element and push it into calledFunctionMap.
			calledFunctionMap[FI].push_back(std::make_pair(F, dyn_cast<Instruction>(cr->first)));
			// for debuging
			map_count++;			
		}

	}
	
	dbgs() << "[Count Number of calledFunctionMap]: "<< calledFunctionMap.size() <<'\n';
	
	// analyze the global function pointer table
	if(function_pointer_analysis()) {
		errs() << "[Analyze global function pointer table success]\n";
	} else {
		errs() << "[Analyze global function pointer table failed]\n";
	}
	
	dbgs() << "[Count Number of calledFunctionMap]: "<< calledFunctionMap.size() <<'\n';
	
	// filter the instructions from uclibc
	//filter_uclibc();

	llvm::errs() << "=================================hh\n";
	llvm::errs() << "get Function Path: " << endFunc->getName() 
		<< " to " << startFunc->getName() << " \n";
	
//	printCalledFuncAndCFGPath(endFunc, startFunc, BB, p);
		
	// modification by wh
	evo_paths = new entire_path;
	//filter_paths = new func_bbs_type;
	//BB_paths_map = new std::map<std::pair<Function*, BasicBlock*>, std::vector<BasicBlock*> >;
	std::vector<std::pair< Function*, Instruction*> > tmp_func_path;
//	std::vector<BasicBlock*> tmp_bb_path;
//	explore_function_paths(endFunc, startFunc, bug_Inst, &tmp_func_path);
	collect_funcitons(endFunc, startFunc, bug_Inst, &tmp_func_path);
//	dbgs() << "++++++Found " << evo_paths->size() << " function paths.\n";
	
//	for (entire_path::iterator ep_it = evo_paths->begin(); ep_it != evo_paths->end(); ep_it++) {
//		for (std::vector<std::pair< Function*, Instruction*> >::iterator pair_it = ep_it->begin(); pair_it != ep_it->end(); pair_it++) {
//			if (filter_paths->size() != 0) {
//				std::vector<Instruction*>::iterator inst_it = std::find((*filter_paths)[pair_it->first].begin(), (*filter_paths)[pair_it->first].end(), pair_it->second);
//				if (inst_it != (*filter_paths)[pair_it->first].end()) {
//					continue;
//				}
//			}
//			(*filter_paths)[pair_it->first].push_back(pair_it->second);
//		}
//	}
	dbgs() << "[filter_paths]: contain " << filter_paths->size() << " functions in all.\n";
	
	for (func_bbs_type::iterator fbs_it = filter_paths->begin(); fbs_it != filter_paths->end(); fbs_it++) {
		for (std::vector<Instruction*>::iterator bb_it2 = fbs_it->second.begin(); bb_it2 != fbs_it->second.end(); bb_it2++) {
			dbgs() << "^^^^^^ " << fbs_it->first->getName() << ": " << (*bb_it2)->getParent()->getName() << '\n';
			// to expand functions
			call_insts.push_back((*bb_it2));
			
			explore_basicblock_paths(fbs_it->first, (*bb_it2)->getParent(), &(*BB_paths_map)[std::make_pair(fbs_it->first, *bb_it2)]);
			dbgs() << "^^^^^^ found " << (*BB_paths_map)[std::make_pair(fbs_it->first, *bb_it2)].size() << " basicblocks.\n";
		}
	}
	
	llvm::dbgs() << "!!!!!!!! Found " << call_insts.size() << " call instructions.\n";
	llvm::dbgs() << "!!!!!!!! Found " << path_basicblocks.size() << " path basicblocks.\n";
	
	// expand functions
	for (std::vector<Instruction*>::iterator ci_it = call_insts.begin(); ci_it != call_insts.end(); ci_it++) {
		BasicBlock *call_bb = (*ci_it)->getParent();
		if (!call_bb) {
			continue;
		}
		for (BasicBlock::iterator inst = call_bb->begin(); inst != call_bb->end(); inst++) {
			if (&*inst == *ci_it) {
				break;
			}
			if (isa<CallInst>(&*inst)) {
				std::vector<Instruction*>::iterator ci = std::find(path_call_insts.begin(), path_call_insts.end(), &*inst);
				if (ci != path_call_insts.end())
					continue;
				path_call_insts.push_back(&*inst);
			}
		}
	}
	llvm::dbgs() << "@@@@@@@@ After search call_insts, found " << path_call_insts.size() << " call instructions.\n";
	for (std::vector<BasicBlock*>::iterator p_bb_it = path_basicblocks.begin(); p_bb_it != path_basicblocks.end(); p_bb_it++) {
		for (BasicBlock::iterator inst = (*p_bb_it)->begin(); inst != (*p_bb_it)->end(); inst++) {
			if (isa<CallInst>(&*inst)) {
				std::vector<Instruction*>::iterator ci = std::find(path_call_insts.begin(), path_call_insts.end(), &*inst);
				if (ci != path_call_insts.end())
					continue;
				path_call_insts.push_back(&*inst);
			}
		}
	}
	llvm::dbgs() << "@@@@@@@@ After search path_basicblocks, found " << path_call_insts.size() << " call instructions.\n";
	for (std::vector<Instruction*>::iterator iit = path_call_insts.begin(); iit != path_call_insts.end(); iit++) {
		CallInst *ci = dyn_cast<CallInst>(*iit);
		if (!ci)
			continue;
		Function *ff = ci->getCalledFunction();
		if (!ff) {
			//ci->dump();
			//dbgs() << "\t[called value] " << ci->getOperand(0)->getName() << '\n'; 
			
			continue;
		}
		std::vector<Function*>::iterator fit = std::find(otherCalledFuncs->begin(), otherCalledFuncs->end(), ff);
		if (fit == otherCalledFuncs->end())
			otherCalledFuncs->push_back(ff);
	}
	llvm::dbgs() << "((((((((( Found " << otherCalledFuncs->size() << " functions.\n";
	
	for (int index = 0; index < otherCalledFuncs->size(); index++) {
		Function *f = otherCalledFuncs->at(index);
/*		if (!f) {
			//f->dump();
			llvm::dbgs() << "?????? index = " << index << " size = " << otherCalledFuncs->size()<< '\n';
			continue;
		}
*/		for (inst_iterator f_it = inst_begin(f); f_it != inst_end(f); f_it++) {
			CallInst *ci = dyn_cast<CallInst>(&*f_it);
			if (!ci)
				continue;
			if (!ci->getCalledFunction()) {
				//ci->dump();
				continue;
			}
			std::vector<Function*>::iterator fit = std::find(otherCalledFuncs->begin(), otherCalledFuncs->end(), ci->getCalledFunction());
			if (fit == otherCalledFuncs->end())
				otherCalledFuncs->push_back(ci->getCalledFunction());
		}
	}
	llvm::dbgs() << "((((((((( Found " << otherCalledFuncs->size() << " functions.\n";
	
	//This should be just for statistic.
	int tmp_funcNum_in_filter_notIn_other = 0;
	for (func_bbs_type::iterator fbs_it = filter_paths->begin(); fbs_it != filter_paths->end(); fbs_it++) {
		if (!fbs_it->first) {
			llvm::dbgs() << "[Warning]: Found a null Function pointer in filter_paths.\n";
			continue;
		}
		std::vector<Function*>::iterator fit = std::find(otherCalledFuncs->begin(), otherCalledFuncs->end(), fbs_it->first);
		if (fit == otherCalledFuncs->end())
			//otherCalledFuncs->push_back(fbs_it->first);
			tmp_funcNum_in_filter_notIn_other ++;
	}
	llvm::dbgs() << "<><><><> After searching filter_paths, found " << otherCalledFuncs->size() + tmp_funcNum_in_filter_notIn_other << " functions.\n";
/*	for (entire_path::iterator ep_it = evo_paths->begin(); ep_it != evo_paths->end(); ep_it++) {
		dbgs() << "Path length is: " << ep_it->size() << '\n';
		for (std::vector<std::pair< Function*, BasicBlock*> >::iterator pair_it = ep_it->begin(); pair_it != ep_it->end(); pair_it++) {
			 dbgs() << "^^^^^^ " << pair_it->first->getName() << ": " << pair_it->second->getName() << '\n';
			 explore_basicblock_paths(pair_it->first, pair_it->second, &(*BB_paths_map)[*pair_it]);
			 dbgs() << "^^^^^^ found " << (*BB_paths_map)[*pair_it].size() << " basicblocks.\n";
		}
	}
*/		
	llvm::errs() << "on-end\n";
	llvm::errs() << "=================================\n";
	
	// output all of the paths
/*	errs()<<"Find "<<paths_found->size()<<" paths in all.\n";
	for(paths::iterator ips = paths_found->begin();ips != paths_found->end();ips++) {
//		std::vector<BasicBlock*> *tmpP = dyn_cast<std::vector<BasicBlock*>*>(&*ips);
		dbgs() << "=========A Path Start============\n";
		for(std::vector<BasicBlock*>::iterator ps = ips->begin(), pe = ips->end(); ps != pe; ps++) {
			BasicBlock *tmpStr = *ps;
			errs()<<"\t"<<tmpStr->getParent()->getName()<<": "<<tmpStr->getName()<<" -> \n";
		}
		errs()<<"=================================\n";
	}
*/	
	return false;
}