[llvm-commits] [poolalloc] r98062 - in /poolalloc/trunk: include/dsa/DSGraph.h include/dsa/DSGraphTraits.h include/dsa/DSNode.h include/dsa/DSSupport.h lib/DSA/Basic.cpp lib/DSA/BottomUpClosure.cpp lib/DSA/DataStructure.cpp lib/DSA/Local.cpp lib/DSA/Printer.cpp lib/DSA/TopDownClosure.cpp
alenhar2 at llvm.org
alenhar2 at llvm.org
Tue Mar 9 08:48:35 PST 2010
Author: alenhar2
Date: Tue Mar 9 10:48:35 2010
New Revision: 98062
URL: http://llvm.org/viewvc/llvm-project?rev=98062&view=rev
Log:
Add byte offset based sets of types
Add byte offset links
add multiple entry points, WIP
get rid of stl/ext hash_
fix graph printer
api update to 2.7
handle malloc, sometimes (TODO: free, generalized allocator framework)
remove cruft
factor common operations out
Modified:
poolalloc/trunk/include/dsa/DSGraph.h
poolalloc/trunk/include/dsa/DSGraphTraits.h
poolalloc/trunk/include/dsa/DSNode.h
poolalloc/trunk/include/dsa/DSSupport.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/TopDownClosure.cpp
Modified: poolalloc/trunk/include/dsa/DSGraph.h
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/dsa/DSGraph.h?rev=98062&r1=98061&r2=98062&view=diff
==============================================================================
--- poolalloc/trunk/include/dsa/DSGraph.h (original)
+++ poolalloc/trunk/include/dsa/DSGraph.h Tue Mar 9 10:48:35 2010
@@ -24,7 +24,7 @@
namespace llvm {
-
+class TargetData;
class GlobalValue;
//===----------------------------------------------------------------------===//
Modified: poolalloc/trunk/include/dsa/DSGraphTraits.h
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/dsa/DSGraphTraits.h?rev=98062&r1=98061&r2=98062&view=diff
==============================================================================
--- poolalloc/trunk/include/dsa/DSGraphTraits.h (original)
+++ poolalloc/trunk/include/dsa/DSGraphTraits.h Tue Mar 9 10:48:35 2010
@@ -34,7 +34,7 @@
DSNodeIterator(NodeTy *N) : Node(N), Offset(0) {} // begin iterator
DSNodeIterator(NodeTy *N, bool) : Node(N) { // Create end iterator
if (N != 0) {
- Offset = N->getNumLinks();
+ Offset = N->getSize();
if (Offset == 0 && Node->getForwardNode() &&
Node->isDeadNode()) // Model Forward link
Offset += 1;
Modified: poolalloc/trunk/include/dsa/DSNode.h
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/dsa/DSNode.h?rev=98062&r1=98061&r2=98062&view=diff
==============================================================================
--- poolalloc/trunk/include/dsa/DSNode.h (original)
+++ poolalloc/trunk/include/dsa/DSNode.h Tue Mar 9 10:48:35 2010
@@ -15,6 +15,8 @@
#define LLVM_ANALYSIS_DSNODE_H
#include "dsa/DSSupport.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/ilist_node.h"
#include <map>
@@ -24,7 +26,6 @@
template<typename BaseType>
class DSNodeIterator; // Data structure graph traversal iterator
-class TargetData;
//===----------------------------------------------------------------------===//
/// DSNode - Data structure node class
@@ -34,9 +35,14 @@
/// different types represented in this object.
///
class DSNode : public ilist_node<DSNode> {
+public:
+ typedef std::map<unsigned, std::set<const Type*> > TyMapTy;
+ typedef std::map<unsigned, DSNodeHandle> LinkMapTy;
+
+private:
friend struct ilist_sentinel_traits<DSNode>;
//Sentinel
- DSNode() : NumReferrers(0), Size(0), Ty(0), NodeType(0) {}
+ DSNode() : NumReferrers(0), Size(0), NodeType(0) {}
/// NumReferrers - The number of DSNodeHandles pointing to this node... if
/// this is a forwarding node, then this is the number of node handles which
@@ -51,12 +57,6 @@
///
DSNodeHandle ForwardNH;
- /// Next, Prev - These instance variables are used to keep the node on a
- /// doubly-linked ilist in the DSGraph.
- ///
- //DSNode *Next, *Prev;
- //friend struct ilist_traits<DSNode>;
-
/// Size - The current size of the node. This should be equal to the size of
/// the current type record.
///
@@ -66,18 +66,14 @@
///
DSGraph *ParentGraph;
- /// Ty - Keep track of the current outer most type of this object, in addition
- /// to whether or not it has been indexed like an array or not. If the
- /// isArray bit is set, the node cannot grow.
- ///
- const Type *Ty; // The type itself...
-
- /// Links - Contains one entry for every sizeof(void*) bytes in this memory
- /// object. Note that if the node is not a multiple of size(void*) bytes
- /// large, that there is an extra entry for the "remainder" of the node as
- /// well. For this reason, nodes of 1 byte in size do have one link.
+ /// TyMap - Keep track of the loadable types and offsets those types are seen
+ // at.
+ TyMapTy TyMap;
+
+ /// Links - Contains one entry for every byte in this memory
+ /// object.
///
- std::vector<DSNodeHandle> Links;
+ LinkMapTy Links;
/// Globals - The list of global values that are merged into this node.
///
@@ -100,13 +96,14 @@
ReadNode = 1 << 8, // This node is read in this context
ArrayNode = 1 << 9, // This node is treated like an array
- ExternalNode = 1 << 10, // This node comes from an external source
- IntToPtrNode = 1 << 11, // This node comes from an int cast
- PtrToIntNode = 1 << 12, // This node excapes to an int cast
- VAStartNode = 1 << 13, // This node excapes to an int cast
+ CollapsedNode = 1 << 10, // This node is collapsed
+ ExternalNode = 1 << 11, // This node comes from an external source
+ IntToPtrNode = 1 << 12, // This node comes from an int cast
+ PtrToIntNode = 1 << 13, // This node excapes to an int cast
+ VAStartNode = 1 << 14, // This node excapes to an int cast
//#ifndef NDEBUG
- DeadNode = 1 << 14, // This node is dead and should not be pointed to
+ DeadNode = 1 << 15, // This node is dead and should not be pointed to
//#endif
Composition = AllocaNode | HeapNode | GlobalNode | UnknownNode
@@ -123,7 +120,7 @@
/// DSNode ctor - Create a node of the specified type, inserting it into the
/// specified graph.
///
- DSNode(const Type *T, DSGraph *G);
+ explicit DSNode(DSGraph *G);
/// DSNode "copy ctor" - Copy the specified node, inserting it into the
/// specified graph. If NullLinks is true, then null out all of the links,
@@ -149,6 +146,21 @@
inline const_iterator begin() const;
inline const_iterator end() const;
+ /// type_* - Provide iterators for accessing types. Some types may be null
+ TyMapTy::iterator type_begin() { return TyMap.begin(); }
+ TyMapTy::iterator type_end() { return TyMap.end(); }
+ TyMapTy::const_iterator type_begin() const { return TyMap.begin(); }
+ TyMapTy::const_iterator type_end() const { return TyMap.end(); }
+
+ /// edge_* - Provide iterators for accessing outgoing edges. Some outgoing
+ /// edges may be null.
+ typedef LinkMapTy::iterator edge_iterator;
+ typedef LinkMapTy::const_iterator const_edge_iterator;
+ edge_iterator edge_begin() { return Links.begin(); }
+ edge_iterator edge_end() { return Links.end(); }
+ const_edge_iterator edge_begin() const { return Links.begin(); }
+ const_edge_iterator edge_end() const { return Links.end(); }
+
//===--------------------------------------------------
// Accessors
@@ -156,12 +168,6 @@
///
unsigned getSize() const { return Size; }
- /// getType - Return the node type of this object...
- ///
- const Type *getType() const { return Ty; }
-
- bool isArray() const { return NodeType & ArrayNode; }
-
/// hasNoReferrers - Return true if nothing is pointing to this node at all.
///
bool hasNoReferrers() const { return getNumReferrers() == 0; }
@@ -171,14 +177,10 @@
/// return the number of nodes forwarding over the node!
unsigned getNumReferrers() const { return NumReferrers; }
+
DSGraph *getParentGraph() const { return ParentGraph; }
void setParentGraph(DSGraph *G) { ParentGraph = G; }
-
- /// getTargetData - Get the target data object used to construct this node.
- ///
- const TargetData &getTargetData() const;
-
/// getForwardNode - This method returns the node that this node is forwarded
/// to, if any.
///
@@ -200,38 +202,30 @@
delete this;
}
+ void growSize(unsigned NSize) {
+ assert(NSize > Size && "Cannot shrink");
+ assert(!isCollapsedNode() && "growing a collapsed node");
+ Size = NSize;
+ }
+
/// hasLink - Return true if this memory object has a link in slot LinkNo
///
bool hasLink(unsigned Offset) const {
- assert(Offset < Links.size() && "Link index is out of range!");
- return Links[Offset].getNode();
+ assert(Offset < getSize() && "Link index is out of range!");
+ return Links.find(Offset) != Links.end();
}
/// getLink - Return the link at the specified offset.
///
DSNodeHandle &getLink(unsigned Offset) {
- assert(Offset < Links.size() && "Link index is out of range!");
+ assert(Offset < getSize() && "Link index is out of range!");
return Links[Offset];
}
const DSNodeHandle &getLink(unsigned Offset) const {
- assert(Offset < Links.size() && "Link index is out of range!");
- return Links[Offset];
+ assert(hasLink(Offset) && "No Link");
+ return Links.find(Offset)->second;
}
- /// getNumLinks - Return the number of links in a node...
- ///
- unsigned getNumLinks() const { return Links.size(); }
-
- /// edge_* - Provide iterators for accessing outgoing edges. Some outgoing
- /// edges may be null.
- typedef std::vector<DSNodeHandle>::iterator edge_iterator;
- typedef std::vector<DSNodeHandle>::const_iterator const_edge_iterator;
- edge_iterator edge_begin() { return Links.begin(); }
- edge_iterator edge_end() { return Links.end(); }
- const_edge_iterator edge_begin() const { return Links.begin(); }
- const_edge_iterator edge_end() const { return Links.end(); }
-
-
/// 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
@@ -239,12 +233,10 @@
/// completely (and return true) if the information is incompatible with what
/// is already known.
///
- /// This method returns true if the node is completely folded, otherwise
- /// false.
- ///
- bool mergeTypeInfo(const Type *Ty, unsigned Offset,
- bool FoldIfIncompatible = true);
-
+ /// FIXME: description
+ void mergeTypeInfo(const Type *Ty, unsigned Offset);
+ void mergeTypeInfo(TyMapTy::const_iterator TyIt, unsigned Offset = 0);
+
/// 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
@@ -263,7 +255,7 @@
/// instead one of the higher level methods should be used, below.
///
void setLink(unsigned Offset, const DSNodeHandle &NH) {
- assert(Offset < Links.size() && "Link index is out of range!");
+ assert(Offset < getSize() && "Link index is out of range!");
Links[Offset] = NH;
}
@@ -341,6 +333,7 @@
bool isModifiedNode() const { return NodeType & ModifiedNode; }
bool isReadNode() const { return NodeType & ReadNode; }
bool isArrayNode() const { return NodeType & ArrayNode; }
+ bool isCollapsedNode() const { return NodeType & CollapsedNode; }
bool isIncompleteNode() const { return NodeType & IncompleteNode;}
bool isCompleteNode() const { return !isIncompleteNode(); }
bool isDeadNode() const { return NodeType & DeadNode; }
@@ -358,6 +351,7 @@
DSNode* setModifiedMarker() { NodeType |= ModifiedNode; return this; }
DSNode* setReadMarker() { NodeType |= ReadNode; return this; }
DSNode* setArrayMarker() { NodeType |= ArrayNode; return this; }
+ DSNode* setCollapsedMarker() { NodeType |= CollapsedNode; return this; }
DSNode* setIncompleteMarker() { NodeType |= IncompleteNode; return this; }
DSNode* setExternalMarker() { NodeType |= ExternalNode; return this; }
DSNode* setIntToPtrMarker() { NodeType |= IntToPtrNode; return this; }
@@ -395,7 +389,7 @@
/// DSNodes, marking any nodes which are reachable. All reachable nodes it
/// adds to the set, which allows it to only traverse visited nodes once.
///
- void markReachableNodes(std::set<const DSNode*> &ReachableNodes) const;
+ void markReachableNodes(llvm::DenseSet<const DSNode*> &ReachableNodes) const;
private:
friend class DSNodeHandle;
Modified: poolalloc/trunk/include/dsa/DSSupport.h
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/include/dsa/DSSupport.h?rev=98062&r1=98061&r2=98062&view=diff
==============================================================================
--- poolalloc/trunk/include/dsa/DSSupport.h (original)
+++ poolalloc/trunk/include/dsa/DSSupport.h Tue Mar 9 10:48:35 2010
@@ -19,6 +19,7 @@
#include <map>
#include <set>
+#include "llvm/ADT/DenseSet.h"
#include "llvm/Support/CallSite.h"
namespace llvm {
@@ -54,8 +55,11 @@
mutable unsigned Offset;
void operator==(const DSNode *N); // DISALLOW, use to promote N to nodehandle
public:
+
+ DSNodeHandle() : N(0), Offset(0) {}
+
// Allow construction, destruction, and assignment...
- DSNodeHandle(DSNode *n = 0, unsigned offs = 0) : N(0), Offset(0) {
+ DSNodeHandle(DSNode *n, unsigned offs = 0) : N(0), Offset(0) {
setTo(n, offs);
}
DSNodeHandle(const DSNodeHandle &H) : N(0), Offset(0) {
@@ -292,7 +296,7 @@
/// DSNodes, marking any nodes which are reachable. All reachable nodes it
/// adds to the set, which allows it to only traverse visited nodes once.
///
- void markReachableNodes(std::set<const DSNode*> &Nodes) const;
+ void markReachableNodes(DenseSet<const DSNode*> &Nodes) const;
bool operator<(const DSCallSite &CS) const {
if (isDirectCall()) { // This must sort by callee first!
Modified: poolalloc/trunk/lib/DSA/Basic.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/Basic.cpp?rev=98062&r1=98061&r2=98062&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/Basic.cpp (original)
+++ poolalloc/trunk/lib/DSA/Basic.cpp Tue Mar 9 10:48:35 2010
@@ -38,11 +38,9 @@
//
// Create a void pointer type. This is simply a pointer to an 8 bit value.
//
- const IntegerType * IT = IntegerType::getInt8Ty(M.getContext());
- const PointerType * VoidPtrTy = PointerType::getUnqual(IT);
- DSNode * GVNodeInternal = new DSNode(VoidPtrTy, GlobalsGraph);
- DSNode * GVNodeExternal = new DSNode(VoidPtrTy, GlobalsGraph);
+ DSNode * GVNodeInternal = new DSNode(GlobalsGraph);
+ DSNode * GVNodeExternal = new DSNode(GlobalsGraph);
for (Module::global_iterator I = M.global_begin(), E = M.global_end();
I != E; ++I) {
if (I->isDeclaration()) {
@@ -64,7 +62,7 @@
for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
if (!F->isDeclaration()) {
DSGraph* G = new DSGraph(GlobalECs, getTargetData(), GlobalsGraph);
- DSNode * Node = new DSNode(VoidPtrTy, G);
+ DSNode * Node = new DSNode(G);
if (!F->hasInternalLinkage())
Node->setExternalMarker();
Modified: poolalloc/trunk/lib/DSA/BottomUpClosure.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/BottomUpClosure.cpp?rev=98062&r1=98061&r2=98062&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/BottomUpClosure.cpp (original)
+++ poolalloc/trunk/lib/DSA/BottomUpClosure.cpp Tue Mar 9 10:48:35 2010
@@ -56,15 +56,13 @@
for (std::vector<const Function*>::iterator ii = EntryPoints.begin(),
ee = EntryPoints.end(); ii != ee; ++ii)
- if (!hasDSGraph(**ii))
+ if (!hasDSGraph(**ii)) {
+ errs() << debugname << ": Main Function: " << (*ii)->getName() << "\n";
calculateGraphs(*ii, Stack, NextID, ValMap);
+ CloneAuxIntoGlobal(getDSGraph(**ii));
+ }
- for (std::vector<const Function*>::iterator ii = EntryPoints.begin(),
- ee = EntryPoints.end(); ii != ee; ++ii) {
- cloneGlobalsInto(getDSGraph(**ii));
- calculateGraph(getDSGraph(**ii));
- CloneAuxIntoGlobal(getDSGraph(**ii));
- }
+ //errs() << "done main Funcs\n";
// Calculate the graphs for any functions that are unreachable from main...
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
@@ -78,6 +76,8 @@
CloneAuxIntoGlobal(getDSGraph(*I));
}
+ //errs() << "done unreachable Funcs\n";
+
// If we computed any temporary indcallgraphs, free them now.
for (std::map<std::vector<const Function*>,
std::pair<DSGraph*, std::vector<DSNodeHandle> > >::iterator I =
@@ -133,7 +133,7 @@
BadCalls.insert(*ii);
else
GoodCalls.insert(*ii);
- std::set<const DSNode*> reachable;
+ DenseSet<const DSNode*> reachable;
for (std::set<DSCallSite>::iterator ii = BadCalls.begin(),
ee = BadCalls.end(); ii != ee; ++ii) {
ii->getRetVal().getNode()->markReachableNodes(reachable);
@@ -142,7 +142,7 @@
}
for (std::set<DSCallSite>::iterator ii = GoodCalls.begin(),
ee = GoodCalls.end(); ii != ee; ++ii)
- if (reachable.find(ii->getCalleeNode()) == reachable.end())
+ if (reachable.count(ii->getCalleeNode()))
GlobalsGraph->getAuxFunctionCalls()
.erase(std::find(GlobalsGraph->getAuxFunctionCalls().begin(),
GlobalsGraph->getAuxFunctionCalls().end(),
@@ -341,6 +341,25 @@
void BUDataStructures::calculateGraph(DSGraph* Graph) {
DEBUG(Graph->AssertGraphOK(); Graph->getGlobalsGraph()->AssertGraphOK());
+ // If this graph contains the main function, clone the globals graph into this
+ // graph before we inline callees and other fun stuff.
+ bool ContainsMain = false;
+ DSGraph::ReturnNodesTy &ReturnNodes = Graph->getReturnNodes();
+
+ for (DSGraph::ReturnNodesTy::iterator I = ReturnNodes.begin(),
+ E = ReturnNodes.end(); I != E; ++I)
+ if (EP->isEntryPoint(I->first)) {
+ ContainsMain = true;
+ break;
+ }
+
+ // If this graph contains main, copy the contents of the globals graph over.
+ // Note that this is *required* for correctness. If a callee contains a use
+ // of a global, we have to make sure to link up nodes due to global-argument
+ // bindings.
+ if (ContainsMain)
+ cloneGlobalsInto(Graph);
+
// Move our call site list into TempFCs so that inline call sites go into the
// new call site list and doesn't invalidate our iterators!
std::list<DSCallSite> TempFCs;
Modified: poolalloc/trunk/lib/DSA/DataStructure.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/DataStructure.cpp?rev=98062&r1=98061&r2=98062&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/DataStructure.cpp (original)
+++ poolalloc/trunk/lib/DSA/DataStructure.cpp Tue Mar 9 10:48:35 2010
@@ -15,6 +15,7 @@
#include "dsa/DataStructure.h"
#include "dsa/DSGraph.h"
#include "dsa/DSSupport.h"
+#include "dsa/DSNode.h"
#include "llvm/Constants.h"
#include "llvm/Function.h"
#include "llvm/GlobalVariable.h"
@@ -43,9 +44,6 @@
STATISTIC (NumDNE , "Number of nodes removed by reachability");
// STATISTIC (NumTrivialDNE , "Number of nodes trivially removed");
// STATISTIC (NumTrivialGlobalDNE, "Number of globals trivially removed");
-#ifdef LLVA_KERNEL
- STATISTIC (LostPools , "Number of pools lost to DSNode Merge");
-#endif
static cl::opt<unsigned>
DSAFieldLimit("dsa-field-limit", cl::Hidden,
cl::desc("Number of fields to track before collapsing a node"),
@@ -82,8 +80,12 @@
N = Next;
N->NumReferrers++;
- if (N->Size <= Offset) {
- assert(N->Size <= 1 && "Forwarded to shrunk but not collapsed node?");
+
+ if (N->isArrayNode())
+ Offset %= N->getSize();
+
+ if (N->getSize() <= Offset) {
+ assert(N->getSize() <= 1 && "Forwarded to shrunk but not collapsed node?");
Offset = 0;
}
return N;
@@ -120,22 +122,20 @@
// DSNode Implementation
//===----------------------------------------------------------------------===//
-DSNode::DSNode(const Type *T, DSGraph *G)
-: NumReferrers(0), Size(0), ParentGraph(G), Ty(0), NodeType(0) {
+DSNode::DSNode(DSGraph *G)
+: NumReferrers(0), Size(0), ParentGraph(G), NodeType(0) {
// Add the type entry if it is specified...
- if (T) mergeTypeInfo(T, 0);
if (G) G->addNode(this);
++NumNodeAllocated;
}
// DSNode copy constructor... do not copy over the referrers list!
DSNode::DSNode(const DSNode &N, DSGraph *G, bool NullLinks)
- : NumReferrers(0), Size(N.Size), ParentGraph(G),
- Ty(N.Ty), Globals(N.Globals), NodeType(N.NodeType) {
+ : NumReferrers(0), Size(N.Size), ParentGraph(G), TyMap(N.TyMap),
+ Globals(N.Globals), NodeType(N.NodeType) {
if (!NullLinks) {
Links = N.Links;
- } else
- Links.resize(N.Links.size()); // Create the appropriate number of null links
+ }
G->addNode(this);
++NumNodeAllocated;
}
@@ -143,30 +143,13 @@
DSNode::~DSNode() {
dropAllReferences();
assert(hasNoReferrers() && "Referrers to dead node exist!");
-
-#ifdef LLVA_KERNEL
- //
- // Remove all references to this node from the Pool Descriptor Map.
- //
- DEBUG(errs() << "LLVA: Removing " << this << "\n");
- if (ParentGraph) {
- hash_map<const DSNode *, MetaPoolHandle*> &pdm=ParentGraph->getPoolDescriptorsMap();
- pdm.erase (this);
- }
-#endif
-}
-
-/// getTargetData - Get the target data object used to construct this node.
-///
-const TargetData &DSNode::getTargetData() const {
- return ParentGraph->getTargetData();
}
void DSNode::assertOK() const {
- assert(((Ty && Ty->getTypeID() != Type::VoidTyID) ||
- ((!Ty || Ty->getTypeID() == Type::VoidTyID) && (Size == 0 ||
- (NodeType & DSNode::ArrayNode)))) &&
- "Node not OK!");
+// assert(((Ty && Ty->getTypeID() != Type::VoidTyID) ||
+// ((!Ty || Ty->getTypeID() == Type::VoidTyID) && (Size == 0 ||
+// (NodeType & DSNode::ArrayNode)))) &&
+// "Node not OK!");
assert(ParentGraph && "Node has no parent?");
const DSScalarMap &SM = ParentGraph->getScalarMap();
@@ -188,7 +171,6 @@
ForwardNH.setTo(To, Offset);
NodeType = DeadNode;
Size = 0;
- Ty = 0;
// Remove this node from the parent graph's Nodes list.
ParentGraph->unlinkNode(this);
@@ -230,55 +212,45 @@
void DSNode::foldNodeCompletely() {
if (isNodeCompletelyFolded()) return; // If this node is already folded...
+// assert(0 && "Folding is happening");
+
++NumFolds;
// If this node has a size that is <= 1, we don't need to create a forwarding
// node.
if (getSize() <= 1) {
- NodeType |= DSNode::ArrayNode;
- Ty = 0;
+ setCollapsedMarker();
Size = 1;
assert(Links.size() <= 1 && "Size is 1, but has more links?");
- Links.resize(1);
} else {
// Create the node we are going to forward to. This is required because
// some referrers may have an offset that is > 0. By forcing them to
// forward, the forwarder has the opportunity to correct the offset.
- DSNode *DestNode = new DSNode(0, ParentGraph);
- DestNode->NodeType = NodeType|DSNode::ArrayNode;
- DestNode->Ty = 0;
+ DSNode *DestNode = new DSNode(ParentGraph);
+ DestNode->NodeType = NodeType;
+ DestNode->setCollapsedMarker();
DestNode->Size = 1;
DestNode->Globals.swap(Globals);
-
- // DOUT << "LLVA: foldNode: " << this << " becomes " << DestNode << "\n";
-#ifdef LLVA_KERNEL
- //Again we have created a new DSNode, we need to fill in the
- // pool desc map appropriately
- assert(ParentGraph && "parent graph is not null \n");
- hash_map<const DSNode *, MetaPoolHandle*> &pdm = ParentGraph->getPoolDescriptorsMap();
- if (pdm.count(this) > 0) {
- pdm[DestNode] = pdm[this];
- } else {
- //do nothing
- }
-#endif
+ DSNodeHandle NH(DestNode);
+
// Start forwarding to the destination node...
forwardNode(DestNode, 0);
-
if (!Links.empty()) {
- DestNode->Links.reserve(1);
-
- DSNodeHandle NH(DestNode);
- DestNode->Links.push_back(Links[0]);
// If we have links, merge all of our outgoing links together...
- for (unsigned i = Links.size()-1; i != 0; --i)
- NH.getNode()->Links[0].mergeWith(Links[i]);
+ for (LinkMapTy::iterator ii = edge_begin(), ee = edge_end();
+ ii != ee; ++ii)
+ NH.getNode()->Links[0].mergeWith(ii->second);
Links.clear();
- } else {
- DestNode->Links.resize(1);
+ }
+ //Merge types
+ if (!TyMap.empty()) {
+ for (TyMapTy::iterator ii = type_begin(), ee = type_end();
+ ii != ee; ++ii)
+ NH.getNode()->mergeTypeInfo(ii);
+ TyMap.clear();
}
}
}
@@ -288,8 +260,7 @@
/// all of the field sensitivity that may be present in the node.
///
bool DSNode::isNodeCompletelyFolded() const {
- return getSize() == 1 && (!Ty || Ty->getTypeID() == Type::VoidTyID)
- && isArray();
+ return isCollapsedNode();
}
/// addFullGlobalsList - Compute the full set of global values that are
@@ -330,179 +301,6 @@
}
}
-namespace {
- /// TypeElementWalker Class - Used for implementation of physical subtyping...
- ///
- class TypeElementWalker {
- struct StackState {
- const Type *Ty;
- unsigned Offset;
- unsigned Idx;
- StackState(const Type *T, unsigned Off = 0)
- : Ty(T), Offset(Off), Idx(0) {}
- };
-
- std::vector<StackState> Stack;
- const TargetData &TD;
- public:
- TypeElementWalker(const Type *T, const TargetData &td) : TD(td) {
- Stack.push_back(T);
- StepToLeaf();
- }
-
- bool isDone() const { return Stack.empty(); }
- const Type *getCurrentType() const { return Stack.back().Ty; }
- unsigned getCurrentOffset() const { return Stack.back().Offset; }
-
- void StepToNextType() {
- PopStackAndAdvance();
- StepToLeaf();
- }
-
- private:
- /// PopStackAndAdvance - Pop the current element off of the stack and
- /// advance the underlying element to the next contained member.
- void PopStackAndAdvance() {
- assert(!Stack.empty() && "Cannot pop an empty stack!");
- Stack.pop_back();
- while (!Stack.empty()) {
- StackState &SS = Stack.back();
- if (const StructType *ST = dyn_cast<StructType>(SS.Ty)) {
- ++SS.Idx;
- if (SS.Idx != ST->getNumElements()) {
- const StructLayout *SL = TD.getStructLayout(ST);
- SS.Offset +=
- unsigned(SL->getElementOffset(SS.Idx)-SL->getElementOffset(SS.Idx-1));
- return;
- }
- Stack.pop_back(); // At the end of the structure
- } else {
- const ArrayType *AT = cast<ArrayType>(SS.Ty);
- ++SS.Idx;
- if (SS.Idx != AT->getNumElements()) {
- SS.Offset += unsigned(TD.getTypeAllocSize(AT->getElementType()));
- return;
- }
- Stack.pop_back(); // At the end of the array
- }
- }
- }
-
- /// StepToLeaf - Used by physical subtyping to move to the first leaf node
- /// on the type stack.
- void StepToLeaf() {
- if (Stack.empty()) return;
- while (!Stack.empty() && !Stack.back().Ty->isFirstClassType()) {
- StackState &SS = Stack.back();
- if (const StructType *ST = dyn_cast<StructType>(SS.Ty)) {
- if (ST->getNumElements() == 0) {
- assert(SS.Idx == 0);
- PopStackAndAdvance();
- } else {
- // Step into the structure...
- assert(SS.Idx < ST->getNumElements());
- const StructLayout *SL = TD.getStructLayout(ST);
- Stack.push_back(StackState(ST->getElementType(SS.Idx),
- SS.Offset+unsigned(SL->getElementOffset(SS.Idx))));
- }
- } else {
- const ArrayType *AT = cast<ArrayType>(SS.Ty);
- if (AT->getNumElements() == 0) {
- assert(SS.Idx == 0);
- PopStackAndAdvance();
- } else {
- // Step into the array...
- assert(SS.Idx < AT->getNumElements());
- Stack.push_back(StackState(AT->getElementType(),
- SS.Offset+SS.Idx*
- unsigned(TD.getTypeAllocSize(AT->getElementType()))));
- }
- }
- }
- }
- };
-} // end anonymous namespace
-
-/// ElementTypesAreCompatible - Check to see if the specified types are
-/// "physically" compatible. If so, return true, else return false. We only
-/// have to check the fields in T1: T2 may be larger than T1. If AllowLargerT1
-/// is true, then we also allow a larger T1.
-///
-static bool ElementTypesAreCompatible(const Type *T1, const Type *T2,
- bool AllowLargerT1, const TargetData &TD){
- TypeElementWalker T1W(T1, TD), T2W(T2, TD);
-
- while (!T1W.isDone() && !T2W.isDone()) {
- if (T1W.getCurrentOffset() != T2W.getCurrentOffset())
- return false;
-
- const Type *T1 = T1W.getCurrentType();
- const Type *T2 = T2W.getCurrentType();
- if (T1 != T2 && !T1->canLosslesslyBitCastTo(T2))
- return false;
-
- T1W.StepToNextType();
- T2W.StepToNextType();
- }
-
- return AllowLargerT1 || T1W.isDone();
-}
-
-//
-// Function: getElementAtOffsetWithPadding()
-//
-// Description:
-// Take a byte offset into a structure and return the type at that byte
-// offset that *includes* any padding that occurs after the structure element.
-//
-static inline const Type *
-getElementAtOffsetWithPadding (const TargetData & TD,
- const StructLayout & SL,
- const StructType * STy,
- unsigned index) {
- //
- // Get the type of the element at the specified type index.
- //
- const Type * SubType = STy->getElementType(index);
-
- //
- // If this is the last element in the structure, just return the subtype;
- // there is no padding after the last element.
- //
- if (index == (STy->getNumElements() - 1))
- return SubType;
-
- //
- // Get the byte offset of this element and its successor element.
- //
- unsigned int thisOffset = (unsigned) SL.getElementOffset(index);
- unsigned int nextOffset = (unsigned) SL.getElementOffset(index + 1);
-
- //
- // If the size of the current element is less than the distance between
- // the offset at this index and the offset at the next index, then there is
- // some padding in between this element and the next. Create a structure
- // type that contains this element *and* the padding.
- //
- if ((TD.getTypeAllocSize (SubType)) < (nextOffset - thisOffset)) {
- //
- // Create an array type that fits the padding size.
- //
- const Type * Int8Type = IntegerType::getInt8Ty(SubType->getContext());
- const Type * paddingType = ArrayType::get (Int8Type, nextOffset-thisOffset);
-
- //
- // Create a structure type that contains the element and the padding array.
- //
- std::vector<const Type *> elementTypes;
- elementTypes.push_back (SubType);
- elementTypes.push_back (paddingType);
- return (StructType::get (SubType->getContext(), elementTypes, true));
- } else {
- return SubType;
- }
-}
-
/// 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 the node if
@@ -511,322 +309,28 @@
///
/// This method returns true if the node is completely folded, otherwise false.
///
-bool DSNode::mergeTypeInfo(const Type *NewTy, unsigned Offset,
- bool FoldIfIncompatible) {
- //DOUT << "merging " << *NewTy << " at " << Offset << " with " << *Ty << "\n";
- if (!Ty) Ty = Type::getVoidTy(NewTy->getContext());
-
- const TargetData &TD = getTargetData();
- // Check to make sure the Size member is up-to-date. Size can be one of the
- // following:
- // Size = 0, Ty = Void: Nothing is known about this node.
- // Size = 0, Ty = FnTy: FunctionPtr doesn't have a size, so we use zero
- // Size = 1, Ty = Void, Array = 1: The node is collapsed
- // Otherwise, sizeof(Ty) = Size
- //
- const Type * VoidType = Type::getVoidTy(NewTy->getContext());
- assert(((Size == 0 && Ty == VoidType && !isArray()) ||
- (Size == 0 && !Ty->isSized() && !isArray()) ||
- (Size == 1 && Ty == VoidType && isArray()) ||
- (Size == 0 && !Ty->isSized() && !isArray()) ||
- (TD.getTypeAllocSize(Ty) == Size)) &&
- "Size member of DSNode doesn't match the type structure!");
- assert(NewTy != VoidType && "Cannot merge void type into DSNode!");
-
- if (Offset == 0 && NewTy == Ty)
- return false; // This should be a common case, handle it efficiently
-
- // Return true immediately if the node is completely folded.
- if (isNodeCompletelyFolded()) return true;
-
- // If this is an array type, eliminate the outside arrays because they won't
- // be used anyway. This greatly reduces the size of large static arrays used
- // as global variables, for example.
- //
- bool WillBeArray = false;
- while (const ArrayType *AT = dyn_cast<ArrayType>(NewTy)) {
- // FIXME: we might want to keep small arrays, but must be careful about
- // things like: [2 x [10000 x int*]]
- NewTy = AT->getElementType();
- WillBeArray = true;
- }
-
- // Figure out how big the new type we're merging in is...
- unsigned NewTySize = NewTy->isSized() ? (unsigned)TD.getTypeAllocSize(NewTy) : 0;
-
- // Otherwise check to see if we can fold this type into the current node. If
- // we can't, we fold the node completely, if we can, we potentially update our
- // internal state.
- //
- if (Ty == VoidType) {
- // If this is the first type that this node has seen, just accept it without
- // question....
- assert(Offset == 0 && !isArray() &&
- "Cannot have an offset into a void node!");
-
- // If this node would have to have an unreasonable number of fields, just
- // collapse it. This can occur for fortran common blocks, which have stupid
- // things like { [100000000 x double], [1000000 x double] }.
- unsigned NumFields = NewTySize;
- if (NumFields > DSAFieldLimit) {
- foldNodeCompletely();
- return true;
- }
-
- Ty = NewTy;
- NodeType &= ~ArrayNode;
- if (WillBeArray) NodeType |= ArrayNode;
- Size = NewTySize;
-
- // Calculate the number of outgoing links from this node.
- Links.resize(NumFields);
- return false;
- }
-
- // Handle node expansion case here...
- if (Offset+NewTySize > Size) {
- // It is illegal to grow this node if we have treated it as an array of
- // objects...
- if (isArray()) {
- if (FoldIfIncompatible) foldNodeCompletely();
- return true;
- }
-
- // If this node would have to have an unreasonable number of fields, just
- // collapse it. This can occur for fortran common blocks, which have stupid
- // things like { [100000000 x double], [1000000 x double] }.
- unsigned NumFields = NewTySize+Offset;
- if (NumFields > DSAFieldLimit) {
- foldNodeCompletely();
- return true;
- }
-
- if (Offset) {
- //handle some common cases:
- // Ty: struct { t1, t2, t3, t4, ..., tn}
- // NewTy: struct { offset, stuff...}
- // try merge with NewTy: struct {t1, t2, stuff...} if offset lands exactly
- // on a field in Ty
- if (isa<StructType>(NewTy) && isa<StructType>(Ty)) {
- DEBUG(errs() << "Ty: " << *Ty << "\nNewTy: " << *NewTy << "@" << Offset << "\n");
- const StructType *STy = cast<StructType>(Ty);
- const StructLayout &SL = *TD.getStructLayout(STy);
- unsigned i = SL.getElementContainingOffset(Offset);
- //Either we hit it exactly or give up
- if (SL.getElementOffset(i) != Offset) {
- if (FoldIfIncompatible) foldNodeCompletely();
- return true;
- }
- std::vector<const Type*> nt;
- for (unsigned x = 0; x < i; ++x)
- nt.push_back(STy->getElementType(x));
- STy = cast<StructType>(NewTy);
- nt.insert(nt.end(), STy->element_begin(), STy->element_end());
- //and merge
- STy = StructType::get(STy->getContext(), nt);
- DEBUG(errs() << "Trying with: " << *STy << "\n");
- return mergeTypeInfo(STy, 0);
- }
-
- //Ty: struct { t1, t2, t3 ... tn}
- //NewTy T offset x
- //try merge with NewTy: struct : {t1, t2, T} if offset lands on a field
- //in Ty
- if (isa<StructType>(Ty)) {
- DEBUG(errs() << "Ty: " << *Ty << "\nNewTy: " << *NewTy << "@" << Offset << "\n");
- const StructType *STy = cast<StructType>(Ty);
- const StructLayout &SL = *TD.getStructLayout(STy);
- unsigned i = SL.getElementContainingOffset(Offset);
- //Either we hit it exactly or give up
- if (SL.getElementOffset(i) != Offset) {
- if (FoldIfIncompatible) foldNodeCompletely();
- return true;
- }
- std::vector<const Type*> nt;
- for (unsigned x = 0; x < i; ++x)
- nt.push_back(STy->getElementType(x));
- nt.push_back(NewTy);
- //and merge
- STy = StructType::get(STy->getContext(), nt);
- DEBUG(errs() << "Trying with: " << *STy << "\n");
- return mergeTypeInfo(STy, 0);
- }
-
- assert(0 &&
- "UNIMP: Trying to merge a growth type into "
- "offset != 0: Collapsing!");
- abort();
- if (FoldIfIncompatible) foldNodeCompletely();
- return true;
-
- }
-
-
- // Okay, the situation is nice and simple, we are trying to merge a type in
- // at offset 0 that is bigger than our current type. Implement this by
- // switching to the new type and then merge in the smaller one, which should
- // hit the other code path here. If the other code path decides it's not
- // ok, it will collapse the node as appropriate.
- //
-
- const Type *OldTy = Ty;
- Ty = NewTy;
- NodeType &= ~ArrayNode;
- if (WillBeArray) NodeType |= ArrayNode;
- Size = NewTySize;
-
- // Must grow links to be the appropriate size...
- Links.resize(NumFields);
-
- // Merge in the old type now... which is guaranteed to be smaller than the
- // "current" type.
- return mergeTypeInfo(OldTy, 0);
- }
-
- assert(Offset <= Size &&
- "Cannot merge something into a part of our type that doesn't exist!");
-
- // Find the section of Ty that NewTy overlaps with... first we find the
- // type that starts at offset Offset.
- //
- unsigned O = 0;
- const Type *SubType = Ty;
- while (O < Offset) {
- assert(Offset-O < TD.getTypeAllocSize(SubType) && "Offset out of range!");
-
- switch (SubType->getTypeID()) {
- case Type::StructTyID: {
- const StructType *STy = cast<StructType>(SubType);
- const StructLayout &SL = *TD.getStructLayout(STy);
-
- unsigned i = SL.getElementContainingOffset(Offset-O);
-
- //
- // The offset we are looking for must be in the i'th element...
- // However, be careful! It is possible that the offset lands in a
- // padding area of the structure. Use a special methods that will either
- // return us the type of the element we seek or a structure that contains
- // an explicit element representing the padding.
- //
- SubType = getElementAtOffsetWithPadding (TD, SL, STy, i);
- O += (unsigned)SL.getElementOffset(i);
- break;
- }
- case Type::ArrayTyID: {
- SubType = cast<ArrayType>(SubType)->getElementType();
- unsigned ElSize = (unsigned)TD.getTypeAllocSize(SubType);
- unsigned Remainder = (Offset-O) % ElSize;
- O = Offset-Remainder;
- break;
- }
- default:
- if (FoldIfIncompatible) foldNodeCompletely();
- return true;
- }
- }
-
- assert(O == Offset && "Could not achieve the correct offset!");
-
- // If we found our type exactly, early exit
- if (SubType == NewTy) return false;
+void DSNode::mergeTypeInfo(const Type *NewTy, unsigned Offset) {
- // Differing function types don't require us to merge. They are not values
- // anyway.
- if (isa<FunctionType>(SubType) &&
- isa<FunctionType>(NewTy)) return false;
-
- unsigned SubTypeSize = SubType->isSized() ?
- (unsigned)TD.getTypeAllocSize(SubType) : 0;
-
- // Ok, we are getting desperate now. Check for physical subtyping, where we
- // just require each element in the node to be compatible.
- if (NewTySize <= SubTypeSize && NewTySize && NewTySize < 256 &&
- SubTypeSize && SubTypeSize < 256 &&
- ElementTypesAreCompatible(NewTy, SubType, !isArray(), TD))
- return false;
-
- // Okay, so we found the leader type at the offset requested. Search the list
- // of types that starts at this offset. If SubType is currently an array or
- // structure, the type desired may actually be the first element of the
- // composite type...
- //
- unsigned PadSize = SubTypeSize; // Size, including pad memory which is ignored
- while (SubType != NewTy) {
- const Type *NextSubType = 0;
- unsigned NextSubTypeSize = 0;
- unsigned NextPadSize = 0;
- switch (SubType->getTypeID()) {
- case Type::StructTyID: {
- const StructType *STy = cast<StructType>(SubType);
- const StructLayout &SL = *TD.getStructLayout(STy);
- if (STy->getNumElements() > 1)
- NextPadSize = (unsigned)SL.getElementOffset(1);
- else
- NextPadSize = SubTypeSize;
- NextSubType = STy->getElementType(0);
- NextSubTypeSize = (unsigned)TD.getTypeAllocSize(NextSubType);
- break;
- }
- case Type::ArrayTyID:
- NextSubType = cast<ArrayType>(SubType)->getElementType();
- NextSubTypeSize = (unsigned)TD.getTypeAllocSize(NextSubType);
- NextPadSize = NextSubTypeSize;
- break;
- default: ;
- // fall out
- }
+ if (!NewTy || NewTy->isVoidTy()) return;
- if (NextSubType == 0)
- break; // In the default case, break out of the loop
+ if (isCollapsedNode()) Offset = 0;
+ if (isArrayNode()) Offset %= getSize();
- if (NextPadSize < NewTySize)
- break; // Don't allow shrinking to a smaller type than NewTySize
- SubType = NextSubType;
- SubTypeSize = NextSubTypeSize;
- PadSize = NextPadSize;
- }
+ if (Offset >= getSize()) growSize(Offset+1);
- // If we found the type exactly, return it...
- if (SubType == NewTy)
- return false;
+ TyMap[Offset].insert(NewTy);
+}
- // Check to see if we have a compatible, but different type...
- if (NewTySize == SubTypeSize) {
- // Check to see if this type is obviously convertible... int -> uint f.e.
- if (NewTy->canLosslesslyBitCastTo(SubType))
- return false;
+void DSNode::mergeTypeInfo(TyMapTy::const_iterator TyIt, unsigned Offset) {
+ Offset += TyIt->first;
+ if (isCollapsedNode()) Offset = 0;
+ if (isArrayNode()) Offset %= getSize();
- // Check to see if we have a pointer & integer mismatch going on here,
- // loading a pointer as a long, for example.
- //
- if ((SubType->isIntegerTy() && NewTy->isPointerTy()) ||
- (NewTy->isIntegerTy() && SubType->isPointerTy()))
- return false;
- } else if (NewTySize > SubTypeSize && NewTySize <= PadSize) {
- // We are accessing the field, plus some structure padding. Ignore the
- // structure padding.
- return false;
- }
-
- const Module *M = 0;
- if (getParentGraph()->retnodes_begin() != getParentGraph()->retnodes_end())
- M = getParentGraph()->retnodes_begin()->first->getParent();
-
- DEBUG(errs() << "MergeTypeInfo Folding OrigTy: ");
- raw_stderr_ostream stream;
- DEBUG(WriteTypeSymbolic(stream, Ty, M);
- stream << "\n due to:";
- WriteTypeSymbolic(stream, NewTy, M);
- stream << " @ " << Offset << "!\n" << "SubType: ";
- WriteTypeSymbolic(stream, SubType, M);
- stream << "\n\n");
+ if (Offset >= getSize()) growSize(Offset+1);
- if (FoldIfIncompatible) foldNodeCompletely();
- return true;
+ TyMap[Offset].insert(TyIt->second.begin(), TyIt->second.end());
}
-
-
/// addEdgeTo - Add an edge from the current node to the specified node. This
/// can cause merging of nodes in the graph.
///
@@ -855,6 +359,16 @@
Globals.swap(Temp);
}
+static unsigned gcd(unsigned m, unsigned n) {
+ if (m < n) return gcd(n,m);
+ unsigned r = m % n;
+ if (r == 0) {
+ return n;
+ } else {
+ return gcd(n, r);
+ }
+}
+
// MergeNodes - Helper function for DSNode::mergeWith().
// This function does the hard work of merging two nodes, CurNodeH
// and NH after filtering out trivial cases and making sure that
@@ -891,62 +405,11 @@
}
#endif
}
-#ifdef LLVA_KERNEL
- DSNode *currNode = CurNodeH.getNode();
- DSNode *NNode = NH.getNode();
- DSGraph *pGraph = currNode->getParentGraph();
- assert((pGraph == NNode->getParentGraph()) && "LLVA_KERNEL : merging nodes in two different graphs?");
- //get the pooldescriptor map
- hash_map<const DSNode *, MetaPoolHandle*> &pdm = pGraph->getPoolDescriptorsMap();
- if (pdm.count(currNode) == 0) {
- if (pdm.count(NNode) == 0) {
- //do nothing (common case)
- } else {
- if (pdm[NNode]) {
- DEBUG(errs() << "LLVA: 1: currNode (" << currNode << ") becomes " << pdm[NNode]->getName() << "(" << NNode << ")\n");
- pdm[currNode] = pdm[NNode];
- }
- }
- } else {
- if (pdm.count(NNode) == 0) {
-#if 1
- //
- // FIXME:
- // Verify that this is correct. I believe it is; it seems to make sense
- // since either node can be used after the merge.
- //
- DEBUG(errs() << "LLVA: MergeNodes: currnode has something, newnode has nothing\n"
- << "LLVA: 2: currNode (" << currNode << ") becomes <no name>"
- << "(" << NNode << ")\n");
- pdm[NNode] = pdm[currNode];
-#endif
- //do nothing
- } else {
- if (pdm[currNode] != pdm[NNode]) {
- //The following is commented because pdm[..] could be null!
- //std::cerr << "LLVA: OldPool: " << pdm[currNode]->getName() << "("
- // << pdm[currNode] << ") "
- // << " NewPool: " << pdm[NNode]->getName() << "("
- // << pdm[NNode] << ")" << std::endl;
- pdm[NNode]->merge(pdm[currNode]);
- /*
- Value *currN = pdm[currNode]->getMetaPoolValue();
- Value *NN = pdm[NNode]->getMetaPoolValue();
- if (currN != NN) {
- std::cerr << "LLVA: Two Pools for one DSNode\n";
- currN->replaceAllUsesWith(NN);
- pdm[currNode]->merge(pdm[NNode]);
- } else {
- //The nodes are same
- }
- */
- }
- }
- }
-#endif
+
// Merge the type entries of the two nodes together...
- if (NH.getNode()->Ty && NH.getNode()->Ty->getTypeID() != Type::VoidTyID)
- CurNodeH.getNode()->mergeTypeInfo(NH.getNode()->Ty, NOffset);
+ 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
@@ -970,6 +433,8 @@
assert(NOffset == 0 && NSize == 1);
}
+
+
DSNode *N = NH.getNode();
if (CurNodeH.getNode() == N || N == 0) return;
assert(!CurNodeH.getNode()->isDeadNode());
@@ -983,9 +448,9 @@
// Make all of the outgoing links of N now be outgoing links of CurNodeH.
//
- for (unsigned i = 0; i < N->getNumLinks(); ++i) {
- DSNodeHandle &Link = N->getLink(i);
- if (Link.getNode()) {
+ 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
@@ -995,10 +460,9 @@
unsigned MergeOffset = 0;
DSNode *CN = CurNodeH.getNode();
if (CN->Size != 1)
- MergeOffset = (i+NOffset) % CN->getSize();
- CN->addEdgeTo(MergeOffset, Link);
+ 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();
@@ -1103,26 +567,15 @@
DN->maskNodeTypes(BitsToKeep);
NH = DN;
//DOUT << "getClonedNH: " << SN << " becomes " << DN << "\n";
-#if 1
-#ifdef LLVA_KERNEL
- //Again we have created a new DSNode, we need to fill in the
- // pool desc map appropriately
- hash_map<const DSNode *, MetaPoolHandle*> &pdm = Dest.getPoolDescriptorsMap();
- if (pdm.count(SN) > 0) {
- pdm[DN] = pdm[SN];
- } else {
- //do nothing
- }
-#endif
-#endif
// Next, recursively clone all outgoing links as necessary. Note that
// adding these links can cause the node to collapse itself at 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 (unsigned i = 0, e = SN->getNumLinks(); i != e; ++i) {
- const DSNodeHandle &SrcEdge = SN->getLink(i);
+ for (DSNode::LinkMapTy::const_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);
// Compute the offset into the current node at which to
@@ -1134,7 +587,7 @@
unsigned MergeOffset = 0;
DSNode *CN = NH.getNode();
if (CN->getSize() != 1)
- MergeOffset = (i + NH.getOffset()) % CN->getSize();
+ MergeOffset = (ii->first + NH.getOffset()) % CN->getSize();
CN->addEdgeTo(MergeOffset, DestEdge);
}
}
@@ -1206,12 +659,15 @@
#endif
}
+ if (DN->getSize() < SN->getSize())
+ DN->growSize(SN->getSize());
+
// Merge the type entries of the two nodes together...
- if ((SN->getType() && SN->getType()->getTypeID() != Type::VoidTyID)
- && !DN->isNodeCompletelyFolded()) {
- DN->mergeTypeInfo(SN->getType(), NH.getOffset() - SrcNH.getOffset());
- DN = NH.getNode();
- }
+ 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());
+
}
assert(!DN->isDeadNode());
@@ -1276,59 +732,14 @@
// DOUT << "LLVA: mergeWith: " << SN << " becomes " << DN << "\n";
-#ifdef LLVA_KERNEL
- //Here some merge is going on just like in DSNode::merge
- //I think because of the inplace merging we don't update the pool desc maps
- //This is modification from DSNode::MergeNodes
- //Here DN and SN may belong to different graphs
- DN = NH.getNode();
-#if 0
- DSGraph *destGraph = DN->getParentGraph();
- DSGraph *srcGraph = SN->getParentGraph();
-#else
- DSGraph *destGraph = NH.getNode()->getParentGraph();
- DSGraph *srcGraph = SN->getParentGraph();
-#endif
- if (destGraph && srcGraph) {
- //get the pooldescriptor map
- hash_map<const DSNode *, MetaPoolHandle*> &destpdm = destGraph->getPoolDescriptorsMap();
- hash_map<const DSNode *, MetaPoolHandle*> &srcpdm = srcGraph->getPoolDescriptorsMap();
- if (destpdm.count(DN) == 0) {
- if (srcpdm.count(SN) == 0) {
- //do nothing (common case)
- } else {
- if (srcpdm[SN]) {
- DEBUG(errs() << "DN becomes " << srcpdm[SN]->getName() << std::endl);
- destpdm[DN] = srcpdm[SN];
- }
- }
- } else {
- if (srcpdm.count(SN) == 0) {
- srcpdm[SN] = destpdm[DN];
- } else {
- if (destpdm[DN] != srcpdm[SN]) {
- srcpdm[SN]->merge(destpdm[DN]);
- /*
- Value *dnv = destpdm[DN]->getMetaPoolValue();
- Value *snv = srcpdm[SN]->getMetaPoolValue();
- if (dnv != snv) {
- DEBUG(std::cerr << "LLVA: Two Pools for one DSNode\n");
- dnv->replaceAllUsesWith(snv);
- destpdm[DN]->setMetaPoolValue(snv);
- }
- */
- }
- }
- }
- }
-#endif
// Next, recursively merge all outgoing links as necessary. Note that
// adding these links can cause the destination node to collapse itself at
// 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 (unsigned i = 0, e = SN->getNumLinks(); i != e; ++i) {
- const DSNodeHandle &SrcEdge = SN->getLink(i);
+ for (DSNode::LinkMapTy::const_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
// merge this link. In the common case, this is a linear
@@ -1337,8 +748,7 @@
// recursive merging, we must make sure to merge in all remaining
// links at offset zero.
DSNode *CN = SCNH.getNode();
- unsigned MergeOffset =
- (i+SCNH.getOffset()) % CN->getSize();
+ unsigned MergeOffset = (ii->first+SCNH.getOffset()) % CN->getSize();
DSNodeHandle Tmp = CN->getLink(MergeOffset);
if (!Tmp.isNull()) {
@@ -1353,7 +763,7 @@
unsigned MergeOffset = 0;
CN = SCNH.getNode();
- MergeOffset = (i + SCNH.getOffset()) %CN->getSize();
+ MergeOffset = (ii->first + SCNH.getOffset()) % CN->getSize();
CN->getLink(MergeOffset).mergeWith(Tmp);
}
}
@@ -1405,53 +815,6 @@
NH = RC.getClonedNH(Src);
}
-#ifdef LLVA_KERNEL
-// MetaPoolHandle Implementation
- //The following should go in a cpp file later
- MetaPoolHandle::MetaPoolHandle(MetaPool *mp, Instruction * Maker) {
- Rep = mp;
- Rep->insert(this);
- Creator = Maker;
- }
- const std::string& MetaPoolHandle::getName() {
- assert(Rep != 0 && "Null meta pool ??\n");
- return Rep->getName();
- }
- Value *MetaPoolHandle::getMetaPoolValue() {
- assert(Rep != 0 && "Null meta pool ??\n");
- return Rep->getMetaPoolValue();
- }
- void MetaPoolHandle::merge(MetaPoolHandle *other) {
- //after this operation other points to what this points to .
- //first replace all uses
- Value *dest = getMetaPoolValue();
- Value *curr = other->getMetaPoolValue();
- if (dest != curr) {
- std::cerr << "LLVA: Merging metapools: " << this->Creator->getParent()->getParent()->getName() << " : " << other->Creator->getParent()->getParent()->getName() << "\n"
- << "LLVA: " << *(this->Creator) << "\n"
- << "LLVA: " << *(other->Creator) << "\n";
- curr->replaceAllUsesWith(dest);
- }
-
- //merge the hash sets in to other
- hash_set<MetaPoolHandle *> &otherHandleSet = other->getMetaPool()->getHandleSet();
- hash_set<MetaPoolHandle *>::iterator ohsI = otherHandleSet.begin(), ohsE = otherHandleSet.end();
- for (; ohsI != ohsE; ++ohsI) {
- MetaPoolHandle *omph = *ohsI;
- //now make sure that this omph points to what we point to
- omph->setMetaPool(Rep);
- Rep->insert(omph);
- }
-
- //now delete others MetaPool
- //gd delete other->getMetaPool();
-
- //Assign our metapool to other
- other->setMetaPool(Rep);
-}
-
-#endif
-
//===----------------------------------------------------------------------===//
// DSGraph Implementation
//===----------------------------------------------------------------------===//
@@ -1502,12 +865,13 @@
/// specified mapping.
///
void DSNode::remapLinks(DSGraph::NodeMapTy &OldNodeMap) {
- for (unsigned i = 0, e = Links.size(); i != e; ++i)
- if (DSNode *N = Links[i].getNode()) {
+ for (LinkMapTy::iterator ii = edge_begin(), ee = edge_end();
+ ii != ee; ++ii)
+ if (DSNode *N = ii->second.getNode()) {
DSGraph::NodeMapTy::const_iterator ONMI = OldNodeMap.find(N);
if (ONMI != OldNodeMap.end()) {
DSNode *ONMIN = ONMI->second.getNode();
- Links[i].setTo(ONMIN, Links[i].getOffset()+ONMI->second.getOffset());
+ ii->second.setTo(ONMIN, ii->second.getOffset()+ONMI->second.getOffset());
}
}
}
@@ -1534,8 +898,7 @@
/// and does not point to any other objects in the graph.
DSNode *DSGraph::addObjectToGraph(Value *Ptr, bool UseDeclaredType) {
assert(isa<PointerType>(Ptr->getType()) && "Ptr is not a pointer!");
- const Type *Ty = cast<PointerType>(Ptr->getType())->getElementType();
- DSNode *N = new DSNode(UseDeclaredType ? Ty : 0, this);
+ DSNode *N = new DSNode(this);
assert(ScalarMap[Ptr].isNull() && "Object already in this graph!");
ScalarMap[Ptr] = N;
@@ -1758,7 +1121,7 @@
bool AnyDirectSuccessorsReachClonedNodes = false;
for (DSNode::const_edge_iterator EI = N->edge_begin(), EE = N->edge_end();
EI != EE; ++EI)
- if (DSNode *Succ = EI->getNode()) {
+ if (DSNode *Succ = EI->second.getNode()) {
std::pair<unsigned, bool> &SuccInfo = VisitForSCCs(Succ);
if (SuccInfo.first < Min) Min = SuccInfo.first;
AnyDirectSuccessorsReachClonedNodes |= SuccInfo.second;
@@ -1778,7 +1141,7 @@
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->getNode())
+ if (DSNode *N = EI->second.getNode())
if (NodeInfo[N].second) {
AnyDirectSuccessorsReachClonedNodes = true;
goto OutOfLoop;
@@ -1872,7 +1235,7 @@
DSNode *GlobalNode = Graph.getNodeForValue(*GI).getNode();
for (DSNode::edge_iterator EI = GlobalNode->edge_begin(),
EE = GlobalNode->edge_end(); EI != EE; ++EI)
- if (SCCFinder.PathExistsToClonedNode(EI->getNode())) {
+ if (SCCFinder.PathExistsToClonedNode(EI->second.getNode())) {
GlobalsToCopy.push_back(*GI);
break;
}
@@ -1961,7 +1324,7 @@
// Recursively process children...
for (DSNode::edge_iterator I = N->edge_begin(),E = N->edge_end(); I != E; ++I)
- if (DSNode *DSN = I->getNode())
+ if (DSNode *DSN = I->second.getNode())
markIncompleteNode(DSN);
}
@@ -2037,9 +1400,9 @@
if (DSNode * N = Edge.getNode()) // Is there an edge?
if (N->getNumReferrers() == 1) // Does it point to a lonely node?
// No interesting info?
- if ((N->getNodeFlags() & ~DSNode::IncompleteNode) == 0 &&
- (!N->getType() || N->getType()->getTypeID() == Type::VoidTyID)
- && !N->isNodeCompletelyFolded())
+ if ((N->getNodeFlags() & ~DSNode::IncompleteNode) == 0
+ && N->type_begin() == N->type_end()
+ && !N->isNodeCompletelyFolded())
Edge.setTo(0, 0); // Kill the edge!
}
@@ -2288,16 +1651,16 @@
/// DSNodes, marking any nodes which are reachable. All reachable nodes it adds
/// to the set, which allows it to only traverse visited nodes once.
///
-void DSNode::markReachableNodes(std::set<const DSNode*> &ReachableNodes) const {
+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?
for (DSNode::const_edge_iterator I = edge_begin(), E = edge_end();
I != E; ++I)
- I->getNode()->markReachableNodes(ReachableNodes);
+ I->second.getNode()->markReachableNodes(ReachableNodes);
}
-void DSCallSite::markReachableNodes(std::set<const DSNode*> &Nodes) const {
+void DSCallSite::markReachableNodes(DenseSet<const DSNode*> &Nodes) const {
getRetVal().getNode()->markReachableNodes(Nodes);
if (isIndirectCall()) getCalleeNode()->markReachableNodes(Nodes);
@@ -2310,8 +1673,8 @@
// true, otherwise return false. If an alive node is reachable, this node is
// marked as alive...
//
-static bool CanReachAliveNodes(DSNode *N, std::set<const DSNode*> &Alive,
- std::set<const DSNode*> &Visited,
+static bool CanReachAliveNodes(DSNode *N, DenseSet<const DSNode*> &Alive,
+ DenseSet<const DSNode*> &Visited,
bool IgnoreGlobals) {
if (N == 0) return false;
assert(N->getForwardNode() == 0 && "Cannot mark a forwarded node!");
@@ -2329,7 +1692,7 @@
Visited.insert(N); // No recursion, insert into Visited...
for (DSNode::edge_iterator I = N->edge_begin(),E = N->edge_end(); I != E; ++I)
- if (CanReachAliveNodes(I->getNode(), Alive, Visited, IgnoreGlobals)) {
+ if (CanReachAliveNodes(I->second.getNode(), Alive, Visited, IgnoreGlobals)) {
N->markReachableNodes(Alive);
return true;
}
@@ -2340,8 +1703,8 @@
// alive nodes.
//
static bool CallSiteUsesAliveArgs(const DSCallSite &CS,
- std::set<const DSNode*> &Alive,
- std::set<const DSNode*> &Visited,
+ DenseSet<const DSNode*> &Alive,
+ DenseSet<const DSNode*> &Visited,
bool IgnoreGlobals) {
if (CanReachAliveNodes(CS.getRetVal().getNode(), Alive, Visited,
IgnoreGlobals))
@@ -2372,7 +1735,7 @@
// FIXME: Merge non-trivially identical call nodes...
// Alive - a set that holds all nodes found to be reachable/alive.
- std::set<const DSNode*> Alive;
+ DenseSet<const DSNode*> Alive;
std::vector<std::pair<const Value*, DSNode*> > GlobalNodes;
// Copy and merge all information about globals to the GlobalsGraph if this is
@@ -2420,7 +1783,7 @@
// value (which makes them live in turn), and continue till no more are found.
//
bool Iterate;
- std::set<const DSNode*> Visited;
+ DenseSet<const DSNode*> Visited;
std::set<const DSCallSite*> AuxFCallsAlive;
do {
Visited.clear();
@@ -2849,7 +2212,7 @@
bool MadeChange = false;
for (DSScalarMap::global_iterator GI = SM.global_begin(), E = SM.global_end();
GI != E; ) {
- const GlobalValue *GV = *GI++;
+ const GlobalValue *GV = *GI; ++GI;
if (!ECGlobals.count(GV)) continue;
const DSNodeHandle &GVNH = SM[GV];
Modified: poolalloc/trunk/lib/DSA/Local.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/Local.cpp?rev=98062&r1=98061&r2=98062&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/Local.cpp (original)
+++ poolalloc/trunk/lib/DSA/Local.cpp Tue Mar 9 10:48:35 2010
@@ -18,6 +18,7 @@
#include "llvm/DerivedTypes.h"
#include "llvm/Instructions.h"
#include "llvm/Intrinsics.h"
+#include "llvm/InlineAsm.h"
#include "llvm/Support/GetElementPtrTypeIterator.h"
#include "llvm/Support/InstVisitor.h"
#include "llvm/Target/TargetData.h"
@@ -28,7 +29,6 @@
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/DenseSet.h"
-#include <iostream>
#include <fstream>
// FIXME: This should eventually be a FunctionPass that is automatically
@@ -56,6 +56,7 @@
DSGraph &G;
Function* FB;
DataStructures* DS;
+ const TargetData& TD;
////////////////////////////////////////////////////////////////////////////
// Helper functions used to implement the visitation functions...
@@ -65,9 +66,9 @@
/// createNode - Create a new DSNode, ensuring that it is properly added to
/// the graph.
///
- DSNode *createNode(const Type *Ty = 0)
+ DSNode *createNode()
{
- DSNode* ret = new DSNode(Ty, &G);
+ DSNode* ret = new DSNode(&G);
assert(ret->getParentGraph() && "No parent?");
return ret;
}
@@ -92,6 +93,17 @@
// Visitor functions, used to handle each instruction type we encounter...
friend class InstVisitor<GraphBuilder>;
+ //TODO: generalize
+ bool visitAllocation(CallSite CS) {
+ if (Function* F = CS.getCalledFunction()) {
+ if (F->hasName() && F->getName() == "malloc") {
+ setDestTo(*CS.getInstruction(), createNode()->setHeapMarker());
+ return true;
+ }
+ }
+ return false;
+ }
+
//FIXME: implement in stdlib pass
// void visitMallocInst(MallocInst &MI)
// { setDestTo(MI, createNode()->setHeapMarker()); }
@@ -130,7 +142,7 @@
public:
GraphBuilder(Function &f, DSGraph &g, DataStructures& DSi)
- : G(g), FB(&f), DS(&DSi) {
+ : G(g), FB(&f), DS(&DSi), TD(g.getTargetData()) {
// Create scalar nodes for all pointer arguments...
for (Function::arg_iterator I = f.arg_begin(), E = f.arg_end();
I != E; ++I) {
@@ -172,7 +184,7 @@
// GraphBuilder ctor for working on the globals graph
explicit GraphBuilder(DSGraph& g)
- :G(g), FB(0)
+ :G(g), FB(0), TD(g.getTargetData())
{}
void mergeInGlobalInitializer(GlobalVariable *GV);
@@ -196,8 +208,8 @@
visited.insert(N);
N->setUnknownMarker();
for (DSNode::edge_iterator I = N->edge_begin(), E = N->edge_end(); I != E; ++I)
- if (!I->isNull())
- workList.push_back(I->getNode());
+ if (!I->second.isNull())
+ workList.push_back(I->second.getNode());
}
}
}
@@ -224,7 +236,7 @@
DSNode* N;
if (GlobalVariable* GV = dyn_cast<GlobalVariable>(V)) {
// Create a new global node for this global variable.
- N = createNode(GV->getType()->getElementType());
+ N = createNode();
N->addGlobal(GV);
if (GV->isDeclaration())
N->setExternGlobalMarker();
@@ -247,7 +259,7 @@
NH = G.getNodeForValue(CE);
} else {
// This returns a conservative unknown node for any unhandled ConstExpr
- return NH = createNode()->setUnknownMarker();
+ NH = createNode()->setUnknownMarker();
}
if (NH.isNull()) { // (getelementptr null, X) returns null
G.eraseNodeForValue(V);
@@ -263,7 +275,7 @@
// not handle the aliases of parameters correctly. Here is only a quick
// fix for some special cases.
NH = getValueDest(cast<GlobalAlias>(C)->getAliasee());
- return 0;
+ return NH;
} else {
errs() << "Unknown constant: " << *C << "\n";
assert(0 && "Unknown constant type!");
@@ -340,7 +352,7 @@
Ptr.getNode()->setReadMarker();
// Ensure a typerecord exists...
- Ptr.getNode()->mergeTypeInfo(LI.getType(), Ptr.getOffset(), false);
+ Ptr.getNode()->mergeTypeInfo(LI.getType(), Ptr.getOffset());
if (isa<PointerType>(LI.getType()))
setDestTo(LI, getLink(Ptr));
@@ -377,7 +389,7 @@
// Ensure a type record exists.
DSNode *PtrN = Ptr.getNode();
- PtrN->mergeTypeInfo(I.getType(), Ptr.getOffset(), false);
+ PtrN->mergeTypeInfo(I.getType(), Ptr.getOffset());
if (isa<PointerType>(I.getType()))
setDestTo(I, getLink(Ptr));
@@ -433,7 +445,7 @@
// Ensure a typerecord exists...
// FIXME: calculate offset
- Ptr.getNode()->mergeTypeInfo(I.getType(), 0, false);
+ Ptr.getNode()->mergeTypeInfo(I.getType(), 0);
if (isa<PointerType>(I.getType()))
setDestTo(I, getLink(Ptr));
@@ -464,18 +476,11 @@
return;
}
-
- const PointerType *PTy = cast<PointerType>(GEP.getOperand(0)->getType());
+ //Make sure the uncollapsed node has a large enough size for the struct type
+ const PointerType *PTy = cast<PointerType > (GEP.getOperand(0)->getType());
const Type *CurTy = PTy->getElementType();
-
- if (Value.getNode()->mergeTypeInfo(CurTy, Value.getOffset())) {
- // If the node had to be folded... exit quickly
- setDestTo(GEP, Value); // GEP result points to folded node
-
- return;
- }
-
- const TargetData &TD = Value.getNode()->getTargetData();
+ if (TD.getTypeAllocSize(CurTy) + Value.getOffset() > Value.getNode()->getSize())
+ Value.getNode()->growSize(TD.getTypeAllocSize(CurTy) + Value.getOffset());
#if 0
// Handle the pointer index specially...
@@ -511,12 +516,7 @@
I != E; ++I)
if (const StructType *STy = dyn_cast<StructType>(*I)) {
const ConstantInt* CUI = cast<ConstantInt>(I.getOperand());
-#if 0
- unsigned FieldNo =
- CUI->getType()->isSigned() ? CUI->getSExtValue() : CUI->getZExtValue();
-#else
int FieldNo = CUI->getSExtValue();
-#endif
Offset += (unsigned)TD.getStructLayout(STy)->getElementOffset(FieldNo);
} else if (isa<PointerType>(*I)) {
if (!isa<Constant>(I.getOperand()) ||
@@ -556,7 +556,7 @@
#endif
// Add in the offset calculated...
- Value.setOffset(Value.getOffset()+Offset);
+ Value.setOffset(Value.getOffset()+Offset);
// Check the offset
DSNode *N = Value.getNode();
@@ -577,20 +577,6 @@
// Value is now the pointer we want to GEP to be...
setDestTo(GEP, Value);
-#if 0
- if (debug && (isa<Instruction>(GEP))) {
- Instruction * IGEP = (Instruction *)(&GEP);
- DSNode * N = Value.getNode();
- if (IGEP->getParent()->getParent()->getName() == "alloc_vfsmnt")
- {
- if (G.getPoolDescriptorsMap().count(N) != 0)
- if (G.getPoolDescriptorsMap()[N]) {
- DEBUG(errs() << "LLVA: GEP[" << 0 << "]: Pool for " << GEP.getName() << " is " << G.getPoolDescriptorsMap()[N]->getName() << "\n");
- }
- }
- }
-#endif
-
}
@@ -753,6 +739,16 @@
if (F->isIntrinsic() && visitIntrinsic(CS, F))
return;
+ if (visitAllocation(CS))
+ return;
+
+ if (isa<InlineAsm>(CS.getCalledValue())) return;
+// if (InlineAsm* IASM = dyn_cast<InlineAsm>(CS.getCalledValue())) {
+// if (IASM->hasSideEffects())
+// errs() << ASM w/ Side Effects\n";
+// return;
+// }
+
// Set up the return value...
DSNodeHandle RetVal;
Instruction *I = CS.getInstruction();
@@ -826,8 +822,6 @@
if (Ty->isIntOrIntVectorTy() || Ty->isFPOrFPVectorTy()) return;
- const TargetData &TD = NH.getNode()->getTargetData();
-
if (ConstantArray *CA = dyn_cast<ConstantArray>(C)) {
for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i)
// We don't currently do any indexing for arrays...
Modified: poolalloc/trunk/lib/DSA/Printer.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/Printer.cpp?rev=98062&r1=98061&r2=98062&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/Printer.cpp (original)
+++ poolalloc/trunk/lib/DSA/Printer.cpp Tue Mar 9 10:48:35 2010
@@ -60,11 +60,20 @@
if (N->isNodeCompletelyFolded())
OS << "COLLAPSED";
else {
- if (N->getType())
- WriteTypeSymbolic(OS, N->getType(), M);
+ if (N->type_begin() != N->type_end())
+ 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 << ", ";
+ }
+ OS << " ";
+ }
else
OS << "VOID";
- if (N->isArray())
+ if (N->isArrayNode())
OS << " array";
}
if (unsigned NodeType = N->getNodeFlags()) {
@@ -137,6 +146,11 @@
return O != 0;
}
+ static std::string getEdgeSourceLabel(const void* Node,
+ DSNode::const_iterator I) {
+ return "*";
+ }
+
static DSNode::const_iterator getEdgeTarget(const DSNode *Node,
DSNode::const_iterator I) {
unsigned O = I.getNode()->getLink(I.getOffset()).getOffset();
Modified: poolalloc/trunk/lib/DSA/TopDownClosure.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/DSA/TopDownClosure.cpp?rev=98062&r1=98061&r2=98062&view=diff
==============================================================================
--- poolalloc/trunk/lib/DSA/TopDownClosure.cpp (original)
+++ poolalloc/trunk/lib/DSA/TopDownClosure.cpp Tue Mar 9 10:48:35 2010
@@ -58,8 +58,9 @@
if (!N || Visited.count(N)) return;
Visited.insert(N);
- for (unsigned i = 0, e = N->getNumLinks(); i != e; ++i) {
- DSNodeHandle &NH = N->getLink(i);
+ for (DSNode::LinkMapTy::iterator ii = N->edge_begin(),
+ ee = N->edge_end(); ii != ee; ++ii) {
+ DSNodeHandle &NH = ii->second;
if (DSNode *NN = NH.getNode()) {
std::vector<const Function*> Functions;
NN->addFullFunctionList(Functions);
More information about the llvm-commits
mailing list