[llvm-commits] CVS: llvm/lib/Analysis/DataStructure/DataStructure.cpp Local.cpp Printer.cpp
Chris Lattner
lattner at cs.uiuc.edu
Wed Nov 6 00:21:00 PST 2002
Changes in directory llvm/lib/Analysis/DataStructure:
DataStructure.cpp updated: 1.42 -> 1.43
Local.cpp updated: 1.27 -> 1.28
Printer.cpp updated: 1.32 -> 1.33
---
Log message:
Dramatically simplify internal DSNode representation, get implementation
*FULLY OPERATIONAL* and safe. We are now capable of completely analyzing
at LEAST the Olden benchmarks + 181.mcf
---
Diffs of the changes:
Index: llvm/lib/Analysis/DataStructure/DataStructure.cpp
diff -u llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.42 llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.43
--- llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.42 Mon Nov 4 18:01:58 2002
+++ llvm/lib/Analysis/DataStructure/DataStructure.cpp Wed Nov 6 00:20:09 2002
@@ -16,6 +16,15 @@
using std::vector;
+namespace {
+ Statistic<> NumFolds("dsnode", "Number of nodes completely folded");
+};
+
+namespace DS {
+ const unsigned PointerShift = 3; // 64bit ptrs = 3, 32 bit ptrs = 2
+ const unsigned PointerSize = 1 << PointerShift;
+};
+
namespace DataStructureAnalysis { // TODO: FIXME
// isPointerType - Return true if this first class type is big enough to hold
// a pointer.
@@ -29,15 +38,16 @@
// DSNode Implementation
//===----------------------------------------------------------------------===//
-DSNode::DSNode(enum NodeTy NT, const Type *T) : NodeType(NT) {
+DSNode::DSNode(enum NodeTy NT, const Type *T)
+ : Ty(Type::VoidTy), Size(0), NodeType(NT) {
// Add the type entry if it is specified...
- if (T) getTypeRec(T, 0);
+ if (T) mergeTypeInfo(T, 0);
}
// DSNode copy constructor... do not copy over the referrers list!
DSNode::DSNode(const DSNode &N)
- : Links(N.Links), MergeMap(N.MergeMap),
- TypeEntries(N.TypeEntries), Globals(N.Globals), NodeType(N.NodeType) {
+ : Links(N.Links), Globals(N.Globals), Ty(N.Ty), Size(N.Size),
+ NodeType(N.NodeType) {
}
void DSNode::removeReferrer(DSNodeHandle *H) {
@@ -70,229 +80,234 @@
/// single byte with a single TypeEntry of "void".
///
void DSNode::foldNodeCompletely() {
+ if (isNodeCompletelyFolded()) return;
+
+ ++NumFolds;
+
// We are no longer typed at all...
- TypeEntries.clear();
- TypeEntries.push_back(DSTypeRec(Type::VoidTy, 0));
+ Ty = DSTypeRec(Type::VoidTy, true);
+ Size = 1;
- // Loop over all of our referrers, making them point to our one byte of space.
+ // Loop over all of our referrers, making them point to our zero bytes of
+ // space.
for (vector<DSNodeHandle*>::iterator I = Referrers.begin(), E=Referrers.end();
I != E; ++I)
(*I)->setOffset(0);
- // Fold the MergeMap down to a single byte of space...
- MergeMap.resize(1);
-
// If we have links, merge all of our outgoing links together...
- if (!Links.empty()) {
- MergeMap[0] = 0; // We now contain an outgoing edge...
- for (unsigned i = 1, e = Links.size(); i != e; ++i)
- Links[0].mergeWith(Links[i]);
- Links.resize(1);
- } else {
- MergeMap[0] = -1;
- }
+ for (unsigned i = 1, e = Links.size(); i < e; ++i)
+ Links[0].mergeWith(Links[i]);
+ Links.resize(1);
}
-
/// isNodeCompletelyFolded - Return true if this node has been completely
/// folded down to something that can never be expanded, effectively losing
/// all of the field sensitivity that may be present in the node.
///
bool DSNode::isNodeCompletelyFolded() const {
- return getSize() == 1 && TypeEntries.size() == 1 &&
- TypeEntries[0].Ty == Type::VoidTy;
+ return getSize() == 1 && Ty.Ty == Type::VoidTy && Ty.isArray;
}
-
-/// setLink - Set the link at the specified offset to the specified
-/// NodeHandle, replacing what was there. It is uncommon to use this method,
-/// instead one of the higher level methods should be used, below.
+/// 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
+/// this information is already known, or it may merge the node completely (and
+/// return true) if the information is incompatible with what is already known.
///
-void DSNode::setLink(unsigned i, const DSNodeHandle &NH) {
- // Create a new entry in the Links vector to hold a new element for offset.
- if (!hasLink(i)) {
- signed char NewIdx = Links.size();
- // Check to see if we allocate more than 128 distinct links for this node.
- // If so, just merge with the last one. This really shouldn't ever happen,
- // but it should work regardless of whether it does or not.
+/// This method returns true if the node is completely folded, otherwise false.
+///
+bool DSNode::mergeTypeInfo(const Type *NewTy, unsigned Offset) {
+ // 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
+ //
+ assert(((Size == 0 && Ty.Ty == Type::VoidTy && !Ty.isArray) ||
+ (Size == 0 && !Ty.Ty->isSized() && !Ty.isArray) ||
+ (Size == 1 && Ty.Ty == Type::VoidTy && Ty.isArray) ||
+ (Size == 0 && !Ty.Ty->isSized() && !Ty.isArray) ||
+ (TD.getTypeSize(Ty.Ty) == Size)) &&
+ "Size member of DSNode doesn't match the type structure!");
+ assert(NewTy != Type::VoidTy && "Cannot merge void type into DSNode!");
+
+ if (Offset == 0 && NewTy == Ty.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;
+
+ // Figure out how big the new type we're merging in is...
+ unsigned NewTySize = NewTy->isSized() ? TD.getTypeSize(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.Ty == Type::VoidTy) {
+ // If this is the first type that this node has seen, just accept it without
+ // question....
+ assert(Offset == 0 && "Cannot have an offset into a void node!");
+ assert(Ty.isArray == false && "This shouldn't happen!");
+ Ty.Ty = NewTy;
+ Size = NewTySize;
+
+ // Calculate the number of outgoing links from this node.
+ Links.resize((Size+DS::PointerSize-1) >> DS::PointerShift);
+ 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 (Ty.isArray) {
+ foldNodeCompletely();
+ return true;
+ }
+
+ if (Offset) { // We could handle this case, but we don't for now...
+ std::cerr << "UNIMP: Trying to merge a growth type into offset != 0: "
+ << "Collapsing!\n";
+ 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.
//
- if (NewIdx >= 0) {
- Links.push_back(NH); // Allocate space: common case
- } else { // Wrap around? Too many links?
- NewIdx--; // Merge with whatever happened last
- assert(NewIdx > 0 && "Should wrap back around");
- std::cerr << "\n*** DSNode found that requires more than 128 "
- << "active links at once!\n\n";
- }
-
- signed char OldIdx = MergeMap[i];
- assert (OldIdx < 0 && "Shouldn't contain link!");
-
- // Make sure that anything aliasing this field gets updated to point to the
- // new link field.
- rewriteMergeMap(OldIdx, NewIdx);
- assert(MergeMap[i] == NewIdx && "Field not replaced!");
- } else {
- assert(MergeMap[i] < (int)Links.size() && "MergeMap index out of range!");
- Links[MergeMap[i]] = NH;
- }
-}
+ const Type *OldTy = Ty.Ty;
+ Ty.Ty = NewTy;
+ Size = NewTySize;
-// addEdgeTo - Add an edge from the current node to the specified node. This
-// can cause merging of nodes in the graph.
-//
-void DSNode::addEdgeTo(unsigned Offset, const DSNodeHandle &NH) {
- assert(Offset < getSize() && "Offset out of range!");
- if (NH.getNode() == 0) return; // Nothing to do
+ // Must grow links to be the appropriate size...
+ Links.resize((Size+DS::PointerSize-1) >> DS::PointerShift);
- if (DSNodeHandle *ExistingNH = getLink(Offset)) {
- // Merge the two nodes...
- ExistingNH->mergeWith(NH);
- } else { // No merging to perform...
- setLink(Offset, NH); // Just force a link in there...
+ // Merge in the old type now... which is guaranteed to be smaller than the
+ // "current" type.
+ return mergeTypeInfo(OldTy, 0);
}
-}
-/// getTypeRec - This method returns the specified type record if it exists.
-/// If it does not yet exist, the method checks to see whether or not the
-/// request would result in an untrackable state. If adding it would cause
-/// untrackable state, we foldNodeCompletely the node and return the void
-/// record, otherwise we add an new TypeEntry and return it.
-///
-DSTypeRec &DSNode::getTypeRec(const Type *Ty, unsigned Offset) {
- // If the node is already collapsed, we can't do anything... bail out early
- if (isNodeCompletelyFolded()) {
- assert(TypeEntries.size() == 1 && "Node folded and Entries.size() != 1?");
- return TypeEntries[0];
+ assert(Offset < Size &&
+ "Cannot merge something into a part of our type that doesn't exist!");
+
+ // Find the section of Ty.Ty that NewTy overlaps with... first we find the
+ // type that starts at offset Offset.
+ //
+ unsigned O = 0;
+ const Type *SubType = Ty.Ty;
+ while (O < Offset) {
+ assert(Offset-O < TD.getTypeSize(SubType) && "Offset out of range!");
+
+ switch (SubType->getPrimitiveID()) {
+ case Type::StructTyID: {
+ const StructType *STy = cast<StructType>(SubType);
+ const StructLayout &SL = *TD.getStructLayout(STy);
+
+ unsigned i = 0, e = SL.MemberOffsets.size();
+ for (; i+1 < e && SL.MemberOffsets[i+1] <= Offset-O; ++i)
+ /* empty */;
+
+ // The offset we are looking for must be in the i'th element...
+ SubType = STy->getElementTypes()[i];
+ O += SL.MemberOffsets[i];
+ break;
+ }
+ case Type::ArrayTyID: {
+ SubType = cast<ArrayType>(SubType)->getElementType();
+ unsigned ElSize = TD.getTypeSize(SubType);
+ unsigned Remainder = (Offset-O) % ElSize;
+ O = Offset-Remainder;
+ break;
+ }
+ default:
+ assert(0 && "Unknown type!");
+ }
}
- // First search to see if we already have a record for this...
- DSTypeRec SearchFor(Ty, Offset);
+ assert(O == Offset && "Could not achieve the correct offset!");
- std::vector<DSTypeRec>::iterator I;
- if (TypeEntries.size() < 5) { // Linear search if we have few entries.
- I = TypeEntries.begin();
- while (I != TypeEntries.end() && *I < SearchFor)
- ++I;
- } else {
- I = std::lower_bound(TypeEntries.begin(), TypeEntries.end(), SearchFor);
- }
-
- // At this point, I either points to the right entry or it points to the entry
- // we are to insert the new entry in front of...
- //
- if (I != TypeEntries.end() && *I == SearchFor)
- return *I;
-
- // ASSUME that it's okay to add this type entry.
- // FIXME: This should check to make sure it's ok.
-
- // If the data size is different then our current size, try to resize the node
- unsigned ReqSize = Ty->isSized() ? TD.getTypeSize(Ty) : 0;
- if (getSize() < ReqSize) {
- // If we are trying to make it bigger, and we can grow the node, do so.
- if (growNode(ReqSize)) {
- assert(isNodeCompletelyFolded() && "Node isn't folded?");
- return TypeEntries[0];
- }
+ // If we found our type exactly, early exit
+ if (SubType == NewTy) return false;
- } else if (getSize() > ReqSize) {
- // If we are trying to make the node smaller, we don't have to do anything.
+ // 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 SubTypeSize = TD.getTypeSize(SubType);
+ while (SubType != NewTy) {
+ const Type *NextSubType = 0;
+ unsigned NextSubTypeSize;
+ switch (SubType->getPrimitiveID()) {
+ case Type::StructTyID:
+ NextSubType = cast<StructType>(SubType)->getElementTypes()[0];
+ NextSubTypeSize = TD.getTypeSize(SubType);
+ break;
+ case Type::ArrayTyID:
+ NextSubType = cast<ArrayType>(SubType)->getElementType();
+ NextSubTypeSize = TD.getTypeSize(SubType);
+ break;
+ default: ;
+ // fall out
+ }
- }
+ if (NextSubType == 0)
+ break; // In the default case, break out of the loop
- return *TypeEntries.insert(I, SearchFor);
-}
+ if (NextSubTypeSize < NewTySize)
+ break; // Don't allow shrinking to a smaller type than NewTySize
+ SubType = NextSubType;
+ SubTypeSize = NextSubTypeSize;
+ }
+
+ // If we found the type exactly, return it...
+ if (SubType == NewTy)
+ return false;
+
+ // Check to see if we have a compatible, but different type...
+ if (NewTySize == SubTypeSize) {
+ // Check to see if this type is obviously convertable... int -> uint f.e.
+ if (NewTy->isLosslesslyConvertableTo(SubType))
+ return false;
-/// growNode - Attempt to grow the node to the specified size. This may do one
-/// of three things:
-/// 1. Grow the node, return false
-/// 2. Refuse to grow the node, but maintain a trackable situation, return
-/// false.
-/// 3. Be unable to track if node was that size, so collapse the node and
-/// return true.
-///
-bool DSNode::growNode(unsigned ReqSize) {
- unsigned OldSize = getSize();
+ // Check to see if we have a pointer & integer mismatch going on here,
+ // loading a pointer as a long, for example.
+ //
+ if (SubType->isInteger() && isa<PointerType>(NewTy) ||
+ NewTy->isInteger() && isa<PointerType>(SubType))
+ return false;
- if (0) {
- // FIXME: DSNode::growNode() doesn't perform correct safety checks yet!
-
- foldNodeCompletely();
- return true;
}
- assert(ReqSize > OldSize && "Not growing node!");
- // Resize the merge map to have enough space...
- MergeMap.resize(ReqSize);
- // Assign unique values to all of the elements of MergeMap
- if (ReqSize < 128) {
- // Handle the common case of reasonable size structures...
- for (unsigned i = OldSize; i != ReqSize; ++i)
- MergeMap[i] = -1-i; // Assign -1, -2, -3, ...
- } else {
- // It's possible that we have something really big here. In this case,
- // divide the object into chunks until it will fit into 128 elements.
- unsigned Multiple = ReqSize/128;
-
- // It's probably an array, and probably some power of two in size.
- // Because of this, find the biggest power of two that is bigger than
- // multiple to use as our real Multiple.
- unsigned RealMultiple = 2;
- while (RealMultiple <= Multiple) RealMultiple <<= 1;
-
- unsigned RealBound = ReqSize/RealMultiple;
- assert(RealBound <= 128 && "Math didn't work out right");
-
- // Now go through and assign indexes that are between -1 and -128
- // inclusive
- //
- for (unsigned i = OldSize; i != ReqSize; ++i)
- MergeMap[i] = -1-(i % RealBound); // Assign -1, -2, -3...
- }
- return false;
+ std::cerr << "MergeTypeInfo Folding OrigTy: " << Ty.Ty
+ << "\n due to:" << NewTy << " @ " << Offset << "!\n";
+ std::cerr << "SubType: " << SubType << "\n\n";
+
+ foldNodeCompletely();
+ return true;
}
-/// mergeMappedValues - This is the higher level form of rewriteMergeMap. It is
-/// fully capable of merging links together if neccesary as well as simply
-/// rewriting the map entries.
-///
-void DSNode::mergeMappedValues(signed char V1, signed char V2) {
- assert(V1 != V2 && "Cannot merge two identical mapped values!");
- assert(V2 < (int)Links.size() &&
- "Attempting to rewrite to invalid link number!");
- assert(V1 < (int)Links.size() &&
- "Attempting to rewrite to invalid link number!");
-
- if (V1 < 0) { // If there is no outgoing link from V1, merge it with V2
- if (V2 < 0 && V1 > V2)
- // If both are not linked, merge to the field closer to 0
- rewriteMergeMap(V2, V1);
- else
- rewriteMergeMap(V1, V2);
- } else if (V2 < 0) { // Is V2 < 0 && V1 >= 0?
- rewriteMergeMap(V2, V1); // Merge into the one with the link...
- } else { // Otherwise, links exist at both locations
- // Merge the V2 link into V1 so that we reduce the overall value of the
- // links are reduced...
- //
- if (V2 < V1) std::swap(V1, V2); // Ensure V1 < V2
- rewriteMergeMap(V2, V1); // After this, V2 is "dead"
- // Merge Links[V1] with Links[V2] so they point to the same place now...
- Links[V1].mergeWith(Links[V2]); // BROKEN, this can invalidate V2!!
- // Change the user of the last link to use V2 instead
- if ((unsigned)V2 != Links.size()-1) {
- rewriteMergeMap(Links.size()-1, V2); // Point to V2 instead of last el...
- // Make sure V2 points the right DSNode
- Links[V2] = Links.back();
- }
+// addEdgeTo - Add an edge from the current node to the specified node. This
+// can cause merging of nodes in the graph.
+//
+void DSNode::addEdgeTo(unsigned Offset, const DSNodeHandle &NH) {
+ if (NH.getNode() == 0) return; // Nothing to do
- // Reduce the number of distinct outgoing links...
- Links.pop_back();
+ DSNodeHandle &ExistingEdge = getLink(Offset);
+ if (ExistingEdge.getNode()) {
+ // Merge the two nodes...
+ ExistingEdge.mergeWith(NH);
+ } else { // No merging to perform...
+ setLink(Offset, NH); // Just force a link in there...
}
}
@@ -354,11 +369,17 @@
return; // Noop
if (N == this) {
- std::cerr << "WARNING: Cannot merge two portions of the same node yet, so we collapse instead!\n";
- N->foldNodeCompletely();
+ // We cannot merge two pieces of the same node together, collapse the node
+ // completely.
+ std::cerr << "Attempting to merge two chunks of the same node together!\n";
+ foldNodeCompletely();
return;
}
+ // Merge the type entries of the two nodes together...
+ if (N->Ty.Ty != Type::VoidTy)
+ mergeTypeInfo(N->Ty.Ty, Offset);
+
// If we are merging a node with a completely folded node, then both nodes are
// now completely folded.
//
@@ -396,15 +417,6 @@
// respect to NH.Offset) is now zero.
//
unsigned NOffset = NH.getOffset()-Offset;
-
- // If our destination node is too small... try to grow it.
- if (N->getSize()+NOffset > getSize() &&
- growNode(N->getSize()+NOffset)) {
- // Catastrophic failure occured and we had to collapse the node. In this
- // case, collapse the other node as well.
- N->foldNodeCompletely();
- NOffset = 0;
- }
unsigned NSize = N->getSize();
// Remove all edges pointing at N, causing them to point to 'this' instead.
@@ -418,71 +430,29 @@
// Make all of the outgoing links of N now be outgoing links of this. This
// can cause recursive merging!
//
- for (unsigned i = 0, e = NSize; i != e; ++i)
- if (DSNodeHandle *Link = N->getLink(i)) {
- addEdgeTo((i+NOffset) % getSize(), *Link);
- N->MergeMap[i] = -1; // Kill outgoing edge
- }
-
-#if 0
- // We must merge fields in this node due to nodes merged in the source node.
- // In order to handle this we build a map that converts from the source node's
- // MergeMap values to our MergeMap values. This map is indexed by the
- // expression: MergeMap[SMM+SourceNodeSize] so we need to allocate at least
- // 2*SourceNodeSize elements of space for the mapping. We can do this because
- // we know that there are at most SourceNodeSize outgoing links in the node
- // (thus that many positive values) and at most SourceNodeSize distinct fields
- // (thus that many negative values).
- //
- std::vector<signed char> MergeMapMap(NSize*2, 127);
-
- // Loop through the structures, merging them together...
- for (unsigned i = 0, e = NSize; i != e; ++i) {
- // Get what this byte of N maps to...
- signed char NElement = N->MergeMap[i];
-
- // Get what we map this byte to...
- signed char Element = MergeMap[i+NOffset];
- assert(Element < (int)Links.size() && "Element in merge map out of range!");
-
- // We use 127 as a sentinal and don't check for it's existence yet...
- assert(Element != 127 && "MergeMapMap doesn't permit 127 values yet!");
-
- signed char CurMappedVal = MergeMapMap[NElement+NSize];
- if (CurMappedVal == 127) { // Haven't seen this NElement yet?
- MergeMapMap[NElement+NSize] = Element; // Map the two together...
- } else if (CurMappedVal != Element) {
- // If we are mapping two different fields together this means that we need
- // to merge fields in the current node due to merging in the source node.
+ for (unsigned i = 0; i < NSize; i += DS::PointerSize) {
+ DSNodeHandle &Link = N->getLink(i);
+ if (Link.getNode()) {
+ addEdgeTo((i+NOffset) % getSize(), Link);
+
+ // It's possible that after adding the new edge that some recursive
+ // merging just occured, causing THIS node to get merged into oblivion.
+ // If that happens, we must not try to merge any more edges into it!
//
- mergeMappedValues(CurMappedVal, Element);
- MergeMapMap[NElement+NSize] = MergeMap[i+NOffset];
- assert(MergeMap[i+NOffset] < (int)Links.size()
- && "Element in merge map out of range!");
+ if (Size == 0) return;
}
}
-#endif
// Now that there are no outgoing edges, all of the Links are dead.
N->Links.clear();
- N->MergeMap.clear();
+ N->Size = 0;
+ N->Ty.Ty = Type::VoidTy;
+ N->Ty.isArray = false;
// Merge the node types
NodeType |= N->NodeType;
N->NodeType = 0; // N is now a dead node.
- // Adjust all of the type entries we are merging in by the offset...
- //
- if (NOffset != 0) { // This case is common enough to optimize for
- // Offset all of the TypeEntries in N with their new offset
- for (unsigned i = 0, e = N->TypeEntries.size(); i != e; ++i)
- N->TypeEntries[i].Offset += NOffset;
- }
-
- // ... now add them to the TypeEntries list.
- MergeSortedVectors(TypeEntries, N->TypeEntries);
- N->TypeEntries.clear(); // N is dead, no type-entries need exist
-
// Merge the globals list...
if (!N->Globals.empty()) {
MergeSortedVectors(Globals, N->Globals);
@@ -564,7 +534,6 @@
DSNodeHandle DSGraph::cloneInto(const DSGraph &G,
std::map<Value*, DSNodeHandle> &OldValMap,
std::map<const DSNode*, DSNode*> &OldNodeMap,
- bool StripScalars, // FIXME: Kill StripScalars
bool StripAllocas) {
assert(OldNodeMap.empty() && "Returned OldNodeMap should be empty!");
@@ -655,9 +624,9 @@
N->NodeType |= DSNode::Incomplete;
// Recusively process children...
- for (unsigned i = 0, e = N->getSize(); i != e; ++i)
- if (DSNodeHandle *DSNH = N->getLink(i))
- markIncompleteNode(DSNH->getNode());
+ for (unsigned i = 0, e = N->getSize(); i < e; i += DS::PointerSize)
+ if (DSNode *DSN = N->getLink(i).getNode())
+ markIncompleteNode(DSN);
}
@@ -694,9 +663,9 @@
if (Nodes[i]->NodeType & DSNode::GlobalNode) {
DSNode *N = Nodes[i];
// FIXME: Make more efficient by looking over Links directly
- for (unsigned i = 0, e = N->getSize(); i != e; ++i)
- if (DSNodeHandle *DSNH = N->getLink(i))
- markIncompleteNode(DSNH->getNode());
+ for (unsigned i = 0, e = N->getSize(); i < e; i += DS::PointerSize)
+ if (DSNode *DSN = N->getLink(i).getNode())
+ markIncompleteNode(DSN);
}
}
@@ -772,11 +741,10 @@
if (N == 0) return;
Alive.insert(N);
- // FIXME: Make more efficient by looking over Links directly
- for (unsigned i = 0, e = N->getSize(); i != e; ++i)
- if (DSNodeHandle *DSNH = N->getLink(i))
- if (!Alive.count(DSNH->getNode()))
- markAlive(DSNH->getNode(), Alive);
+ for (unsigned i = 0, e = N->getSize(); i < e; i += DS::PointerSize)
+ if (DSNode *DSN = N->getLink(i).getNode())
+ if (!Alive.count(DSN))
+ markAlive(DSN, Alive);
}
static bool checkGlobalAlive(DSNode *N, std::set<DSNode*> &Alive,
@@ -787,17 +755,17 @@
Visiting.insert(N);
// If any immediate successor is alive, N is alive
- for (unsigned i = 0, e = N->getSize(); i != e; ++i)
- if (DSNodeHandle *DSNH = N->getLink(i))
- if (Alive.count(DSNH->getNode())) {
+ for (unsigned i = 0, e = N->getSize(); i < e; i += DS::PointerSize)
+ if (DSNode *DSN = N->getLink(i).getNode())
+ if (Alive.count(DSN)) {
Visiting.erase(N);
return true;
}
// Else if any successor reaches a live node, N is alive
- for (unsigned i = 0, e = N->getSize(); i != e; ++i)
- if (DSNodeHandle *DSNH = N->getLink(i))
- if (checkGlobalAlive(DSNH->getNode(), Alive, Visiting)) {
+ for (unsigned i = 0, e = N->getSize(); i < e; i += DS::PointerSize)
+ if (DSNode *DSN = N->getLink(i).getNode())
+ if (checkGlobalAlive(DSN, Alive, Visiting)) {
Visiting.erase(N); return true;
}
Index: llvm/lib/Analysis/DataStructure/Local.cpp
diff -u llvm/lib/Analysis/DataStructure/Local.cpp:1.27 llvm/lib/Analysis/DataStructure/Local.cpp:1.28
--- llvm/lib/Analysis/DataStructure/Local.cpp:1.27 Sun Nov 3 15:27:48 2002
+++ llvm/lib/Analysis/DataStructure/Local.cpp Wed Nov 6 00:20:09 2002
@@ -184,13 +184,12 @@
///
DSNodeHandle &GraphBuilder::getLink(const DSNodeHandle &node, unsigned LinkNo) {
DSNodeHandle &Node = const_cast<DSNodeHandle&>(node);
- DSNodeHandle *Link = Node.getLink(LinkNo);
- if (Link) return *Link;
-
- // If the link hasn't been created yet, make and return a new shadow node
- DSNode *N = createNode(DSNode::ShadowNode);
- Node.setLink(LinkNo, N);
- return *Node.getLink(LinkNo);
+ DSNodeHandle &Link = Node.getLink(LinkNo);
+ if (!Link.getNode()) {
+ // If the link hasn't been created yet, make and return a new shadow node
+ Link = createNode(DSNode::ShadowNode);
+ }
+ return Link;
}
@@ -236,15 +235,14 @@
unsigned Offset = 0;
const PointerType *PTy = cast<PointerType>(GEP.getOperand(0)->getType());
const Type *CurTy = PTy->getElementType();
- DSTypeRec &TopTypeRec =
- Value.getNode()->getTypeRec(PTy->getElementType(), Value.getOffset());
- // If the node had to be folded... exit quickly
- if (TopTypeRec.Ty == Type::VoidTy) {
+ 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;
}
+#if 0
// Handle the pointer index specially...
if (GEP.getNumOperands() > 1 &&
GEP.getOperand(1) != ConstantSInt::getNullValue(Type::LongTy)) {
@@ -269,6 +267,7 @@
}
}
}
+#endif
// All of these subscripts are indexing INTO the elements we have...
for (unsigned i = 2, e = GEP.getNumOperands(); i < e; ++i)
@@ -276,6 +275,7 @@
// Get the type indexing into...
const SequentialType *STy = cast<SequentialType>(CurTy);
CurTy = STy->getElementType();
+#if 0
if (ConstantSInt *CS = dyn_cast<ConstantSInt>(GEP.getOperand(i))) {
Offset += CS->getValue()*TD.getTypeSize(CurTy);
} else {
@@ -298,6 +298,7 @@
N->mergeIndexes(RawOffset+j, RawOffset+i*ElSize+j);
}
}
+#endif
} else if (GEP.getOperand(i)->getType() == Type::UByteTy) {
unsigned FieldNo = cast<ConstantUInt>(GEP.getOperand(i))->getValue();
const StructType *STy = cast<StructType>(CurTy);
@@ -320,7 +321,7 @@
Ptr.getNode()->NodeType |= DSNode::Read;
// Ensure a typerecord exists...
- Ptr.getNode()->getTypeRec(LI.getType(), Ptr.getOffset());
+ Ptr.getNode()->mergeTypeInfo(LI.getType(), Ptr.getOffset());
if (isPointerType(LI.getType()))
setDestTo(LI, getLink(Ptr));
@@ -335,7 +336,7 @@
Dest.getNode()->NodeType |= DSNode::Modified;
// Ensure a typerecord exists...
- Dest.getNode()->getTypeRec(StoredTy, Dest.getOffset());
+ Dest.getNode()->mergeTypeInfo(StoredTy, Dest.getOffset());
// Avoid adding edges from null, or processing non-"pointer" stores
if (isPointerType(StoredTy))
Index: llvm/lib/Analysis/DataStructure/Printer.cpp
diff -u llvm/lib/Analysis/DataStructure/Printer.cpp:1.32 llvm/lib/Analysis/DataStructure/Printer.cpp:1.33
--- llvm/lib/Analysis/DataStructure/Printer.cpp:1.32 Sun Nov 3 15:27:48 2002
+++ llvm/lib/Analysis/DataStructure/Printer.cpp Wed Nov 6 00:20:09 2002
@@ -27,23 +27,25 @@
std::stringstream OS;
Module *M = G && &G->getFunction() ? G->getFunction().getParent() : 0;
- for (unsigned i = 0, e = N->getTypeEntries().size(); i != e; ++i) {
- WriteTypeSymbolic(OS, N->getTypeEntries()[i].Ty, M);
- if (N->getTypeEntries()[i].Offset)
- OS << "@" << N->getTypeEntries()[i].Offset;
- if (N->getTypeEntries()[i].isArray)
+ if (N->isNodeCompletelyFolded())
+ OS << "FOLDED";
+ else {
+ WriteTypeSymbolic(OS, N->getType().Ty, M);
+ if (N->getType().isArray)
OS << " array";
+ }
+ if (N->NodeType) {
+ OS << ": ";
+ if (N->NodeType & DSNode::AllocaNode ) OS << "S";
+ if (N->NodeType & DSNode::HeapNode ) OS << "H";
+ if (N->NodeType & DSNode::GlobalNode ) OS << "G";
+ if (N->NodeType & DSNode::UnknownNode) OS << "U";
+ if (N->NodeType & DSNode::Incomplete ) OS << "I";
+ if (N->NodeType & DSNode::Modified ) OS << "M";
+ if (N->NodeType & DSNode::Read ) OS << "R";
OS << "\n";
}
- if (N->NodeType & DSNode::AllocaNode ) OS << "S";
- if (N->NodeType & DSNode::HeapNode ) OS << "H";
- if (N->NodeType & DSNode::GlobalNode ) OS << "G";
- if (N->NodeType & DSNode::UnknownNode) OS << "U";
- if (N->NodeType & DSNode::Incomplete ) OS << "I";
- if (N->NodeType & DSNode::Modified ) OS << "M";
- if (N->NodeType & DSNode::Read ) OS << "R";
-
for (unsigned i = 0, e = N->getGlobals().size(); i != e; ++i) {
WriteAsOperand(OS, N->getGlobals()[i], false, true, M);
OS << "\n";
@@ -75,11 +77,6 @@
return "shape=Mrecord";//fontname=Courier";
}
- static int getEdgeSourceLabel(const DSNode *Node, DSNode::iterator I) {
- assert(Node == I.getNode() && "Iterator not for this node!");
- return Node->getMergeMapLabel(I.getOffset());
- }
-
/// addCustomGraphFeatures - Use this graph writing hook to emit call nodes
/// and the return node.
///
@@ -95,7 +92,7 @@
GW.emitSimpleNode(I->first, "plaintext=circle", OS.str());
// Add edge from return node to real destination
- int EdgeDest = I->second.getOffset();
+ int EdgeDest = I->second.getOffset() >> DS::PointerShift;
if (EdgeDest == 0) EdgeDest = -1;
GW.emitEdge(I->first, -1, I->second.getNode(),
EdgeDest, "arrowtail=tee,color=gray63");
@@ -108,7 +105,7 @@
GW.emitSimpleNode((void*)1, "plaintext=circle", "returning");
// Add edge from return node to real destination
- int RetEdgeDest = G->getRetNode().getOffset();
+ int RetEdgeDest = G->getRetNode().getOffset() >> DS::PointerShift;;
if (RetEdgeDest == 0) RetEdgeDest = -1;
GW.emitEdge((void*)1, -1, G->getRetNode().getNode(),
RetEdgeDest, "arrowtail=tee,color=gray63");
@@ -121,18 +118,18 @@
GW.emitSimpleNode(&Call, "shape=record", "call", Call.getNumPtrArgs()+2);
if (DSNode *N = Call.getRetVal().getNode()) {
- int EdgeDest = Call.getRetVal().getOffset();
+ int EdgeDest = Call.getRetVal().getOffset() >> DS::PointerShift;
if (EdgeDest == 0) EdgeDest = -1;
GW.emitEdge(&Call, 0, N, EdgeDest, "color=gray63");
}
if (DSNode *N = Call.getCallee().getNode()) {
- int EdgeDest = Call.getCallee().getOffset();
+ int EdgeDest = Call.getCallee().getOffset() >> DS::PointerShift;
if (EdgeDest == 0) EdgeDest = -1;
GW.emitEdge(&Call, 1, N, EdgeDest, "color=gray63");
}
for (unsigned j = 0, e = Call.getNumPtrArgs(); j != e; ++j)
if (DSNode *N = Call.getPtrArg(j).getNode()) {
- int EdgeDest = Call.getPtrArg(j).getOffset();
+ int EdgeDest = Call.getPtrArg(j).getOffset() >> DS::PointerShift;
if (EdgeDest == 0) EdgeDest = -1;
GW.emitEdge(&Call, j+2, N, EdgeDest, "color=gray63");
}
More information about the llvm-commits
mailing list