[llvm-commits] [poolalloc] r98209 - in /poolalloc/trunk: include/dsa/DSGraph.h include/dsa/DSGraphTraits.h include/dsa/DSNode.h include/dsa/DataStructure.h lib/DSA/Basic.cpp lib/DSA/BottomUpClosure.cpp lib/DSA/DataStructure.cpp lib/DSA/Local.cpp lib/DSA/Printer.cpp lib/DSA/Steensgaard.cpp lib/DSA/TopDownClosure.cpp lib/PoolAllocate/PASimple.cpp
Andrew Lenharth
andrewl at lenharth.org
Wed Mar 10 16:18:04 PST 2010
Author: alenhar2
Date: Wed Mar 10 18:18:04 2010
New Revision: 98209
URL: http://llvm.org/viewvc/llvm-project?rev=98209&view=rev
Log:
Hold types in global uniqued sets, saves memory and time (despite being inefficient)
Use sorted vector sets some places to save memory and time.
Modified:
poolalloc/trunk/include/dsa/DSGraph.h
poolalloc/trunk/include/dsa/DSGraphTraits.h
poolalloc/trunk/include/dsa/DSNode.h
poolalloc/trunk/include/dsa/DataStructure.h
poolalloc/trunk/lib/DSA/Basic.cpp
poolalloc/trunk/lib/DSA/BottomUpClosure.cpp
poolalloc/trunk/lib/DSA/DataStructure.cpp
poolalloc/trunk/lib/DSA/Local.cpp
poolalloc/trunk/lib/DSA/Printer.cpp
poolalloc/trunk/lib/DSA/Steensgaard.cpp
poolalloc/trunk/lib/DSA/TopDownClosure.cpp
poolalloc/trunk/lib/PoolAllocate/PASimple.cpp
Modified: poolalloc/trunk/include/dsa/DSGraph.h
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/dsa/DSGraph.h?rev=98209&r1=98208&r2=98209&view=diff
==============================================================================
--- poolalloc/trunk/include/dsa/DSGraph.h (original)
+++ poolalloc/trunk/include/dsa/DSGraph.h Wed Mar 10 18:18:04 2010
@@ -42,7 +42,7 @@
typedef std::map<const Value*, DSNodeHandle> ValueMapTy;
ValueMapTy ValueMap;
- typedef std::set<const GlobalValue*> GlobalSetTy;
+ typedef sv::set<const GlobalValue*> GlobalSetTy;
GlobalSetTy GlobalSet;
EquivalenceClasses<const GlobalValue*> &GlobalECs;
@@ -232,14 +232,17 @@
/// constructed for.
const TargetData &TD;
+ SuperSet<const Type*>& TypeSS;
+
void operator=(const DSGraph &); // DO NOT IMPLEMENT
DSGraph(const DSGraph&); // DO NOT IMPLEMENT
public:
// Create a new, empty, DSGraph.
DSGraph(EquivalenceClasses<const GlobalValue*> &ECs, const TargetData &td,
+ SuperSet<const Type*>& tss,
DSGraph *GG = 0)
:GlobalsGraph(GG), PrintAuxCalls(false),
- ScalarMap(ECs), TD(td)
+ ScalarMap(ECs), TD(td), TypeSS(tss)
{ }
// Copy ctor - If you want to capture the node mapping between the source and
@@ -251,6 +254,7 @@
// method.
//
DSGraph( DSGraph* DSG, EquivalenceClasses<const GlobalValue*> &ECs,
+ SuperSet<const Type*>& tss,
unsigned CloneFlags = 0);
~DSGraph();
@@ -263,6 +267,10 @@
return ScalarMap.getGlobalECs();
}
+ SuperSet<const Type*>& getTypeSS() const {
+ return TypeSS;
+ }
+
/// getTargetData - Return the TargetData object for the current target.
///
const TargetData &getTargetData() const { return TD; }
@@ -558,7 +566,7 @@
/// merged with other nodes in the graph. This is used as the first step of
/// removeDeadNodes.
///
- void removeTriviallyDeadNodes(bool updateForwarders = false);
+ void removeTriviallyDeadNodes();
};
@@ -581,7 +589,11 @@
// NodeMap - A mapping from nodes in the source graph to the nodes that
// represent them in the destination graph.
- DSGraph::NodeMapTy NodeMap;
+ // We cannot use a densemap here as references into it are not stable across
+ // insertion
+ typedef std::map<const DSNode*, DSNodeHandle> RCNodeMap;
+ RCNodeMap NodeMap;
+
public:
ReachabilityCloner(DSGraph* dest, const DSGraph* src, unsigned cloneFlags,
bool _createDest = true)
Modified: poolalloc/trunk/include/dsa/DSGraphTraits.h
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/dsa/DSGraphTraits.h?rev=98209&r1=98208&r2=98209&view=diff
==============================================================================
--- poolalloc/trunk/include/dsa/DSGraphTraits.h (original)
+++ poolalloc/trunk/include/dsa/DSGraphTraits.h Wed Mar 10 18:18:04 2010
@@ -35,7 +35,7 @@
DSNodeIterator(NodeTy *N, bool) : Node(N) { // Create end iterator
if (N != 0) {
Offset = N->getSize();
- if (Offset == 0 && Node->getForwardNode() &&
+ if (Offset == 0 && Node->isForwarding() &&
Node->isDeadNode()) // Model Forward link
Offset += 1;
} else {
@@ -60,8 +60,10 @@
pointer operator*() const {
if (Node->isDeadNode())
return Node->getForwardNode();
- else
+ else if (Node->hasLink(Offset))
return Node->getLink(Offset).getNode();
+ else
+ return 0;
}
pointer operator->() const { return operator*(); }
Modified: poolalloc/trunk/include/dsa/DSNode.h
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/dsa/DSNode.h?rev=98209&r1=98208&r2=98209&view=diff
==============================================================================
--- poolalloc/trunk/include/dsa/DSNode.h (original)
+++ poolalloc/trunk/include/dsa/DSNode.h Wed Mar 10 18:18:04 2010
@@ -21,6 +21,9 @@
#include <map>
#include <set>
+#include "dsa/sv/set.h"
+#include "dsa/sv/super_set.h"
+#include "DSGraph.h"
namespace llvm {
@@ -36,7 +39,7 @@
///
class DSNode : public ilist_node<DSNode> {
public:
- typedef std::map<unsigned, std::set<const Type*> > TyMapTy;
+ typedef std::map<unsigned, SuperSet<const Type*>::setPtr> TyMapTy;
typedef std::map<unsigned, DSNodeHandle> LinkMapTy;
private:
@@ -77,7 +80,7 @@
/// Globals - The list of global values that are merged into this node.
///
- std::vector<const GlobalValue*> Globals;
+ sv::set<const GlobalValue*> Globals;
void operator=(const DSNode &); // DO NOT IMPLEMENT
DSNode(const DSNode &); // DO NOT IMPLEMENT
@@ -219,13 +222,20 @@
///
DSNodeHandle &getLink(unsigned Offset) {
assert(Offset < getSize() && "Link index is out of range!");
+ assert(!isForwarding() && "Link on a forwarding node");
return Links[Offset];
- }
+ }
const DSNodeHandle &getLink(unsigned Offset) const {
assert(hasLink(Offset) && "No Link");
+ assert(!isForwarding() && "Link on a forwarding node");
return Links.find(Offset)->second;
}
+ //unsigned getNumLinks() const {
+// assert(!isForwarding() && "Link on a forwarding node");
+// return Links.size();
+// }
+
/// mergeTypeInfo - This method merges the specified type into the current
/// node at the specified offset. This may update the current node's type
/// record if this gives more information to the node, it may do nothing to
@@ -235,8 +245,9 @@
///
/// FIXME: description
void mergeTypeInfo(const Type *Ty, unsigned Offset);
- void mergeTypeInfo(TyMapTy::const_iterator TyIt, unsigned Offset = 0);
-
+ void mergeTypeInfo(const TyMapTy::mapped_type TyIt, unsigned Offset);
+ void mergeTypeInfo(const DSNode* D, unsigned Offset);
+
/// foldNodeCompletely - If we determine that this node has some funny
/// behavior happening to it that we cannot represent, we fold it down to a
/// single, completely pessimistic, node. This node is represented as a
@@ -303,7 +314,7 @@
/// value leaders set that is merged into this node. Like the getGlobalsList
/// method, these iterators do not return globals that are part of the
/// equivalence classes for globals in this node, but aren't leaders.
- typedef std::vector<const GlobalValue*>::const_iterator globals_iterator;
+ typedef sv::set<const GlobalValue*>::const_iterator globals_iterator;
globals_iterator globals_begin() const { return Globals.begin(); }
globals_iterator globals_end() const { return Globals.end(); }
@@ -378,6 +389,7 @@
void dropAllReferences() {
Links.clear();
+ TyMap.clear();
if (isForwarding())
ForwardNH.setTo(0, 0);
}
Modified: poolalloc/trunk/include/dsa/DataStructure.h
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/dsa/DataStructure.h?rev=98209&r1=98208&r2=98209&view=diff
==============================================================================
--- poolalloc/trunk/include/dsa/DataStructure.h (original)
+++ poolalloc/trunk/include/dsa/DataStructure.h Wed Mar 10 18:18:04 2010
@@ -20,6 +20,8 @@
#include "llvm/ADT/EquivalenceClasses.h"
#include "dsa/EntryPointAnalysis.h"
+#include "dsa/sv/set.h"
+#include "dsa/sv/super_set.h"
#include <map>
@@ -37,10 +39,10 @@
FunctionPass *createDataStructureGraphCheckerPass();
class DataStructures : public ModulePass {
- typedef std::map<const Instruction*, std::set<const Function*> > ActualCalleesTy;
+ typedef std::map<const Instruction*, sv::set<const Function*> > ActualCalleesTy;
typedef std::map<const Function*, DSGraph*> DSInfoTy;
public:
- typedef std::set<const Function*>::const_iterator callee_iterator;
+ typedef sv::set<const Function*>::const_iterator callee_iterator;
private:
/// TargetData, comes in handy
@@ -58,9 +60,9 @@
/// Were are DSGraphs stolen by another pass?
bool DSGraphsStolen;
- void buildGlobalECs(std::set<const GlobalValue*>& ECGlobals);
+ void buildGlobalECs(sv::set<const GlobalValue*>& ECGlobals);
- void eliminateUsesOfECGlobals(DSGraph& G, const std::set<const GlobalValue*> &ECGlobals);
+ void eliminateUsesOfECGlobals(DSGraph& G, const sv::set<const GlobalValue*> &ECGlobals);
// DSInfo, one graph for each function
DSInfoTy DSInfo;
@@ -80,6 +82,7 @@
/// with other global values in the DSGraphs.
EquivalenceClasses<const GlobalValue*> GlobalECs;
+ SuperSet<const Type*>* TypeSS;
void init(DataStructures* D, bool clone, bool printAuxCalls, bool copyGlobalAuxCalls, bool resetAux);
void init(TargetData* T);
@@ -173,6 +176,8 @@
TargetData& getTargetData() const { return *TD; }
+ SuperSet<const Type*>& getTypeSS() const { return *TypeSS; }
+
/// deleteValue/copyValue - Interfaces to update the DSGraphs in the program.
/// These correspond to the interfaces defined in the AliasAnalysis class.
void deleteValue(Value *V);
@@ -348,7 +353,7 @@
/// by the bottom-up pass.
///
class TDDataStructures : public DataStructures {
- std::set<const Function*> ArgsRemainIncomplete;
+ sv::set<const Function*> ArgsRemainIncomplete;
/// CallerCallEdges - For a particular graph, we keep a list of these records
/// which indicates which graphs call this function and from where.
@@ -400,10 +405,10 @@
private:
void markReachableFunctionsExternallyAccessible(DSNode *N,
- std::set<DSNode*> &Visited);
+ sv::set<DSNode*> &Visited);
void InlineCallersIntoGraph(DSGraph* G);
- void ComputePostOrder(const Function &F, std::set<DSGraph*> &Visited,
+ void ComputePostOrder(const Function &F, sv::set<DSGraph*> &Visited,
std::vector<DSGraph*> &PostOrder);
};
Modified: poolalloc/trunk/lib/DSA/Basic.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/Basic.cpp?rev=98209&r1=98208&r2=98209&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/Basic.cpp (original)
+++ poolalloc/trunk/lib/DSA/Basic.cpp Wed Mar 10 18:18:04 2010
@@ -61,7 +61,7 @@
for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
if (!F->isDeclaration()) {
- DSGraph* G = new DSGraph(GlobalECs, getTargetData(), GlobalsGraph);
+ DSGraph* G = new DSGraph(GlobalECs, getTargetData(), *TypeSS, GlobalsGraph);
DSNode * Node = new DSNode(G);
if (!F->hasInternalLinkage())
Modified: poolalloc/trunk/lib/DSA/BottomUpClosure.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/BottomUpClosure.cpp?rev=98209&r1=98208&r2=98209&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/BottomUpClosure.cpp (original)
+++ poolalloc/trunk/lib/DSA/BottomUpClosure.cpp Wed Mar 10 18:18:04 2010
@@ -96,7 +96,7 @@
//finalizeGlobals();
- GlobalsGraph->removeTriviallyDeadNodes(true);
+ GlobalsGraph->removeTriviallyDeadNodes();
GlobalsGraph->maskIncompleteMarkers();
// Mark external globals incomplete.
@@ -449,7 +449,7 @@
E = CalledFuncs.end();
// Start with a copy of the first graph.
- GI = IndCallGraph.first = new DSGraph(getDSGraph(**I), GlobalECs);
+ GI = IndCallGraph.first = new DSGraph(getDSGraph(**I), GlobalECs, *TypeSS);
GI->setGlobalsGraph(Graph->getGlobalsGraph());
std::vector<DSNodeHandle> &Args = IndCallGraph.second;
@@ -537,7 +537,10 @@
// When this graph is finalized, clone the globals in the graph into the
// globals graph to make sure it has everything, from all graphs.
DSScalarMap &MainSM = Graph->getScalarMap();
- ReachabilityCloner RC(GlobalsGraph, Graph, DSGraph::StripAllocaBit);
+ ReachabilityCloner RC(GlobalsGraph, Graph,
+ DSGraph::DontCloneCallNodes |
+ DSGraph::DontCloneAuxCallNodes |
+ DSGraph::StripAllocaBit);
// Clone everything reachable from globals in the function graph into the
// globals graph.
Modified: poolalloc/trunk/lib/DSA/DataStructure.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/DataStructure.cpp?rev=98209&r1=98208&r2=98209&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/DataStructure.cpp (original)
+++ poolalloc/trunk/lib/DSA/DataStructure.cpp Wed Mar 10 18:18:04 2010
@@ -42,8 +42,8 @@
STATISTIC (NumCallNodesMerged, "Number of call nodes merged");
STATISTIC (NumNodeAllocated , "Number of nodes allocated");
STATISTIC (NumDNE , "Number of nodes removed by reachability");
-// STATISTIC (NumTrivialDNE , "Number of nodes trivially removed");
-// STATISTIC (NumTrivialGlobalDNE, "Number of globals trivially removed");
+ STATISTIC (NumTrivialDNE , "Number of nodes trivially removed");
+ STATISTIC (NumTrivialGlobalDNE, "Number of globals trivially removed");
static cl::opt<unsigned>
DSAFieldLimit("dsa-field-limit", cl::Hidden,
cl::desc("Number of fields to track before collapsing a node"),
@@ -61,7 +61,7 @@
DEBUG(
{ //assert not looping
DSNode* NH = N;
- std::set<DSNode*> seen;
+ sv::set<DSNode*> seen;
while(NH && NH->isForwarding()) {
assert(seen.find(NH) == seen.end() && "Loop detected");
seen.insert(NH);
@@ -81,9 +81,6 @@
N = Next;
N->NumReferrers++;
- if (N->isArrayNode())
- Offset %= N->getSize();
-
if (N->getSize() <= Offset) {
assert(N->getSize() <= 1 && "Forwarded to shrunk but not collapsed node?");
Offset = 0;
@@ -133,9 +130,7 @@
DSNode::DSNode(const DSNode &N, DSGraph *G, bool NullLinks)
: NumReferrers(0), Size(N.Size), ParentGraph(G), TyMap(N.TyMap),
Globals(N.Globals), NodeType(N.NodeType) {
- if (!NullLinks) {
- Links = N.Links;
- }
+ if (!NullLinks) Links = N.Links;
G->addNode(this);
++NumNodeAllocated;
}
@@ -153,9 +148,10 @@
assert(ParentGraph && "Node has no parent?");
const DSScalarMap &SM = ParentGraph->getScalarMap();
- for (unsigned i = 0, e = Globals.size(); i != e; ++i) {
- assert(SM.global_count(Globals[i]));
- assert(SM.find(Globals[i])->second.getNode() == this);
+ for (globals_iterator ii = globals_begin(), ee = globals_end();
+ ii != ee; ++ii) {
+ assert(SM.global_count(*ii));
+ assert(SM.find(*ii)->second.getNode() == this);
}
}
@@ -172,6 +168,24 @@
NodeType = DeadNode;
Size = 0;
+ DSNodeHandle ToNH(To,Offset);
+
+ //Move the Links
+ for (unsigned x = 0, xe = Links.size(); x != xe; ++x)
+ if (!Links[x].isNull()) {
+ // Compute the offset into the current node at which to
+ // merge this link. In the common case, this is a linear
+ // relation to the offset in the original node (with
+ // wrapping), but if the current node gets collapsed due to
+ // recursive merging, we must make sure to merge in all remaining
+ // links at offset zero.
+ unsigned MergeOffset = 0;
+ if (ToNH.getNode()->getSize() != 1)
+ MergeOffset = (x + Offset) % ToNH.getNode()->getSize();
+ ToNH.getNode()->addEdgeTo(MergeOffset, Links[x]);
+ }
+ Links.clear();
+
// Remove this node from the parent graph's Nodes list.
ParentGraph->unlinkNode(this);
ParentGraph = 0;
@@ -185,23 +199,19 @@
// equivalence class.
GV = getParentGraph()->getScalarMap().getLeaderForGlobal(GV);
- // Keep the list sorted.
- std::vector<const GlobalValue*>::iterator I =
- std::lower_bound(Globals.begin(), Globals.end(), GV);
-
- if (I == Globals.end() || *I != GV) {
- Globals.insert(I, GV);
- setGlobalMarker();
- }
+ Globals.insert(GV);
+ setGlobalMarker();
+}
+
+void DSNode::addFunction(const Function* F) {
+ addGlobal(F);
}
// removeGlobal - Remove the specified global that is explicitly in the globals
// list.
void DSNode::removeGlobal(const GlobalValue *GV) {
- std::vector<const GlobalValue*>::iterator I =
- std::lower_bound(Globals.begin(), Globals.end(), GV);
- assert(I != Globals.end() && *I == GV && "Global not in node!");
- Globals.erase(I);
+ assert (Globals.count(GV) && "Global not in Node!");
+ Globals.erase(GV);
}
/// foldNodeCompletely - If we determine that this node has some funny
@@ -216,6 +226,9 @@
++NumFolds;
+ //Collapsed nodes don't really need a type
+ TyMap.clear();
+
// If this node has a size that is <= 1, we don't need to create a forwarding
// node.
if (getSize() <= 1) {
@@ -232,26 +245,9 @@
DestNode->Size = 1;
DestNode->Globals.swap(Globals);
- DSNodeHandle NH(DestNode);
-
// Start forwarding to the destination node...
forwardNode(DestNode, 0);
- if (!Links.empty()) {
-
- // If we have links, merge all of our outgoing links together...
- for (LinkMapTy::iterator ii = edge_begin(), ee = edge_end();
- ii != ee; ++ii)
- NH.getNode()->Links[0].mergeWith(ii->second);
- Links.clear();
- }
- //Merge types
- if (!TyMap.empty()) {
- for (TyMapTy::iterator ii = type_begin(), ee = type_end();
- ii != ee; ++ii)
- NH.getNode()->mergeTypeInfo(ii);
- TyMap.clear();
- }
}
}
@@ -313,22 +309,36 @@
if (!NewTy || NewTy->isVoidTy()) return;
- if (isCollapsedNode()) Offset = 0;
+ if (isCollapsedNode()) return;
if (isArrayNode()) Offset %= getSize();
if (Offset >= getSize()) growSize(Offset+1);
- TyMap[Offset].insert(NewTy);
+ TyMap[Offset] = getParentGraph()->getTypeSS().getOrCreate(TyMap[Offset], NewTy);
}
-void DSNode::mergeTypeInfo(TyMapTy::const_iterator TyIt, unsigned Offset) {
- Offset += TyIt->first;
- if (isCollapsedNode()) Offset = 0;
+void DSNode::mergeTypeInfo(const TyMapTy::mapped_type TyIt, unsigned Offset) {
+ if (isCollapsedNode()) return;
if (isArrayNode()) Offset %= getSize();
- if (Offset >= getSize()) growSize(Offset+1);
+ if (Offset >= getSize())
+ growSize(Offset + 1);
+
+ if (!TyMap[Offset])
+ TyMap[Offset] = TyIt;
+ if (TyIt) {
+ sv::set<const Type*> S(*TyMap[Offset]);
+ S.insert(TyIt->begin(), TyIt->end());
+ TyMap[Offset] = getParentGraph()->getTypeSS().getOrCreate(S);
+ }
+}
+
+void DSNode::mergeTypeInfo(const DSNode* DN, unsigned Offset) {
+ if (isCollapsedNode()) return;
- TyMap[Offset].insert(TyIt->second.begin(), TyIt->second.end());
+ for (TyMapTy::const_iterator ii = DN->TyMap.begin(), ee = DN->TyMap.end();
+ ii != ee; ++ii)
+ mergeTypeInfo(ii->second, ii->first + Offset);
}
/// addEdgeTo - Add an edge from the current node to the specified node. This
@@ -351,12 +361,7 @@
void DSNode::mergeGlobals(const DSNode &RHS) {
- std::vector<const GlobalValue*> Temp;
- std::back_insert_iterator< std::vector<const GlobalValue*> > back_it (Temp);
- std::set_union(Globals.begin(), Globals.end(),
- RHS.Globals.begin(), RHS.Globals.end(),
- back_it);
- Globals.swap(Temp);
+ Globals.insert(RHS.Globals.begin(), RHS.Globals.end());
}
static unsigned gcd(unsigned m, unsigned n) {
@@ -406,12 +411,6 @@
#endif
}
- // Merge the type entries of the two nodes together...
- for (TyMapTy::iterator ii = NH.getNode()->TyMap.begin(),
- ee = NH.getNode()->TyMap.end(); ii != ee; ++ii)
- CurNodeH.getNode()->mergeTypeInfo(ii, NOffset);
- assert(!CurNodeH.getNode()->isDeadNode());
-
// If we are merging a node with a completely folded node, then both nodes are
// now completely folded.
//
@@ -431,14 +430,18 @@
NSize = NH.getNode()->getSize();
NOffset = NH.getOffset();
assert(NOffset == 0 && NSize == 1);
- }
-
-
+ }
DSNode *N = NH.getNode();
if (CurNodeH.getNode() == N || N == 0) return;
assert(!CurNodeH.getNode()->isDeadNode());
+ // Merge the type entries of the two nodes together...
+ CurNodeH.getNode()->mergeTypeInfo(NH.getNode(), NOffset);
+ if (NH.getNode()->getSize() + NOffset > CurNodeH.getNode()->getSize())
+ CurNodeH.getNode()->growSize(NH.getNode()->getSize() + NOffset);
+ assert(!CurNodeH.getNode()->isDeadNode());
+
// Merge the NodeType information.
CurNodeH.getNode()->NodeType |= N->NodeType;
@@ -446,27 +449,6 @@
N->forwardNode(CurNodeH.getNode(), NOffset);
assert(!CurNodeH.getNode()->isDeadNode());
- // Make all of the outgoing links of N now be outgoing links of CurNodeH.
- //
- for (LinkMapTy::iterator ii = N->Links.begin(), ee = N->Links.end();
- ii != ee; ++ii)
- if (ii->second.getNode()) {
- // Compute the offset into the current node at which to
- // merge this link. In the common case, this is a linear
- // relation to the offset in the original node (with
- // wrapping), but if the current node gets collapsed due to
- // recursive merging, we must make sure to merge in all remaining
- // links at offset zero.
- unsigned MergeOffset = 0;
- DSNode *CN = CurNodeH.getNode();
- if (CN->Size != 1)
- MergeOffset = (ii->first+NOffset) % CN->getSize();
- CN->addEdgeTo(MergeOffset, ii->second);
- }
-
- // Now that there are no outgoing edges, all of the Links are dead.
- N->Links.clear();
-
// Merge the globals list...
CurNodeH.getNode()->mergeGlobals(*N);
@@ -538,11 +520,11 @@
const DSNode *SN = SrcNH.getNode();
DSNodeHandle &NH = NodeMap[SN];
- if (!NH.isNull()) { // Node already mapped?
+ if (!NH.isNull()) { // Node already mapped?
DSNode *NHN = NH.getNode();
- return DSNodeHandle(NHN, NH.getOffset()+SrcNH.getOffset());
+ return DSNodeHandle(NHN, NH.getOffset() + SrcNH.getOffset());
}
-
+
// If SrcNH has globals and the destination graph has one of the same globals,
// merge this node with the destination node, which is much more efficient.
if (SN->globals_begin() != SN->globals_end()) {
@@ -573,8 +555,8 @@
// the current node may be merged with arbitrary other nodes. For this
// reason, we must always go through NH.
DN = 0;
- for (DSNode::LinkMapTy::const_iterator ii = SN->edge_begin(),
- ee = SN->edge_end(); ii != ee; ++ii) {
+ for (DSNode::const_edge_iterator ii = SN->edge_begin(), ee = SN->edge_end();
+ ii != ee; ++ii) {
const DSNodeHandle &SrcEdge = ii->second;
if (!SrcEdge.isNull()) {
const DSNodeHandle &DestEdge = getClonedNH(SrcEdge);
@@ -658,15 +640,12 @@
}
#endif
}
-
if (DN->getSize() < SN->getSize())
DN->growSize(SN->getSize());
// Merge the type entries of the two nodes together...
if (!DN->isNodeCompletelyFolded())
- for (DSNode::TyMapTy::const_iterator ii = SN->type_begin(),
- ee = SN->type_end(); ii != ee; ++ii)
- DN->mergeTypeInfo(ii, NH.getOffset() - SrcNH.getOffset());
+ DN->mergeTypeInfo(SN, NH.getOffset() - SrcNH.getOffset());
}
@@ -737,8 +716,8 @@
// any time, and the current node may be merged with arbitrary other nodes.
// For this reason, we must always go through NH.
DN = 0;
- for (DSNode::LinkMapTy::const_iterator ii = SN->edge_begin(),
- ee = SN->edge_end(); ii != ee; ++ii) {
+ for (DSNode::const_edge_iterator ii = SN->edge_begin(), ee = SN->edge_end();
+ ii != ee; ++ii) {
const DSNodeHandle &SrcEdge = ii->second;
if (!SrcEdge.isNull()) {
// Compute the offset into the current node at which to
@@ -837,8 +816,9 @@
DSGraph::DSGraph(DSGraph* G, EquivalenceClasses<const GlobalValue*> &ECs,
+ SuperSet<const Type*>& tss,
unsigned CloneFlags)
- : GlobalsGraph(0), ScalarMap(ECs), TD(G->TD) {
+ : GlobalsGraph(0), ScalarMap(ECs), TD(G->TD), TypeSS(tss) {
PrintAuxCalls = false;
cloneInto(G, CloneFlags);
}
@@ -1121,7 +1101,7 @@
bool AnyDirectSuccessorsReachClonedNodes = false;
for (DSNode::const_edge_iterator EI = N->edge_begin(), EE = N->edge_end();
EI != EE; ++EI)
- if (DSNode *Succ = EI->second.getNode()) {
+ if (DSNode * Succ = EI->second.getNode()) {
std::pair<unsigned, bool> &SuccInfo = VisitForSCCs(Succ);
if (SuccInfo.first < Min) Min = SuccInfo.first;
AnyDirectSuccessorsReachClonedNodes |= SuccInfo.second;
@@ -1138,10 +1118,10 @@
// Find out if any direct successors of any node reach cloned nodes.
if (!AnyDirectSuccessorsReachClonedNodes)
- for (unsigned i = SCCStack.size()-1; SCCStack[i] != N; --i)
+ for (unsigned i = SCCStack.size() - 1; SCCStack[i] != N; --i)
for (DSNode::const_edge_iterator EI = N->edge_begin(), EE = N->edge_end();
EI != EE; ++EI)
- if (DSNode *N = EI->second.getNode())
+ if (DSNode * N = EI->second.getNode())
if (NodeInfo[N].second) {
AnyDirectSuccessorsReachClonedNodes = true;
goto OutOfLoop;
@@ -1323,9 +1303,9 @@
N->setIncompleteMarker();
// Recursively process children...
- for (DSNode::edge_iterator I = N->edge_begin(),E = N->edge_end(); I != E; ++I)
- if (DSNode *DSN = I->second.getNode())
- markIncompleteNode(DSN);
+ for (DSNode::edge_iterator ii = N->edge_begin(), ee = N->edge_end();
+ ii != ee; ++ii)
+ markIncompleteNode(ii->second.getNode());
}
static void markIncomplete(DSCallSite &Call) {
@@ -1563,33 +1543,23 @@
// other nodes in the graph. These nodes will all be trivially unreachable, so
// we don't have to perform any non-trivial analysis here.
//
-void DSGraph::removeTriviallyDeadNodes(bool updateForwarders) {
-#if 0
- if (updateForwarders) {
- /// NOTE: This code is disabled. This slows down DSA on 177.mesa
- /// substantially!
-
- // Loop over all of the nodes in the graph, calling getNode on each field.
- // This will cause all nodes to update their forwarding edges, causing
- // forwarded nodes to be delete-able.
- for (node_iterator NI = node_begin(), E = node_end(); NI != E; ++NI) {
- DSNode &N = *NI;
- for (unsigned l = 0, e = N.getNumLinks(); l != e; ++l)
- N.getLink(l).getNode();
- }
-
- // NOTE: This code is disabled. Though it should, in theory, allow us to
- // remove more nodes down below, the scan of the scalar map is incredibly
- // expensive for certain programs (with large SCCs). In the future, if we can
- // make the scalar map scan more efficient, then we can reenable this.
-
- // Likewise, forward any edges from the scalar nodes. While we are at it,
- // clean house a bit.
- for (DSScalarMap::iterator I = ScalarMap.begin(), E = ScalarMap.end(); I != E;) {
- I->second.getNode();
- ++I;
- }
- }
+void DSGraph::removeTriviallyDeadNodes() {
+ /// NOTE: This code is disabled. This slows down DSA on 177.mesa
+ /// substantially!
+
+ // Loop over all of the nodes in the graph, calling getNode on each field.
+ // This will cause all nodes to update their forwarding edges, causing
+ // forwarded nodes to be delete-able.
+ for (node_iterator NI = node_begin(), E = node_end(); NI != E; ++NI)
+ for (DSNode::edge_iterator ii = NI->edge_begin(), ee = NI->edge_end();
+ ii != ee; ++ii)
+ ii->second.getNode();
+
+ // Likewise, forward any edges from the scalar nodes. While we are at it,
+ // clean house a bit.
+ for (DSScalarMap::iterator I = ScalarMap.begin(), E = ScalarMap.end();
+ I != E; ++I)
+ I->second.getNode();
bool isGlobalsGraph = !GlobalsGraph;
@@ -1641,7 +1611,7 @@
++NI;
}
}
-#endif
+
removeIdenticalCalls(FunctionCalls);
removeIdenticalCalls(AuxFunctionCalls);
}
@@ -1653,8 +1623,8 @@
///
void DSNode::markReachableNodes(DenseSet<const DSNode*> &ReachableNodes) const {
if (this == 0) return;
- assert(getForwardNode() == 0 && "Cannot mark a forwarded node!");
- if (ReachableNodes.insert(this).second) // Is newly reachable?
+ assert(!isForwarding() && "Cannot mark a forwarded node!");
+ if (ReachableNodes.insert(this).second) // Is newly reachable?
for (DSNode::const_edge_iterator I = edge_begin(), E = edge_end();
I != E; ++I)
I->second.getNode()->markReachableNodes(ReachableNodes);
@@ -1677,7 +1647,7 @@
DenseSet<const DSNode*> &Visited,
bool IgnoreGlobals) {
if (N == 0) return false;
- assert(N->getForwardNode() == 0 && "Cannot mark a forwarded node!");
+ assert(N->isForwarding() == 0 && "Cannot mark a forwarded node!");
// If this is a global node, it will end up in the globals graph anyway, so we
// don't need to worry about it.
@@ -2098,7 +2068,7 @@
if (Function *FromF = dyn_cast<Function>(From)) {
Function *ToF = cast<Function>(To);
assert(!DSInfo.count(ToF) && "New Function already exists!");
- DSGraph *NG = new DSGraph(getDSGraph(*FromF), GlobalECs);
+ DSGraph *NG = new DSGraph(getDSGraph(*FromF), GlobalECs, *TypeSS);
DSInfo[ToF] = NG;
assert(NG->getReturnNodes().size() == 1 && "Cannot copy SCC's yet!");
@@ -2127,9 +2097,9 @@
//Clone or Steal the Source Graph
DSGraph* BaseGraph = GraphSource->getDSGraph(*F);
if (Clone) {
- G = new DSGraph(BaseGraph, GlobalECs, DSGraph::DontCloneAuxCallNodes);
+ G = new DSGraph(BaseGraph, GlobalECs, *TypeSS, DSGraph::DontCloneAuxCallNodes);
} else {
- G = new DSGraph(GlobalECs, GraphSource->getTargetData());
+ G = new DSGraph(GlobalECs, GraphSource->getTargetData(), *TypeSS);
G->spliceFrom(BaseGraph);
if (resetAuxCalls)
G->getAuxFunctionCalls() = G->getFunctionCalls();
@@ -2151,7 +2121,7 @@
void DataStructures::formGlobalECs() {
// Grow the equivalence classes for the globals to include anything that we
// now know to be aliased.
- std::set<const GlobalValue*> ECGlobals;
+ sv::set<const GlobalValue*> ECGlobals;
buildGlobalECs(ECGlobals);
if (!ECGlobals.empty()) {
DEBUG(errs() << "Eliminating " << ECGlobals.size() << " EC Globals!\n");
@@ -2166,7 +2136,7 @@
/// apart. Instead of maintaining this information in all of the graphs
/// throughout the entire program, store only a single global (the "leader") in
/// the graphs, and build equivalence classes for the rest of the globals.
-void DataStructures::buildGlobalECs(std::set<const GlobalValue*> &ECGlobals) {
+void DataStructures::buildGlobalECs(sv::set<const GlobalValue*> &ECGlobals) {
DSScalarMap &SM = GlobalsGraph->getScalarMap();
EquivalenceClasses<const GlobalValue*> &GlobalECs = SM.getGlobalECs();
for (DSGraph::node_iterator I = GlobalsGraph->node_begin(),
@@ -2205,13 +2175,15 @@
/// really just equivalent to some other globals, remove the globals from the
/// specified DSGraph (if present), and merge any nodes with their leader nodes.
void DataStructures::eliminateUsesOfECGlobals(DSGraph &G,
- const std::set<const GlobalValue*> &ECGlobals) {
+ const sv::set<const GlobalValue*> &ECGlobals) {
DSScalarMap &SM = G.getScalarMap();
EquivalenceClasses<const GlobalValue*> &GlobalECs = SM.getGlobalECs();
bool MadeChange = false;
- for (DSScalarMap::global_iterator GI = SM.global_begin(), E = SM.global_end();
- GI != E; ) {
+ std::vector<const GlobalValue*> SMGVV(SM.global_begin(), SM.global_end());
+
+ for (std::vector<const GlobalValue*>::iterator GI = SMGVV.begin(),
+ E = SMGVV.end(); GI != E; ) {
const GlobalValue *GV = *GI; ++GI;
if (!ECGlobals.count(GV)) continue;
@@ -2253,9 +2225,10 @@
Clone = clone;
resetAuxCalls = resetAux;
TD = D->TD;
+ TypeSS = D->TypeSS;
ActualCallees = D->ActualCallees;
GlobalECs = D->getGlobalECs();
- GlobalsGraph = new DSGraph(D->getGlobalsGraph(), GlobalECs,
+ GlobalsGraph = new DSGraph(D->getGlobalsGraph(), GlobalECs, *TypeSS,
copyGlobalAuxCalls?0:DSGraph::DontCloneAuxCallNodes);
if (printAuxCalls) GlobalsGraph->setPrintAuxCalls();
@@ -2270,7 +2243,8 @@
GraphSource = 0;
Clone = false;
TD = T;
- GlobalsGraph = new DSGraph(GlobalECs, *T);
+ TypeSS = new SuperSet<const Type*>();
+ GlobalsGraph = new DSGraph(GlobalECs, *T, *TypeSS);
}
void DataStructures::releaseMemory() {
Modified: poolalloc/trunk/lib/DSA/Local.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/Local.cpp?rev=98209&r1=98208&r2=98209&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/Local.cpp (original)
+++ poolalloc/trunk/lib/DSA/Local.cpp Wed Mar 10 18:18:04 2010
@@ -169,10 +169,12 @@
// graph
if (g.getScalarMap().global_begin() != g.getScalarMap().global_end()) {
ReachabilityCloner RC(&g, g.getGlobalsGraph(), 0);
- for (DSScalarMap::global_iterator I = g.getScalarMap().global_begin();
- I != g.getScalarMap().global_end(); ++I)
+ std::vector<const GlobalValue*> GVV(g.getScalarMap().global_begin(),
+ g.getScalarMap().global_end());
+ for (std::vector<const GlobalValue*>::iterator I = GVV.begin();
+ I != GVV.end(); ++I)
if (const GlobalVariable * GV = dyn_cast<GlobalVariable > (*I))
- //if (GV->isConstant())
+ if (GV->isConstant())
RC.merge(g.getNodeForValue(GV), g.getGlobalsGraph()->getNodeForValue(GV));
}
@@ -246,7 +248,7 @@
N->addGlobal(GV);
if (GV->isDeclaration())
N->setExternGlobalMarker();
- } else if (Constant * C = dyn_cast<Constant > (V)) {
+ } else if (Constant *C = dyn_cast<Constant>(V)) {
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
if (CE->isCast()) {
if (isa<PointerType>(CE->getOperand(0)->getType()))
@@ -269,6 +271,13 @@
} else if (isa<UndefValue>(C)) {
G.eraseNodeForValue(V);
return 0;
+ } else if (isa<GlobalAlias>(C)) {
+ // XXX: Need more investigation
+ // According to Andrew, DSA is broken on global aliasing, since it does
+ // not handle the aliases of parameters correctly. Here is only a quick
+ // fix for some special cases.
+ NH = getValueDest(cast<GlobalAlias>(C)->getAliasee());
+ return NH;
} else {
errs() << "Unknown constant: " << *C << "\n";
assert(0 && "Unknown constant type!");
@@ -866,7 +875,7 @@
while (count) {
std::string section;
msf >> section;
- std::set<Value*> inSection;
+ sv::set<Value*> inSection;
for (Module::iterator MI = M.begin(), ME = M.end();
MI != ME; ++MI)
if (MI->hasSection() && MI->getSection() == section)
@@ -882,7 +891,7 @@
Value* V = M.getNamedValue(global);
if (V) {
DSNodeHandle& DHV = GlobalsGraph->getNodeForValue(V);
- for (std::set<Value*>::iterator SI = inSection.begin(),
+ for (sv::set<Value*>::iterator SI = inSection.begin(),
SE = inSection.end(); SI != SE; ++SI) {
DEBUG(errs() << "Merging " << V->getNameStr() << " with "
<< (*SI)->getNameStr() << "\n");
@@ -931,7 +940,7 @@
// Calculate all of the graphs...
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
if (!I->isDeclaration()) {
- DSGraph* G = new DSGraph(GlobalECs, getTargetData(), GlobalsGraph);
+ DSGraph* G = new DSGraph(GlobalECs, getTargetData(), *TypeSS, GlobalsGraph);
GraphBuilder GGB(*I, *G, *this);
G->getAuxFunctionCalls() = G->getFunctionCalls();
setDSGraph(*I, G);
Modified: poolalloc/trunk/lib/DSA/Printer.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/Printer.cpp?rev=98209&r1=98208&r2=98209&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/Printer.cpp (original)
+++ poolalloc/trunk/lib/DSA/Printer.cpp Wed Mar 10 18:18:04 2010
@@ -64,11 +64,14 @@
for (DSNode::TyMapTy::const_iterator ii = N->type_begin(),
ee = N->type_end(); ii != ee; ++ii) {
OS << ii->first << ": ";
- for (DSNode::TyMapTy::mapped_type::iterator ni = ii->second.begin(),
- ne = ii->second.end(); ni != ne; ++ni) {
- WriteTypeSymbolic(OS, *ni, M);
- OS << ", ";
- }
+ if (ii->second)
+ for (sv::set<const Type*>::const_iterator ni = ii->second->begin(),
+ ne = ii->second->end(); ni != ne; ++ni) {
+ WriteTypeSymbolic(OS, *ni, M);
+ OS << ", ";
+ }
+ else
+ OS << "VOID";
OS << " ";
}
else
Modified: poolalloc/trunk/lib/DSA/Steensgaard.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/Steensgaard.cpp?rev=98209&r1=98208&r2=98209&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/Steensgaard.cpp (original)
+++ poolalloc/trunk/lib/DSA/Steensgaard.cpp Wed Mar 10 18:18:04 2010
@@ -55,10 +55,10 @@
// Get a copy for the globals graph.
DSGraph * GG = DS->getGlobalsGraph();
- GlobalsGraph = new DSGraph(GG, GG->getGlobalECs());
+ GlobalsGraph = new DSGraph(GG, GG->getGlobalECs(), *TypeSS);
// Create a new, empty, graph...
- ResultGraph = new DSGraph(GG->getGlobalECs(), getTargetData());
+ ResultGraph = new DSGraph(GG->getGlobalECs(), getTargetData(), *TypeSS);
ResultGraph->setGlobalsGraph(GlobalsGraph);
// ResultGraph->spliceFrom(DS->getGlobalsGraph());
@@ -132,7 +132,7 @@
ResultGraph->removeDeadNodes(DSGraph::KeepUnreachableGlobals);
- GlobalsGraph->removeTriviallyDeadNodes(true);
+ GlobalsGraph->removeTriviallyDeadNodes();
GlobalsGraph->maskIncompleteMarkers();
// Mark external globals incomplete.
Modified: poolalloc/trunk/lib/DSA/TopDownClosure.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/TopDownClosure.cpp?rev=98209&r1=98208&r2=98209&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/TopDownClosure.cpp (original)
+++ poolalloc/trunk/lib/DSA/TopDownClosure.cpp Wed Mar 10 18:18:04 2010
@@ -54,20 +54,20 @@
}
void TDDataStructures::markReachableFunctionsExternallyAccessible(DSNode *N,
- std::set<DSNode*> &Visited) {
+ sv::set<DSNode*> &Visited) {
if (!N || Visited.count(N)) return;
Visited.insert(N);
- for (DSNode::LinkMapTy::iterator ii = N->edge_begin(),
- ee = N->edge_end(); ii != ee; ++ii) {
- DSNodeHandle &NH = ii->second;
- if (DSNode *NN = NH.getNode()) {
+ for (DSNode::edge_iterator ii = N->edge_begin(),
+ ee = N->edge_end(); ii != ee; ++ii)
+ if (!ii->second.isNull()) {
+ DSNodeHandle &NH = ii->second;
+ DSNode * NN = NH.getNode();
std::vector<const Function*> Functions;
NN->addFullFunctionList(Functions);
ArgsRemainIncomplete.insert(Functions.begin(), Functions.end());
markReachableFunctionsExternallyAccessible(NN, Visited);
}
- }
}
@@ -85,7 +85,7 @@
// arguments are functions which are reachable by global variables in the
// globals graph.
const DSScalarMap &GGSM = GlobalsGraph->getScalarMap();
- std::set<DSNode*> Visited;
+ sv::set<DSNode*> Visited;
for (DSScalarMap::global_iterator I=GGSM.global_begin(), E=GGSM.global_end();
I != E; ++I) {
DSNode *N = GGSM.find(*I)->second.getNode();
@@ -114,7 +114,7 @@
// We want to traverse the call graph in reverse post-order. To do this, we
// calculate a post-order traversal, then reverse it.
- std::set<DSGraph*> VisitedGraph;
+ sv::set<DSGraph*> VisitedGraph;
std::vector<DSGraph*> PostOrder;
{TIME_REGION(XXX, "td:Compute postorder");
@@ -156,7 +156,7 @@
void TDDataStructures::ComputePostOrder(const Function &F,
- std::set<DSGraph*> &Visited,
+ sv::set<DSGraph*> &Visited,
std::vector<DSGraph*> &PostOrder) {
if (F.isDeclaration()) return;
DSGraph* G = getOrCreateGraph(&F);
@@ -353,7 +353,7 @@
IndCallGraph = IndCallRecI->second;
} else {
// Otherwise, create a new DSGraph to represent this.
- IndCallGraph = new DSGraph(DSG->getGlobalECs(), DSG->getTargetData());
+ IndCallGraph = new DSGraph(DSG->getGlobalECs(), DSG->getTargetData(), *TypeSS);
// Make a nullary dummy call site, which will eventually get some content
// merged into it. The actual callee function doesn't matter here, so we
// just pass it something to keep the ctor happy.
Modified: poolalloc/trunk/lib/PoolAllocate/PASimple.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/PoolAllocate/PASimple.cpp?rev=98209&r1=98208&r2=98209&view=diff
==============================================================================
--- poolalloc/trunk/lib/PoolAllocate/PASimple.cpp (original)
+++ poolalloc/trunk/lib/PoolAllocate/PASimple.cpp Wed Mar 10 18:18:04 2010
@@ -127,7 +127,7 @@
// Merge all of the DSNodes in the DSGraphs.
//
GlobalECs = Graphs->getGlobalECs();
- CombinedDSGraph = new DSGraph (GlobalECs, TD, Graphs->getGlobalsGraph());
+ CombinedDSGraph = new DSGraph (GlobalECs, TD, Graphs->getTypeSS(), Graphs->getGlobalsGraph());
//CombinedDSGraph.cloneInto (getGlobalsGraph());
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
if (Graphs->hasDSGraph (*I))
More information about the llvm-commits
mailing list