[llvm-commits] CVS: llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp DataStructure.cpp DataStructureAA.cpp Local.cpp Printer.cpp TopDownClosure.cpp
John Criswell
criswell at choi.cs.uiuc.edu
Thu Jun 26 16:43:04 PDT 2003
Changes in directory llvm/lib/Analysis/DataStructure:
BottomUpClosure.cpp updated: 1.52 -> 1.52.2.1
DataStructure.cpp updated: 1.98 -> 1.98.2.1
DataStructureAA.cpp updated: 1.3 -> 1.3.2.1
Local.cpp updated: 1.52 -> 1.52.2.1
Printer.cpp updated: 1.51 -> 1.51.2.1
TopDownClosure.cpp updated: 1.40 -> 1.40.2.1
---
Log message:
Merged with mainline on Thursday, June 26, 2003.
---
Diffs of the changes:
Index: llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp
diff -u llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.52 llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.52.2.1
--- llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.52 Wed Feb 5 15:59:56 2003
+++ llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp Thu Jun 26 16:35:10 2003
@@ -33,7 +33,7 @@
// if the call sites are not external.
//
static inline bool isCompleteNode(DSNode *N) {
- if (N->NodeType & DSNode::Incomplete) return false;
+ if (N->isIncomplete()) return false;
const std::vector<GlobalValue*> &Callees = N->getGlobals();
for (unsigned i = 0, e = Callees.size(); i != e; ++i)
if (Callees[i]->isExternal())
Index: llvm/lib/Analysis/DataStructure/DataStructure.cpp
diff -u llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.98 llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.98.2.1
--- llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.98 Tue May 20 13:45:31 2003
+++ llvm/lib/Analysis/DataStructure/DataStructure.cpp Thu Jun 26 16:35:10 2003
@@ -49,8 +49,8 @@
// DSNode Implementation
//===----------------------------------------------------------------------===//
-DSNode::DSNode(unsigned NT, const Type *T, DSGraph *G)
- : NumReferrers(0), Size(0), ParentGraph(G), Ty(Type::VoidTy), NodeType(NT) {
+DSNode::DSNode(const Type *T, DSGraph *G)
+ : NumReferrers(0), Size(0), ParentGraph(G), Ty(Type::VoidTy), NodeType(0) {
// Add the type entry if it is specified...
if (T) mergeTypeInfo(T, 0);
G->getNodes().push_back(this);
@@ -107,14 +107,13 @@
/// single byte with a single TypeEntry of "void".
///
void DSNode::foldNodeCompletely() {
- assert(!hasNoReferrers() &&
- "Why would we collapse a node with no referrers?");
if (isNodeCompletelyFolded()) return; // If this node is already folded...
++NumFolds;
// Create the node we are going to forward to...
- DSNode *DestNode = new DSNode(NodeType|DSNode::Array, 0, ParentGraph);
+ DSNode *DestNode = new DSNode(0, ParentGraph);
+ DestNode->NodeType = NodeType|DSNode::Array;
DestNode->Ty = Type::VoidTy;
DestNode->Size = 1;
DestNode->Globals.swap(Globals);
@@ -448,7 +447,7 @@
// Merge the type entries of the two nodes together...
if (NH.getNode()->Ty != Type::VoidTy)
CurNodeH.getNode()->mergeTypeInfo(NH.getNode()->Ty, NOffset);
- assert((CurNodeH.getNode()->NodeType & DSNode::DEAD) == 0);
+ assert(!CurNodeH.getNode()->isDeadNode());
// If we are merging a node with a completely folded node, then both nodes are
// now completely folded.
@@ -473,12 +472,14 @@
DSNode *N = NH.getNode();
if (CurNodeH.getNode() == N || N == 0) return;
- assert((CurNodeH.getNode()->NodeType & DSNode::DEAD) == 0);
+ assert(!CurNodeH.getNode()->isDeadNode());
- // Start forwarding to the new node!
+ // Merge the NodeType information...
CurNodeH.getNode()->NodeType |= N->NodeType;
+
+ // Start forwarding to the new node!
N->forwardNode(CurNodeH.getNode(), NOffset);
- assert((CurNodeH.getNode()->NodeType & DSNode::DEAD) == 0);
+ assert(!CurNodeH.getNode()->isDeadNode());
// Make all of the outgoing links of N now be outgoing links of CurNodeH.
//
@@ -524,8 +525,7 @@
if (N == 0 || (N == this && NH.getOffset() == Offset))
return; // Noop
- assert((N->NodeType & DSNode::DEAD) == 0);
- assert((NodeType & DSNode::DEAD) == 0);
+ assert(!N->isDeadNode() && !isDeadNode());
assert(!hasNoReferrers() && "Should not try to fold a useless node!");
if (N == this) {
@@ -632,13 +632,13 @@
Nodes.reserve(FN+G.Nodes.size());
// Remove alloca or mod/ref bits as specified...
- unsigned clearBits = (CloneFlags & StripAllocaBit ? DSNode::AllocaNode : 0)
- | (CloneFlags & StripModRefBits ? (DSNode::Modified | DSNode::Read) : 0);
- clearBits |= DSNode::DEAD; // Clear dead flag...
+ unsigned BitsToClear =((CloneFlags & StripAllocaBit) ? DSNode::AllocaNode : 0)
+ | ((CloneFlags & StripModRefBits) ? (DSNode::Modified | DSNode::Read) : 0);
+ BitsToClear |= DSNode::DEAD; // Clear dead flag...
for (unsigned i = 0, e = G.Nodes.size(); i != e; ++i) {
DSNode *Old = G.Nodes[i];
DSNode *New = new DSNode(*Old, this);
- New->NodeType &= ~clearBits;
+ New->maskNodeTypes(~BitsToClear);
OldNodeMap[Old] = New;
}
@@ -745,16 +745,16 @@
// markIncompleteNodes - Mark the specified node as having contents that are not
// known with the current analysis we have performed. Because a node makes all
-// of the nodes it can reach imcomplete if the node itself is incomplete, we
+// of the nodes it can reach incomplete if the node itself is incomplete, we
// must recursively traverse the data structure graph, marking all reachable
// nodes as incomplete.
//
static void markIncompleteNode(DSNode *N) {
// Stop recursion if no node, or if node already marked...
- if (N == 0 || (N->NodeType & DSNode::Incomplete)) return;
+ if (N == 0 || (N->isIncomplete())) return;
// Actually mark the node
- N->NodeType |= DSNode::Incomplete;
+ N->setIncompleteMarker();
// Recusively process children...
for (unsigned i = 0, e = N->getSize(); i < e; i += DS::PointerSize)
@@ -800,14 +800,15 @@
// Mark all global nodes as incomplete...
if ((Flags & DSGraph::IgnoreGlobals) == 0)
for (unsigned i = 0, e = Nodes.size(); i != e; ++i)
- if (Nodes[i]->NodeType & DSNode::GlobalNode && Nodes[i]->getNumLinks())
+ if (Nodes[i]->isGlobalNode() && Nodes[i]->getNumLinks())
markIncompleteNode(Nodes[i]);
}
static inline void killIfUselessEdge(DSNodeHandle &Edge) {
if (DSNode *N = Edge.getNode()) // Is there an edge?
if (N->getNumReferrers() == 1) // Does it point to a lonely node?
- if ((N->NodeType & ~DSNode::Incomplete) == 0 && // No interesting info?
+ // No interesting info?
+ if ((N->getNodeFlags() & ~DSNode::Incomplete) == 0 &&
N->getType() == Type::VoidTy && !N->isNodeCompletelyFolded())
Edge.setNode(0); // Kill the edge!
}
@@ -837,7 +838,7 @@
// If the Callee is a useless edge, this must be an unreachable call site,
// eliminate it.
if (CS.isIndirectCall() && CS.getCalleeNode()->getNumReferrers() == 1 &&
- CS.getCalleeNode()->NodeType == 0) { // No useful info?
+ CS.getCalleeNode()->getNodeFlags() == 0) { // No useful info?
std::cerr << "WARNING: Useless call site found??\n";
CS.swap(Calls.back());
Calls.pop_back();
@@ -916,8 +917,7 @@
for (unsigned i = 0; i != Nodes.size(); ++i) {
DSNode *Node = Nodes[i];
- if (!(Node->NodeType & ~(DSNode::Composition | DSNode::Array |
- DSNode::DEAD))) {
+ if (!Node->isIncomplete() && !Node->isModified() && !Node->isRead()) {
// This is a useless node if it has no mod/ref info (checked above),
// outgoing edges (which it cannot, as it is not modified in this
// context), and it has no incoming edges. If it is a global node it may
@@ -925,7 +925,7 @@
// scalar map, so we check those now.
//
if (Node->getNumReferrers() == Node->getGlobals().size()) {
- std::vector<GlobalValue*> &Globals = Node->getGlobals();
+ const std::vector<GlobalValue*> &Globals = Node->getGlobals();
// Loop through and make sure all of the globals are referring directly
// to the node...
@@ -934,20 +934,16 @@
assert(N == Node && "ScalarMap doesn't match globals list!");
}
- // Make sure numreferrers still agrees, if so, the node is truely dead.
+ // Make sure NumReferrers still agrees, if so, the node is truly dead.
if (Node->getNumReferrers() == Globals.size()) {
for (unsigned j = 0, e = Globals.size(); j != e; ++j)
ScalarMap.erase(Globals[j]);
-
- Globals.clear();
- assert(Node->hasNoReferrers() && "Shouldn't have refs now!");
-
- Node->NodeType = DSNode::DEAD;
+ Node->makeNodeDead();
}
}
}
- if ((Node->NodeType & ~DSNode::DEAD) == 0 && Node->hasNoReferrers()) {
+ if (Node->getNodeFlags() == 0 && Node->hasNoReferrers()) {
// This node is dead!
delete Node; // Free memory...
Nodes[i--] = Nodes.back();
@@ -1057,7 +1053,7 @@
// these, prune the scalar pointing to it.
//
DSNode *N = I->second.getNode();
- if (N->NodeType == DSNode::UnknownNode && !isa<Argument>(I->first)) {
+ if (N->isUnknownNode() && !isa<Argument>(I->first)) {
ScalarMap.erase(I++);
} else {
I->second.getNode()->markReachableNodes(Alive);
@@ -1130,7 +1126,7 @@
GlobalsGraph->Nodes.push_back(N); // Move node to globals graph
N->setParentGraph(GlobalsGraph);
} else { // Otherwise, delete the node
- assert(((N->NodeType & DSNode::GlobalNode) == 0 ||
+ assert((!N->isGlobalNode() ||
(Flags & DSGraph::RemoveUnreachableGlobals))
&& "Killing a global?");
//std::cerr << "[" << i+1 << "/" << DeadNodes.size()
@@ -1191,7 +1187,7 @@
assert(I->second.getNode() && "Null node in scalarmap!");
AssertNodeInGraph(I->second.getNode());
if (GlobalValue *GV = dyn_cast<GlobalValue>(I->first)) {
- assert((I->second.getNode()->NodeType & DSNode::GlobalNode) &&
+ assert(I->second.getNode()->isGlobalNode() &&
"Global points to node, but node isn't global?");
AssertNodeContainsGlobal(I->second.getNode(), GV);
}
Index: llvm/lib/Analysis/DataStructure/DataStructureAA.cpp
diff -u llvm/lib/Analysis/DataStructure/DataStructureAA.cpp:1.3 llvm/lib/Analysis/DataStructure/DataStructureAA.cpp:1.3.2.1
--- llvm/lib/Analysis/DataStructure/DataStructureAA.cpp:1.3 Wed Feb 26 13:29:36 2003
+++ llvm/lib/Analysis/DataStructure/DataStructureAA.cpp Thu Jun 26 16:35:10 2003
@@ -68,15 +68,12 @@
// alias - This is the only method here that does anything interesting...
AliasAnalysis::AliasResult DSAA::alias(const Value *V1, unsigned V1Size,
const Value *V2, unsigned V2Size) {
- // FIXME: This should handle the Size argument as well!
+ if (V1 == V2) return MustAlias;
+
const Function *F1 = getValueFunction(V1);
const Function *F2 = getValueFunction(V2);
assert((!F1 || !F2 || F1 == F2) && "Alias query for 2 different functions?");
-
- // FIXME: This can return must alias if querying a DSNode for a global value
- // where the node has only the G composition bit set, and only one entry in
- // the globals list...
if (F2) F1 = F2;
if (F1) {
// Get the graph for a function...
@@ -88,17 +85,33 @@
hash_map<Value*, DSNodeHandle>::iterator J = GSM.find((Value*)V2);
if (J != GSM.end()) {
assert(J->second.getNode() && "Scalar map points to null node?");
- if (I->second.getNode() != J->second.getNode()) {
- // Return noalias if one of the nodes is complete...
- if ((~I->second.getNode()->NodeType | ~J->second.getNode()->NodeType)
- & DSNode::Incomplete)
- return NoAlias;
- // both are incomplete, they may alias...
- } else {
- // Both point to the same node, see if they point to different
- // offsets... FIXME: This needs to know the size of the alias query
- if (I->second.getOffset() != J->second.getOffset())
- return NoAlias;
+
+ DSNode *N1 = I->second.getNode(), *N2 = J->second.getNode();
+ unsigned O1 = I->second.getOffset(), O2 = J->second.getOffset();
+
+ // We can only make a judgement of one of the nodes is complete...
+ if (!N1->isIncomplete() || !N2->isIncomplete()) {
+ if (N1 != N2)
+ return NoAlias; // Completely different nodes.
+
+ // Both point to the same node and same offset, and there is only one
+ // physical memory object represented in the node, return must alias.
+ //if (O1 == O2 && !N1->isMultiObject())
+ // return MustAlias; // Exactly the same object & offset
+
+ // See if they point to different offsets... if so, we may be able to
+ // determine that they do not alias...
+ if (O1 != O2) {
+ if (O2 < O1) { // Ensure that O1 <= O2
+ std::swap(V1, V2);
+ std::swap(O1, O2);
+ std::swap(V1Size, V2Size);
+ }
+
+ // FIXME: This is not correct because we do not handle array
+ // indexing correctly with this check!
+ //if (O1+V1Size <= O2) return NoAlias;
+ }
}
}
}
Index: llvm/lib/Analysis/DataStructure/Local.cpp
diff -u llvm/lib/Analysis/DataStructure/Local.cpp:1.52 llvm/lib/Analysis/DataStructure/Local.cpp:1.52.2.1
--- llvm/lib/Analysis/DataStructure/Local.cpp:1.52 Mon Mar 3 11:13:31 2003
+++ llvm/lib/Analysis/DataStructure/Local.cpp Thu Jun 26 16:35:10 2003
@@ -86,9 +86,9 @@
private:
// Visitor functions, used to handle each instruction type we encounter...
friend class InstVisitor<GraphBuilder>;
- void visitMallocInst(MallocInst &MI) { handleAlloc(MI, DSNode::HeapNode); }
- void visitAllocaInst(AllocaInst &AI) { handleAlloc(AI, DSNode::AllocaNode);}
- void handleAlloc(AllocationInst &AI, DSNode::NodeTy NT);
+ void visitMallocInst(MallocInst &MI) { handleAlloc(MI, true); }
+ void visitAllocaInst(AllocaInst &AI) { handleAlloc(AI, false); }
+ void handleAlloc(AllocationInst &AI, bool isHeap);
void visitPHINode(PHINode &PN);
@@ -108,10 +108,13 @@
/// createNode - Create a new DSNode, ensuring that it is properly added to
/// the graph.
///
- DSNode *createNode(DSNode::NodeTy NodeType, const Type *Ty = 0) {
- DSNode *N = new DSNode(NodeType, Ty, &G); // Create the node
- if (DisableFieldSensitivity)
+ DSNode *createNode(const Type *Ty = 0) {
+ DSNode *N = new DSNode(Ty, &G); // Create the node
+ if (DisableFieldSensitivity) {
N->foldNodeCompletely();
+ if (DSNode *FN = N->getForwardNode())
+ N = FN;
+ }
return N;
}
@@ -191,7 +194,7 @@
NH = I->second;
} else {
// This returns a conservative unknown node for any unhandled ConstExpr
- return NH = createNode(DSNode::UnknownNode);
+ return NH = createNode()->setUnknownNodeMarker();
}
if (NH.getNode() == 0) { // (getelementptr null, X) returns null
ScalarMap.erase(V);
@@ -201,7 +204,7 @@
} else if (ConstantIntegral *CI = dyn_cast<ConstantIntegral>(C)) {
// Random constants are unknown mem
- return NH = createNode(DSNode::UnknownNode);
+ return NH = createNode()->setUnknownNodeMarker();
} else {
assert(0 && "Unknown constant type!");
}
@@ -210,11 +213,11 @@
DSNode *N;
if (GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
// Create a new global node for this global variable...
- N = createNode(DSNode::GlobalNode, GV->getType()->getElementType());
+ N = createNode(GV->getType()->getElementType());
N->addGlobal(GV);
} else {
// Otherwise just create a shadow node
- N = createNode(DSNode::ShadowNode);
+ N = createNode();
}
NH.setNode(N); // Remember that we are pointing to it...
@@ -234,7 +237,7 @@
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);
+ Link = createNode();
}
return Link;
}
@@ -260,8 +263,13 @@
/// Alloca & Malloc instruction implementation - Simply create a new memory
/// object, pointing the scalar to it.
///
-void GraphBuilder::handleAlloc(AllocationInst &AI, DSNode::NodeTy NodeType) {
- setDestTo(AI, createNode(NodeType));
+void GraphBuilder::handleAlloc(AllocationInst &AI, bool isHeap) {
+ DSNode *N = createNode();
+ if (isHeap)
+ N->setHeapNodeMarker();
+ else
+ N->setAllocaNodeMarker();
+ setDestTo(AI, N);
}
// PHINode - Make the scalar for the PHI node point to all of the things the
@@ -365,7 +373,7 @@
if (Ptr.getNode() == 0) return;
// Make that the node is read from...
- Ptr.getNode()->NodeType |= DSNode::Read;
+ Ptr.getNode()->setReadMarker();
// Ensure a typerecord exists...
Ptr.getNode()->mergeTypeInfo(LI.getType(), Ptr.getOffset(), false);
@@ -380,7 +388,7 @@
if (Dest.getNode() == 0) return;
// Mark that the node is written to...
- Dest.getNode()->NodeType |= DSNode::Modified;
+ Dest.getNode()->setModifiedMarker();
// Ensure a typerecord exists...
Dest.getNode()->mergeTypeInfo(StoredTy, Dest.getOffset());
@@ -423,8 +431,9 @@
void GraphBuilder::visitFreeInst(FreeInst &FI) {
// Mark that the node is written to...
- getValueDest(*FI.getOperand(0)).getNode()->NodeType
- |= DSNode::Modified | DSNode::HeapNode;
+ DSNode *N = getValueDest(*FI.getOperand(0)).getNode();
+ N->setModifiedMarker();
+ N->setHeapNodeMarker();
}
/// Handle casts...
@@ -438,7 +447,7 @@
// to track the fact that the node points to SOMETHING, just something we
// don't know about. Make an "Unknown" node.
//
- setDestTo(CI, createNode(DSNode::UnknownNode));
+ setDestTo(CI, createNode()->setUnknownNodeMarker());
}
}
@@ -455,7 +464,7 @@
CurNode.mergeWith(getValueDest(**I));
if (CurNode.getNode())
- CurNode.getNode()->NodeType |= DSNode::UnknownNode;
+ CurNode.getNode()->setUnknownNodeMarker();
}
Index: llvm/lib/Analysis/DataStructure/Printer.cpp
diff -u llvm/lib/Analysis/DataStructure/Printer.cpp:1.51 llvm/lib/Analysis/DataStructure/Printer.cpp:1.51.2.1
--- llvm/lib/Analysis/DataStructure/Printer.cpp:1.51 Fri Feb 14 14:25:47 2003
+++ llvm/lib/Analysis/DataStructure/Printer.cpp Thu Jun 26 16:35:10 2003
@@ -38,16 +38,18 @@
if (N->isArray())
OS << " array";
}
- if (N->NodeType) {
+ if (unsigned NodeType = N->getNodeFlags()) {
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";
- if (N->NodeType & DSNode::DEAD ) OS << "<dead>";
+ if (NodeType & DSNode::AllocaNode ) OS << "S";
+ if (NodeType & DSNode::HeapNode ) OS << "H";
+ if (NodeType & DSNode::GlobalNode ) OS << "G";
+ if (NodeType & DSNode::UnknownNode) OS << "U";
+ if (NodeType & DSNode::Incomplete ) OS << "I";
+ if (NodeType & DSNode::Modified ) OS << "M";
+ if (NodeType & DSNode::Read ) OS << "R";
+#ifndef NDEBUG
+ if (NodeType & DSNode::DEAD ) OS << "<dead>";
+#endif
OS << "\n";
}
Index: llvm/lib/Analysis/DataStructure/TopDownClosure.cpp
diff -u llvm/lib/Analysis/DataStructure/TopDownClosure.cpp:1.40 llvm/lib/Analysis/DataStructure/TopDownClosure.cpp:1.40.2.1
--- llvm/lib/Analysis/DataStructure/TopDownClosure.cpp:1.40 Tue Feb 11 17:11:44 2003
+++ llvm/lib/Analysis/DataStructure/TopDownClosure.cpp Thu Jun 26 16:35:10 2003
@@ -45,6 +45,7 @@
// has no way to extend the lifetime of the pass, which screws up ds-aa.
//
void TDDataStructures::releaseMyMemory() {
+ return;
for (hash_map<const Function*, DSGraph*>::iterator I = DSInfo.begin(),
E = DSInfo.end(); I != E; ++I)
delete I->second;
More information about the llvm-commits
mailing list