From 7650b94c758f55066b43799ecfb50c729c2153af Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 16 Apr 2002 20:39:59 +0000 Subject: [PATCH] * Remove the concept of a critical shadow node * Make the function pointer argument explicit for a call nodes * Eliminate unreachable global values * Merge call nodes that are identical git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@2266 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Analysis/DataStructure/ComputeClosure.cpp | 20 +++++++- lib/Analysis/DataStructure/DataStructure.cpp | 11 +++-- lib/Analysis/DataStructure/EliminateNodes.cpp | 47 +++++++++---------- .../DataStructure/FunctionRepBuilder.cpp | 30 ++++++++---- lib/Analysis/DataStructure/NodeImpl.cpp | 26 +++++----- 5 files changed, 79 insertions(+), 55 deletions(-) diff --git a/lib/Analysis/DataStructure/ComputeClosure.cpp b/lib/Analysis/DataStructure/ComputeClosure.cpp index 30c21a33227..67309e8c77d 100644 --- a/lib/Analysis/DataStructure/ComputeClosure.cpp +++ b/lib/Analysis/DataStructure/ComputeClosure.cpp @@ -100,6 +100,8 @@ void FunctionDSGraph::computeClosure(const DataStructure &DS) { NI = std::find_if(CallNodes.begin(), CallNodes.end(), isResolvableCallNode); while (NI != CallNodes.end()) { CallDSNode *CN = *NI; + // FIXME: This should work based on the pointer val set of the first arg + // link (which is the function to call) Function *F = CN->getCall()->getCalledFunction(); if (NumInlines++ == 100) { // CUTE hack huh? @@ -181,14 +183,14 @@ void FunctionDSGraph::computeClosure(const DataStructure &DS) { RetVals)); // If the call node has arguments, process them now! - assert(Args.size() == CN->getNumArgs() && + assert(Args.size() == CN->getNumArgs()-1 && "Call node doesn't match function?"); for (unsigned i = 0, e = Args.size(); i != e; ++i) { // Now we make all of the nodes inside of the incorporated method // point to the real arguments values, not to the shadow nodes for the // argument. - ResolveNodesTo(Args[i], CN->getArgValues(i)); + ResolveNodesTo(Args[i], CN->getArgValues(i+1)); } // Loop through the nodes, deleting alloca nodes in the inlined function. @@ -231,4 +233,18 @@ void FunctionDSGraph::computeClosure(const DataStructure &DS) { // Move on to the next call node... NI = std::find_if(CallNodes.begin(), CallNodes.end(), isResolvableCallNode); } + + // Drop references to globals... + CallMap.clear(); + + bool Changed = true; + while (Changed) { + // Eliminate shadow nodes that are not distinguishable from some other + // node in the graph... + // + Changed = UnlinkUndistinguishableNodes(); + + // Eliminate shadow nodes that are now extraneous due to linking... + Changed |= RemoveUnreachableNodes(); + } } diff --git a/lib/Analysis/DataStructure/DataStructure.cpp b/lib/Analysis/DataStructure/DataStructure.cpp index 01ef27383ce..248ed918bb6 100644 --- a/lib/Analysis/DataStructure/DataStructure.cpp +++ b/lib/Analysis/DataStructure/DataStructure.cpp @@ -56,7 +56,7 @@ void DataStructure::print(std::ostream &O, Module *M) const { if (!(*I)->isExternal()) { string Filename = "ds." + (*I)->getName() + ".dot"; - O << "Writing '" << Filename << "'...\n"; + O << "Writing '" << Filename << "'..."; ofstream F(Filename.c_str()); if (F.good()) { F << "digraph DataStructures {\n" @@ -72,9 +72,12 @@ void DataStructure::print(std::ostream &O, Module *M) const { } else { O << " error opening file for writing!\n"; } - - O << (*I)->getName() << " " << getDSGraph(*I).getGraphSize() << " " - << getClosedDSGraph(*I).getGraphSize() << "\n"; + + if (Time) + O << " [" << getDSGraph(*I).getGraphSize() << ", " + << getClosedDSGraph(*I).getGraphSize() << "]\n"; + else + O << "\n"; } } diff --git a/lib/Analysis/DataStructure/EliminateNodes.cpp b/lib/Analysis/DataStructure/EliminateNodes.cpp index 6b22f69617d..edd8285bc81 100644 --- a/lib/Analysis/DataStructure/EliminateNodes.cpp +++ b/lib/Analysis/DataStructure/EliminateNodes.cpp @@ -53,23 +53,6 @@ static void DestroyFirstNodeOfPair(DSNode *N1, DSNode *N2) { assert(RanOnce && "Node on user set but cannot find the use!"); } - // If we are about to eliminate a call node that returns a pointer, make the - // shadow node it points to not be critical anymore! - // - if (isa(N1) && N1->getNumLinks()) { - assert(N1->getNumLinks() == 1 && "Call node can only return one pointer!"); - PointerValSet &PVS = N1->getLink(0); - - for (unsigned i = 0, e = PVS.size(); i != e; ++i) - if (ShadowDSNode *Shad = dyn_cast(PVS[i].Node)) - if (Shad->isCriticalNode()) { - Shad->resetCriticalMark(); // Only unmark _ONE_ node.. - break; - } - - } - - N1->removeAllIncomingEdges(); delete N1; } @@ -80,9 +63,10 @@ static void DestroyFirstNodeOfPair(DSNode *N1, DSNode *N2) { // static bool isIndistinguishableNode(DSNode *DN) { if (DN->getReferrers().empty()) { // No referrers... - if (isa(DN) || isa(DN)) + if (isa(DN) || isa(DN)) { + delete DN; return true; // Node is trivially dead - else + } else return false; } @@ -328,17 +312,30 @@ bool FunctionDSGraph::RemoveUnreachableNodes() { } } - // Loop over the global nodes, removing nodes that have no edges into them. - // + // Loop over the global nodes, removing nodes that have no edges into them or + // out of them. + // for (std::vector::iterator I = GlobalNodes.begin(); I != GlobalNodes.end(); ) - if ((*I)->getReferrers().empty()) { // No referrers... - delete *I; - I = GlobalNodes.erase(I); // Remove the node... - Changed = true; + if ((*I)->getReferrers().empty()) { + GlobalDSNode *GDN = *I; + bool NoLinks = true; // Make sure there are no outgoing links... + for (unsigned i = 0, e = GDN->getNumLinks(); i != e; ++i) + if (!GDN->getLink(i).empty()) { + NoLinks = false; + break; + } + if (NoLinks) { + delete GDN; + I = GlobalNodes.erase(I); // Remove the node... + Changed = true; + } else { + ++I; + } } else { ++I; } + return Changed; } diff --git a/lib/Analysis/DataStructure/FunctionRepBuilder.cpp b/lib/Analysis/DataStructure/FunctionRepBuilder.cpp index 2afede5dfa0..6dc2930243c 100644 --- a/lib/Analysis/DataStructure/FunctionRepBuilder.cpp +++ b/lib/Analysis/DataStructure/FunctionRepBuilder.cpp @@ -69,7 +69,7 @@ void InitVisitor::visitCallInst(CallInst *CI) { // Create a critical shadow node to represent the memory object that the // return value points to... ShadowDSNode *Shad = new ShadowDSNode(PT->getElementType(), - Func->getParent(), true); + Func->getParent()); Rep->ShadowNodes.push_back(Shad); // The return value of the function is a pointer to the shadow value @@ -88,7 +88,7 @@ void InitVisitor::visitCallInst(CallInst *CI) { // Loop over all of the operands of the call instruction (except the first // one), to look for global variable references... // - for_each(CI->op_begin()+1, CI->op_end(), // Skip first arg + for_each(CI->op_begin(), CI->op_end(), bind_obj(this, &InitVisitor::visitOperand)); } @@ -150,7 +150,7 @@ void FunctionRepBuilder::initializeWorkList(Function *Func) { // Add a shadow value for it to represent what it is pointing to and add // this to the value map... ShadowDSNode *Shad = new ShadowDSNode(PT->getElementType(), - Func->getParent(), true); + Func->getParent()); ShadowNodes.push_back(Shad); ValueMap[Arg].add(PointerVal(Shad), Arg); @@ -296,12 +296,8 @@ void FunctionRepBuilder::visitStoreInst(StoreInst *SI) { void FunctionRepBuilder::visitCallInst(CallInst *CI) { CallDSNode *DSN = CallMap[CI]; - - unsigned PtrNum = 0, i = 0; - if (isa(CI->getOperand(0))) - ++i; // Not an Indirect function call? Skip the function pointer... - - for (unsigned e = CI->getNumOperands(); i != e; ++i) + unsigned PtrNum = 0; + for (unsigned i = 0, e = CI->getNumOperands(); i != e; ++i) if (isa(CI->getOperand(i)->getType())) DSN->addArgValue(PtrNum++, ValueMap[CI->getOperand(i)]); } @@ -333,6 +329,22 @@ FunctionDSGraph::FunctionDSGraph(Function *F) : Func(F) { RetNode = Builder.getRetNode(); ValueMap = Builder.getValueMap(); + // Remove all entries in the value map that consist of global values pointing + // at things. They can only point to their node, so there is no use keeping + // them. + // + for (map::iterator I = ValueMap.begin(), + E = ValueMap.end(); I != E;) + if (isa(I->first)) { +#if MAP_DOESNT_HAVE_BROKEN_ERASE_MEMBER + I = ValueMap.erase(I); +#else + ValueMap.erase(I); // This is really lame. + I = ValueMap.begin(); // GCC's stdc++ lib doesn't return an it! +#endif + } else + ++I; + bool Changed = true; while (Changed) { // Eliminate shadow nodes that are not distinguishable from some other diff --git a/lib/Analysis/DataStructure/NodeImpl.cpp b/lib/Analysis/DataStructure/NodeImpl.cpp index 47a7dc28e65..732ab6a9950 100644 --- a/lib/Analysis/DataStructure/NodeImpl.cpp +++ b/lib/Analysis/DataStructure/NodeImpl.cpp @@ -40,8 +40,8 @@ bool GlobalDSNode::isEquivalentTo(DSNode *Node) const { // bool CallDSNode::isEquivalentTo(DSNode *Node) const { if (CallDSNode *C = dyn_cast(Node)) { - if (C->CI->getCalledFunction() != CI->getCalledFunction() || - getReferrers().size() != C->getReferrers().size()) + if (getReferrers().size() != C->getReferrers().size() || + C->getType() != getType()) return false; // Quick check... // Check that the outgoing links are identical... @@ -70,7 +70,6 @@ bool CallDSNode::isEquivalentTo(DSNode *Node) const { // bool ShadowDSNode::isEquivalentTo(DSNode *Node) const { return getType() == Node->getType(); - return !isCriticalNode(); // Must not be a critical node... } @@ -237,31 +236,31 @@ GlobalDSNode::GlobalDSNode(GlobalValue *V) string GlobalDSNode::getCaption() const { stringstream OS; + if (isa(Val)) + OS << "fn "; + else + OS << "global "; + WriteTypeSymbolic(OS, getType(), Val->getParent()); - return "global " + OS.str() + " %" + Val->getName(); + return OS.str() + " %" + Val->getName(); } -ShadowDSNode::ShadowDSNode(const Type *Ty, Module *M, bool C = false) - : DSNode(ShadowNode, Ty) { +ShadowDSNode::ShadowDSNode(const Type *Ty, Module *M) : DSNode(ShadowNode, Ty) { Mod = M; ShadowParent = 0; - CriticalNode = C; } ShadowDSNode::ShadowDSNode(const Type *Ty, Module *M, ShadowDSNode *ShadParent) : DSNode(ShadowNode, Ty) { Mod = M; ShadowParent = ShadParent; - CriticalNode = false; } std::string ShadowDSNode::getCaption() const { stringstream OS; - if (CriticalNode) OS << "# "; OS << "shadow "; WriteTypeSymbolic(OS, getType(), Mod); - if (CriticalNode) OS << " #"; return OS.str(); } @@ -281,10 +280,7 @@ void ShadowDSNode::mapNode(map &NodeMap, CallDSNode::CallDSNode(CallInst *ci) : DSNode(CallNode, ci->getType()), CI(ci) { unsigned NumPtrs = 0; - if (!isa(ci->getOperand(0))) - NumPtrs++; // Include the method pointer... - - for (unsigned i = 1, e = ci->getNumOperands(); i != e; ++i) + for (unsigned i = 0, e = ci->getNumOperands(); i != e; ++i) if (isa(ci->getOperand(i)->getType())) NumPtrs++; ArgLinks.resize(NumPtrs); @@ -334,7 +330,7 @@ void FunctionDSGraph::printFunction(std::ostream &O, O << "\n"; for (std::map::const_iterator I = ValueMap.begin(), E = ValueMap.end(); I != E; ++I) { - if (I->second.size()) { // Only output nodes with edges... + if (I->second.size()) { // Only output nodes with edges... stringstream OS; WriteTypeSymbolic(OS, I->first->getType(), Func->getParent());