diff --git a/llvm/lib/Analysis/DataStructure/CompleteBottomUp.cpp b/llvm/lib/Analysis/DataStructure/CompleteBottomUp.cpp new file mode 100644 index 0000000000000000000000000000000000000000..751d5b0ff2b362a01b741733bd65ef8a3a652832 --- /dev/null +++ b/llvm/lib/Analysis/DataStructure/CompleteBottomUp.cpp @@ -0,0 +1,75 @@ +//===- 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; +}