[llvm-commits] [poolalloc] r114971 - in /poolalloc/trunk: include/poolalloc/Heuristic.h lib/PoolAllocate/Heuristic.cpp lib/PoolAllocate/PoolAllocate.cpp
John Criswell
criswell at uiuc.edu
Tue Sep 28 11:17:13 PDT 2010
Author: criswell
Date: Tue Sep 28 13:17:13 2010
New Revision: 114971
URL: http://llvm.org/viewvc/llvm-project?rev=114971&view=rev
Log:
Moved the code that decides which DSNodes get global pools into the Heuristic
passes (the findGlobalPoolNodes() method).
Fixed a bug in the constructor of the AllNodes intrinsic.
Made poolalloc preserve the heuristic pass for good measure.
Modified:
poolalloc/trunk/include/poolalloc/Heuristic.h
poolalloc/trunk/lib/PoolAllocate/Heuristic.cpp
poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp
Modified: poolalloc/trunk/include/poolalloc/Heuristic.h
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/poolalloc/Heuristic.h?rev=114971&r1=114970&r2=114971&view=diff
==============================================================================
--- poolalloc/trunk/include/poolalloc/Heuristic.h (original)
+++ poolalloc/trunk/include/poolalloc/Heuristic.h Tue Sep 28 13:17:13 2010
@@ -48,6 +48,7 @@
protected:
Module *M;
PoolAllocate *PA;
+ DataStructures *Graphs;
public:
// Virtual Destructor
@@ -93,6 +94,9 @@
}
};
+ /// Find globally reachable DSNodes that need a pool
+ virtual void findGlobalPoolNodes (std::vector<const DSNode *> & Nodes);
+
/// AssignToPools - Partition NodesToPA into a set of disjoint pools,
/// returning the result in ResultPools. If this is a function being pool
/// allocated, F will not be null.
@@ -139,9 +143,12 @@
return this;
}
- AllNodesHeuristic (intptr_t IDp = (intptr_t) (&ID)): ModulePass (&IDp) { }
+ AllNodesHeuristic (intptr_t IDp = (intptr_t) (&ID)): ModulePass (IDp) { }
virtual ~AllNodesHeuristic () {return;}
virtual bool runOnModule (Module & M);
+ virtual const char * getPassName () const {
+ return "All Nodes Pool Allocation Heurisitic";
+ }
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
// We require DSA while this pass is still responding to queries
Modified: poolalloc/trunk/lib/PoolAllocate/Heuristic.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/PoolAllocate/Heuristic.cpp?rev=114971&r1=114970&r2=114971&view=diff
==============================================================================
--- poolalloc/trunk/lib/PoolAllocate/Heuristic.cpp (original)
+++ poolalloc/trunk/lib/PoolAllocate/Heuristic.cpp Tue Sep 28 13:17:13 2010
@@ -205,7 +205,164 @@
return 4;
}
-
+
+//
+// Function: GetNodesReachableFromGlobals()
+//
+// Description:
+// This function finds all DSNodes which are reachable from globals. It finds
+// DSNodes both within the local DSGraph as well as in the Globals graph that
+// are reachable from globals.
+//
+// Inputs:
+// G - The DSGraph for which to find DSNodes which are reachable by globals.
+// This DSGraph can either by a DSGraph associated with a function *or*
+// it can be the globals graph itself.
+//
+// Outputs:
+// NodesFromGlobals - A reference to a container object in which to record
+// DSNodes reachable from globals. DSNodes are *added* to
+// this container; it is not cleared by this function.
+// DSNodes from both the local and globals graph are added.
+static void
+GetNodesReachableFromGlobals (DSGraph* G,
+ DenseSet<const DSNode*> &NodesFromGlobals) {
+ //
+ // Get the globals graph associated with this DSGraph. If the globals graph
+ // is NULL, then the graph that was passed in *is* the globals graph.
+ //
+ DSGraph * GlobalsGraph = G->getGlobalsGraph();
+ if (!GlobalsGraph)
+ GlobalsGraph = G;
+
+ //
+ // Find all DSNodes which are reachable in the globals graph.
+ //
+ for (DSGraph::node_iterator NI = GlobalsGraph->node_begin();
+ NI != GlobalsGraph->node_end();
+ ++NI) {
+ NI->markReachableNodes(NodesFromGlobals);
+ }
+
+ //
+ // Now the fun part. Find DSNodes in the local graph that correspond to
+ // those nodes reachable in the globals graph. Add them to the set of
+ // reachable nodes, too.
+ //
+ if (G->getGlobalsGraph()) {
+ //
+ // Compute a mapping between local DSNodes and DSNodes in the globals
+ // graph.
+ //
+ DSGraph::NodeMapTy NodeMap;
+ G->computeGToGGMapping (NodeMap);
+
+ //
+ // Scan through all DSNodes in the local graph. If a local DSNode has a
+ // corresponding DSNode in the globals graph that is reachable from a
+ // global, then add the local DSNode to the set of DSNodes reachable from a
+ // global.
+ //
+ // FIXME: A node's existance within the global DSGraph is probably
+ // sufficient evidence that it is reachable from a global.
+ //
+ DSGraph::node_iterator ni = G->node_begin();
+ for (; ni != G->node_end(); ++ni) {
+ DSNode * N = ni;
+ if (NodesFromGlobals.count (NodeMap[N].getNode()))
+ NodesFromGlobals.insert (N);
+ }
+ }
+}
+
+//
+// Method: findGlobalPoolNodes()
+//
+// Description:
+// This method finds DSNodes that are reachable from globals and that need a
+// pool. The Automatic Pool Allocation transform will use the returned
+// information to build global pools for the DSNodes in question.
+//
+// Note that this method does not assign DSNodes to pools; it merely decides
+// which DSNodes are reachable from globals and will need a pool of global
+// scope.
+//
+// Outputs:
+// Nodes - The DSNodes that are both reachable from globals and which should
+// have global pools will be *added* to this container.
+//
+void
+Heuristic::findGlobalPoolNodes (std::vector<const DSNode *> & Nodes) {
+ // Get the globals graph for the program.
+ DSGraph* GG = Graphs->getGlobalsGraph();
+
+ // Get all of the nodes reachable from globals.
+ DenseSet<const DSNode*> GlobalHeapNodes;
+ GetNodesReachableFromGlobals (GG, GlobalHeapNodes);
+
+ //
+ // We do not want to create pools for all memory objects reachable from
+ // globals. We only want those that are or could be heap objects.
+ //
+ std::vector<const DSNode *> toRemove;
+ for (DenseSet<const DSNode*>::iterator I = GlobalHeapNodes.begin(),
+ E = GlobalHeapNodes.end(); I != E; ) {
+ DenseSet<const DSNode*>::iterator Last = I; ++I;
+
+ //
+ // Nodes that escape to external code could be reachable from globals.
+ // Nodes that are incomplete could be heap nodes.
+ // Unknown nodes could be anything.
+ //
+ const DSNode *tmp = *Last;
+ if (!(tmp->isHeapNode() ||
+ tmp->isExternalNode() ||
+ tmp->isIncompleteNode() ||
+ tmp->isUnknownNode()))
+ toRemove.push_back (tmp);
+ }
+
+ //
+ // Remove all globally reachable DSNodes which do not require pools.
+ //
+ for (unsigned index = 0; index < toRemove.size(); ++index) {
+ GlobalHeapNodes.erase(toRemove[index]);
+ }
+
+ //
+ // Scan through all the local graphs looking for DSNodes which may be
+ // reachable by a global. These nodes may not end up in the globals graph
+ // because of the fact that DSA doesn't actually know what is happening to
+ // them.
+ //
+ for (Module::iterator F = M->begin(); F != M->end(); ++F) {
+ if (F->isDeclaration()) continue;
+ DSGraph* G = Graphs->getDSGraph(*F);
+ for (DSGraph::node_iterator I = G->node_begin(), E = G->node_end();
+ I != E;
+ ++I) {
+ DSNode * Node = I;
+ if (Node->isExternalNode() || Node->isIncompleteNode() ||
+ Node->isUnknownNode()) {
+ GlobalHeapNodes.insert (Node);
+ }
+ }
+ }
+
+ //
+ // Copy the values into the output container. Note that DenseSet has no
+ // iterator traits (or whatever allows us to treat DenseSet has a generic
+ // container), so we have to use a loop to copy values from the DenseSet into
+ // the output container.
+ //
+ for (DenseSet<const DSNode*>::iterator I = GlobalHeapNodes.begin(),
+ E = GlobalHeapNodes.end(); I != E; ++I) {
+ Nodes.push_back (*I);
+ }
+
+ return;
+}
+
//===-- AllNodes Heuristic ------------------------------------------------===//
//
// This heuristic pool allocates everything possible into separate pools.
@@ -218,6 +375,13 @@
//
M = &Module;
+ //
+ // Get the reference to the DSA Graph.
+ //
+ Graphs = &getAnalysis<EQTDDataStructures>();
+ assert (Graphs && "No DSGraphs!\n");
+ std::cerr << "JTC: Ran on Module: " << this << std::endl;
+
// We never modify anything in this pass
return false;
}
@@ -244,6 +408,11 @@
//
M = &Module;
+ //
+ // Get the reference to the DSA Graph.
+ //
+ Graphs = &getAnalysis<EQTDDataStructures>();
+
// We never modify anything in this pass
return false;
}
@@ -307,6 +476,11 @@
//
M = &Module;
+ //
+ // Get the reference to the DSA Graph.
+ //
+ Graphs = &getAnalysis<EQTDDataStructures>();
+
// We never modify anything in this pass
return false;
}
@@ -339,6 +513,11 @@
//
M = &Module;
+ //
+ // Get the reference to the DSA Graph.
+ //
+ Graphs = &getAnalysis<EQTDDataStructures>();
+
// We never modify anything in this pass
return false;
}
@@ -525,6 +704,11 @@
//
M = &Module;
+ //
+ // Get the reference to the DSA Graph.
+ //
+ Graphs = &getAnalysis<EQTDDataStructures>();
+
// We never modify anything in this pass
return false;
}
@@ -557,6 +741,11 @@
//
M = &Module;
+ //
+ // Get the reference to the DSA Graph.
+ //
+ Graphs = &getAnalysis<EQTDDataStructures>();
+
// We never modify anything in this pass
return false;
}
@@ -657,13 +846,13 @@
F ("paheur-OnlyOverhead", "Do not pool allocate anything, but induce all overhead from it");
static RegisterPass<NoNodesHeuristic>
-G ("paheur-NoNodes", "Pool allocate nothing");
+G ("paheur-NoNodes", "Pool allocate nothing heuristic");
//
// Create the heuristic analysis group.
//
-//static RegisterAnalysisGroup<Heuristic>
-//HeuristicGroup ("Pool Allocation Heuristic");
+static RegisterAnalysisGroup<Heuristic>
+HeuristicGroup ("Pool Allocation Heuristic");
RegisterAnalysisGroup<Heuristic> Heuristic1(A);
RegisterAnalysisGroup<Heuristic> Heuristic2(B);
Modified: poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp?rev=114971&r1=114970&r2=114971&view=diff
==============================================================================
--- poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp (original)
+++ poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp Tue Sep 28 13:17:13 2010
@@ -108,6 +108,7 @@
void PoolAllocate::getAnalysisUsage(AnalysisUsage &AU) const {
// We will need the heuristic pass to tell us what to do and how to do it
AU.addRequired<Heuristic>();
+ AU.addPreserved<Heuristic>();
if (dsa_pass_to_use == PASS_EQTD) {
AU.addRequiredTransitive<EQTDDataStructures>();
if(lie_preserve_passes != LIE_NONE)
@@ -862,87 +863,12 @@
// global pools.
//
bool PoolAllocate::SetupGlobalPools(Module &M) {
- // Get the globals graph for the program.
- DSGraph* GG = Graphs->getGlobalsGraph();
-
- // Get all of the nodes reachable from globals.
- DenseSet<const DSNode*> GlobalHeapNodes;
- GetNodesReachableFromGlobals(GG, GlobalHeapNodes);
-
- //
- // We do not want to create pools for all memory objects reachable from
- // globals. We only want those that are heap objects, could be heap objects,
- // or are array objects.
- //
- std::vector<const DSNode *> toRemove;
- for (DenseSet<const DSNode*>::iterator I = GlobalHeapNodes.begin(),
- E = GlobalHeapNodes.end(); I != E; ) {
- DenseSet<const DSNode*>::iterator Last = I; ++I;
-
- //
- // FIXME: If the PoolAllocateAllGlobalNodes option is selected for the
- // heuristic, then we should make global pools for heap and
- // non-heap DSNodes.
- //
-#if 0
- //
- // FIXME:
- // This code was disabled for regular pool allocation, but I don't know
- // why.
- //
- if (!SAFECodeEnabled) {
- if (!(*Last)->isHeapNode());
- GlobalHeapNodes.erase(Last);
- }
-#endif
-
- //
- // Nodes that escape to external code could be reachable from globals.
- // Nodes that are incomplete could be heap nodes.
- // Unknown nodes could be anything.
- //
- const DSNode *tmp = *Last;
- if (!(tmp->isHeapNode() || tmp->isArrayNode() ||
- tmp->isExternalNode() || tmp->isIncompleteNode() ||
- tmp->isUnknownNode()))
- toRemove.push_back (tmp);
- }
-
//
- // Remove all the DSNodes for which we do not want to create a global pool.
+ // Find all of the DSNodes which are reachable from globals and may require
+ // pools.
//
- while (toRemove.size()) {
- const DSNode * Node = toRemove.back();
- toRemove.pop_back();
- GlobalHeapNodes.erase(Node);
- }
-
- //
- // Scan through all the local graphs looking for DSNodes which may be
- // reachable by a global. These nodes may not end up in the globals graph
- // because of the fact that DSA doesn't actually know what is happening to
- // them.
- //
- for (Module::iterator F = M.begin(); F != M.end(); ++F) {
- if (F->isDeclaration()) continue;
- DSGraph* G = Graphs->getDSGraph(*F);
- for (DSGraph::node_iterator I = G->node_begin(), E = G->node_end();
- I != E;
- ++I){
- DSNode * Node = I;
- if (Node->isExternalNode() || Node->isIncompleteNode() ||
- Node->isUnknownNode()) {
- GlobalHeapNodes.insert (Node);
- }
-
- //
- // If a DSNode is used as an array and bounds checking is enabled,
- // then also give it a global node.
- //
- if (BoundsChecksEnabled && (Node->isArrayNode()))
- GlobalHeapNodes.insert (Node);
- }
- }
+ std::vector<const DSNode*> NodesToPA;
+ CurHeuristic->findGlobalPoolNodes (NodesToPA);
// Otherwise get the main function to insert the poolinit calls.
Function *MainFunc = M.getFunction("main");
@@ -952,23 +878,21 @@
return true;
}
- errs() << "Pool allocating " << GlobalHeapNodes.size()
- << " global nodes!\n";
-
-
- //std::vector<const DSNode*> NodesToPA(GlobalHeapNodes.begin(),
- // GlobalHeapNodes.end());
- //FIXME: Explain in more detail: DenseSet Doesn't have polite iterators
- std::vector<const DSNode*> NodesToPA;
- for (DenseSet<const DSNode*>::iterator ii = GlobalHeapNodes.begin(),
- ee = GlobalHeapNodes.end(); ii != ee; ++ii)
- NodesToPA.push_back(*ii);
+ errs() << "Pool allocating " << NodesToPA.size() << " global nodes!\n";
+ DSGraph* GG = Graphs->getGlobalsGraph();
std::vector<Heuristic::OnePool> ResultPools;
CurHeuristic->AssignToPools(NodesToPA, 0, GG, ResultPools);
BasicBlock::iterator InsertPt = MainFunc->getEntryBlock().begin();
+ //
+ // Create a set of the DSNodes globally reachable from memory. We'll assign
+ // NULL pool handles for those nodes which are globally reachable but for
+ // which the heuristic did not assign a pool.
+ //
+ std::set<const DSNode *> GlobalHeapNodes (NodesToPA.begin(), NodesToPA.end());
+
// Perform all global assignments as specified.
for (unsigned i = 0, e = ResultPools.size(); i != e; ++i) {
Heuristic::OnePool &Pool = ResultPools[i];
@@ -987,12 +911,12 @@
}
// Any unallocated DSNodes get null pool descriptor pointers.
- for (DenseSet<const DSNode*>::iterator I = GlobalHeapNodes.begin(),
+ for (std::set<const DSNode*>::iterator I = GlobalHeapNodes.begin(),
E = GlobalHeapNodes.end(); I != E; ++I) {
GlobalNodes[*I] = ConstantPointerNull::get(PointerType::getUnqual(PoolDescType));
++NumNonprofit;
}
-
+
return false;
}
More information about the llvm-commits
mailing list