本文整理汇总了C++中CallGraphNode::getFunction方法的典型用法代码示例。如果您正苦于以下问题:C++ CallGraphNode::getFunction方法的具体用法?C++ CallGraphNode::getFunction怎么用?C++ CallGraphNode::getFunction使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类CallGraphNode
的用法示例。
在下文中一共展示了CallGraphNode::getFunction方法的11个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: runOnModule
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: removeDeadFunctions
/// 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: runOnSCC
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: removeDeadFunctions
/// 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: verify
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
}
示例6: findBBPath
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: 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;
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) {
//.........这里部分代码省略.........
示例8: runOnModule
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);
//.........这里部分代码省略.........
示例9: removeDeadFunctions
/// 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: runOnModule
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: runOnModule
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;
// }
//}
//.........这里部分代码省略.........