[llvm-commits] CVS: poolalloc/lib/PoolAllocate/PoolAllocate.cpp
Vikram Adve
vadve at cs.uiuc.edu
Sun May 23 02:56:01 PDT 2004
Changes in directory poolalloc/lib/PoolAllocate:
PoolAllocate.cpp updated: 1.68 -> 1.69
---
Log message:
Pull out equivalance-class partitioning and graph merging into
a separate pass (class EquivClassGraphs), and fix it to inline
the resulting graphs bottom-up on the SCCs of the CBU call graph.
---
Diffs of the changes: (+8 -182)
Index: poolalloc/lib/PoolAllocate/PoolAllocate.cpp
diff -u poolalloc/lib/PoolAllocate/PoolAllocate.cpp:1.68 poolalloc/lib/PoolAllocate/PoolAllocate.cpp:1.69
--- poolalloc/lib/PoolAllocate/PoolAllocate.cpp:1.68 Fri May 14 17:43:09 2004
+++ poolalloc/lib/PoolAllocate/PoolAllocate.cpp Sun May 23 02:55:12 2004
@@ -6,6 +6,7 @@
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "PoolAllocator"
+#include "EquivClassGraphs.h"
#include "poolalloc/PoolAllocate.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
@@ -77,20 +78,18 @@
void PoolAllocate::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<CompleteBUDataStructures>();
+ AU.addRequired<EquivClassGraphs>();
AU.addRequired<TargetData>();
}
bool PoolAllocate::run(Module &M) {
if (M.begin() == M.end()) return false;
CurModule = &M;
- BU = &getAnalysis<CompleteBUDataStructures>();
+ ECGraphs = &getAnalysis<EquivClassGraphs>(); // folded inlined CBU graphs
// Add the pool* prototypes to the module
AddPoolPrototypes();
- // Figure out what the equivalence classes are for indirectly called functions
- BuildIndirectFunctionSets(M);
-
// Create the pools for memory objects reachable by global variables.
if (SetupGlobalPools(M))
return true;
@@ -223,186 +222,13 @@
}
}
-const PA::EquivClassInfo &PoolAllocate::getECIForIndirectCallSite(CallSite CS) {
- Instruction *I = CS.getInstruction();
- assert(I && "Not a call site?");
- Function *thisFunc = I->getParent()->getParent();
- DSNode *calleeNode = BU->getDSGraph(*thisFunc).getNodeForValue(CS.getCalledValue()).getNode();
- if (!OneCalledFunction.count(calleeNode))
- return ECInfoForLeadersMap[0]; // Special null function for empty graphs
- Function *Called = OneCalledFunction[calleeNode];
- Function *Leader = FuncECs.findClass(Called);
- assert(Leader && "Leader not found for indirect call target!");
- assert(ECInfoForLeadersMap.count(Leader) && "No ECI for indirect call site!");
- return ECInfoForLeadersMap[Leader];
-}
-
-// BuildIndirectFunctionSets - Iterate over the module looking for indirect
-// calls to functions. If a call site can invoke any functions [F1, F2... FN],
-// unify the N functions together in the FuncECs set.
-//
-void PoolAllocate::BuildIndirectFunctionSets(Module &M) {
- const CompleteBUDataStructures::ActualCalleesTy AC = BU->getActualCallees();
-
- // Loop over all of the indirect calls in the program. If a call site can
- // call multiple different functions, we need to unify all of the callees into
- // the same equivalence class.
- Instruction *LastInst = 0;
- Function *FirstFunc = 0;
- for (CompleteBUDataStructures::ActualCalleesTy::const_iterator I = AC.begin(),
- E = AC.end(); I != E; ++I) {
- CallSite CS = CallSite::get(I->first);
- if (!CS.getCalledFunction() && // Ignore direct calls
- !I->second->isExternal()) { // Ignore functions we cannot modify
- //std::cerr << "CALLEE: " << I->second->getName() << " from : " <<
- //I->first;
- if (I->first != LastInst) {
- // This is the first callee from this call site.
- LastInst = I->first;
- FirstFunc = I->second;
- //Instead of storing the lastInst For Indirection call Sites we store the
- //DSNode for the function ptr arguemnt
- Function *thisFunc = LastInst->getParent()->getParent();
- DSNode *calleeNode = BU->getDSGraph(*thisFunc).getNodeForValue(CS.getCalledValue()).getNode();
- OneCalledFunction[calleeNode] = FirstFunc;
- FuncECs.addElement(I->second);
- } else {
- // This is not the first possible callee from a particular call site.
- // Union the callee in with the other functions.
- FuncECs.unionSetsWith(FirstFunc, I->second);
- }
- }
- }
-
- // Now that all of the equivalences have been built, turn the union-find data
- // structure into a simple map from each function in the equiv class to the
- // DSGraph used to represent the union of graphs.
- //
- std::map<Function*, Function*> &leaderMap = FuncECs.getLeaderMap();
- DEBUG(std::cerr << "Indirect Function Equivalence Map:\n");
- for (std::map<Function*, Function*>::iterator LI = leaderMap.begin(),
- LE = leaderMap.end(); LI != LE; ++LI) {
- DEBUG(std::cerr << " " << LI->first->getName() << ": leader is "
- << LI->second->getName() << "\n");
-
- // Now the we have the equiv class info for this object, merge the DSGraph
- // for this function into the composite DSGraph.
- EquivClassInfo &ECI = ECInfoForLeadersMap[LI->second];
-
- // If this is the first function in this equiv class, create the graph now.
- if (ECI.G == 0)
- ECI.G = new DSGraph(BU->getGlobalsGraph().getTargetData());
-
- // Clone this member of the equivalence class into ECI.
- DSGraph::NodeMapTy NodeMap;
- ECI.G->cloneInto(BU->getDSGraph(*LI->first), ECI.G->getScalarMap(),
- ECI.G->getReturnNodes(), NodeMap, 0);
-
- // This is N^2 with the number of functions in this equiv class, but I don't
- // really care right now. FIXME!
- for (unsigned i = 0, e = ECI.FuncsInClass.size(); i != e; ++i) {
- Function *F = ECI.FuncsInClass[i];
- // Merge the return nodes together.
- ECI.G->getReturnNodes()[F].mergeWith(ECI.G->getReturnNodes()[LI->first]);
-
- // Merge the arguments of the functions together.
- Function::aiterator AI1 = F->abegin();
- Function::aiterator AI2 = LI->first->abegin();
- for (; AI1 != F->aend() && AI2 != LI->first->aend(); ++AI1,++AI2)
- ECI.G->getNodeForValue(AI1).mergeWith(ECI.G->getNodeForValue(AI2));
- }
- ECI.FuncsInClass.push_back(LI->first);
- }
- DEBUG(std::cerr << "\n");
-
- // Now that we have created the graphs for each of the equivalence sets, we
- // have to figure out which pool descriptors to pass into the functions. We
- // must pass arguments for any pool descriptor that is needed by any function
- // in the equiv. class.
- for (ECInfoForLeadersMapTy::iterator ECII = ECInfoForLeadersMap.begin(),
- E = ECInfoForLeadersMap.end(); ECII != E; ++ECII) {
- EquivClassInfo &ECI = ECII->second;
-
- // Traverse part of the graph to provoke most of the node forwardings to
- // occur.
- DSGraph::ScalarMapTy &SM = ECI.G->getScalarMap();
- for (DSGraph::ScalarMapTy::iterator I = SM.begin(), E = SM.end(); I!=E; ++I)
- I->second.getNode(); // Collapse forward references...
-
- // Remove breadcrumbs from merging nodes.
- ECI.G->removeTriviallyDeadNodes();
-
- // Loop over all of the functions in this equiv class, figuring out which
- // pools must be passed in for each function.
- for (unsigned i = 0, e = ECI.FuncsInClass.size(); i != e; ++i) {
- Function *F = ECI.FuncsInClass[i];
- DSGraph &FG = BU->getDSGraph(*F);
-
- // Figure out which nodes need to be passed in for this function (if any)
- hash_set<DSNode*> &MarkedNodes = FunctionInfo[F].MarkedNodes;
- MarkNodesWhichMustBePassedIn(MarkedNodes, *F, FG);
-
- if (!MarkedNodes.empty()) {
- // If any nodes need to be passed in, figure out which nodes these are
- // in the unified graph for this equivalence class.
- DSGraph::NodeMapTy NodeMapping;
- for (Function::aiterator I = F->abegin(), E = F->aend(); I != E; ++I)
- DSGraph::computeNodeMapping(FG.getNodeForValue(I),
- ECI.G->getNodeForValue(I), NodeMapping);
- DSGraph::computeNodeMapping(FG.getReturnNodeFor(*F),
- ECI.G->getReturnNodeFor(*F), NodeMapping);
-
- // Loop through all of the nodes which must be passed through for this
- // callee, and add them to the arguments list.
- for (hash_set<DSNode*>::iterator I = MarkedNodes.begin(),
- E = MarkedNodes.end(); I != E; ++I) {
- DSNode *LocGraphNode = *I, *ECIGraphNode = NodeMapping[*I].getNode();
-
- // Remember the mapping of this node
- ECI.ECGraphToPrivateMap[std::make_pair(F,ECIGraphNode)] =LocGraphNode;
-
- // Add this argument to be passed in. Don't worry about duplicates,
- // they will be eliminated soon.
- ECI.ArgNodes.push_back(ECIGraphNode);
- }
- }
- }
-
- // Okay, all of the functions have had their required nodes added to the
- // ECI.ArgNodes list, but there might be duplicates. Eliminate the dups
- // now.
- std::sort(ECI.ArgNodes.begin(), ECI.ArgNodes.end());
- ECI.ArgNodes.erase(std::unique(ECI.ArgNodes.begin(), ECI.ArgNodes.end()),
- ECI.ArgNodes.end());
-
- // Uncomment this if you want to see the aggregate graph result
- //ECI.G->viewGraph();
- }
-}
-
void PoolAllocate::FindFunctionPoolArgs(Function &F) {
- DSGraph &G = BU->getDSGraph(F);
+ DSGraph &G = ECGraphs->getDSGraph(F);
FuncInfo &FI = FunctionInfo[&F]; // Create a new entry for F
hash_set<DSNode*> &MarkedNodes = FI.MarkedNodes;
- // If this function is part of an indirectly called function equivalence
- // class, we have to handle it specially.
- if (Function *Leader = FuncECs.findClass(&F)) {
- EquivClassInfo &ECI = ECInfoForLeadersMap[Leader];
-
- // The arguments passed in will be the ones specified by the ArgNodes list.
- for (unsigned i = 0, e = ECI.ArgNodes.size(); i != e; ++i) {
- DSNode *ArgNode =
- ECI.ECGraphToPrivateMap[std::make_pair(&F, ECI.ArgNodes[i])];
- FI.ArgNodes.push_back(ArgNode);
- MarkedNodes.insert(ArgNode);
- }
-
- return;
- }
-
if (G.node_begin() == G.node_end())
return; // No memory activity, nothing is required
@@ -419,7 +245,7 @@
// necessary, and return it. If not, just return null.
//
Function *PoolAllocate::MakeFunctionClone(Function &F) {
- DSGraph &G = BU->getDSGraph(F);
+ DSGraph &G = ECGraphs->getDSGraph(F);
if (G.node_begin() == G.node_end()) return 0;
FuncInfo &FI = FunctionInfo[&F];
@@ -540,7 +366,7 @@
//
bool PoolAllocate::SetupGlobalPools(Module &M) {
// Get the globals graph for the program.
- DSGraph &GG = BU->getGlobalsGraph();
+ DSGraph &GG = ECGraphs->getGlobalsGraph();
// Get all of the nodes reachable from globals.
hash_set<DSNode*> GlobalHeapNodes;
@@ -791,7 +617,7 @@
// the specified function...
//
void PoolAllocate::ProcessFunctionBody(Function &F, Function &NewF) {
- DSGraph &G = BU->getDSGraph(F);
+ DSGraph &G = ECGraphs->getDSGraph(F);
if (G.node_begin() == G.node_end()) return; // Quick exit if nothing to do...
@@ -801,7 +627,7 @@
// Calculate which DSNodes are reachable from globals. If a node is reachable
// from a global, we will create a global pool for it, so no argument passage
// is required.
- DSGraph &GG = BU->getGlobalsGraph();
+ DSGraph &GG = ECGraphs->getGlobalsGraph();
DSGraph::NodeMapTy GlobalsGraphNodeMapping;
for (DSScalarMap::global_iterator I = G.getScalarMap().global_begin(),
E = G.getScalarMap().global_end(); I != E; ++I) {
More information about the llvm-commits
mailing list