[llvm-commits] CVS: llvm/lib/Analysis/DataStructure/DataStructure.cpp
Chris Lattner
lattner at cs.uiuc.edu
Mon Nov 18 15:45:02 PST 2002
Changes in directory llvm/lib/Analysis/DataStructure:
DataStructure.cpp updated: 1.67 -> 1.68
---
Log message:
Add peak memory usage measurement stuff
Add structure padding optimizations
---
Diffs of the changes:
Index: llvm/lib/Analysis/DataStructure/DataStructure.cpp
diff -u llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.67 llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.68
--- llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.67 Tue Nov 12 01:20:45 2002
+++ llvm/lib/Analysis/DataStructure/DataStructure.cpp Mon Nov 18 15:44:46 2002
@@ -11,6 +11,7 @@
#include "llvm/Target/TargetData.h"
#include "Support/STLExtras.h"
#include "Support/Statistic.h"
+#include "Support/Timer.h"
#include <algorithm>
#include <set>
@@ -77,7 +78,8 @@
++NumFolds;
// We are no longer typed at all...
- Ty = DSTypeRec(Type::VoidTy, true);
+ Ty = Type::VoidTy;
+ NodeType |= Array;
Size = 1;
// Loop over all of our referrers, making them point to our zero bytes of
@@ -97,7 +99,7 @@
/// all of the field sensitivity that may be present in the node.
///
bool DSNode::isNodeCompletelyFolded() const {
- return getSize() == 1 && Ty.Ty == Type::VoidTy && Ty.isArray;
+ return getSize() == 1 && Ty == Type::VoidTy && isArray();
}
@@ -117,15 +119,15 @@
// 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)) &&
+ assert(((Size == 0 && Ty == Type::VoidTy && !isArray()) ||
+ (Size == 0 && !Ty->isSized() && !isArray()) ||
+ (Size == 1 && Ty == Type::VoidTy && isArray()) ||
+ (Size == 0 && !Ty->isSized() && !isArray()) ||
+ (TD.getTypeSize(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)
+ 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.
@@ -150,13 +152,14 @@
// we can't, we fold the node completely, if we can, we potentially update our
// internal state.
//
- if (Ty.Ty == Type::VoidTy) {
+ if (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 && "This shouldn't happen!");
- Ty.Ty = NewTy;
- Ty.isArray = WillBeArray;
+ assert(!isArray() && "This shouldn't happen!");
+ Ty = NewTy;
+ NodeType &= ~Array;
+ if (WillBeArray) NodeType |= Array;
Size = NewTySize;
// Calculate the number of outgoing links from this node.
@@ -168,7 +171,7 @@
if (Offset+NewTySize > Size) {
// It is illegal to grow this node if we have treated it as an array of
// objects...
- if (Ty.isArray) {
+ if (isArray()) {
foldNodeCompletely();
return true;
}
@@ -186,9 +189,10 @@
// 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;
- Ty.Ty = NewTy;
- Ty.isArray = WillBeArray;
+ const Type *OldTy = Ty;
+ Ty = NewTy;
+ NodeType &= ~Array;
+ if (WillBeArray) NodeType |= Array;
Size = NewTySize;
// Must grow links to be the appropriate size...
@@ -202,11 +206,11 @@
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
+ // 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.Ty;
+ const Type *SubType = Ty;
while (O < Offset) {
assert(Offset-O < TD.getTypeSize(SubType) && "Offset out of range!");
@@ -247,17 +251,27 @@
// composite type...
//
unsigned SubTypeSize = SubType->isSized() ? TD.getTypeSize(SubType) : 0;
+ 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->getPrimitiveID()) {
- case Type::StructTyID:
- NextSubType = cast<StructType>(SubType)->getElementTypes()[0];
- NextSubTypeSize = TD.getTypeSize(SubType);
+ case Type::StructTyID: {
+ const StructType *STy = cast<StructType>(SubType);
+ const StructLayout &SL = *TD.getStructLayout(STy);
+ if (SL.MemberOffsets.size() > 1)
+ NextPadSize = SL.MemberOffsets[1];
+ else
+ NextPadSize = SubTypeSize;
+ NextSubType = STy->getElementTypes()[0];
+ NextSubTypeSize = TD.getTypeSize(NextSubType);
break;
+ }
case Type::ArrayTyID:
NextSubType = cast<ArrayType>(SubType)->getElementType();
- NextSubTypeSize = TD.getTypeSize(SubType);
+ NextSubTypeSize = TD.getTypeSize(NextSubType);
+ NextPadSize = NextSubTypeSize;
break;
default: ;
// fall out
@@ -266,10 +280,11 @@
if (NextSubType == 0)
break; // In the default case, break out of the loop
- if (NextSubTypeSize < NewTySize)
+ if (NextPadSize < NewTySize)
break; // Don't allow shrinking to a smaller type than NewTySize
SubType = NextSubType;
SubTypeSize = NextSubTypeSize;
+ PadSize = NextPadSize;
}
// If we found the type exactly, return it...
@@ -288,11 +303,14 @@
if (SubType->isInteger() && isa<PointerType>(NewTy) ||
NewTy->isInteger() && isa<PointerType>(SubType))
return false;
-
+ } else if (NewTySize > SubTypeSize && NewTySize <= PadSize) {
+ // We are accessing the field, plus some structure padding. Ignore the
+ // structure padding.
+ return false;
}
- DEBUG(std::cerr << "MergeTypeInfo Folding OrigTy: " << Ty.Ty
+ DEBUG(std::cerr << "MergeTypeInfo Folding OrigTy: " << Ty
<< "\n due to:" << NewTy << " @ " << Offset << "!\n"
<< "SubType: " << SubType << "\n\n");
@@ -322,8 +340,8 @@
// duplicates are not allowed and both are sorted. This assumes that 'T's are
// efficiently copyable and have sane comparison semantics.
//
-template<typename T>
-void MergeSortedVectors(vector<T> &Dest, const vector<T> &Src) {
+static void MergeSortedVectors(vector<GlobalValue*> &Dest,
+ const vector<GlobalValue*> &Src) {
// By far, the most common cases will be the simple ones. In these cases,
// avoid having to allocate a temporary vector...
//
@@ -332,22 +350,22 @@
} else if (Dest.empty()) { // Just copy the result in...
Dest = Src;
} else if (Src.size() == 1) { // Insert a single element...
- const T &V = Src[0];
- typename vector<T>::iterator I =
+ const GlobalValue *V = Src[0];
+ vector<GlobalValue*>::iterator I =
std::lower_bound(Dest.begin(), Dest.end(), V);
if (I == Dest.end() || *I != Src[0]) // If not already contained...
Dest.insert(I, Src[0]);
} else if (Dest.size() == 1) {
- T Tmp = Dest[0]; // Save value in temporary...
+ GlobalValue *Tmp = Dest[0]; // Save value in temporary...
Dest = Src; // Copy over list...
- typename vector<T>::iterator I =
+ vector<GlobalValue*>::iterator I =
std::lower_bound(Dest.begin(), Dest.end(), Tmp);
if (I == Dest.end() || *I != Tmp) // If not already contained...
Dest.insert(I, Tmp);
} else {
// Make a copy to the side of Dest...
- vector<T> Old(Dest);
+ vector<GlobalValue*> Old(Dest);
// Make space for all of the type entries now...
Dest.resize(Dest.size()+Src.size());
@@ -407,8 +425,8 @@
unsigned NSize = N->getSize();
// Merge the type entries of the two nodes together...
- if (N->Ty.Ty != Type::VoidTy) {
- mergeTypeInfo(N->Ty.Ty, NOffset);
+ if (N->Ty != Type::VoidTy) {
+ mergeTypeInfo(N->Ty, NOffset);
// mergeTypeInfo can cause collapsing, which can cause this node to become
// dead.
@@ -423,14 +441,14 @@
if (!N->isNodeCompletelyFolded()) {
N->foldNodeCompletely();
if (hasNoReferrers()) return;
- NSize = N->getSize();
+ NSize = N->getSize();
}
} else if (N->isNodeCompletelyFolded()) {
foldNodeCompletely();
if (hasNoReferrers()) return;
Offset = 0;
NOffset = NH.getOffset();
- NSize = N->getSize();
+ NSize = N->getSize();
}
N = NH.getNode();
if (this == N || N == 0) return;
@@ -464,15 +482,17 @@
// 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!
//
- if (Size == 0) return;
+ if (Size == 0)
+ return; // Node is now dead
+ if (Size == 1)
+ break; // Node got collapsed
}
}
// Now that there are no outgoing edges, all of the Links are dead.
N->Links.clear();
N->Size = 0;
- N->Ty.Ty = Type::VoidTy;
- N->Ty.isArray = false;
+ N->Ty = Type::VoidTy;
// Merge the node types
NodeType |= N->NodeType;
@@ -569,6 +589,10 @@
OldNodeMap[Old] = New;
}
+#ifndef NDEBUG
+ Timer::addPeakMemoryMeasurement();
+#endif
+
// Rewrite the links in the new nodes to point into the current graph now.
for (unsigned i = FN, e = Nodes.size(); i != e; ++i)
Nodes[i]->remapLinks(OldNodeMap);
@@ -786,7 +810,7 @@
if (DSNode *N = Edge.getNode()) // Is there an edge?
if (N->getReferrers().size() == 1) // Does it point to a lonely node?
if ((N->NodeType & ~DSNode::Incomplete) == 0 && // No interesting info?
- N->getType().Ty == Type::VoidTy && !N->isNodeCompletelyFolded())
+ N->getType() == Type::VoidTy && !N->isNodeCompletelyFolded())
Edge.setNode(0); // Kill the edge!
}
More information about the llvm-commits
mailing list