// // Method: getDSNodeHandle() // // Description: // This method looks up the DSNodeHandle for a given LLVM value. The context // of the value is the specified function, although if it is a global value, // the DSNodeHandle may exist within the global DSGraph. // // Return value: // A DSNodeHandle for the value is returned. This DSNodeHandle could either // be in the function's DSGraph or from the GlobalsGraph. Note that the // DSNodeHandle may represent a NULL DSNode. // DSNodeHandle CompleteChecks::getDSNodeHandle (const Value * V, const Function * F) { // // Get access to the points-to results. // EQTDDataStructures & dsaPass = getAnalysis<EQTDDataStructures>(); // // Ensure that the function has a DSGraph // assert (dsaPass.hasDSGraph(*F) && "No DSGraph for function!\n"); // // Lookup the DSNode for the value in the function's DSGraph. // DSGraph * TDG = dsaPass.getDSGraph(*F); DSNodeHandle DSH = TDG->getNodeForValue(V); // // If the value wasn't found in the function's DSGraph, then maybe we can // find the value in the globals graph. // if ((DSH.isNull()) && (isa<GlobalValue>(V))) { // // Try looking up this DSNode value in the globals graph. Note that // globals are put into equivalence classes; we may need to first find the // equivalence class to which our global belongs, find the global that // represents all globals in that equivalence class, and then look up the // DSNode Handle for *that* global. // DSGraph * GlobalsGraph = TDG->getGlobalsGraph (); DSH = GlobalsGraph->getNodeForValue(V); if (DSH.isNull()) { // // DSA does not currently handle global aliases. // if (!isa<GlobalAlias>(V)) { // // We have to dig into the globalEC of the DSGraph to find the DSNode. // const GlobalValue * GV = dyn_cast<GlobalValue>(V); const GlobalValue * Leader; Leader = GlobalsGraph->getGlobalECs().getLeaderValue(GV); DSH = GlobalsGraph->getNodeForValue(Leader); } } } return DSH; }
bool BUDataStructures::runOnModuleInternal(Module& M) { std::vector<const Function*> Stack; hash_map<const Function*, unsigned> ValMap; unsigned NextID = 1; Function *MainFunc = M.getFunction("main"); if (MainFunc && !MainFunc->isDeclaration()) { calculateGraphs(MainFunc, Stack, NextID, ValMap); CloneAuxIntoGlobal(getDSGraph(MainFunc)); } else { DEBUG(errs() << debugname << ": No 'main' function found!\n"); } // Calculate the graphs for any functions that are unreachable from main... for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) if (!I->isDeclaration() && !hasDSGraph(I)) { if (MainFunc) DEBUG(errs() << debugname << ": Function unreachable from main: " << I->getName() << "\n"); calculateGraphs(I, Stack, NextID, ValMap); // Calculate all graphs. CloneAuxIntoGlobal(getDSGraph(I)); } // If we computed any temporary indcallgraphs, free them now. for (std::map<std::vector<const Function*>, std::pair<DSGraph*, std::vector<DSNodeHandle> > >::iterator I = IndCallGraphMap.begin(), E = IndCallGraphMap.end(); I != E; ++I) { I->second.second.clear(); // Drop arg refs into the graph. delete I->second.first; } IndCallGraphMap.clear(); // At the end of the bottom-up pass, the globals graph becomes complete. // FIXME: This is not the right way to do this, but it is sorta better than // nothing! In particular, externally visible globals and unresolvable call // nodes at the end of the BU phase should make things that they point to // incomplete in the globals graph. // finalizeGlobals(); GlobalsGraph->removeTriviallyDeadNodes(true); GlobalsGraph->maskIncompleteMarkers(); // Mark external globals incomplete. GlobalsGraph->markIncompleteNodes(DSGraph::IgnoreGlobals); formGlobalECs(); // Merge the globals variables (not the calls) from the globals graph back // into the main function's graph so that the main function contains all of // the information about global pools and GV usage in the program. if (MainFunc && !MainFunc->isDeclaration()) { DSGraph* MainGraph = getDSGraph(MainFunc); const DSGraph* GG = MainGraph->getGlobalsGraph(); ReachabilityCloner RC(MainGraph, GG, DSGraph::DontCloneCallNodes | DSGraph::DontCloneAuxCallNodes); // Clone the global nodes into this graph. for (DSScalarMap::global_iterator I = GG->getScalarMap().global_begin(), E = GG->getScalarMap().global_end(); I != E; ++I) if (isa<GlobalVariable>(*I)) RC.getClonedNH(GG->getNodeForValue(*I)); MainGraph->maskIncompleteMarkers(); MainGraph->markIncompleteNodes(DSGraph::MarkFormalArgs | DSGraph::IgnoreGlobals); } NumCallEdges += callee.size(); return false; }