//===- CompleteBottomUp.cpp - Complete Bottom-Up Data Structure Graphs ----===// // // The LLVM Compiler Infrastructure // // This file was developed by the LLVM research group and is distributed under // the University of Illinois Open Source License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This is the exact same as the bottom-up graphs, but we use take a completed // call graph and inline all indirect callees into their callers graphs, making // the result more useful for things like pool allocation. // //===----------------------------------------------------------------------===// #include "llvm/Analysis/DataStructure.h" #include "llvm/Module.h" #include "llvm/Analysis/DSGraph.h" using namespace llvm; namespace { RegisterAnalysis X("cbudatastructure", "'Complete' Bottom-up Data Structure Analysis"); } using namespace DS; // run - Calculate the bottom up data structure graphs for each function in the // program. // bool CompleteBUDataStructures::run(Module &M) { BUDataStructures &BU = getAnalysis(); GlobalsGraph = new DSGraph(BU.getGlobalsGraph()); GlobalsGraph->setPrintAuxCalls(); // Our call graph is the same as the BU data structures call graph ActualCallees = BU.getActualCallees(); #if 1 // REMOVE ME EVENTUALLY // FIXME: TEMPORARY (remove once finalization of indirect call sites in the // globals graph has been implemented in the BU pass) TDDataStructures &TD = getAnalysis(); // The call graph extractable from the TD pass is _much more complete_ and // trustable than that generated by the BU pass so far. Until this is fixed, // we hack it like this: for (Module::iterator MI = M.begin(), ME = M.end(); MI != ME; ++MI) { if (MI->isExternal()) continue; const std::vector &CSs = TD.getDSGraph(*MI).getFunctionCalls(); for (unsigned CSi = 0, e = CSs.size(); CSi != e; ++CSi) { if (CSs[CSi].isIndirectCall()) { Instruction *TheCall = CSs[CSi].getCallSite().getInstruction(); const std::vector &Callees = CSs[CSi].getCalleeNode()->getGlobals(); for (unsigned i = 0, e = Callees.size(); i != e; ++i) if (Function *F = dyn_cast(Callees[i])) ActualCallees.insert(std::make_pair(TheCall, F)); } } } #endif // Start by copying all of the BU data structures graphs over, verbatim. for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) if (!I->isExternal()) { DSInfo[I] = new DSGraph(BU.getDSGraph(*I)); DSInfo[I]->setGlobalsGraph(GlobalsGraph); DSInfo[I]->setPrintAuxCalls(); } return false; }