From lattner at cs.uiuc.edu Mon Feb 3 13:08:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Feb 3 13:08:02 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/Transforms/PoolAllocate.h Message-ID: <200302031907.NAA11459@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Transforms: PoolAllocate.h added (r1.1) --- Log message: Expose information about pool allocation --- Diffs of the changes: From lattner at cs.uiuc.edu Mon Feb 3 13:09:04 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Feb 3 13:09:04 2003 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/PoolAllocate.cpp Message-ID: <200302031908.NAA11489@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: PoolAllocate.cpp updated: 1.2 -> 1.3 --- Log message: Split public interface out into header file --- Diffs of the changes: Index: llvm/lib/Transforms/IPO/PoolAllocate.cpp diff -u llvm/lib/Transforms/IPO/PoolAllocate.cpp:1.2 llvm/lib/Transforms/IPO/PoolAllocate.cpp:1.3 --- llvm/lib/Transforms/IPO/PoolAllocate.cpp:1.2 Fri Jan 31 22:52:08 2003 +++ llvm/lib/Transforms/IPO/PoolAllocate.cpp Mon Feb 3 13:08:18 2003 @@ -5,7 +5,7 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Transforms/IPO.h" +#include "llvm/Transforms/PoolAllocate.h" #include "llvm/Transforms/Utils/Cloning.h" #include "llvm/Analysis/DataStructure.h" #include "llvm/Analysis/DSGraph.h" @@ -18,6 +18,8 @@ #include "Support/Statistic.h" #include "Support/VectorExtras.h" +using namespace PA; + namespace { const Type *VoidPtrTy = PointerType::get(Type::SByteTy); // The type to allocate for a pool descriptor: { sbyte*, uint } @@ -25,100 +27,16 @@ StructType::get(make_vector(VoidPtrTy, Type::UIntTy, 0)); const PointerType *PoolDescPtr = PointerType::get(PoolDescType); + RegisterOpt + X("poolalloc", "Pool allocate disjoint data structures"); +} - /// PoolInfo - This struct represents a single pool in the context of a - /// function. Pools are mapped one to one with nodes in the DSGraph, so this - /// contains a pointer to the node it corresponds to. In addition, the pool - /// is initialized by calling the "poolinit" library function with a chunk of - /// memory allocated with an alloca instruction. This entry contains a - /// pointer to that alloca if the pool is locally allocated or the argument it - /// is passed in through if not. - /// - struct PoolInfo { - Value *PoolHandle; // Pool Handle, an alloca or incoming argument. - PoolInfo(Value *PH) : PoolHandle(PH) {} - }; - - struct FuncInfo { - /// MarkedNodes - The set of nodes which are not locally pool allocatable in - /// the current function. - /// - hash_set MarkedNodes; - - /// Clone - The cloned version of the function, if applicable. - Function *Clone; - - /// ArgNodes - The list of DSNodes which have pools passed in as arguments. - /// - std::vector ArgNodes; - - /// PoolDescriptors - A PoolInfo object for each relevant DSNode in the - /// current graph. - std::map PoolDescriptors; - - /// NewToOldValueMap - When and if a function needs to be cloned, this map - /// contains a mapping from all of the values in the new function back to - /// the values they correspond to in the old function. - /// - std::map NewToOldValueMap; - }; - - /// PA - The main pool allocation pass - /// - class PA : public Pass { - Module *CurModule; - BUDataStructures *BU; - - std::map FunctionInfo; - public: - Function *PoolInit, *PoolDestroy, *PoolAlloc, *PoolFree; - public: - bool run(Module &M); - - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.addRequired(); - AU.addRequired(); - } - - BUDataStructures &getBUDataStructures() const { return *BU; } - - FuncInfo *getFuncInfo(Function &F) { - std::map::iterator I = FunctionInfo.find(&F); - return I != FunctionInfo.end() ? &I->second : 0; - } - - private: - - /// AddPoolPrototypes - Add prototypes for the pool functions to the - /// specified module and update the Pool* instance variables to point to - /// them. - /// - void AddPoolPrototypes(); - - /// MakeFunctionClone - If the specified function needs to be modified for - /// pool allocation support, make a clone of it, adding additional arguments - /// as neccesary, and return it. If not, just return null. - /// - Function *MakeFunctionClone(Function &F); - - /// ProcessFunctionBody - Rewrite the body of a transformed function to use - /// pool allocation where appropriate. - /// - void ProcessFunctionBody(Function &Old, Function &New); - - /// CreatePools - This creates the pool initialization and destruction code - /// for the DSNodes specified by the NodesToPA list. This adds an entry to - /// the PoolDescriptors map for each DSNode. - /// - void CreatePools(Function &F, const std::vector &NodesToPA, - std::map &PoolDescriptors); - - void TransformFunctionBody(Function &F, DSGraph &G, FuncInfo &FI); - }; - RegisterOpt X("poolalloc", "Pool allocate disjoint data structures"); +void PoolAllocate::getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired(); + AU.addRequired(); } -bool PA::run(Module &M) { +bool PoolAllocate::run(Module &M) { if (M.begin() == M.end()) return false; CurModule = &M; @@ -155,7 +73,7 @@ // AddPoolPrototypes - Add prototypes for the pool functions to the specified // module and update the Pool* instance variables to point to them. // -void PA::AddPoolPrototypes() { +void PoolAllocate::AddPoolPrototypes() { CurModule->addTypeName("PoolDescriptor", PoolDescType); // Get poolinit function... @@ -193,7 +111,7 @@ // allocation support, make a clone of it, adding additional arguments as // neccesary, and return it. If not, just return null. // -Function *PA::MakeFunctionClone(Function &F) { +Function *PoolAllocate::MakeFunctionClone(Function &F) { DSGraph &G = BU->getDSGraph(F); std::vector &Nodes = G.getNodes(); if (Nodes.empty()) return 0; // No memory activity, nothing is required @@ -245,11 +163,11 @@ // Set the rest of the new arguments names to be PDa and add entries to the // pool descriptors map - std::map &PoolDescriptors = FI.PoolDescriptors; + std::map &PoolDescriptors = FI.PoolDescriptors; Function::aiterator NI = New->abegin(); for (unsigned i = 0, e = FI.ArgNodes.size(); i != e; ++i, ++NI) { NI->setName("PDa"); // Add pd entry - PoolDescriptors.insert(std::make_pair(FI.ArgNodes[i], PoolInfo(NI))); + PoolDescriptors.insert(std::make_pair(FI.ArgNodes[i], NI)); } // Map the existing arguments of the old function to the corresponding @@ -283,7 +201,7 @@ // processFunction - Pool allocate any data structures which are contained in // the specified function... // -void PA::ProcessFunctionBody(Function &F, Function &NewF) { +void PoolAllocate::ProcessFunctionBody(Function &F, Function &NewF) { DSGraph &G = BU->getDSGraph(F); std::vector &Nodes = G.getNodes(); if (Nodes.empty()) return; // Quick exit if nothing to do... @@ -305,7 +223,7 @@ DEBUG(std::cerr << NodesToPA.size() << " nodes to pool allocate\n"); if (!NodesToPA.empty()) { // Create pool construction/destruction code - std::map &PoolDescriptors = FI.PoolDescriptors; + std::map &PoolDescriptors = FI.PoolDescriptors; CreatePools(NewF, NodesToPA, PoolDescriptors); } @@ -318,8 +236,9 @@ // the DSNodes specified by the NodesToPA list. This adds an entry to the // PoolDescriptors map for each DSNode. // -void PA::CreatePools(Function &F, const std::vector &NodesToPA, - std::map &PoolDescriptors) { +void PoolAllocate::CreatePools(Function &F, + const std::vector &NodesToPA, + std::map &PoolDescriptors) { // Find all of the return nodes in the CFG... std::vector ReturnNodes; for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) @@ -346,7 +265,7 @@ new CallInst(PoolInit, make_vector(AI, ElSize, 0), "", InsertPoint); // Update the PoolDescriptors map - PoolDescriptors.insert(std::make_pair(Node, PoolInfo(AI))); + PoolDescriptors.insert(std::make_pair(Node, AI)); // Insert a call to pool destroy before each return inst in the function for (unsigned r = 0, e = ReturnNodes.size(); r != e; ++r) @@ -360,11 +279,12 @@ /// FuncTransform - This class implements transformation required of pool /// allocated functions. struct FuncTransform : public InstVisitor { - PA &PAInfo; + PoolAllocate &PAInfo; DSGraph &G; FuncInfo &FI; - FuncTransform(PA &P, DSGraph &g, FuncInfo &fi) : PAInfo(P), G(g), FI(fi) {} + FuncTransform(PoolAllocate &P, DSGraph &g, FuncInfo &fi) + : PAInfo(P), G(g), FI(fi) {} void visitMallocInst(MallocInst &MI); void visitFreeInst(FreeInst &FI); @@ -384,13 +304,13 @@ Value *getPoolHandle(Value *V) { DSNode *Node = getDSNodeFor(V); // Get the pool handle for this DSNode... - std::map::iterator I = FI.PoolDescriptors.find(Node); - return I != FI.PoolDescriptors.end() ? I->second.PoolHandle : 0; + std::map::iterator I = FI.PoolDescriptors.find(Node); + return I != FI.PoolDescriptors.end() ? I->second : 0; } }; } -void PA::TransformFunctionBody(Function &F, DSGraph &G, FuncInfo &FI) { +void PoolAllocate::TransformFunctionBody(Function &F, DSGraph &G, FuncInfo &FI){ FuncTransform(*this, G, FI).visit(F); } @@ -505,7 +425,7 @@ assert(NodeMapping.count(CFI->ArgNodes[i]) && "Node not in mapping!"); DSNode *LocalNode = NodeMapping.find(CFI->ArgNodes[i])->second; assert(FI.PoolDescriptors.count(LocalNode) && "Node not pool allocated?"); - Args.push_back(FI.PoolDescriptors.find(LocalNode)->second.PoolHandle); + Args.push_back(FI.PoolDescriptors.find(LocalNode)->second); } else { Args.push_back(Constant::getNullValue(PoolDescPtr)); } @@ -520,12 +440,4 @@ DEBUG(std::cerr << " Result Call: " << *NewCall); CI.getParent()->getInstList().erase(&CI); -} - - -// createPoolAllocatePass - Global function to access the functionality of this -// pass... -// -Pass *createPoolAllocatePass() { - return new PA(); } From lattner at cs.uiuc.edu Mon Feb 3 13:09:31 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Feb 3 13:09:31 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/Transforms/IPO.h Message-ID: <200302031908.NAA11501@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Transforms: IPO.h updated: 1.15 -> 1.16 --- Log message: Remove pool alloc accessor --- Diffs of the changes: Index: llvm/include/llvm/Transforms/IPO.h diff -u llvm/include/llvm/Transforms/IPO.h:1.15 llvm/include/llvm/Transforms/IPO.h:1.16 --- llvm/include/llvm/Transforms/IPO.h:1.15 Tue Nov 19 14:43:24 2002 +++ llvm/include/llvm/Transforms/IPO.h Mon Feb 3 13:08:33 2003 @@ -70,14 +70,6 @@ //===----------------------------------------------------------------------===// -// createPoolAllocatePass - This transform changes programs so that disjoint -// data structures are allocated out of different pools of memory, increasing -// locality and shrinking pointer size. -// -Pass *createPoolAllocatePass(); - - -//===----------------------------------------------------------------------===// // These passes are wrappers that can do a few simple structure mutation // transformations. // From lattner at cs.uiuc.edu Mon Feb 3 13:11:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Feb 3 13:11:02 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/DSGraph.h Message-ID: <200302031910.NAA11524@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: DSGraph.h updated: 1.41 -> 1.42 --- Log message: * Add a bunch of stuff for checking the integrity of the graph * remove the isNodeDead method --- Diffs of the changes: Index: llvm/include/llvm/Analysis/DSGraph.h diff -u llvm/include/llvm/Analysis/DSGraph.h:1.41 llvm/include/llvm/Analysis/DSGraph.h:1.42 --- llvm/include/llvm/Analysis/DSGraph.h:1.41 Fri Jan 31 22:51:52 2003 +++ llvm/include/llvm/Analysis/DSGraph.h Mon Feb 3 13:10:24 2003 @@ -180,8 +180,33 @@ /// void mergeInGraph(DSCallSite &CS, const DSGraph &Graph, unsigned CloneFlags); -private: - bool isNodeDead(DSNode *N); + // Methods for checking to make sure graphs are well formed... + void AssertNodeInGraph(DSNode *N) const { + assert((!N || find(Nodes.begin(), Nodes.end(), N) != Nodes.end()) && + "AssertNodeInGraph: Node is not in graph!"); + } + void AssertNodeContainsGlobal(const DSNode *N, GlobalValue *GV) const { + assert(std::find(N->getGlobals().begin(), N->getGlobals().end(), GV) != + N->getGlobals().end() && "Global value not in node!"); + } + + void AssertCallSiteInGraph(const DSCallSite &CS) const { + AssertNodeInGraph(CS.getCallee().getNode()); + AssertNodeInGraph(CS.getRetVal().getNode()); + for (unsigned j = 0, e = CS.getNumPtrArgs(); j != e; ++j) + AssertNodeInGraph(CS.getPtrArg(j).getNode()); + } + + void AssertCallNodesInGraph() const { + for (unsigned i = 0, e = FunctionCalls.size(); i != e; ++i) + AssertCallSiteInGraph(FunctionCalls[i]); + } + void AssertAuxCallNodesInGraph() const { + for (unsigned i = 0, e = AuxFunctionCalls.size(); i != e; ++i) + AssertCallSiteInGraph(AuxFunctionCalls[i]); + } + + void AssertGraphOK() const; public: // removeTriviallyDeadNodes - After the graph has been constructed, this From lattner at cs.uiuc.edu Mon Feb 3 13:12:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Feb 3 13:12:01 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/DSSupport.h Message-ID: <200302031911.NAA11537@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: DSSupport.h updated: 1.10 -> 1.11 --- Log message: Eliminate unused resolving caller stuff --- Diffs of the changes: Index: llvm/include/llvm/Analysis/DSSupport.h diff -u llvm/include/llvm/Analysis/DSSupport.h:1.10 llvm/include/llvm/Analysis/DSSupport.h:1.11 --- llvm/include/llvm/Analysis/DSSupport.h:1.10 Fri Jan 31 22:51:53 2003 +++ llvm/include/llvm/Analysis/DSSupport.h Mon Feb 3 13:11:04 2003 @@ -47,6 +47,7 @@ class DSNodeHandle { DSNode *N; unsigned Offset; + void operator==(const DSNode *N); // DISALLOW, use to promote N to nodehandle public: // Allow construction, destruction, and assignment... DSNodeHandle(DSNode *n = 0, unsigned offs = 0) : N(0), Offset(offs) { @@ -103,19 +104,12 @@ /// DSCallSite - Representation of a call site via its call instruction, /// the DSNode handle for the callee function (or function pointer), and /// the DSNode handles for the function arguments. -/// -/// One unusual aspect of this callsite record is the ResolvingCaller member. -/// If this is non-null, then it indicates the function that allowed a call-site -/// to finally be resolved. Because of indirect calls, this function may not -/// actually be the function that contains the Call instruction itself. This is -/// used by the BU and TD passes to communicate. /// class DSCallSite { CallInst *Inst; // Actual call site DSNodeHandle RetVal; // Returned value DSNodeHandle Callee; // The function node called std::vector CallArgs; // The pointer arguments - Function *ResolvingCaller; // See comments above static void InitNH(DSNodeHandle &NH, const DSNodeHandle &Src, const hash_map &NodeMap) { @@ -146,14 +140,13 @@ /// DSCallSite(CallInst &inst, const DSNodeHandle &rv, const DSNodeHandle &callee, std::vector &Args) - : Inst(&inst), RetVal(rv), Callee(callee), ResolvingCaller(0) { + : Inst(&inst), RetVal(rv), Callee(callee) { Args.swap(CallArgs); } DSCallSite(const DSCallSite &DSCS) // Simple copy ctor : Inst(DSCS.Inst), RetVal(DSCS.RetVal), - Callee(DSCS.Callee), CallArgs(DSCS.CallArgs), - ResolvingCaller(DSCS.ResolvingCaller) {} + Callee(DSCS.Callee), CallArgs(DSCS.CallArgs) {} /// Mapping copy constructor - This constructor takes a preexisting call site /// to copy plus a map that specifies how the links should be transformed. @@ -168,7 +161,6 @@ CallArgs.resize(FromCall.CallArgs.size()); for (unsigned i = 0, e = FromCall.CallArgs.size(); i != e; ++i) InitNH(CallArgs[i], FromCall.CallArgs[i], NodeMap); - ResolvingCaller = FromCall.ResolvingCaller; } // Accessor functions... @@ -182,9 +174,6 @@ unsigned getNumPtrArgs() const { return CallArgs.size(); } - Function *getResolvingCaller() const { return ResolvingCaller; } - void setResolvingCaller(Function *F) { ResolvingCaller = F; } - DSNodeHandle &getPtrArg(unsigned i) { assert(i < CallArgs.size() && "Argument to getPtrArgNode is out of range!"); return CallArgs[i]; @@ -200,7 +189,6 @@ std::swap(RetVal, CS.RetVal); std::swap(Callee, CS.Callee); std::swap(CallArgs, CS.CallArgs); - std::swap(ResolvingCaller, CS.ResolvingCaller); } } From lattner at cs.uiuc.edu Mon Feb 3 13:12:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Feb 3 13:12:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp Message-ID: <200302031911.NAA11549@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: BottomUpClosure.cpp updated: 1.50 -> 1.51 --- Log message: Add better debug output --- Diffs of the changes: Index: llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp diff -u llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.50 llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.51 --- llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.50 Fri Jan 31 22:51:55 2003 +++ llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp Mon Feb 3 13:11:38 2003 @@ -109,6 +109,7 @@ // bool BUDataStructures::run(Module &M) { GlobalsGraph = new DSGraph(); + GlobalsGraph->setPrintAuxCalls(); Function *MainFunc = M.getMainFunction(); if (MainFunc) @@ -336,9 +337,10 @@ DSGraph &GI = getDSGraph(*Callee); // Graph to inline DEBUG(std::cerr << " Inlining graph for " << Callee->getName() - << " in: " << F.getName() << "[" << GI.getGraphSize() << "+" - << GI.getAuxFunctionCalls().size() << "]\n"); - + << "[" << GI.getGraphSize() << "+" + << GI.getAuxFunctionCalls().size() << "] into: " << F.getName() + << "[" << Graph.getGraphSize() << "+" + << Graph.getAuxFunctionCalls().size() << "]\n"); #if 0 Graph.writeGraphToFile(std::cerr, "bu_" + F.getName() + "_before_" + Callee->getName()); @@ -366,6 +368,7 @@ // now that are complete, we must loop! Graph.maskIncompleteMarkers(); Graph.markIncompleteNodes(DSGraph::MarkFormalArgs); + // FIXME: materialize nodes from the globals graph as neccesary... Graph.removeDeadNodes(DSGraph::KeepUnreachableGlobals); DEBUG(std::cerr << " [BU] Done inlining: " << F.getName() << " [" @@ -420,10 +423,12 @@ // Get the data structure graph for the called function. // DSGraph &GI = getDSGraph(*Callee); // Graph to inline - + DEBUG(std::cerr << " Inlining graph for " << Callee->getName() - << " in: " << F.getName() << "[" << GI.getGraphSize() << "+" - << GI.getAuxFunctionCalls().size() << "]\n"); + << "[" << GI.getGraphSize() << "+" + << GI.getAuxFunctionCalls().size() << "] into: " << F.getName() + << "[" << Graph.getGraphSize() << "+" + << Graph.getAuxFunctionCalls().size() << "]\n"); // Handle self recursion by resolving the arguments and return value Graph.mergeInGraph(CS, GI, @@ -447,7 +452,7 @@ DEBUG(std::cerr << " [BU] Done Non-SCC inlining: " << F.getName() << " [" << Graph.getGraphSize() << "+" << Graph.getAuxFunctionCalls().size() << "]\n"); - + //Graph.writeGraphToFile(std::cerr, "nscc_" + F.getName()); return Graph; } @@ -466,7 +471,7 @@ // the new call site list and doesn't invalidate our iterators! std::vector TempFCs; TempFCs.swap(AuxCallsList); - + // Loop over all of the resolvable call sites unsigned LastCallSiteIdx = ~0U; CallSiteIterator I = CallSiteIterator::begin(TempFCs), @@ -505,10 +510,11 @@ // Get the data structure graph for the called function. // DSGraph &GI = getDSGraph(*Callee); // Graph to inline - DEBUG(std::cerr << " Inlining graph for " << Callee->getName() - << " in: " << F.getName() << "[" << GI.getGraphSize() << "+" - << GI.getAuxFunctionCalls().size() << "]\n"); + << "[" << GI.getGraphSize() << "+" + << GI.getAuxFunctionCalls().size() << "] into: " << F.getName() + << "[" << Graph.getGraphSize() << "+" + << Graph.getAuxFunctionCalls().size() << "]\n"); // Handle self recursion by resolving the arguments and return value Graph.mergeInGraph(CS, GI, @@ -537,12 +543,14 @@ // now that are complete, we must loop! Graph.maskIncompleteMarkers(); Graph.markIncompleteNodes(DSGraph::MarkFormalArgs); + + // FIXME: materialize nodes from the globals graph as neccesary... + Graph.removeDeadNodes(DSGraph::KeepUnreachableGlobals); DEBUG(std::cerr << " [BU] Done inlining: " << F.getName() << " [" << Graph.getGraphSize() << "+" << Graph.getAuxFunctionCalls().size() << "]\n"); //Graph.writeGraphToFile(std::cerr, "bu_" + F.getName()); - return Graph; } From lattner at cs.uiuc.edu Mon Feb 3 13:13:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Feb 3 13:13:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/DataStructure.cpp Message-ID: <200302031912.NAA11570@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: DataStructure.cpp updated: 1.83 -> 1.84 --- Log message: Implement the globals graph! --- Diffs of the changes: Index: llvm/lib/Analysis/DataStructure/DataStructure.cpp diff -u llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.83 llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.84 --- llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.83 Sat Feb 1 00:54:31 2003 +++ llvm/lib/Analysis/DataStructure/DataStructure.cpp Mon Feb 3 13:12:15 2003 @@ -233,7 +233,8 @@ break; } default: - assert(0 && "Unknown type!"); + foldNodeCompletely(); + return true; } } @@ -616,15 +617,12 @@ // Remove alloca markers as specified if (CloneFlags & (StripAllocaBit | StripModRefBits)) { - unsigned short clearBits = (CloneFlags & StripAllocaBit - ? DSNode::AllocaNode : 0) - | (CloneFlags & StripModRefBits - ? (DSNode::Modified | DSNode::Read) : 0); - for (unsigned i = FN, e = Nodes.size(); i != e; ++i) - Nodes[i]->NodeType &= ~clearBits; + unsigned clearBits = (CloneFlags & StripAllocaBit ? DSNode::AllocaNode : 0) + | (CloneFlags & StripModRefBits ? (DSNode::Modified | DSNode::Read) : 0); + maskNodeTypes(~clearBits); } - // Copy the value map... and merge all of the global nodes... + // Copy the scalar map... merging all of the global nodes... for (hash_map::const_iterator I = G.ScalarMap.begin(), E = G.ScalarMap.end(); I != E; ++I) { DSNodeHandle &H = OldValMap[I->first]; @@ -634,11 +632,10 @@ if (isa(I->first)) { // Is this a global? hash_map::iterator GVI = ScalarMap.find(I->first); - if (GVI != ScalarMap.end()) { // Is the global value in this fn already? + if (GVI != ScalarMap.end()) // Is the global value in this fn already? GVI->second.mergeWith(H); - } else { + else ScalarMap[I->first] = H; // Add global pointer to this graph - } } } @@ -716,33 +713,6 @@ } } -#if 0 -// cloneGlobalInto - Clone the given global node and all its target links -// (and all their llinks, recursively). -// -DSNode *DSGraph::cloneGlobalInto(const DSNode *GNode) { - if (GNode == 0 || GNode->getGlobals().size() == 0) return 0; - - // If a clone has already been created for GNode, return it. - DSNodeHandle& ValMapEntry = ScalarMap[GNode->getGlobals()[0]]; - if (ValMapEntry != 0) - return ValMapEntry; - - // Clone the node and update the ValMap. - DSNode* NewNode = new DSNode(*GNode); - ValMapEntry = NewNode; // j=0 case of loop below! - Nodes.push_back(NewNode); - for (unsigned j = 1, N = NewNode->getGlobals().size(); j < N; ++j) - ScalarMap[NewNode->getGlobals()[j]] = NewNode; - - // Rewrite the links in the new node to point into the current graph. - for (unsigned j = 0, e = GNode->getNumLinks(); j != e; ++j) - NewNode->setLink(j, cloneGlobalInto(GNode->getLink(j))); - - return NewNode; -} -#endif - // markIncompleteNodes - Mark the specified node as having contents that are not // known with the current analysis we have performed. Because a node makes all @@ -808,27 +778,6 @@ } } -// removeRefsToGlobal - Helper function that removes globals from the -// ScalarMap so that the referrer count will go down to zero. -static void removeRefsToGlobal(DSNode* N, - hash_map &ScalarMap) { - while (!N->getGlobals().empty()) { - GlobalValue *GV = N->getGlobals().back(); - N->getGlobals().pop_back(); - ScalarMap.erase(GV); - } -} - - -// isNodeDead - This method checks to see if a node is dead, and if it isn't, it -// checks to see if there are simple transformations that it can do to make it -// dead. -// -bool DSGraph::isNodeDead(DSNode *N) { - // Is it a trivially dead shadow node? - return N->getReferrers().empty() && (N->NodeType & ~DSNode::DEAD) == 0; -} - static inline void killIfUselessEdge(DSNodeHandle &Edge) { if (DSNode *N = Edge.getNode()) // Is there an edge? if (N->getReferrers().size() == 1) // Does it point to a lonely node? @@ -927,11 +876,32 @@ removeIdenticalCalls(FunctionCalls, Func ? Func->getName() : ""); removeIdenticalCalls(AuxFunctionCalls, Func ? Func->getName() : ""); - for (unsigned i = 0; i != Nodes.size(); ++i) - if (isNodeDead(Nodes[i])) { // This node is dead! - delete Nodes[i]; // Free memory... + for (unsigned i = 0; i != Nodes.size(); ++i) { + DSNode *Node = Nodes[i]; + if (!(Node->NodeType & ~(DSNode::Composition | DSNode::Array | + DSNode::DEAD))) { + // 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 + // have all of these properties and still have incoming edges, due to the + // scalar map, so we check those now. + // + if (Node->getReferrers().size() == Node->getGlobals().size()) { + std::vector &Globals = Node->getGlobals(); + for (unsigned j = 0, e = Globals.size(); j != e; ++j) + ScalarMap.erase(Globals[j]); + Globals.clear(); + + Node->NodeType = DSNode::DEAD; + } + } + + if ((Node->NodeType & ~DSNode::DEAD) == 0 && + Node->getReferrers().empty()) { // This node is dead! + delete Node; // Free memory... Nodes.erase(Nodes.begin()+i--); // Remove from node list... } + } } @@ -952,8 +922,8 @@ getRetVal().getNode()->markReachableNodes(Nodes); getCallee().getNode()->markReachableNodes(Nodes); - for (unsigned j = 0, e = getNumPtrArgs(); j != e; ++j) - getPtrArg(j).getNode()->markReachableNodes(Nodes); + for (unsigned i = 0, e = getNumPtrArgs(); i != e; ++i) + getPtrArg(i).getNode()->markReachableNodes(Nodes); } // CanReachAliveNodes - Simple graph walker that recursively traverses the graph @@ -989,30 +959,12 @@ if (CanReachAliveNodes(CS.getRetVal().getNode(), Alive, Visited) || CanReachAliveNodes(CS.getCallee().getNode(), Alive, Visited)) return true; - for (unsigned j = 0, e = CS.getNumPtrArgs(); j != e; ++j) - if (CanReachAliveNodes(CS.getPtrArg(j).getNode(), Alive, Visited)) + for (unsigned i = 0, e = CS.getNumPtrArgs(); i != e; ++i) + if (CanReachAliveNodes(CS.getPtrArg(i).getNode(), Alive, Visited)) return true; return false; } -// GlobalIsAlivenessRoot - Return true if the specified global node is -// intrinsically alive in the context of the current graph (ie, it is a root of -// aliveness). For TD graphs, no globals are. For the BU graphs all are unless -// they are trivial globals... -// -static bool GlobalIsAlivenessRoot(DSNode *N, unsigned Flags) { - if (Flags & DSGraph::RemoveUnreachableGlobals) - return false; // If we are to remove all globals, go for it. - - // Ok, we are keeping globals... hrm, we can still delete it if it has no - // links, and no mod/ref or other info... If it is not modified, it can't - // have links... - // - if ((N->NodeType & ~(DSNode::Composition | DSNode::Array)) == 0) - return false; - return true; -} - // removeDeadNodes - Use a more powerful reachability analysis to eliminate // subgraphs that are unreachable. This often occurs because the data // structure doesn't "escape" into it's caller, and thus should be eliminated @@ -1020,7 +972,8 @@ // inlining graphs. // void DSGraph::removeDeadNodes(unsigned Flags) { - // Reduce the amount of work we have to do... + // Reduce the amount of work we have to do... remove dummy nodes left over by + // merging... removeTriviallyDeadNodes(); // FIXME: Merge nontrivially identical call nodes... @@ -1032,75 +985,133 @@ // Mark all nodes reachable by (non-global) scalar nodes as alive... for (hash_map::iterator I = ScalarMap.begin(), E = ScalarMap.end(); I != E; ++I) - if (!isa(I->first) || - GlobalIsAlivenessRoot(I->second.getNode(), Flags)) + if (!isa(I->first)) I->second.getNode()->markReachableNodes(Alive); - else // Keep track of global nodes + else { // Keep track of global nodes GlobalNodes.push_back(std::make_pair(I->first, I->second.getNode())); + assert(I->second.getNode() && "Null global node?"); + } // The return value is alive as well... RetNode.getNode()->markReachableNodes(Alive); - // If any global nodes points to a non-global that is "alive", the global is - // "alive" as well... - // - hash_set Visited; - for (unsigned i = 0, e = GlobalNodes.size(); i != e; ++i) - CanReachAliveNodes(GlobalNodes[i].second, Alive, Visited); - - std::vector FCallsAlive(FunctionCalls.size()); + // Mark any nodes reachable by primary calls as alive... for (unsigned i = 0, e = FunctionCalls.size(); i != e; ++i) - if (!(Flags & DSGraph::RemoveUnreachableGlobals) || - CallSiteUsesAliveArgs(FunctionCalls[i], Alive, Visited)) { - FunctionCalls[i].markReachableNodes(Alive); - FCallsAlive[i] = true; - } + FunctionCalls[i].markReachableNodes(Alive); - std::vector AuxFCallsAlive(AuxFunctionCalls.size()); - for (unsigned i = 0, e = AuxFunctionCalls.size(); i != e; ++i) - if (!(Flags & DSGraph::RemoveUnreachableGlobals) || - CallSiteUsesAliveArgs(AuxFunctionCalls[i], Alive, Visited)) { - AuxFunctionCalls[i].markReachableNodes(Alive); - AuxFCallsAlive[i] = true; - } + bool Iterate; + hash_set Visited; + std::vector AuxFCallsAlive(AuxFunctionCalls.size()); + do { + Visited.clear(); + // If any global nodes points to a non-global that is "alive", the global is + // "alive" as well... Remov it from the GlobalNodes list so we only have + // unreachable globals in the list. + // + Iterate = false; + for (unsigned i = 0; i != GlobalNodes.size(); ++i) + if (CanReachAliveNodes(GlobalNodes[i].second, Alive, Visited)) { + std::swap(GlobalNodes[i--], GlobalNodes.back()); // Move to end to erase + GlobalNodes.pop_back(); // Erase efficiently + Iterate = true; + } - // Remove all dead function calls... - unsigned CurIdx = 0; - for (unsigned i = 0, e = FunctionCalls.size(); i != e; ++i) - if (FCallsAlive[i]) - FunctionCalls[CurIdx++].swap(FunctionCalls[i]); - // Crop all the bad ones out... - FunctionCalls.erase(FunctionCalls.begin()+CurIdx, FunctionCalls.end()); + for (unsigned i = 0, e = AuxFunctionCalls.size(); i != e; ++i) + if (!AuxFCallsAlive[i] && + CallSiteUsesAliveArgs(AuxFunctionCalls[i], Alive, Visited)) { + AuxFunctionCalls[i].markReachableNodes(Alive); + AuxFCallsAlive[i] = true; + Iterate = true; + } + } while (Iterate); // Remove all dead aux function calls... - CurIdx = 0; + unsigned CurIdx = 0; for (unsigned i = 0, e = AuxFunctionCalls.size(); i != e; ++i) if (AuxFCallsAlive[i]) AuxFunctionCalls[CurIdx++].swap(AuxFunctionCalls[i]); - // Crop all the bad ones out... + if (!(Flags & DSGraph::RemoveUnreachableGlobals)) { + // Move the unreachable call nodes to the globals graph... + GlobalsGraph->AuxFunctionCalls.insert(GlobalsGraph->AuxFunctionCalls.end(), + AuxFunctionCalls.begin()+CurIdx, + AuxFunctionCalls.end()); + } + // Crop all the useless ones out... AuxFunctionCalls.erase(AuxFunctionCalls.begin()+CurIdx, AuxFunctionCalls.end()); - - // Remove all unreachable globals from the ScalarMap - for (unsigned i = 0, e = GlobalNodes.size(); i != e; ++i) - if (!Alive.count(GlobalNodes[i].second)) - ScalarMap.erase(GlobalNodes[i].first); - - // Loop over all unreachable nodes, dropping their references... + // At this point, any nodes which are visited, but not alive, are nodes which + // should be moved to the globals graph. Loop over all nodes, eliminating + // completely unreachable nodes, and moving visited nodes to the globals graph + // for (unsigned i = 0; i != Nodes.size(); ++i) if (!Alive.count(Nodes[i])) { DSNode *N = Nodes[i]; std::swap(Nodes[i--], Nodes.back()); // move node to end of vector Nodes.pop_back(); // Erase node from alive list. - N->dropAllReferences(); // Drop all outgoing edges + if (!(Flags & DSGraph::RemoveUnreachableGlobals) && // Not in TD pass + Visited.count(N)) { // Visited but not alive? + GlobalsGraph->Nodes.push_back(N); // Move node to globals graph + } else { // Otherwise, delete the node + assert(((N->NodeType & DSNode::GlobalNode) == 0 || + (Flags & DSGraph::RemoveUnreachableGlobals)) + && "Killing a global?"); + while (!N->getReferrers().empty()) // Rewrite referrers + N->getReferrers().back()->setNode(0); + delete N; // Usecount is zero + } + } + + // Now that the nodes have either been deleted or moved to the globals graph, + // loop over the scalarmap, updating the entries for globals... + // + if (!(Flags & DSGraph::RemoveUnreachableGlobals)) { // Not in the TD pass? + // In this array we start the remapping, which can cause merging. Because + // of this, the DSNode pointers in GlobalNodes may be invalidated, so we + // must always go through the ScalarMap (which contains DSNodeHandles [which + // cannot be invalidated by merging]). + // + for (unsigned i = 0, e = GlobalNodes.size(); i != e; ++i) { + Value *G = GlobalNodes[i].first; + hash_map::iterator I = ScalarMap.find(G); + assert(I != ScalarMap.end() && "Global not in scalar map anymore?"); + assert(I->second.getNode() && "Global not pointing to anything?"); + assert(!Alive.count(I->second.getNode()) && "Node is alive??"); + GlobalsGraph->ScalarMap[G].mergeWith(I->second); + assert(GlobalsGraph->ScalarMap[G].getNode() && + "Global not pointing to anything?"); + ScalarMap.erase(I); + } + + // Merging leaves behind silly nodes, we remove them to avoid polluting the + // globals graph. + GlobalsGraph->removeTriviallyDeadNodes(); + } else { + // If we are in the top-down pass, remove all unreachable globals from the + // ScalarMap... + for (unsigned i = 0, e = GlobalNodes.size(); i != e; ++i) + ScalarMap.erase(GlobalNodes[i].first); + } + + DEBUG(AssertGraphOK(); GlobalsGraph->AssertGraphOK()); +} - while (!N->getReferrers().empty()) - N->getReferrers().back()->setNode(0); - delete N; +void DSGraph::AssertGraphOK() const { + for (hash_map::const_iterator I = ScalarMap.begin(), + E = ScalarMap.end(); I != E; ++I) { + assert(I->second.getNode() && "Null node in scalarmap!"); + AssertNodeInGraph(I->second.getNode()); + if (GlobalValue *GV = dyn_cast(I->first)) { + assert((I->second.getNode()->NodeType & DSNode::GlobalNode) && + "Global points to node, but node isn't global?"); + AssertNodeContainsGlobal(I->second.getNode(), GV); } + } + AssertCallNodesInGraph(); + AssertAuxCallNodesInGraph(); } + #if 0 //===----------------------------------------------------------------------===// // GlobalDSGraph Implementation @@ -1110,6 +1121,30 @@ // Bits used in the next function static const char ExternalTypeBits = DSNode::GlobalNode | DSNode::HeapNode; +// cloneGlobalInto - Clone the given global node and all its target links +// (and all their llinks, recursively). +// +DSNode *DSGraph::cloneGlobalInto(const DSNode *GNode) { + if (GNode == 0 || GNode->getGlobals().size() == 0) return 0; + + // If a clone has already been created for GNode, return it. + DSNodeHandle& ValMapEntry = ScalarMap[GNode->getGlobals()[0]]; + if (ValMapEntry != 0) + return ValMapEntry; + + // Clone the node and update the ValMap. + DSNode* NewNode = new DSNode(*GNode); + ValMapEntry = NewNode; // j=0 case of loop below! + Nodes.push_back(NewNode); + for (unsigned j = 1, N = NewNode->getGlobals().size(); j < N; ++j) + ScalarMap[NewNode->getGlobals()[j]] = NewNode; + + // Rewrite the links in the new node to point into the current graph. + for (unsigned j = 0, e = GNode->getNumLinks(); j != e; ++j) + NewNode->setLink(j, cloneGlobalInto(GNode->getLink(j))); + + return NewNode; +} // GlobalDSGraph::cloneNodeInto - Clone a global node and all its externally // visible target links (and recursively their such links) into this graph. From lattner at cs.uiuc.edu Mon Feb 3 13:13:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Feb 3 13:13:02 2003 Subject: [llvm-commits] CVS: llvm/test/Libraries/libdummy/dummylib.c Message-ID: <200302031912.NAA11583@apoc.cs.uiuc.edu> Changes in directory llvm/test/Libraries/libdummy: dummylib.c updated: 1.2 -> 1.3 --- Log message: Implement feof and xmalloc --- Diffs of the changes: Index: llvm/test/Libraries/libdummy/dummylib.c diff -u llvm/test/Libraries/libdummy/dummylib.c:1.2 llvm/test/Libraries/libdummy/dummylib.c:1.3 --- llvm/test/Libraries/libdummy/dummylib.c:1.2 Fri Jan 31 22:51:12 2003 +++ llvm/test/Libraries/libdummy/dummylib.c Mon Feb 3 13:12:38 2003 @@ -5,6 +5,7 @@ #include int gettimeofday(struct timeval *tv, void *tz) { return 0; } +void *xmalloc(size_t X) { return malloc(X); } void srand(unsigned x) {} double exp(double x) { return 0; } @@ -35,6 +36,7 @@ int getc(FILE *S) { return 0; } size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream) { return 0; } int fseek(FILE *stream, long offset, int whence) { return 0; } +int feof(FILE *stream) { return 0; } int fputs(const char *s, FILE *stream) { return 0; } int ferror(FILE *F) { return 0; } FILE *fdopen(int fildes, const char *mode) { return 0;} From lattner at cs.uiuc.edu Mon Feb 3 14:09:06 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Feb 3 14:09:06 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/DataStructure.cpp Message-ID: <200302032009.OAA12154@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: DataStructure.cpp updated: 1.84 -> 1.85 --- Log message: * Fix a bug introduced in the last checkin wrt Stack markers * Make cloning more efficient in the process... --- Diffs of the changes: Index: llvm/lib/Analysis/DataStructure/DataStructure.cpp diff -u llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.84 llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.85 --- llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.84 Mon Feb 3 13:12:15 2003 +++ llvm/lib/Analysis/DataStructure/DataStructure.cpp Mon Feb 3 14:08:51 2003 @@ -599,10 +599,15 @@ // Duplicate all of the nodes, populating the node map... 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... for (unsigned i = 0, e = G.Nodes.size(); i != e; ++i) { DSNode *Old = G.Nodes[i]; DSNode *New = new DSNode(*Old); - New->NodeType &= ~DSNode::DEAD; // Clear dead flag... + New->NodeType &= ~clearBits; Nodes.push_back(New); OldNodeMap[Old] = New; } @@ -614,13 +619,6 @@ // 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); - - // Remove alloca markers as specified - if (CloneFlags & (StripAllocaBit | StripModRefBits)) { - unsigned clearBits = (CloneFlags & StripAllocaBit ? DSNode::AllocaNode : 0) - | (CloneFlags & StripModRefBits ? (DSNode::Modified | DSNode::Read) : 0); - maskNodeTypes(~clearBits); - } // Copy the scalar map... merging all of the global nodes... for (hash_map::const_iterator I = G.ScalarMap.begin(), From lattner at cs.uiuc.edu Mon Feb 3 14:32:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Feb 3 14:32:01 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/DSGraphAA/ Message-ID: <200302032031.OAA12991@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/DSGraphAA: --- Log message: Directory /home/vadve/vadve/Research/DynOpt/CVSRepository/llvm/test/Regression/Transforms/DSGraphAA added to the repository --- Diffs of the changes: From lattner at cs.uiuc.edu Mon Feb 3 15:17:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Feb 3 15:17:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/AliasAnalysis.cpp Message-ID: <200302032116.PAA15279@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: AliasAnalysis.cpp updated: 1.6 -> 1.7 --- Log message: Add statistics to basicAA pass --- Diffs of the changes: Index: llvm/lib/Analysis/AliasAnalysis.cpp diff -u llvm/lib/Analysis/AliasAnalysis.cpp:1.6 llvm/lib/Analysis/AliasAnalysis.cpp:1.7 --- llvm/lib/Analysis/AliasAnalysis.cpp:1.6 Wed Nov 6 11:17:29 2002 +++ llvm/lib/Analysis/AliasAnalysis.cpp Mon Feb 3 15:16:17 2003 @@ -25,9 +25,15 @@ #include "llvm/Constants.h" #include "llvm/GlobalValue.h" #include "llvm/DerivedTypes.h" +#include "Support/Statistic.h" // Register the AliasAnalysis interface, providing a nice name to refer to. -static RegisterAnalysisGroup X("Alias Analysis"); +namespace { + RegisterAnalysisGroup Z("Alias Analysis"); + Statistic<> NumNoAlias ("basic-aa", "Number of 'no alias' replies"); + Statistic<> NumMayAlias ("basic-aa", "Number of 'may alias' replies"); + Statistic<> NumMustAlias("basic-aa", "Number of 'must alias' replies"); +} // CanModify - Define a little visitor class that is used to check to see if // arbitrary chunks of code can modify a specified pointer. @@ -139,6 +145,21 @@ return 0; } +static inline AliasAnalysis::Result MustAlias() { + ++NumMustAlias; + return AliasAnalysis::MustAlias; +} + +static inline AliasAnalysis::Result MayAlias() { + ++NumMayAlias; + return AliasAnalysis::MayAlias; +} + +static inline AliasAnalysis::Result NoAlias() { + ++NumNoAlias; + return AliasAnalysis::NoAlias; +} + // alias - Provide a bunch of ad-hoc rules to disambiguate in common cases, such // as array references. Note that this function is heavily tail recursive. // Hopefully we have a smart C++ compiler. :) @@ -152,11 +173,11 @@ V2 = CPR->getValue(); // Are we checking for alias of the same value? - if (V1 == V2) return MustAlias; + if (V1 == V2) return ::MustAlias(); if ((!isa(V1->getType()) || !isa(V2->getType())) && V1->getType() != Type::LongTy && V2->getType() != Type::LongTy) - return NoAlias; // Scalars cannot alias each other + return ::NoAlias(); // Scalars cannot alias each other // Strip off cast instructions... if (const Instruction *I = dyn_cast(V1)) @@ -195,7 +216,7 @@ // if (AllConstant && alias(GEP1->getOperand(0), GEP2->getOperand(1)) != MayAlias) - return NoAlias; + return ::NoAlias(); } // Figure out what objects these things are pointing to if we can... @@ -205,16 +226,16 @@ // Pointing at a discernable object? if (O1 && O2) { // If they are two different objects, we know that we have no alias... - if (O1 != O2) return NoAlias; + if (O1 != O2) return ::NoAlias(); // If they are the same object, they we can look at the indexes. If they // index off of the object is the same for both pointers, they must alias. // If they are provably different, they must not alias. Otherwise, we can't // tell anything. } else if (O1 && isa(V2)) { - return NoAlias; // Unique values don't alias null + return ::NoAlias(); // Unique values don't alias null } else if (O2 && isa(V1)) { - return NoAlias; // Unique values don't alias null + return ::NoAlias(); // Unique values don't alias null } return MayAlias; From lattner at cs.uiuc.edu Mon Feb 3 15:32:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Feb 3 15:32:01 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/DSGraphAA/Makefile gcsetest.ll Message-ID: <200302032131.PAA15420@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/DSGraphAA: Makefile added (r1.1) gcsetest.ll added (r1.1) --- Log message: Initial tests for DS alias analysis --- Diffs of the changes: From lattner at cs.uiuc.edu Mon Feb 3 15:33:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Feb 3 15:33:01 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/Makefile Message-ID: <200302032132.PAA15430@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms: Makefile updated: 1.19 -> 1.20 --- Log message: Build DS-AA tests --- Diffs of the changes: Index: llvm/test/Regression/Transforms/Makefile diff -u llvm/test/Regression/Transforms/Makefile:1.19 llvm/test/Regression/Transforms/Makefile:1.20 --- llvm/test/Regression/Transforms/Makefile:1.19 Tue Oct 15 16:20:18 2002 +++ llvm/test/Regression/Transforms/Makefile Mon Feb 3 15:31:53 2003 @@ -5,6 +5,7 @@ ConstantMerge \ CorrelatedExprs \ DecomposeMultiDimRefs \ + DSGraphAA \ FunctionResolve \ GCSE \ GlobalDCE \ From lattner at cs.uiuc.edu Mon Feb 3 15:41:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Feb 3 15:41:01 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/DSGraphAA/gcsetest.ll Message-ID: <200302032140.PAA15487@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/DSGraphAA: gcsetest.ll updated: 1.1 -> 1.2 --- Log message: Check field sensitivity --- Diffs of the changes: Index: llvm/test/Regression/Transforms/DSGraphAA/gcsetest.ll diff -u llvm/test/Regression/Transforms/DSGraphAA/gcsetest.ll:1.1 llvm/test/Regression/Transforms/DSGraphAA/gcsetest.ll:1.2 --- llvm/test/Regression/Transforms/DSGraphAA/gcsetest.ll:1.1 Mon Feb 3 15:31:43 2003 +++ llvm/test/Regression/Transforms/DSGraphAA/gcsetest.ll Mon Feb 3 15:40:14 2003 @@ -20,12 +20,22 @@ ret %intpair* %C } +int* %getp(%intpair* %P) { + %pp = getelementptr %intpair* %P, long 0, ubyte 0 + %V = load int** %pp + ret int *%V +} + +int* %getq(%intpair* %P) { + %pp = getelementptr %intpair* %P, long 0, ubyte 1 + %V = load int** %pp + ret int *%V +} + int %test() { %C = call %intpair* %alloc_pair() - %C1p = getelementptr %intpair* %C, long 0, ubyte 0 - %C2p = getelementptr %intpair* %C, long 0, ubyte 1 - %A = load int** %C1p - %B = load int** %C2p + %A = call int* %getp(%intpair* %C) + %B = call int* %getp(%intpair* %C) %A1 = load int* %A store int 123, int* %B ; Store cannot alias %A @@ -35,12 +45,6 @@ ret int %ELIM_x } -int* %getp(%intpair* %P) { - %pp = getelementptr %intpair* %P, long 0, ubyte 0 - %V = load int** %pp - ret int *%V -} - int %test2() { ; Test context sensitivity %C1 = call %intpair* %alloc_pair() %C2 = call %intpair* %alloc_pair() @@ -53,3 +57,13 @@ ret int %ELIM_x } +int %test3() { + %C = call %intpair* %alloc_pair() + %P1 = call int* %getp(%intpair* %C) + %P2 = call int* %getq(%intpair* %C) + %X = load int* %P1 + store int 7, int* %P2 + %Y = load int* %P1 + %ELIM_x = sub int %X, %Y ; Check field sensitivity + ret int %ELIM_x +} From lattner at cs.uiuc.edu Mon Feb 3 16:52:00 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Feb 3 16:52:00 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/DataStructureAA.cpp Message-ID: <200302032251.QAA18350@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: DataStructureAA.cpp added (r1.1) --- Log message: Initial implementation of ds-aa --- Diffs of the changes: From lattner at cs.uiuc.edu Mon Feb 3 16:52:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Feb 3 16:52:02 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/DataStructure.h Message-ID: <200302032251.QAA18369@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: DataStructure.h updated: 1.61 -> 1.62 --- Log message: Hack to work around deficiency in pass infrastructure --- Diffs of the changes: Index: llvm/include/llvm/Analysis/DataStructure.h diff -u llvm/include/llvm/Analysis/DataStructure.h:1.61 llvm/include/llvm/Analysis/DataStructure.h:1.62 --- llvm/include/llvm/Analysis/DataStructure.h:1.61 Fri Jan 31 22:51:53 2003 +++ llvm/include/llvm/Analysis/DataStructure.h Mon Feb 3 16:51:26 2003 @@ -136,7 +136,7 @@ hash_set GraphDone; DSGraph *GlobalsGraph; public: - ~TDDataStructures() { releaseMemory(); } + ~TDDataStructures() { releaseMyMemory(); } virtual bool run(Module &M); @@ -157,13 +157,14 @@ void print(std::ostream &O, const Module *M) const; // If the pass pipeline is done with this pass, we can release our memory... - virtual void releaseMemory(); + virtual void releaseMyMemory(); // getAnalysisUsage - This obviously provides a data structure graph. virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); AU.addRequired(); } + private: void calculateGraph(Function &F); DSGraph &getOrCreateDSGraph(Function &F); From lattner at cs.uiuc.edu Mon Feb 3 16:52:03 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Feb 3 16:52:03 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/TopDownClosure.cpp Message-ID: <200302032251.QAA18376@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: TopDownClosure.cpp updated: 1.33 -> 1.34 --- Log message: Hack to work around deficiency in pass infrastructure --- Diffs of the changes: Index: llvm/lib/Analysis/DataStructure/TopDownClosure.cpp diff -u llvm/lib/Analysis/DataStructure/TopDownClosure.cpp:1.33 llvm/lib/Analysis/DataStructure/TopDownClosure.cpp:1.34 --- llvm/lib/Analysis/DataStructure/TopDownClosure.cpp:1.33 Fri Jan 31 22:51:55 2003 +++ llvm/lib/Analysis/DataStructure/TopDownClosure.cpp Mon Feb 3 16:51:28 2003 @@ -13,8 +13,10 @@ #include "llvm/DerivedTypes.h" #include "Support/Statistic.h" -static RegisterAnalysis -Y("tddatastructure", "Top-down Data Structure Analysis Closure"); +namespace { + RegisterAnalysis // Register the pass + Y("tddatastructure", "Top-down Data Structure Analysis Closure"); +} // run - Calculate the top down data structure graphs for each function in the // program. @@ -39,7 +41,10 @@ // releaseMemory - If the pass pipeline is done with this pass, we can release // our memory... here... // -void TDDataStructures::releaseMemory() { +// FIXME: This should be releaseMemory and will work fine, except that LoadVN +// has no way to extend the lifetime of the pass, which screws up ds-aa. +// +void TDDataStructures::releaseMyMemory() { for (hash_map::iterator I = DSInfo.begin(), E = DSInfo.end(); I != E; ++I) delete I->second; @@ -206,3 +211,4 @@ calculateGraph(*I->first); } } + From lattner at cs.uiuc.edu Mon Feb 3 16:53:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Feb 3 16:53:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/Steensgaard.cpp Message-ID: <200302032252.QAA18388@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: Steensgaard.cpp updated: 1.16 -> 1.17 --- Log message: Rename variable --- Diffs of the changes: Index: llvm/lib/Analysis/DataStructure/Steensgaard.cpp diff -u llvm/lib/Analysis/DataStructure/Steensgaard.cpp:1.16 llvm/lib/Analysis/DataStructure/Steensgaard.cpp:1.17 --- llvm/lib/Analysis/DataStructure/Steensgaard.cpp:1.16 Fri Jan 31 22:51:55 2003 +++ llvm/lib/Analysis/DataStructure/Steensgaard.cpp Mon Feb 3 16:51:53 2003 @@ -209,17 +209,17 @@ AliasAnalysis::Result Steens::alias(const Value *V1, const Value *V2) { assert(ResultGraph && "Result graph has not been computed yet!"); - hash_map &GVM = ResultGraph->getScalarMap(); + hash_map &GSM = ResultGraph->getScalarMap(); - hash_map::iterator I = GVM.find(const_cast(V1)); - if (I != GVM.end() && I->second.getNode()) { + hash_map::iterator I = GSM.find(const_cast(V1)); + if (I != GSM.end() && I->second.getNode()) { DSNodeHandle &V1H = I->second; - hash_map::iterator J=GVM.find(const_cast(V2)); - if (J != GVM.end() && J->second.getNode()) { + hash_map::iterator J=GSM.find(const_cast(V2)); + if (J != GSM.end() && J->second.getNode()) { DSNodeHandle &V2H = J->second; // If the two pointers point to different data structure graph nodes, they // cannot alias! - if (V1H.getNode() != V2H.getNode()) { + if (V1H.getNode() != V2H.getNode()) { // FIXME: Handle incompleteness! ++NumNoAlias; return NoAlias; } From lattner at cs.uiuc.edu Mon Feb 3 18:04:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Feb 3 18:04:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/Printer.cpp Message-ID: <200302040003.SAA19678@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: Printer.cpp updated: 1.45 -> 1.46 --- Log message: Fix printing of nonfunction graphs --- Diffs of the changes: Index: llvm/lib/Analysis/DataStructure/Printer.cpp diff -u llvm/lib/Analysis/DataStructure/Printer.cpp:1.45 llvm/lib/Analysis/DataStructure/Printer.cpp:1.46 --- llvm/lib/Analysis/DataStructure/Printer.cpp:1.45 Sun Feb 2 10:42:01 2003 +++ llvm/lib/Analysis/DataStructure/Printer.cpp Mon Feb 3 18:03:18 2003 @@ -29,7 +29,7 @@ static std::string getCaption(const DSNode *N, const DSGraph *G) { std::stringstream OS; - Module *M = G && &G->getFunction() ? G->getFunction().getParent() : 0; + Module *M = G && G->hasFunction() ? G->getFunction().getParent() : 0; if (N->isNodeCompletelyFolded()) OS << "FOLDED"; @@ -86,13 +86,15 @@ /// static void addCustomGraphFeatures(const DSGraph *G, GraphWriter &GW) { + Module *CurMod = G->hasFunction() ? G->getFunction().getParent() : 0; + // Add scalar nodes to the graph... const hash_map &VM = G->getScalarMap(); for (hash_map::const_iterator I = VM.begin(); I != VM.end(); ++I) if (!isa(I->first)) { std::stringstream OS; - WriteAsOperand(OS, I->first, false, true, G->getFunction().getParent()); + WriteAsOperand(OS, I->first, false, true, CurMod); GW.emitSimpleNode(I->first, "", OS.str()); // Add edge from return node to real destination From lattner at cs.uiuc.edu Mon Feb 3 18:04:03 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Feb 3 18:04:03 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/DataStructure.cpp Message-ID: <200302040003.SAA19688@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: DataStructure.cpp updated: 1.85 -> 1.86 --- Log message: Add sanity check --- Diffs of the changes: Index: llvm/lib/Analysis/DataStructure/DataStructure.cpp diff -u llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.85 llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.86 --- llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.85 Mon Feb 3 14:08:51 2003 +++ llvm/lib/Analysis/DataStructure/DataStructure.cpp Mon Feb 3 18:03:04 2003 @@ -1029,6 +1029,7 @@ if (AuxFCallsAlive[i]) AuxFunctionCalls[CurIdx++].swap(AuxFunctionCalls[i]); if (!(Flags & DSGraph::RemoveUnreachableGlobals)) { + assert(GlobalsGraph && "No globals graph available??"); // Move the unreachable call nodes to the globals graph... GlobalsGraph->AuxFunctionCalls.insert(GlobalsGraph->AuxFunctionCalls.end(), AuxFunctionCalls.begin()+CurIdx, From lattner at cs.uiuc.edu Mon Feb 3 18:04:04 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Feb 3 18:04:04 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/Steensgaard.cpp Message-ID: <200302040003.SAA19695@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: Steensgaard.cpp updated: 1.17 -> 1.18 --- Log message: Fix steensgaard to work on a lot more cases... --- Diffs of the changes: Index: llvm/lib/Analysis/DataStructure/Steensgaard.cpp diff -u llvm/lib/Analysis/DataStructure/Steensgaard.cpp:1.17 llvm/lib/Analysis/DataStructure/Steensgaard.cpp:1.18 --- llvm/lib/Analysis/DataStructure/Steensgaard.cpp:1.17 Mon Feb 3 16:51:53 2003 +++ llvm/lib/Analysis/DataStructure/Steensgaard.cpp Mon Feb 3 18:03:37 2003 @@ -21,6 +21,7 @@ namespace { class Steens : public Pass, public AliasAnalysis { DSGraph *ResultGraph; + DSGraph *GlobalsGraph; // FIXME: Eliminate globals graph stuff from DNE public: Steens() : ResultGraph(0) {} ~Steens() { assert(ResultGraph == 0 && "releaseMemory not called?"); } @@ -85,8 +86,7 @@ /// with the specified call site descriptor. This function links the arguments /// and the return value for the call site context-insensitively. /// -void Steens::ResolveFunctionCall(Function *F, - const DSCallSite &Call, +void Steens::ResolveFunctionCall(Function *F, const DSCallSite &Call, DSNodeHandle &RetVal) { assert(ResultGraph != 0 && "Result graph not allocated!"); hash_map &ValMap = ResultGraph->getScalarMap(); @@ -100,7 +100,7 @@ for (Function::aiterator AI = F->abegin(), AE = F->aend(); AI != AE; ++AI) { hash_map::iterator I = ValMap.find(AI); if (I != ValMap.end()) // If its a pointer argument... - I->second.addEdgeTo(Call.getPtrArg(PtrArgIdx++)); + I->second.mergeWith(Call.getPtrArg(PtrArgIdx++)); } assert(PtrArgIdx == Call.getNumPtrArgs() && "Argument resolution mismatch!"); @@ -116,7 +116,8 @@ // Create a new, empty, graph... ResultGraph = new DSGraph(); - + GlobalsGraph = new DSGraph(); + ResultGraph->setGlobalsGraph(GlobalsGraph); // RetValMap - Keep track of the return values for all functions that return // valid pointers. // @@ -143,16 +144,9 @@ // Incorporate the inlined Function's ScalarMap into the global // ScalarMap... hash_map &GVM = ResultGraph->getScalarMap(); - - while (!ValMap.empty()) { // Loop over value map, moving entries over... - const std::pair &DSN = *ValMap.begin(); - hash_map::iterator I = GVM.find(DSN.first); - if (I == GVM.end()) - GVM[DSN.first] = DSN.second; - else - I->second.mergeWith(DSN.second); - ValMap.erase(ValMap.begin()); - } + for (hash_map::iterator I = ValMap.begin(), + E = ValMap.end(); I != E; ++I) + GVM[I->first].mergeWith(I->second); } // FIXME: Must recalculate and use the Incomplete markers!! @@ -199,6 +193,7 @@ ResultGraph->markIncompleteNodes(DSGraph::IgnoreFormalArgs); // Remove any nodes that are dead after all of the merging we have done... + // FIXME: We should be able to disable the globals graph for steens! ResultGraph->removeDeadNodes(DSGraph::KeepUnreachableGlobals); DEBUG(print(std::cerr, &M)); From lattner at cs.uiuc.edu Mon Feb 3 18:05:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Feb 3 18:05:01 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/DSGraph.h Message-ID: <200302040004.SAA19707@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: DSGraph.h updated: 1.42 -> 1.43 --- Log message: Add sanity check --- Diffs of the changes: Index: llvm/include/llvm/Analysis/DSGraph.h diff -u llvm/include/llvm/Analysis/DSGraph.h:1.42 llvm/include/llvm/Analysis/DSGraph.h:1.43 --- llvm/include/llvm/Analysis/DSGraph.h:1.42 Mon Feb 3 13:10:24 2003 +++ llvm/include/llvm/Analysis/DSGraph.h Mon Feb 3 18:03:57 2003 @@ -53,7 +53,10 @@ ~DSGraph(); bool hasFunction() const { return Func != 0; } - Function &getFunction() const { return *Func; } + Function &getFunction() const { + assert(hasFunction() && "Cannot call getFunction on graph without a fn!"); + return *Func; + } DSGraph *getGlobalsGraph() const { return GlobalsGraph; } void setGlobalsGraph(DSGraph *G) { GlobalsGraph = G; } From lattner at cs.uiuc.edu Mon Feb 3 19:01:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Feb 3 19:01:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/Local.cpp Message-ID: <200302040100.TAA20558@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: Local.cpp updated: 1.45 -> 1.46 --- Log message: Fix a huge bug with handling non-pointer instructions --- Diffs of the changes: Index: llvm/lib/Analysis/DataStructure/Local.cpp diff -u llvm/lib/Analysis/DataStructure/Local.cpp:1.45 llvm/lib/Analysis/DataStructure/Local.cpp:1.46 --- llvm/lib/Analysis/DataStructure/Local.cpp:1.45 Fri Jan 31 22:51:55 2003 +++ llvm/lib/Analysis/DataStructure/Local.cpp Mon Feb 3 18:59:50 2003 @@ -91,7 +91,7 @@ void visitSetCondInst(SetCondInst &SCI) {} // SetEQ & friends are ignored void visitFreeInst(FreeInst &FI); void visitCastInst(CastInst &CI); - void visitInstruction(Instruction &I) {} + void visitInstruction(Instruction &I); private: // Helper functions used to implement the visitation functions... @@ -410,6 +410,21 @@ } } + +// visitInstruction - For all other instruction types, if we have any arguments +// that are of pointer type, make them have unknown composition bits, and merge +// the nodes together. +void GraphBuilder::visitInstruction(Instruction &Inst) { + DSNodeHandle CurNode; + if (isPointerType(Inst.getType())) + CurNode = getValueDest(Inst); + for (User::op_iterator I = Inst.op_begin(), E = Inst.op_end(); I != E; ++I) + if (isPointerType((*I)->getType())) + CurNode.mergeWith(getValueDest(**I)); + + if (CurNode.getNode()) + CurNode.getNode()->NodeType |= DSNode::UnknownNode; +} From lattner at cs.uiuc.edu Mon Feb 3 19:01:03 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Mon Feb 3 19:01:03 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/TopDownClosure.cpp Message-ID: <200302040100.TAA20568@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: TopDownClosure.cpp updated: 1.34 -> 1.35 --- Log message: Make the TD pass not include all of the call nodes from the local pass, eliminating incomplete markers from them --- Diffs of the changes: Index: llvm/lib/Analysis/DataStructure/TopDownClosure.cpp diff -u llvm/lib/Analysis/DataStructure/TopDownClosure.cpp:1.34 llvm/lib/Analysis/DataStructure/TopDownClosure.cpp:1.35 --- llvm/lib/Analysis/DataStructure/TopDownClosure.cpp:1.34 Mon Feb 3 16:51:28 2003 +++ llvm/lib/Analysis/DataStructure/TopDownClosure.cpp Mon Feb 3 18:59:32 2003 @@ -87,6 +87,7 @@ if (G == 0) { // Not created yet? Clone BU graph... G = new DSGraph(getAnalysis().getDSGraph(F)); G->getAuxFunctionCalls().clear(); + G->setPrintAuxCalls(); G->setGlobalsGraph(GlobalsGraph); } return *G; From lattner at cs.uiuc.edu Tue Feb 4 10:34:00 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Tue Feb 4 10:34:00 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/Steensgaard.cpp Message-ID: <200302041633.KAA01259@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: Steensgaard.cpp updated: 1.18 -> 1.19 --- Log message: Remove bogus assertion --- Diffs of the changes: Index: llvm/lib/Analysis/DataStructure/Steensgaard.cpp diff -u llvm/lib/Analysis/DataStructure/Steensgaard.cpp:1.18 llvm/lib/Analysis/DataStructure/Steensgaard.cpp:1.19 --- llvm/lib/Analysis/DataStructure/Steensgaard.cpp:1.18 Mon Feb 3 18:03:37 2003 +++ llvm/lib/Analysis/DataStructure/Steensgaard.cpp Tue Feb 4 10:33:23 2003 @@ -102,8 +102,6 @@ if (I != ValMap.end()) // If its a pointer argument... I->second.mergeWith(Call.getPtrArg(PtrArgIdx++)); } - - assert(PtrArgIdx == Call.getNumPtrArgs() && "Argument resolution mismatch!"); } From lattner at cs.uiuc.edu Wed Feb 5 13:42:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Feb 5 13:42:01 2003 Subject: [llvm-commits] CVS: llvm/include/Support/GraphWriter.h Message-ID: <200302051941.NAA28946@apoc.cs.uiuc.edu> Changes in directory llvm/include/Support: GraphWriter.h updated: 1.12 -> 1.13 --- Log message: Allow the addition of edge source labels --- Diffs of the changes: Index: llvm/include/Support/GraphWriter.h diff -u llvm/include/Support/GraphWriter.h:1.12 llvm/include/Support/GraphWriter.h:1.13 --- llvm/include/Support/GraphWriter.h:1.12 Sun Nov 10 00:47:03 2002 +++ llvm/include/Support/GraphWriter.h Wed Feb 5 13:40:59 2003 @@ -18,6 +18,7 @@ #include "Support/DOTGraphTraits.h" #include "Support/GraphTraits.h" +#include #include namespace DOT { // Private functions... @@ -136,7 +137,8 @@ /// emitSimpleNode - Outputs a simple (non-record) node void emitSimpleNode(const void *ID, const std::string &Attr, - const std::string &Label, unsigned NumEdgeSources = 0) { + const std::string &Label, unsigned NumEdgeSources = 0, + const std::vector *EdgeSourceLabels = 0) { O << "\tNode" << ID << "[ "; if (!Attr.empty()) O << Attr << ","; @@ -149,6 +151,7 @@ for (unsigned i = 0; i != NumEdgeSources; ++i) { if (i) O << "|"; O << ""; + if (EdgeSourceLabels) O << (*EdgeSourceLabels)[i]; } O << "}}"; } From lattner at cs.uiuc.edu Wed Feb 5 15:45:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Feb 5 15:45:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Support/Timer.cpp Message-ID: <200302052144.PAA32094@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Support: Timer.cpp updated: 1.11 -> 1.12 --- Log message: Squelch warning --- Diffs of the changes: Index: llvm/lib/Support/Timer.cpp diff -u llvm/lib/Support/Timer.cpp:1.11 llvm/lib/Support/Timer.cpp:1.12 --- llvm/lib/Support/Timer.cpp:1.11 Thu Jan 30 17:08:50 2003 +++ llvm/lib/Support/Timer.cpp Wed Feb 5 15:44:28 2003 @@ -89,7 +89,7 @@ static TimeRecord getTimeRecord(bool Start) { struct rusage RU; struct timeval T; - long MemUsed; + long MemUsed = 0; if (Start) { MemUsed = getMemUsage(); if (getrusage(RUSAGE_SELF, &RU)) From lattner at cs.uiuc.edu Wed Feb 5 16:00:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Feb 5 16:00:01 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/DSGraph.h DSSupport.h Message-ID: <200302052159.PAA00318@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: DSGraph.h updated: 1.43 -> 1.44 DSSupport.h updated: 1.11 -> 1.12 --- Log message: Implement optimization for direct function call case. This dramatically reduces the number of function nodes created and speeds up analysis by about 10% overall. --- Diffs of the changes: Index: llvm/include/llvm/Analysis/DSGraph.h diff -u llvm/include/llvm/Analysis/DSGraph.h:1.43 llvm/include/llvm/Analysis/DSGraph.h:1.44 --- llvm/include/llvm/Analysis/DSGraph.h:1.43 Mon Feb 3 18:03:57 2003 +++ llvm/include/llvm/Analysis/DSGraph.h Wed Feb 5 15:59:36 2003 @@ -184,7 +184,7 @@ void mergeInGraph(DSCallSite &CS, const DSGraph &Graph, unsigned CloneFlags); // Methods for checking to make sure graphs are well formed... - void AssertNodeInGraph(DSNode *N) const { + void AssertNodeInGraph(const DSNode *N) const { assert((!N || find(Nodes.begin(), Nodes.end(), N) != Nodes.end()) && "AssertNodeInGraph: Node is not in graph!"); } @@ -194,7 +194,8 @@ } void AssertCallSiteInGraph(const DSCallSite &CS) const { - AssertNodeInGraph(CS.getCallee().getNode()); + if (CS.isIndirectCall()) + AssertNodeInGraph(CS.getCalleeNode()); AssertNodeInGraph(CS.getRetVal().getNode()); for (unsigned j = 0, e = CS.getNumPtrArgs(); j != e; ++j) AssertNodeInGraph(CS.getPtrArg(j).getNode()); Index: llvm/include/llvm/Analysis/DSSupport.h diff -u llvm/include/llvm/Analysis/DSSupport.h:1.11 llvm/include/llvm/Analysis/DSSupport.h:1.12 --- llvm/include/llvm/Analysis/DSSupport.h:1.11 Mon Feb 3 13:11:04 2003 +++ llvm/include/llvm/Analysis/DSSupport.h Wed Feb 5 15:59:36 2003 @@ -106,10 +106,11 @@ /// the DSNode handles for the function arguments. /// class DSCallSite { - CallInst *Inst; // Actual call site - DSNodeHandle RetVal; // Returned value - DSNodeHandle Callee; // The function node called - std::vector CallArgs; // The pointer arguments + CallInst *Inst; // Actual call site + Function *CalleeF; // The function called (direct call) + DSNodeHandle CalleeN; // The function node called (indirect call) + DSNodeHandle RetVal; // Returned value + std::vector CallArgs;// The pointer arguments static void InitNH(DSNodeHandle &NH, const DSNodeHandle &Src, const hash_map &NodeMap) { @@ -138,15 +139,22 @@ /// Constructor. Note - This ctor destroys the argument vector passed in. On /// exit, the argument vector is empty. /// - DSCallSite(CallInst &inst, const DSNodeHandle &rv, const DSNodeHandle &callee, + DSCallSite(CallInst &inst, const DSNodeHandle &rv, DSNode *Callee, std::vector &Args) - : Inst(&inst), RetVal(rv), Callee(callee) { + : Inst(&inst), CalleeF(0), CalleeN(Callee), RetVal(rv) { + assert(Callee && "Null callee node specified for call site!"); + Args.swap(CallArgs); + } + DSCallSite(CallInst &inst, const DSNodeHandle &rv, Function *Callee, + std::vector &Args) + : Inst(&inst), CalleeF(Callee), RetVal(rv) { + assert(Callee && "Null callee function specified for call site!"); Args.swap(CallArgs); } DSCallSite(const DSCallSite &DSCS) // Simple copy ctor - : Inst(DSCS.Inst), RetVal(DSCS.RetVal), - Callee(DSCS.Callee), CallArgs(DSCS.CallArgs) {} + : Inst(DSCS.Inst), CalleeF(DSCS.CalleeF), CalleeN(DSCS.CalleeN), + RetVal(DSCS.RetVal), CallArgs(DSCS.CallArgs) {} /// Mapping copy constructor - This constructor takes a preexisting call site /// to copy plus a map that specifies how the links should be transformed. @@ -156,21 +164,34 @@ DSCallSite(const DSCallSite &FromCall, const MapTy &NodeMap) { Inst = FromCall.Inst; InitNH(RetVal, FromCall.RetVal, NodeMap); - InitNH(Callee, FromCall.Callee, NodeMap); + InitNH(CalleeN, FromCall.CalleeN, NodeMap); + CalleeF = FromCall.CalleeF; CallArgs.resize(FromCall.CallArgs.size()); for (unsigned i = 0, e = FromCall.CallArgs.size(); i != e; ++i) InitNH(CallArgs[i], FromCall.CallArgs[i], NodeMap); } + /// isDirectCall - Return true if this call site is a direct call of the + /// function specified by getCalleeFunc. If not, it is an indirect call to + /// the node specified by getCalleeNode. + /// + bool isDirectCall() const { return CalleeF != 0; } + bool isIndirectCall() const { return !isDirectCall(); } + + // Accessor functions... Function &getCaller() const; CallInst &getCallInst() const { return *Inst; } DSNodeHandle &getRetVal() { return RetVal; } - DSNodeHandle &getCallee() { return Callee; } const DSNodeHandle &getRetVal() const { return RetVal; } - const DSNodeHandle &getCallee() const { return Callee; } - void setCallee(const DSNodeHandle &H) { Callee = H; } + + DSNode *getCalleeNode() const { + assert(!CalleeF && CalleeN.getNode()); return CalleeN.getNode(); + } + Function *getCalleeFunc() const { + assert(!CalleeN.getNode() && CalleeF); return CalleeF; + } unsigned getNumPtrArgs() const { return CallArgs.size(); } @@ -187,7 +208,8 @@ if (this != &CS) { std::swap(Inst, CS.Inst); std::swap(RetVal, CS.RetVal); - std::swap(Callee, CS.Callee); + std::swap(CalleeN, CS.CalleeN); + std::swap(CalleeF, CS.CalleeF); std::swap(CallArgs, CS.CallArgs); } } @@ -210,16 +232,23 @@ void markReachableNodes(hash_set &Nodes); bool operator<(const DSCallSite &CS) const { - if (Callee < CS.Callee) return true; // This must sort by callee first! - if (Callee > CS.Callee) return false; + if (isDirectCall()) { // This must sort by callee first! + if (CS.isIndirectCall()) return true; + if (CalleeF < CS.CalleeF) return true; + if (CalleeF > CS.CalleeF) return false; + } else { + if (CS.isDirectCall()) return false; + if (CalleeN < CS.CalleeN) return true; + if (CalleeN > CS.CalleeN) return false; + } if (RetVal < CS.RetVal) return true; if (RetVal > CS.RetVal) return false; return CallArgs < CS.CallArgs; } bool operator==(const DSCallSite &CS) const { - return RetVal == CS.RetVal && Callee == CS.Callee && - CallArgs == CS.CallArgs; + return RetVal == CS.RetVal && CalleeN == CS.CalleeN && + CalleeF == CS.CalleeF && CallArgs == CS.CallArgs; } }; From lattner at cs.uiuc.edu Wed Feb 5 16:01:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Feb 5 16:01:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp DataStructure.cpp DataStructureStats.cpp Local.cpp Printer.cpp Steensgaard.cpp TopDownClosure.cpp Message-ID: <200302052200.QAA00374@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: BottomUpClosure.cpp updated: 1.51 -> 1.52 DataStructure.cpp updated: 1.86 -> 1.87 DataStructureStats.cpp updated: 1.2 -> 1.3 Local.cpp updated: 1.46 -> 1.47 Printer.cpp updated: 1.46 -> 1.47 Steensgaard.cpp updated: 1.19 -> 1.20 TopDownClosure.cpp updated: 1.35 -> 1.36 --- Log message: Implement optimization for direct function call case. This dramatically reduces the number of function nodes created and speeds up analysis by about 10% overall. --- Diffs of the changes: Index: llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp diff -u llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.51 llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.52 --- llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp:1.51 Mon Feb 3 13:11:38 2003 +++ llvm/lib/Analysis/DataStructure/BottomUpClosure.cpp Wed Feb 5 15:59:56 2003 @@ -22,6 +22,13 @@ using namespace DS; +static bool isVAHackFn(const Function *F) { + return F->getName() == "printf" || F->getName() == "sscanf" || + F->getName() == "fprintf" || F->getName() == "open" || + F->getName() == "sprintf" || F->getName() == "fputs" || + F->getName() == "fscanf"; +} + // isCompleteNode - Return true if we know all of the targets of this node, and // if the call sites are not external. // @@ -29,14 +36,9 @@ if (N->NodeType & DSNode::Incomplete) return false; const std::vector &Callees = N->getGlobals(); for (unsigned i = 0, e = Callees.size(); i != e; ++i) - if (Callees[i]->isExternal()) { - GlobalValue &FI = cast(*Callees[i]); - if (FI.getName() != "printf" && FI.getName() != "sscanf" && - FI.getName() != "fprintf" && FI.getName() != "open" && - FI.getName() != "sprintf" && FI.getName() != "fputs" && - FI.getName() != "fscanf") + if (Callees[i]->isExternal()) + if (!isVAHackFn(cast(Callees[i]))) return false; // External function found... - } return true; // otherwise ok } @@ -48,7 +50,7 @@ CallSiteIterator(std::vector &CS) : FCs(&CS) { CallSite = 0; CallSiteEntry = 0; - advanceToNextValid(); + advanceToValidCallee(); } // End iterator ctor... @@ -56,18 +58,24 @@ CallSite = FCs->size(); CallSiteEntry = 0; } - void advanceToNextValid() { + void advanceToValidCallee() { while (CallSite < FCs->size()) { - if (DSNode *CalleeNode = (*FCs)[CallSite].getCallee().getNode()) { + if ((*FCs)[CallSite].isDirectCall()) { + if (CallSiteEntry == 0 && // direct call only has one target... + (!(*FCs)[CallSite].getCalleeFunc()->isExternal() || + isVAHackFn((*FCs)[CallSite].getCalleeFunc()))) // If not external + return; + } else { + DSNode *CalleeNode = (*FCs)[CallSite].getCalleeNode(); if (CallSiteEntry || isCompleteNode(CalleeNode)) { const std::vector &Callees = CalleeNode->getGlobals(); if (CallSiteEntry < Callees.size()) return; } - CallSiteEntry = 0; - ++CallSite; } + CallSiteEntry = 0; + ++CallSite; } } public: @@ -87,14 +95,18 @@ unsigned getCallSiteIdx() const { return CallSite; } DSCallSite &getCallSite() const { return (*FCs)[CallSite]; } - Function* operator*() const { - DSNode *Node = (*FCs)[CallSite].getCallee().getNode(); - return cast(Node->getGlobals()[CallSiteEntry]); + Function *operator*() const { + if ((*FCs)[CallSite].isDirectCall()) { + return (*FCs)[CallSite].getCalleeFunc(); + } else { + DSNode *Node = (*FCs)[CallSite].getCalleeNode(); + return cast(Node->getGlobals()[CallSiteEntry]); + } } CallSiteIterator& operator++() { // Preincrement ++CallSiteEntry; - advanceToNextValid(); + advanceToValidCallee(); return *this; } CallSiteIterator operator++(int) { // Postincrement Index: llvm/lib/Analysis/DataStructure/DataStructure.cpp diff -u llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.86 llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.87 --- llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.86 Mon Feb 3 18:03:04 2003 +++ llvm/lib/Analysis/DataStructure/DataStructure.cpp Wed Feb 5 15:59:56 2003 @@ -799,7 +799,8 @@ std::sort(Calls.begin(), Calls.end()); // Sort by callee as primary key! // Scan the call list cleaning it up as necessary... - DSNode *LastCalleeNode = 0; + DSNode *LastCalleeNode = 0; + Function *LastCalleeFunc = 0; unsigned NumDuplicateCalls = 0; bool LastCalleeContainsExternalFunction = false; for (unsigned i = 0; i != Calls.size(); ++i) { @@ -807,8 +808,9 @@ // If the Callee is a useless edge, this must be an unreachable call site, // eliminate it. - killIfUselessEdge(CS.getCallee()); - if (CS.getCallee().getNode() == 0) { + if (CS.isIndirectCall() && CS.getCalleeNode()->getReferrers().size() == 1 && + CS.getCalleeNode()->NodeType == 0) { // No useful info? + std::cerr << "WARNING: Useless call site found??\n"; CS.swap(Calls.back()); Calls.pop_back(); --i; @@ -826,11 +828,15 @@ // never be resolved. Merge the arguments of the call node because no // information will be lost. // - if (CS.getCallee().getNode() == LastCalleeNode) { + if ((CS.isDirectCall() && CS.getCalleeFunc() == LastCalleeFunc) || + (CS.isIndirectCall() && CS.getCalleeNode() == LastCalleeNode)) { ++NumDuplicateCalls; if (NumDuplicateCalls == 1) { - LastCalleeContainsExternalFunction = - nodeContainsExternalFunction(LastCalleeNode); + if (LastCalleeNode) + LastCalleeContainsExternalFunction = + nodeContainsExternalFunction(LastCalleeNode); + else + LastCalleeContainsExternalFunction = LastCalleeFunc->isExternal(); } if (LastCalleeContainsExternalFunction || @@ -847,7 +853,13 @@ OCS = CS; } } else { - LastCalleeNode = CS.getCallee().getNode(); + if (CS.isDirectCall()) { + LastCalleeFunc = CS.getCalleeFunc(); + LastCalleeNode = 0; + } else { + LastCalleeNode = CS.getCalleeNode(); + LastCalleeFunc = 0; + } NumDuplicateCalls = 0; } } @@ -877,7 +889,7 @@ for (unsigned i = 0; i != Nodes.size(); ++i) { DSNode *Node = Nodes[i]; if (!(Node->NodeType & ~(DSNode::Composition | DSNode::Array | - DSNode::DEAD))) { + DSNode::DEAD))) { // 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 @@ -918,7 +930,7 @@ void DSCallSite::markReachableNodes(hash_set &Nodes) { getRetVal().getNode()->markReachableNodes(Nodes); - getCallee().getNode()->markReachableNodes(Nodes); + if (isIndirectCall()) getCalleeNode()->markReachableNodes(Nodes); for (unsigned i = 0, e = getNumPtrArgs(); i != e; ++i) getPtrArg(i).getNode()->markReachableNodes(Nodes); @@ -954,8 +966,10 @@ // static bool CallSiteUsesAliveArgs(DSCallSite &CS, hash_set &Alive, hash_set &Visited) { - if (CanReachAliveNodes(CS.getRetVal().getNode(), Alive, Visited) || - CanReachAliveNodes(CS.getCallee().getNode(), Alive, Visited)) + if (CanReachAliveNodes(CS.getRetVal().getNode(), Alive, Visited)) + return true; + if (CS.isIndirectCall() && + CanReachAliveNodes(CS.getCalleeNode(), Alive, Visited)) return true; for (unsigned i = 0, e = CS.getNumPtrArgs(); i != e; ++i) if (CanReachAliveNodes(CS.getPtrArg(i).getNode(), Alive, Visited)) Index: llvm/lib/Analysis/DataStructure/DataStructureStats.cpp diff -u llvm/lib/Analysis/DataStructure/DataStructureStats.cpp:1.2 llvm/lib/Analysis/DataStructure/DataStructureStats.cpp:1.3 --- llvm/lib/Analysis/DataStructure/DataStructureStats.cpp:1.2 Sun Nov 17 16:17:12 2002 +++ llvm/lib/Analysis/DataStructure/DataStructureStats.cpp Wed Feb 5 15:59:56 2003 @@ -48,9 +48,7 @@ } -void DSGraphStats::countCallees(const Function& F, - const DSGraph& tdGraph) -{ +void DSGraphStats::countCallees(const Function& F, const DSGraph& tdGraph) { unsigned numIndirectCalls = 0, totalNumCallees = 0; const std::vector& callSites = tdGraph.getFunctionCalls(); @@ -58,12 +56,11 @@ if (isIndirectCallee(callSites[i].getCallInst().getCalledValue())) { // This is an indirect function call std::vector Callees = - callSites[i].getCallee().getNode()->getGlobals(); - if (Callees.size() > 0) - { - totalNumCallees += Callees.size(); - ++numIndirectCalls; - } + callSites[i].getCalleeNode()->getGlobals(); + if (Callees.size() > 0) { + totalNumCallees += Callees.size(); + ++numIndirectCalls; + } #ifndef NDEBUG else std::cerr << "WARNING: No callee in Function " << F.getName() @@ -81,8 +78,7 @@ } -bool DSGraphStats::runOnFunction(Function& F) -{ +bool DSGraphStats::runOnFunction(Function& F) { const DSGraph& tdGraph = getAnalysis().getDSGraph(F); countCallees(F, tdGraph); return true; Index: llvm/lib/Analysis/DataStructure/Local.cpp diff -u llvm/lib/Analysis/DataStructure/Local.cpp:1.46 llvm/lib/Analysis/DataStructure/Local.cpp:1.47 --- llvm/lib/Analysis/DataStructure/Local.cpp:1.46 Mon Feb 3 18:59:50 2003 +++ llvm/lib/Analysis/DataStructure/Local.cpp Wed Feb 5 15:59:56 2003 @@ -19,6 +19,7 @@ #include "llvm/Target/TargetData.h" #include "Support/Statistic.h" #include "Support/Timer.h" +#include "Support/CommandLine.h" // FIXME: This should eventually be a FunctionPass that is automatically // aggregated into a Pass. @@ -45,6 +46,11 @@ namespace { + cl::opt + DisableDirectCallOpt("disable-direct-call-dsopt", cl::Hidden, + cl::desc("Disable direct call optimization in " + "DSGraph construction")); + //===--------------------------------------------------------------------===// // GraphBuilder Class //===--------------------------------------------------------------------===// @@ -375,7 +381,9 @@ if (isPointerType(CI.getType())) RetVal = getValueDest(CI); - DSNodeHandle Callee = getValueDest(*CI.getOperand(0)); + DSNode *Callee = 0; + if (DisableDirectCallOpt || !isa(CI.getOperand(0))) + Callee = getValueDest(*CI.getOperand(0)).getNode(); std::vector Args; Args.reserve(CI.getNumOperands()-1); @@ -386,7 +394,11 @@ Args.push_back(getValueDest(*CI.getOperand(i))); // Add a new function call entry... - FunctionCalls.push_back(DSCallSite(CI, RetVal, Callee, Args)); + if (Callee) + FunctionCalls.push_back(DSCallSite(CI, RetVal, Callee, Args)); + else + FunctionCalls.push_back(DSCallSite(CI, RetVal, + cast(CI.getOperand(0)), Args)); } void GraphBuilder::visitFreeInst(FreeInst &FI) { Index: llvm/lib/Analysis/DataStructure/Printer.cpp diff -u llvm/lib/Analysis/DataStructure/Printer.cpp:1.46 llvm/lib/Analysis/DataStructure/Printer.cpp:1.47 --- llvm/lib/Analysis/DataStructure/Printer.cpp:1.46 Mon Feb 3 18:03:18 2003 +++ llvm/lib/Analysis/DataStructure/Printer.cpp Wed Feb 5 15:59:56 2003 @@ -123,18 +123,27 @@ : G->getFunctionCalls(); for (unsigned i = 0, e = FCs.size(); i != e; ++i) { const DSCallSite &Call = FCs[i]; - GW.emitSimpleNode(&Call, "shape=record", "call", Call.getNumPtrArgs()+2); + std::vector EdgeSourceCaptions(Call.getNumPtrArgs()+2); + EdgeSourceCaptions[0] = "r"; + if (Call.isDirectCall()) + EdgeSourceCaptions[1] = Call.getCalleeFunc()->getName(); + + GW.emitSimpleNode(&Call, "shape=record", "call", Call.getNumPtrArgs()+2, + &EdgeSourceCaptions); if (DSNode *N = Call.getRetVal().getNode()) { 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() >> DS::PointerShift; - if (EdgeDest == 0) EdgeDest = -1; - GW.emitEdge(&Call, 1, N, EdgeDest, "color=gray63"); + + // Print out the callee... + if (Call.isIndirectCall()) { + DSNode *N = Call.getCalleeNode(); + assert(N && "Null call site callee node!"); + GW.emitEdge(&Call, 1, N, -1, "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() >> DS::PointerShift; Index: llvm/lib/Analysis/DataStructure/Steensgaard.cpp diff -u llvm/lib/Analysis/DataStructure/Steensgaard.cpp:1.19 llvm/lib/Analysis/DataStructure/Steensgaard.cpp:1.20 --- llvm/lib/Analysis/DataStructure/Steensgaard.cpp:1.19 Tue Feb 4 10:33:23 2003 +++ llvm/lib/Analysis/DataStructure/Steensgaard.cpp Wed Feb 5 15:59:56 2003 @@ -163,8 +163,12 @@ DSCallSite &CurCall = Calls[i]; // Loop over the called functions, eliminating as many as possible... - std::vector CallTargets = - CurCall.getCallee().getNode()->getGlobals(); + std::vector CallTargets; + if (CurCall.isDirectCall()) + CallTargets.push_back(CurCall.getCalleeFunc()); + else + CallTargets = CurCall.getCalleeNode()->getGlobals(); + for (unsigned c = 0; c != CallTargets.size(); ) { // If we can eliminate this function call, do so! bool Eliminated = false; Index: llvm/lib/Analysis/DataStructure/TopDownClosure.cpp diff -u llvm/lib/Analysis/DataStructure/TopDownClosure.cpp:1.35 llvm/lib/Analysis/DataStructure/TopDownClosure.cpp:1.36 --- llvm/lib/Analysis/DataStructure/TopDownClosure.cpp:1.35 Mon Feb 3 18:59:32 2003 +++ llvm/lib/Analysis/DataStructure/TopDownClosure.cpp Wed Feb 5 15:59:56 2003 @@ -116,17 +116,22 @@ std::multimap CalleeSites; for (unsigned i = 0, e = CallSites.size(); i != e; ++i) { const DSCallSite &CS = CallSites[i]; - const std::vector Callees = - CS.getCallee().getNode()->getGlobals(); + if (CS.isDirectCall()) { + if (!CS.getCalleeFunc()->isExternal()) // If it's not external + CalleeSites.insert(std::make_pair(CS.getCalleeFunc(), &CS)); // Keep it + } else { + const std::vector &Callees = + CS.getCalleeNode()->getGlobals(); - // Loop over all of the functions that this call may invoke... - for (unsigned c = 0, e = Callees.size(); c != e; ++c) - if (Function *F = dyn_cast(Callees[c])) // If this is a fn... - if (!F->isExternal()) // If it's not external - CalleeSites.insert(std::make_pair(F, &CS)); // Keep track of it! + // Loop over all of the functions that this call may invoke... + for (unsigned c = 0, e = Callees.size(); c != e; ++c) + if (Function *F = dyn_cast(Callees[c])) // If this is a fn... + if (!F->isExternal()) // If it's not extern + CalleeSites.insert(std::make_pair(F, &CS)); // Keep track of it! + } } - // Now that we have information about all of the callees, propogate the + // Now that we have information about all of the callees, propagate the // current graph into the callees. // DEBUG(std::cerr << " [TD] Inlining '" << F.getName() << "' into " From lattner at cs.uiuc.edu Wed Feb 5 16:01:03 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Feb 5 16:01:03 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/IPA/IPModRef.cpp Message-ID: <200302052200.QAA00381@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/IPA: IPModRef.cpp updated: 1.13 -> 1.14 --- Log message: Implement optimization for direct function call case. This dramatically reduces the number of function nodes created and speeds up analysis by about 10% overall. --- Diffs of the changes: Index: llvm/lib/Analysis/IPA/IPModRef.cpp diff -u llvm/lib/Analysis/IPA/IPModRef.cpp:1.13 llvm/lib/Analysis/IPA/IPModRef.cpp:1.14 --- llvm/lib/Analysis/IPA/IPModRef.cpp:1.13 Fri Jan 31 22:51:57 2003 +++ llvm/lib/Analysis/IPA/IPModRef.cpp Wed Feb 5 15:59:58 2003 @@ -144,7 +144,7 @@ Result->maskNodeTypes(~(DSNode::Modified | DSNode::Read)); // Step #3: clone the bottom up graphs for the callees into the caller graph - if (const Function *F = CI.getCalledFunction()) + if (Function *F = CI.getCalledFunction()) { assert(!F->isExternal()); @@ -162,7 +162,7 @@ Args.push_back(Result->getNodeForValue(CI.getOperand(i))); // Build the call site... - DSCallSite CS(CI, RetVal, 0, Args); + DSCallSite CS(CI, RetVal, F, Args); // Perform the merging now of the graph for the callee, which will // come with mod/ref bits set... From lattner at cs.uiuc.edu Wed Feb 5 18:16:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Wed Feb 5 18:16:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/DataStructure.cpp Message-ID: <200302060015.SAA01939@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: DataStructure.cpp updated: 1.87 -> 1.88 --- Log message: Fix an assertion failure --- Diffs of the changes: Index: llvm/lib/Analysis/DataStructure/DataStructure.cpp diff -u llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.87 llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.88 --- llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.87 Wed Feb 5 15:59:56 2003 +++ llvm/lib/Analysis/DataStructure/DataStructure.cpp Wed Feb 5 18:15:08 2003 @@ -695,14 +695,14 @@ for (unsigned i = 0, e = CS.getNumPtrArgs(); i != e; ++i, ++AI) { // Advance the argument iterator to the first pointer argument... - while (!isPointerType(AI->getType())) { + while (AI != F.aend() && !isPointerType(AI->getType())) { ++AI; #ifndef NDEBUG if (AI == F.aend()) std::cerr << "Bad call to Function: " << F.getName() << "\n"; #endif - assert(AI != F.aend() && "# Args provided is not # Args required!"); } + if (AI == F.aend()) break; // Add the link from the argument scalar to the provided value DSNodeHandle &NH = (*ScalarMap)[AI]; From lattner at cs.uiuc.edu Thu Feb 6 13:40:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Feb 6 13:40:02 2003 Subject: [llvm-commits] CVS: llvm/www/docs/OpenProjects.html Message-ID: <200302061939.NAA04258@tank.cs.uiuc.edu> Changes in directory llvm/www/docs: OpenProjects.html added (r1.1) --- Log message: New "open projects" document --- Diffs of the changes: From lattner at cs.uiuc.edu Thu Feb 6 13:45:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Feb 6 13:45:01 2003 Subject: [llvm-commits] CVS: llvm/www/www-index.html Message-ID: <200302061944.NAA04307@tank.cs.uiuc.edu> Changes in directory llvm/www: www-index.html updated: 1.12 -> 1.13 --- Log message: Add links to the Open Projects page --- Diffs of the changes: Index: llvm/www/www-index.html diff -u llvm/www/www-index.html:1.12 llvm/www/www-index.html:1.13 --- llvm/www/www-index.html:1.12 Wed Jan 22 14:51:49 2003 +++ llvm/www/www-index.html Thu Feb 6 13:44:14 2003 @@ -193,6 +193,13 @@ + + + + + @@ -140,7 +140,7 @@ From lattner at cs.uiuc.edu Thu Feb 6 15:31:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Feb 6 15:31:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/AliasAnalysisEvaluator.cpp Message-ID: <200302062130.PAA16658@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: AliasAnalysisEvaluator.cpp added (r1.1) --- Log message: Simple N^2 alias anlysis accuracy checker --- Diffs of the changes: From lattner at cs.uiuc.edu Thu Feb 6 16:05:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Feb 6 16:05:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Transforms/IPO/PoolAllocate.cpp Message-ID: <200302062204.QAA17867@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/IPO: PoolAllocate.cpp updated: 1.3 -> 1.4 --- Log message: Fix a problem Sumant was running into --- Diffs of the changes: Index: llvm/lib/Transforms/IPO/PoolAllocate.cpp diff -u llvm/lib/Transforms/IPO/PoolAllocate.cpp:1.3 llvm/lib/Transforms/IPO/PoolAllocate.cpp:1.4 --- llvm/lib/Transforms/IPO/PoolAllocate.cpp:1.3 Mon Feb 3 13:08:18 2003 +++ llvm/lib/Transforms/IPO/PoolAllocate.cpp Thu Feb 6 16:03:46 2003 @@ -46,7 +46,7 @@ std::map FuncMap; // Loop over only the function initially in the program, don't traverse newly - // added ones. If the function uses memory, make it's clone. + // added ones. If the function uses memory, make its clone. Module::iterator LastOrigFunction = --M.end(); for (Module::iterator I = M.begin(); ; ++I) { if (!I->isExternal()) @@ -132,7 +132,9 @@ Nodes[i]->markReachableNodes(MarkedNodes); // Marked the returned node as alive... - G.getRetNode().getNode()->markReachableNodes(MarkedNodes); + if (DSNode *RetNode = G.getRetNode().getNode()) + if (RetNode->NodeType & DSNode::HeapNode) + RetNode->markReachableNodes(MarkedNodes); if (MarkedNodes.empty()) // We don't need to clone the function if there return 0; // are no incoming arguments to be added. From lattner at cs.uiuc.edu Thu Feb 6 16:07:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Feb 6 16:07:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/AliasAnalysisEvaluator.cpp Message-ID: <200302062206.QAA17884@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: AliasAnalysisEvaluator.cpp updated: 1.1 -> 1.2 --- Log message: Add a summary --- Diffs of the changes: Index: llvm/lib/Analysis/AliasAnalysisEvaluator.cpp diff -u llvm/lib/Analysis/AliasAnalysisEvaluator.cpp:1.1 llvm/lib/Analysis/AliasAnalysisEvaluator.cpp:1.2 --- llvm/lib/Analysis/AliasAnalysisEvaluator.cpp:1.1 Thu Feb 6 15:29:49 2003 +++ llvm/lib/Analysis/AliasAnalysisEvaluator.cpp Thu Feb 6 16:06:08 2003 @@ -70,5 +70,7 @@ std::cerr << " " << No << " no alias responses (" << No*100/Sum << "%)\n"; std::cerr << " " << May << " may alias responses (" << May*100/Sum << "%)\n"; std::cerr << " " << Must << " must alias responses (" < Changes in directory llvm/www/docs: TestStatus.html (r1.16) removed --- Log message: Remove obsolete page --- Diffs of the changes: From lattner at cs.uiuc.edu Fri Feb 7 13:26:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Feb 7 13:26:01 2003 Subject: [llvm-commits] CVS: llvm/www/docs/OpenProjects.html Message-ID: <200302071925.NAA14854@tank.cs.uiuc.edu> Changes in directory llvm/www/docs: OpenProjects.html updated: 1.1 -> 1.2 --- Log message: Add notes from Vikram's email --- Diffs of the changes: Index: llvm/www/docs/OpenProjects.html diff -u llvm/www/docs/OpenProjects.html:1.1 llvm/www/docs/OpenProjects.html:1.2 --- llvm/www/docs/OpenProjects.html:1.1 Thu Feb 6 13:39:21 2003 +++ llvm/www/docs/OpenProjects.html Fri Feb 7 13:25:35 2003 @@ -98,6 +98,7 @@ program tests...

+

Feb 6th, 2003-Added a new + open projects + page, listing possibly improvements to LLVM.
Jan 22nd, 2003 - Implemented a new @@ -312,6 +319,11 @@
  • Writing an LLVM Pass - Information on how to write LLVM transformations and analyses.
  • + +
  • Open projects in + the LLVM system. Look here if you are interested in + doing something with LLVM, but aren't sure what needs + to be done.
  • Other useful information:

      From lattner at cs.uiuc.edu Thu Feb 6 13:49:00 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Thu Feb 6 13:49:00 2003 Subject: [llvm-commits] CVS: llvm/www/www-index.html Message-ID: <200302061948.NAA04354@tank.cs.uiuc.edu> Changes in directory llvm/www: www-index.html updated: 1.13 -> 1.14 --- Log message: Fix broken links --- Diffs of the changes: Index: llvm/www/www-index.html diff -u llvm/www/www-index.html:1.13 llvm/www/www-index.html:1.14 --- llvm/www/www-index.html:1.13 Thu Feb 6 13:44:14 2003 +++ llvm/www/www-index.html Thu Feb 6 13:48:33 2003 @@ -96,7 +96,7 @@
    Publications & Papers
    Funding
       @@ -111,7 +112,11 @@ href="http://mail.cs.uiuc.edu/pipermail/llvmbugs/">llvm-bugs list. If you get the program to compile, it would be extremely useful to convert the build system to be compatible with the LLVM Programs testsuite so that we can check it -into CVS and the automated tester can use it to track progress of the compiler. +into CVS and the automated tester can use it to track progress of the +compiler.

    + +When testing a code, try running it with a variety of optimizations, and with +all the back-ends: CBE, llc, and lli.

    @@ -282,6 +287,6 @@

    Chris Lattner
    -Last modified: Thu Feb 6 13:38:41 CST 2003 +Last modified: Fri Feb 7 13:24:26 CST 2003 From lattner at cs.uiuc.edu Fri Feb 7 13:47:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Feb 7 13:47:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/AliasAnalysisCounter.cpp Message-ID: <200302071946.NAA01843@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: AliasAnalysisCounter.cpp added (r1.1) --- Log message: New general purpose alias analysis result auditor --- Diffs of the changes: From lattner at cs.uiuc.edu Fri Feb 7 14:40:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Feb 7 14:40:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/AliasAnalysisCounter.cpp Message-ID: <200302072039.OAA02331@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: AliasAnalysisCounter.cpp updated: 1.1 -> 1.2 --- Log message: Allow counting multiple passes, and print the pass name counted --- Diffs of the changes: Index: llvm/lib/Analysis/AliasAnalysisCounter.cpp diff -u llvm/lib/Analysis/AliasAnalysisCounter.cpp:1.1 llvm/lib/Analysis/AliasAnalysisCounter.cpp:1.2 --- llvm/lib/Analysis/AliasAnalysisCounter.cpp:1.1 Fri Feb 7 13:46:03 2003 +++ llvm/lib/Analysis/AliasAnalysisCounter.cpp Fri Feb 7 14:39:17 2003 @@ -10,10 +10,31 @@ #include namespace { - unsigned No = 0, May = 0, Must = 0; + class AliasAnalysisCounter : public Pass, public AliasAnalysis { + unsigned No, May, Must; + const char *Name; + public: + AliasAnalysisCounter() : No(0), May(0), Must(0) {} + ~AliasAnalysisCounter() { + unsigned Sum = No+May+Must; + if (Sum) { // Print a report if any counted queries occurred... + std::cerr + << "\n===== Alias Analysis Counter Report =====\n" + << " Analysis counted: " << Name << "\n" + << " " << Sum << " Total Alias Queries Performed\n" + << " " << No << " no alias responses (" << No*100/Sum << "%)\n" + << " " << May << " may alias responses (" << May*100/Sum << "%)\n" + << " " << Must << " must alias responses (" <(&getAnalysis())->getPassName(); + return false; + } - struct AliasAnalysisCounter : public Pass, public AliasAnalysis { - bool run(Module &M) { return false; } virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired(); AU.setPreservesAll(); @@ -44,21 +65,4 @@ RegisterOpt X("count-aa", "Count Alias Analysis Query Responses"); RegisterAnalysisGroup Y; - - - struct ResultPrinter { - ~ResultPrinter() { - unsigned Sum = No+May+Must; - if (Sum) { // Print a report if any counted queries occurred... - std::cerr - << "\n===== Alias Analysis Counter Report =====\n" - << " " << Sum << " Total Alias Queries Performed\n" - << " " << No << " no alias responses (" << No*100/Sum << "%)\n" - << " " << May << " may alias responses (" << May*100/Sum << "%)\n" - << " " << Must << " must alias responses (" < Changes in directory llvm/lib/Analysis: AliasAnalysis.cpp updated: 1.7 -> 1.8 --- Log message: Don't bother counting alias results, allow the AliasAnalysisCounter to do that. --- Diffs of the changes: Index: llvm/lib/Analysis/AliasAnalysis.cpp diff -u llvm/lib/Analysis/AliasAnalysis.cpp:1.7 llvm/lib/Analysis/AliasAnalysis.cpp:1.8 --- llvm/lib/Analysis/AliasAnalysis.cpp:1.7 Mon Feb 3 15:16:17 2003 +++ llvm/lib/Analysis/AliasAnalysis.cpp Fri Feb 7 14:39:46 2003 @@ -25,14 +25,10 @@ #include "llvm/Constants.h" #include "llvm/GlobalValue.h" #include "llvm/DerivedTypes.h" -#include "Support/Statistic.h" // Register the AliasAnalysis interface, providing a nice name to refer to. namespace { RegisterAnalysisGroup Z("Alias Analysis"); - Statistic<> NumNoAlias ("basic-aa", "Number of 'no alias' replies"); - Statistic<> NumMayAlias ("basic-aa", "Number of 'may alias' replies"); - Statistic<> NumMustAlias("basic-aa", "Number of 'must alias' replies"); } // CanModify - Define a little visitor class that is used to check to see if @@ -145,20 +141,6 @@ return 0; } -static inline AliasAnalysis::Result MustAlias() { - ++NumMustAlias; - return AliasAnalysis::MustAlias; -} - -static inline AliasAnalysis::Result MayAlias() { - ++NumMayAlias; - return AliasAnalysis::MayAlias; -} - -static inline AliasAnalysis::Result NoAlias() { - ++NumNoAlias; - return AliasAnalysis::NoAlias; -} // alias - Provide a bunch of ad-hoc rules to disambiguate in common cases, such // as array references. Note that this function is heavily tail recursive. @@ -173,11 +155,11 @@ V2 = CPR->getValue(); // Are we checking for alias of the same value? - if (V1 == V2) return ::MustAlias(); + if (V1 == V2) return MustAlias; if ((!isa(V1->getType()) || !isa(V2->getType())) && V1->getType() != Type::LongTy && V2->getType() != Type::LongTy) - return ::NoAlias(); // Scalars cannot alias each other + return NoAlias; // Scalars cannot alias each other // Strip off cast instructions... if (const Instruction *I = dyn_cast(V1)) @@ -216,7 +198,7 @@ // if (AllConstant && alias(GEP1->getOperand(0), GEP2->getOperand(1)) != MayAlias) - return ::NoAlias(); + return NoAlias; } // Figure out what objects these things are pointing to if we can... @@ -226,16 +208,16 @@ // Pointing at a discernable object? if (O1 && O2) { // If they are two different objects, we know that we have no alias... - if (O1 != O2) return ::NoAlias(); + if (O1 != O2) return NoAlias; // If they are the same object, they we can look at the indexes. If they // index off of the object is the same for both pointers, they must alias. // If they are provably different, they must not alias. Otherwise, we can't // tell anything. } else if (O1 && isa(V2)) { - return ::NoAlias(); // Unique values don't alias null + return NoAlias; // Unique values don't alias null } else if (O2 && isa(V1)) { - return ::NoAlias(); // Unique values don't alias null + return NoAlias; // Unique values don't alias null } return MayAlias; From lattner at cs.uiuc.edu Fri Feb 7 14:40:05 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Fri Feb 7 14:40:05 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/DataStructureAA.cpp Message-ID: <200302072039.OAA02352@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: DataStructureAA.cpp updated: 1.1 -> 1.2 --- Log message: Don't bother counting alias results, allow the AliasAnalysisCounter to do that. --- Diffs of the changes: Index: llvm/lib/Analysis/DataStructure/DataStructureAA.cpp diff -u llvm/lib/Analysis/DataStructure/DataStructureAA.cpp:1.1 llvm/lib/Analysis/DataStructure/DataStructureAA.cpp:1.2 --- llvm/lib/Analysis/DataStructure/DataStructureAA.cpp:1.1 Mon Feb 3 16:50:46 2003 +++ llvm/lib/Analysis/DataStructure/DataStructureAA.cpp Fri Feb 7 14:39:48 2003 @@ -9,12 +9,6 @@ #include "llvm/Analysis/DSGraph.h" #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Module.h" -#include "Support/Statistic.h" - -namespace { - Statistic<> NumNoAlias ("ds-aa", "Number of 'no alias' replies"); - Statistic<> NumMayAlias ("ds-aa", "Number of 'may alias' replies"); -}; namespace { class DSAA : public Pass, public AliasAnalysis { @@ -104,18 +98,14 @@ 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) { - ++NumNoAlias; + & 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()) { - ++NumNoAlias; + if (I->second.getOffset() != J->second.getOffset()) return NoAlias; - } } } } @@ -123,6 +113,5 @@ // FIXME: we could improve on this by checking the globals graph for aliased // global queries... - ++NumMayAlias; return getAnalysis().alias(V1, V2); } From lattner at cs.uiuc.edu Sat Feb 8 14:19:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Feb 8 14:19:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/Local.cpp Message-ID: <200302082018.OAA23454@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: Local.cpp updated: 1.47 -> 1.48 --- Log message: Add a flag which effectively disables field sensitivity --- Diffs of the changes: Index: llvm/lib/Analysis/DataStructure/Local.cpp diff -u llvm/lib/Analysis/DataStructure/Local.cpp:1.47 llvm/lib/Analysis/DataStructure/Local.cpp:1.48 --- llvm/lib/Analysis/DataStructure/Local.cpp:1.47 Wed Feb 5 15:59:56 2003 +++ llvm/lib/Analysis/DataStructure/Local.cpp Sat Feb 8 14:18:39 2003 @@ -50,6 +50,9 @@ DisableDirectCallOpt("disable-direct-call-dsopt", cl::Hidden, cl::desc("Disable direct call optimization in " "DSGraph construction")); + cl::opt + DisableFieldSensitivity("disable-ds-field-sensitivity", cl::Hidden, + cl::desc("Disable field sensitivity in DSGraphs")); //===--------------------------------------------------------------------===// // GraphBuilder Class @@ -108,6 +111,8 @@ DSNode *createNode(DSNode::NodeTy NodeType, const Type *Ty = 0) { DSNode *N = new DSNode(NodeType, Ty); // Create the node Nodes.push_back(N); // Add node to nodes list + if (DisableFieldSensitivity) + N->foldNodeCompletely(); return N; } From lattner at cs.uiuc.edu Sat Feb 8 14:44:00 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Feb 8 14:44:00 2003 Subject: [llvm-commits] CVS: llvm/test/Programs/Makefile.dummylib TEST.dsgraph.Makefile Message-ID: <200302082043.OAA23893@apoc.cs.uiuc.edu> Changes in directory llvm/test/Programs: Makefile.dummylib added (r1.1) TEST.dsgraph.Makefile updated: 1.6 -> 1.7 --- Log message: Factor makefile code out into Makefile.dummylib --- Diffs of the changes: Index: llvm/test/Programs/TEST.dsgraph.Makefile diff -u llvm/test/Programs/TEST.dsgraph.Makefile:1.6 llvm/test/Programs/TEST.dsgraph.Makefile:1.7 --- llvm/test/Programs/TEST.dsgraph.Makefile:1.6 Fri Jan 17 17:25:08 2003 +++ llvm/test/Programs/TEST.dsgraph.Makefile Sat Feb 8 14:43:46 2003 @@ -5,25 +5,11 @@ # ##===----------------------------------------------------------------------===## +# We require the programs to be linked with libdummy +include $(LEVEL)/test/Programs/Makefile.dummylib + # PASS - The dsgraph pass to run: ds, bu, td PASS := td - -# DUMMYLIB - The path to the library of stub functions which is used to resolve -# external functions for dsanalysis. -# -DUMMYLIB := $(LEVEL)/test/Libraries/Output/libdummy.bc -DUMMYSRC := $(LEVEL)/test/Libraries/libdummy - -# Rebuild dummylib if neccesary... -$(DUMMYLIB) : $(wildcard $(DUMMYSRC)/*.c) - cd $(DUMMYSRC); $(MAKE) - -# LINKED_PROGS - All of the programs linked to libdummy -LINKED_PROGS := $(PROGRAMS_TO_TEST:%=Output/%.lib.bc) - -IPO_OPTS := -internalize -funcresolve -globaldce -$(LINKED_PROGS): Output/%.lib.bc: Output/%.llvm.bc $(DUMMYLIB) - $(LLINK) $< $(DUMMYLIB) | $(LOPT) $(IPO_OPTS) > $@ ANALYZE_OPTS := -stats -time-passes -only-print-main-ds -dsstats -instcount From lattner at cs.uiuc.edu Sat Feb 8 17:04:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Feb 8 17:04:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/Steensgaard.cpp Message-ID: <200302082303.RAA01010@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: Steensgaard.cpp updated: 1.20 -> 1.21 --- Log message: Remove explicit result counters --- Diffs of the changes: Index: llvm/lib/Analysis/DataStructure/Steensgaard.cpp diff -u llvm/lib/Analysis/DataStructure/Steensgaard.cpp:1.20 llvm/lib/Analysis/DataStructure/Steensgaard.cpp:1.21 --- llvm/lib/Analysis/DataStructure/Steensgaard.cpp:1.20 Wed Feb 5 15:59:56 2003 +++ llvm/lib/Analysis/DataStructure/Steensgaard.cpp Sat Feb 8 17:03:17 2003 @@ -11,12 +11,6 @@ #include "llvm/Analysis/DSGraph.h" #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Module.h" -#include "Support/Statistic.h" - -namespace { - Statistic<> NumNoAlias ("steens", "Number of 'no alias' replies"); - Statistic<> NumMayAlias ("steens", "Number of 'may alias' replies"); -}; namespace { class Steens : public Pass, public AliasAnalysis { @@ -75,7 +69,7 @@ // Register the pass... RegisterOpt X("steens-aa", - "Steensgaard's FlowInsensitive/ConIns alias analysis"); + "Steensgaard's alias analysis (DSGraph based)"); // Register as an implementation of AliasAnalysis RegisterAnalysisGroup Y; @@ -198,7 +192,7 @@ // FIXME: We should be able to disable the globals graph for steens! ResultGraph->removeDeadNodes(DSGraph::KeepUnreachableGlobals); - DEBUG(print(std::cerr, &M)); + //print(std::cerr, &M); return false; } @@ -216,10 +210,9 @@ DSNodeHandle &V2H = J->second; // If the two pointers point to different data structure graph nodes, they // cannot alias! - if (V1H.getNode() != V2H.getNode()) { // FIXME: Handle incompleteness! - ++NumNoAlias; + if (V1H.getNode() != V2H.getNode()) // FIXME: Handle incompleteness! return NoAlias; - } + // FIXME: If the two pointers point to the same node, and the offsets are // different, and the LinkIndex vector doesn't alias the section, then the // two pointers do not alias. We need access size information for the two @@ -227,9 +220,6 @@ // } } - - // Since Steensgaard cannot do any better, count it as a 'may alias' - ++NumMayAlias; // If we cannot determine alias properties based on our graph, fall back on // some other AA implementation. From lattner at cs.uiuc.edu Sat Feb 8 17:06:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Feb 8 17:06:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/AliasAnalysisEvaluator.cpp Message-ID: <200302082305.RAA01021@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: AliasAnalysisEvaluator.cpp updated: 1.2 -> 1.3 --- Log message: Fix division by zero problem --- Diffs of the changes: Index: llvm/lib/Analysis/AliasAnalysisEvaluator.cpp diff -u llvm/lib/Analysis/AliasAnalysisEvaluator.cpp:1.2 llvm/lib/Analysis/AliasAnalysisEvaluator.cpp:1.3 --- llvm/lib/Analysis/AliasAnalysisEvaluator.cpp:1.2 Thu Feb 6 16:06:08 2003 +++ llvm/lib/Analysis/AliasAnalysisEvaluator.cpp Sat Feb 8 17:04:50 2003 @@ -66,6 +66,11 @@ bool AAEval::doFinalization(Module &M) { unsigned Sum = No+May+Must; std::cerr << "===== Alias Analysis Evaluator Report =====\n"; + if (Sum == 0) { + std::cerr << " Alias Analysis Evaluator Summary: No pointers!\n"; + return false; + } + std::cerr << " " << Sum << " Total Alias Queries Performed\n"; std::cerr << " " << No << " no alias responses (" << No*100/Sum << "%)\n"; std::cerr << " " << May << " may alias responses (" << May*100/Sum << "%)\n"; From lattner at cs.uiuc.edu Sat Feb 8 17:08:00 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Feb 8 17:08:00 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/TopDownClosure.cpp Message-ID: <200302082307.RAA01038@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: TopDownClosure.cpp updated: 1.36 -> 1.37 --- Log message: Fix a bug where we would mark the callees arguments incomplete if the caller was external. --- Diffs of the changes: Index: llvm/lib/Analysis/DataStructure/TopDownClosure.cpp diff -u llvm/lib/Analysis/DataStructure/TopDownClosure.cpp:1.36 llvm/lib/Analysis/DataStructure/TopDownClosure.cpp:1.37 --- llvm/lib/Analysis/DataStructure/TopDownClosure.cpp:1.36 Wed Feb 5 15:59:56 2003 +++ llvm/lib/Analysis/DataStructure/TopDownClosure.cpp Sat Feb 8 17:07:39 2003 @@ -197,8 +197,8 @@ // Recompute the Incomplete markers and eliminate unreachable nodes. CG.maskIncompleteMarkers(); - CG.markIncompleteNodes(F.hasInternalLinkage() ? DSGraph::IgnoreFormalArgs: - DSGraph::MarkFormalArgs + CG.markIncompleteNodes(Callee->hasInternalLinkage() ? + DSGraph::IgnoreFormalArgs : DSGraph::MarkFormalArgs /*&& FIXME: NEED TO CHECK IF ALL CALLERS FOUND!*/); CG.removeDeadNodes(DSGraph::RemoveUnreachableGlobals); } From lattner at cs.uiuc.edu Sat Feb 8 17:09:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sat Feb 8 17:09:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/DataStructure.cpp Message-ID: <200302082308.RAA01049@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: DataStructure.cpp updated: 1.88 -> 1.89 --- Log message: Add a special case for main because we know it's incoming arguments don't alias --- Diffs of the changes: Index: llvm/lib/Analysis/DataStructure/DataStructure.cpp diff -u llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.88 llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.89 --- llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.88 Wed Feb 5 18:15:08 2003 +++ llvm/lib/Analysis/DataStructure/DataStructure.cpp Sat Feb 8 17:08:02 2003 @@ -752,7 +752,7 @@ // void DSGraph::markIncompleteNodes(unsigned Flags) { // Mark any incoming arguments as incomplete... - if ((Flags & DSGraph::MarkFormalArgs) && Func) + if ((Flags & DSGraph::MarkFormalArgs) && Func && Func->getName() != "main") for (Function::aiterator I = Func->abegin(), E = Func->aend(); I != E; ++I) if (isPointerType(I->getType()) && ScalarMap.find(I) != ScalarMap.end()) markIncompleteNode(ScalarMap[I].getNode()); From lattner at cs.uiuc.edu Sun Feb 9 12:41:00 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Feb 9 12:41:00 2003 Subject: [llvm-commits] CVS: llvm/include/llvm/Analysis/DSGraph.h Message-ID: <200302091840.MAA26034@apoc.cs.uiuc.edu> Changes in directory llvm/include/llvm/Analysis: DSGraph.h updated: 1.44 -> 1.45 --- Log message: TD Pass now does not cause globals to mark nodes incomplete. --- Diffs of the changes: Index: llvm/include/llvm/Analysis/DSGraph.h diff -u llvm/include/llvm/Analysis/DSGraph.h:1.44 llvm/include/llvm/Analysis/DSGraph.h:1.45 --- llvm/include/llvm/Analysis/DSGraph.h:1.44 Wed Feb 5 15:59:36 2003 +++ llvm/include/llvm/Analysis/DSGraph.h Sun Feb 9 12:40:25 2003 @@ -142,6 +142,7 @@ // enum MarkIncompleteFlags { MarkFormalArgs = 1, IgnoreFormalArgs = 0, + IgnoreGlobals = 2, MarkGlobalsIncomplete = 0, }; void markIncompleteNodes(unsigned Flags); From lattner at cs.uiuc.edu Sun Feb 9 12:42:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Feb 9 12:42:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/DataStructure.cpp Message-ID: <200302091841.MAA26048@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: DataStructure.cpp updated: 1.89 -> 1.90 --- Log message: * Fix a bug where global incompleteness marking would not mark the global itself incomplete! * Allow incompleteness callers to specify they don't want globals to be considered sources of incompleteness. --- Diffs of the changes: Index: llvm/lib/Analysis/DataStructure/DataStructure.cpp diff -u llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.89 llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.90 --- llvm/lib/Analysis/DataStructure/DataStructure.cpp:1.89 Sat Feb 8 17:08:02 2003 +++ llvm/lib/Analysis/DataStructure/DataStructure.cpp Sun Feb 9 12:41:49 2003 @@ -766,14 +766,11 @@ markIncomplete(AuxFunctionCalls[i]); - // Mark all of the nodes pointed to by global nodes as incomplete... - for (unsigned i = 0, e = Nodes.size(); i != e; ++i) - if (Nodes[i]->NodeType & DSNode::GlobalNode) { - DSNode *N = Nodes[i]; - for (unsigned i = 0, e = N->getSize(); i < e; i += DS::PointerSize) - if (DSNode *DSN = N->getLink(i).getNode()) - markIncompleteNode(DSN); - } + // 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) + markIncompleteNode(Nodes[i]); } static inline void killIfUselessEdge(DSNodeHandle &Edge) { From lattner at cs.uiuc.edu Sun Feb 9 12:43:00 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Feb 9 12:43:00 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/Steensgaard.cpp Message-ID: <200302091842.MAA26069@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: Steensgaard.cpp updated: 1.21 -> 1.22 --- Log message: Print out the steens graph if -debug is specified --- Diffs of the changes: Index: llvm/lib/Analysis/DataStructure/Steensgaard.cpp diff -u llvm/lib/Analysis/DataStructure/Steensgaard.cpp:1.21 llvm/lib/Analysis/DataStructure/Steensgaard.cpp:1.22 --- llvm/lib/Analysis/DataStructure/Steensgaard.cpp:1.21 Sat Feb 8 17:03:17 2003 +++ llvm/lib/Analysis/DataStructure/Steensgaard.cpp Sun Feb 9 12:42:16 2003 @@ -11,6 +11,7 @@ #include "llvm/Analysis/DSGraph.h" #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Module.h" +#include "Support/Statistic.h" namespace { class Steens : public Pass, public AliasAnalysis { @@ -192,7 +193,7 @@ // FIXME: We should be able to disable the globals graph for steens! ResultGraph->removeDeadNodes(DSGraph::KeepUnreachableGlobals); - //print(std::cerr, &M); + DEBUG(print(std::cerr, &M)); return false; } From lattner at cs.uiuc.edu Sun Feb 9 12:43:02 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Feb 9 12:43:02 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/TopDownClosure.cpp Message-ID: <200302091842.MAA26080@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: TopDownClosure.cpp updated: 1.37 -> 1.38 --- Log message: Fix major bugs in incompleteness marking that were pessimizing results --- Diffs of the changes: Index: llvm/lib/Analysis/DataStructure/TopDownClosure.cpp diff -u llvm/lib/Analysis/DataStructure/TopDownClosure.cpp:1.37 llvm/lib/Analysis/DataStructure/TopDownClosure.cpp:1.38 --- llvm/lib/Analysis/DataStructure/TopDownClosure.cpp:1.37 Sat Feb 8 17:07:39 2003 +++ llvm/lib/Analysis/DataStructure/TopDownClosure.cpp Sun Feb 9 12:42:43 2003 @@ -106,115 +106,120 @@ const std::vector &CallSites = Graph.getFunctionCalls(); if (CallSites.empty()) { DEBUG(std::cerr << " [TD] No callees for: " << F.getName() << "\n"); - return; // If no call sites, there is nothing more to do here - } - - // Loop over all of the call sites, building a multi-map from Callees to - // DSCallSite*'s. With this map we can then loop over each callee, cloning - // this graph once into it, then resolving arguments. - // - std::multimap CalleeSites; - for (unsigned i = 0, e = CallSites.size(); i != e; ++i) { - const DSCallSite &CS = CallSites[i]; - if (CS.isDirectCall()) { - if (!CS.getCalleeFunc()->isExternal()) // If it's not external - CalleeSites.insert(std::make_pair(CS.getCalleeFunc(), &CS)); // Keep it - } else { - const std::vector &Callees = - CS.getCalleeNode()->getGlobals(); - - // Loop over all of the functions that this call may invoke... - for (unsigned c = 0, e = Callees.size(); c != e; ++c) - if (Function *F = dyn_cast(Callees[c])) // If this is a fn... - if (!F->isExternal()) // If it's not extern - CalleeSites.insert(std::make_pair(F, &CS)); // Keep track of it! + } else { + // Loop over all of the call sites, building a multi-map from Callees to + // DSCallSite*'s. With this map we can then loop over each callee, cloning + // this graph once into it, then resolving arguments. + // + std::multimap CalleeSites; + for (unsigned i = 0, e = CallSites.size(); i != e; ++i) { + const DSCallSite &CS = CallSites[i]; + if (CS.isDirectCall()) { + if (!CS.getCalleeFunc()->isExternal()) // If it's not external + CalleeSites.insert(std::make_pair(CS.getCalleeFunc(), &CS));// Keep it + } else { + const std::vector &Callees = + CS.getCalleeNode()->getGlobals(); + + // Loop over all of the functions that this call may invoke... + for (unsigned c = 0, e = Callees.size(); c != e; ++c) + if (Function *F = dyn_cast(Callees[c]))// If this is a fn... + if (!F->isExternal()) // If it's not extern + CalleeSites.insert(std::make_pair(F, &CS)); // Keep track of it! + } } - } - // Now that we have information about all of the callees, propagate the - // current graph into the callees. - // - DEBUG(std::cerr << " [TD] Inlining '" << F.getName() << "' into " - << CalleeSites.size() << " callees.\n"); - - // Loop over all the callees... - for (std::multimap::iterator - I = CalleeSites.begin(), E = CalleeSites.end(); I != E; ) - if (I->first == &F) { // Bottom-up pass takes care of self loops! - ++I; - } else { - // For each callee... - Function *Callee = I->first; - DSGraph &CG = getOrCreateDSGraph(*Callee); // Get the callee's graph... + // Now that we have information about all of the callees, propagate the + // current graph into the callees. + // + DEBUG(std::cerr << " [TD] Inlining '" << F.getName() << "' into " + << CalleeSites.size() << " callees.\n"); + + // Loop over all the callees... + for (std::multimap::iterator + I = CalleeSites.begin(), E = CalleeSites.end(); I != E; ) + if (I->first == &F) { // Bottom-up pass takes care of self loops! + ++I; + } else { + // For each callee... + Function *Callee = I->first; + DSGraph &CG = getOrCreateDSGraph(*Callee); // Get the callee's graph... - DEBUG(std::cerr << "\t [TD] Inlining into callee '" << Callee->getName() - << "'\n"); + DEBUG(std::cerr << "\t [TD] Inlining into callee '" << Callee->getName() + << "'\n"); - // Clone our current graph into the callee... - hash_map OldValMap; - hash_map OldNodeMap; - CG.cloneInto(Graph, OldValMap, OldNodeMap, - DSGraph::StripModRefBits | - DSGraph::KeepAllocaBit | DSGraph::DontCloneCallNodes); - OldValMap.clear(); // We don't care about the ValMap - - // Loop over all of the invocation sites of the callee, resolving - // arguments to our graph. This loop may iterate multiple times if the - // current function calls this callee multiple times with different - // signatures. - // - for (; I != E && I->first == Callee; ++I) { - // Map call site into callee graph - DSCallSite NewCS(*I->second, OldNodeMap); + // Clone our current graph into the callee... + hash_map OldValMap; + hash_map OldNodeMap; + CG.cloneInto(Graph, OldValMap, OldNodeMap, + DSGraph::StripModRefBits | + DSGraph::KeepAllocaBit | DSGraph::DontCloneCallNodes); + OldValMap.clear(); // We don't care about the ValMap + + // Loop over all of the invocation sites of the callee, resolving + // arguments to our graph. This loop may iterate multiple times if the + // current function calls this callee multiple times with different + // signatures. + // + for (; I != E && I->first == Callee; ++I) { + // Map call site into callee graph + DSCallSite NewCS(*I->second, OldNodeMap); - // Resolve the return values... - NewCS.getRetVal().mergeWith(CG.getRetNode()); + // Resolve the return values... + NewCS.getRetVal().mergeWith(CG.getRetNode()); - // Resolve all of the arguments... - Function::aiterator AI = Callee->abegin(); - for (unsigned i = 0, e = NewCS.getNumPtrArgs(); - i != e && AI != Callee->aend(); ++i, ++AI) { - // Advance the argument iterator to the first pointer argument... - while (!DS::isPointerType(AI->getType())) { - ++AI; + // Resolve all of the arguments... + Function::aiterator AI = Callee->abegin(); + for (unsigned i = 0, e = NewCS.getNumPtrArgs(); + i != e && AI != Callee->aend(); ++i, ++AI) { + // Advance the argument iterator to the first pointer argument... + while (!DS::isPointerType(AI->getType())) { + ++AI; #ifndef NDEBUG - if (AI == Callee->aend()) - std::cerr << "Bad call to Function: " << Callee->getName()<< "\n"; + if (AI == Callee->aend()) + std::cerr << "Bad call to Func: " << Callee->getName() << "\n"; #endif - assert(AI != Callee->aend() && - "# Args provided is not # Args required!"); - } + assert(AI != Callee->aend() && + "# Args provided is not # Args required!"); + } - // Add the link from the argument scalar to the provided value - DSNodeHandle &NH = CG.getNodeForValue(AI); - assert(NH.getNode() && "Pointer argument without scalarmap entry?"); - NH.mergeWith(NewCS.getPtrArg(i)); + // Add the link from the argument scalar to the provided value + DSNodeHandle &NH = CG.getNodeForValue(AI); + assert(NH.getNode() && "Pointer argument without scalarmap entry?"); + NH.mergeWith(NewCS.getPtrArg(i)); + } } - } - // Done with the nodemap... - OldNodeMap.clear(); + // Done with the nodemap... + OldNodeMap.clear(); - // Recompute the Incomplete markers and eliminate unreachable nodes. - CG.maskIncompleteMarkers(); - CG.markIncompleteNodes(Callee->hasInternalLinkage() ? - DSGraph::IgnoreFormalArgs : DSGraph::MarkFormalArgs - /*&& FIXME: NEED TO CHECK IF ALL CALLERS FOUND!*/); - CG.removeDeadNodes(DSGraph::RemoveUnreachableGlobals); - } + // Recompute the Incomplete markers and eliminate unreachable nodes. + CG.maskIncompleteMarkers(); + CG.markIncompleteNodes(DSGraph::MarkFormalArgs); + CG.removeDeadNodes(DSGraph::RemoveUnreachableGlobals); + } - DEBUG(std::cerr << " [TD] Done inlining into callees for: " << F.getName() - << " [" << Graph.getGraphSize() << "+" - << Graph.getFunctionCalls().size() << "]\n"); - - - // Loop over all the callees... making sure they are all resolved now... - Function *LastFunc = 0; - for (std::multimap::iterator - I = CalleeSites.begin(), E = CalleeSites.end(); I != E; ++I) - if (I->first != LastFunc) { // Only visit each callee once... - LastFunc = I->first; - calculateGraph(*I->first); - } + DEBUG(std::cerr << " [TD] Done inlining into callees for: " << F.getName() + << " [" << Graph.getGraphSize() << "+" + << Graph.getFunctionCalls().size() << "]\n"); + + // Loop over all the callees... making sure they are all resolved now... + Function *LastFunc = 0; + for (std::multimap::iterator + I = CalleeSites.begin(), E = CalleeSites.end(); I != E; ++I) + if (I->first != LastFunc) { // Only visit each callee once... + LastFunc = I->first; + calculateGraph(*I->first); + } + } + + // Recompute the Incomplete markers and eliminate unreachable nodes. + Graph.maskIncompleteMarkers(); + // FIXME: Need to check if all callers have been found, or rather if a + // funcpointer escapes! + unsigned Flags = F.hasInternalLinkage() ? + DSGraph::IgnoreFormalArgs : DSGraph::MarkFormalArgs; + Graph.markIncompleteNodes(Flags | DSGraph::IgnoreGlobals); + Graph.removeDeadNodes(DSGraph::RemoveUnreachableGlobals); } From lattner at cs.uiuc.edu Sun Feb 9 13:02:00 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Feb 9 13:02:00 2003 Subject: [llvm-commits] CVS: llvm/test/Regression/Transforms/BasicAA/featuretest.ll Message-ID: <200302091901.NAA26376@apoc.cs.uiuc.edu> Changes in directory llvm/test/Regression/Transforms/BasicAA: featuretest.ll updated: 1.2 -> 1.3 --- Log message: Add a basic-aa test --- Diffs of the changes: Index: llvm/test/Regression/Transforms/BasicAA/featuretest.ll diff -u llvm/test/Regression/Transforms/BasicAA/featuretest.ll:1.2 llvm/test/Regression/Transforms/BasicAA/featuretest.ll:1.3 --- llvm/test/Regression/Transforms/BasicAA/featuretest.ll:1.2 Fri Oct 25 17:29:07 2002 +++ llvm/test/Regression/Transforms/BasicAA/featuretest.ll Sun Feb 9 13:01:00 2003 @@ -40,3 +40,14 @@ ret int %Val } +; Test that if two pointers are spaced out by a constant getelementptr, that +; they cannot alias. +int %gep_distance_test(int* %A) { + %REMOVEu = load int* %A + %B = getelementptr int* %A, long 2 ; Cannot alias A + store int 7, int* %B + %REMOVEv = load int* %A + %r = sub int %REMOVEu, %REMOVEv + ret int %r +} + From lattner at cs.uiuc.edu Sun Feb 9 13:27:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Feb 9 13:27:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/Steensgaard.cpp Message-ID: <200302091926.NAA28564@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: Steensgaard.cpp updated: 1.22 -> 1.23 --- Log message: Switch to using the right call vector --- Diffs of the changes: Index: llvm/lib/Analysis/DataStructure/Steensgaard.cpp diff -u llvm/lib/Analysis/DataStructure/Steensgaard.cpp:1.22 llvm/lib/Analysis/DataStructure/Steensgaard.cpp:1.23 --- llvm/lib/Analysis/DataStructure/Steensgaard.cpp:1.22 Sun Feb 9 12:42:16 2003 +++ llvm/lib/Analysis/DataStructure/Steensgaard.cpp Sun Feb 9 13:26:47 2003 @@ -111,6 +111,8 @@ ResultGraph = new DSGraph(); GlobalsGraph = new DSGraph(); ResultGraph->setGlobalsGraph(GlobalsGraph); + ResultGraph->setPrintAuxCalls(); + // RetValMap - Keep track of the return values for all functions that return // valid pointers. // From lattner at cs.uiuc.edu Sun Feb 9 13:28:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Feb 9 13:28:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/AliasAnalysis.cpp Message-ID: <200302091927.NAA28576@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: AliasAnalysis.cpp updated: 1.8 -> 1.9 --- Log message: - Fix BasicAA to correctly detect the non-aliasness of A[1] & A[2] --- Diffs of the changes: Index: llvm/lib/Analysis/AliasAnalysis.cpp diff -u llvm/lib/Analysis/AliasAnalysis.cpp:1.8 llvm/lib/Analysis/AliasAnalysis.cpp:1.9 --- llvm/lib/Analysis/AliasAnalysis.cpp:1.8 Fri Feb 7 14:39:46 2003 +++ llvm/lib/Analysis/AliasAnalysis.cpp Sun Feb 9 13:27:21 2003 @@ -165,7 +165,7 @@ if (const Instruction *I = dyn_cast(V1)) return alias(I->getOperand(0), V2); if (const Instruction *I = dyn_cast(V2)) - return alias(I->getOperand(0), V1); + return alias(V1, I->getOperand(0)); // If we have two gep instructions with identical indices, return an alias // result equal to the alias result of the original pointer... @@ -197,7 +197,7 @@ // doesn't tell us anything. // if (AllConstant && - alias(GEP1->getOperand(0), GEP2->getOperand(1)) != MayAlias) + alias(GEP1->getOperand(0), GEP2->getOperand(0)) != MayAlias) return NoAlias; } From lattner at cs.uiuc.edu Sun Feb 9 13:39:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Feb 9 13:39:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/AliasAnalysis.cpp Message-ID: <200302091938.NAA28692@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: AliasAnalysis.cpp updated: 1.9 -> 1.10 --- Log message: Implement knowledge in BasicAA that &A->field != &A and (P+1) != P --- Diffs of the changes: Index: llvm/lib/Analysis/AliasAnalysis.cpp diff -u llvm/lib/Analysis/AliasAnalysis.cpp:1.9 llvm/lib/Analysis/AliasAnalysis.cpp:1.10 --- llvm/lib/Analysis/AliasAnalysis.cpp:1.9 Sun Feb 9 13:27:21 2003 +++ llvm/lib/Analysis/AliasAnalysis.cpp Sun Feb 9 13:38:11 2003 @@ -220,5 +220,22 @@ return NoAlias; // Unique values don't alias null } + // Check to see if these two pointers are related by a getelementptr + // instruction. If one pointer is a GEP with a non-zero index of the other + // pointer, we know they cannot alias. + // + if (isa(V2)) + std::swap(V1, V2); + + if (const GetElementPtrInst *GEP = dyn_cast(V1)) + if (GEP->getOperand(0) == V2) { + // If there is at least one non-zero constant index, we know they cannot + // alias. + for (unsigned i = 1, e = GEP->getNumOperands(); i != e; ++i) + if (const Constant *C = dyn_cast(GEP->getOperand(i))) + if (!C->isNullValue()) + return NoAlias; + } + return MayAlias; } From lattner at cs.uiuc.edu Sun Feb 9 14:41:00 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Feb 9 14:41:00 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/AliasAnalysisEvaluator.cpp Message-ID: <200302092040.OAA29599@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis: AliasAnalysisEvaluator.cpp updated: 1.3 -> 1.4 --- Log message: Allow printing of various types of alias analysis results --- Diffs of the changes: Index: llvm/lib/Analysis/AliasAnalysisEvaluator.cpp diff -u llvm/lib/Analysis/AliasAnalysisEvaluator.cpp:1.3 llvm/lib/Analysis/AliasAnalysisEvaluator.cpp:1.4 --- llvm/lib/Analysis/AliasAnalysisEvaluator.cpp:1.3 Sat Feb 8 17:04:50 2003 +++ llvm/lib/Analysis/AliasAnalysisEvaluator.cpp Sun Feb 9 14:40:13 2003 @@ -13,10 +13,16 @@ #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Pass.h" #include "llvm/Function.h" -#include "llvm/Support/InstIterator.h" #include "llvm/Type.h" +#include "llvm/Support/InstIterator.h" +#include "llvm/Assembly/Writer.h" +#include "Support/CommandLine.h" namespace { + cl::opt PrintNo ("print-no-alias-results", cl::ReallyHidden); + cl::opt PrintMay ("print-may-alias-results", cl::ReallyHidden); + cl::opt PrintMust("print-must-alias-results", cl::ReallyHidden); + class AAEval : public FunctionPass { unsigned No, May, Must; @@ -35,6 +41,14 @@ X("aa-eval", "Exhaustive Alias Analysis Precision Evaluator"); } +static inline void PrintResults(const char *Msg, bool P, Value *V1, Value *V2) { + if (P) { + std::cerr << " " << Msg << ":\t"; + WriteAsOperand(std::cerr, V1) << ", "; + WriteAsOperand(std::cerr, V2) << "\n"; + } +} + bool AAEval::runOnFunction(Function &F) { AliasAnalysis &AA = getAnalysis(); @@ -48,14 +62,23 @@ if (isa((*I)->getType())) // Add all pointer instructions Pointers.push_back(*I); + if (PrintNo || PrintMay || PrintMust) + std::cerr << "Function: " << F.getName() << "\n"; + // iterate over the worklist, and run the full (n^2)/2 disambiguations for (std::vector::iterator I1 = Pointers.begin(), E = Pointers.end(); I1 != E; ++I1) for (std::vector::iterator I2 = Pointers.begin(); I2 != I1; ++I2) switch (AA.alias(*I1, *I2)) { - case AliasAnalysis::NoAlias: ++No; break; - case AliasAnalysis::MayAlias: ++May; break; - case AliasAnalysis::MustAlias: ++Must; break; + case AliasAnalysis::NoAlias: + PrintResults("No", PrintNo, *I1, *I2); + ++No; break; + case AliasAnalysis::MayAlias: + PrintResults("May", PrintMay, *I1, *I2); + ++May; break; + case AliasAnalysis::MustAlias: + PrintResults("Must", PrintMust, *I1, *I2); + ++Must; break; default: std::cerr << "Unknown alias query result!\n"; } From lattner at cs.uiuc.edu Sun Feb 9 15:15:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Feb 9 15:15:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Support/Statistic.cpp Message-ID: <200302092114.PAA29846@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Support: Statistic.cpp updated: 1.6 -> 1.7 --- Log message: Remove the -debug option from release executables --- Diffs of the changes: Index: llvm/lib/Support/Statistic.cpp diff -u llvm/lib/Support/Statistic.cpp:1.6 llvm/lib/Support/Statistic.cpp:1.7 --- llvm/lib/Support/Statistic.cpp:1.6 Sun Oct 27 13:07:47 2002 +++ llvm/lib/Support/Statistic.cpp Sun Feb 9 15:13:57 2003 @@ -30,10 +30,13 @@ static cl::opt Enabled("stats", cl::desc("Enable statistics output from program")); +#ifndef NDEBUG // -debug - Command line option to enable the DEBUG statements in the passes. +// This flag may only be enabled in debug builds. static cl::opt Debug("debug", cl::desc("Enable debug output"), cl::Hidden, cl::location(DebugFlag)); +#endif struct StatRecord { std::string Value; From ashukla at cs.uiuc.edu Sun Feb 9 15:17:01 2003 From: ashukla at cs.uiuc.edu (Anand Shukla) Date: Sun Feb 9 15:17:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Transforms/Instrumentation/ProfilePaths/Graph.h Message-ID: <200302092116.PAA26856@morpheus.cs.uiuc.edu> Changes in directory llvm/lib/Transforms/Instrumentation/ProfilePaths: Graph.h updated: 1.5 -> 1.6 --- Log message: --- Diffs of the changes: Index: llvm/lib/Transforms/Instrumentation/ProfilePaths/Graph.h diff -u llvm/lib/Transforms/Instrumentation/ProfilePaths/Graph.h:1.5 llvm/lib/Transforms/Instrumentation/ProfilePaths/Graph.h:1.6 --- llvm/lib/Transforms/Instrumentation/ProfilePaths/Graph.h:1.5 Tue Oct 1 17:40:31 2002 +++ llvm/lib/Transforms/Instrumentation/ProfilePaths/Graph.h Sun Feb 9 15:15:36 2003 @@ -410,7 +410,7 @@ //get the code to be inserted on the edge //This is determined from cond (1-6) - void getCode(Instruction *a, Instruction *b, Function *M, BasicBlock *BB, + void getCode(Instruction *a, Value *b, Function *M, BasicBlock *BB, std::vector &retVec); }; @@ -423,7 +423,7 @@ //Do graph processing: to determine minimal edge increments, //appropriate code insertions etc and insert the code at //appropriate locations -void processGraph(Graph &g, Instruction *rInst, Instruction *countInst, std::vector &be, std::vector &stDummy, std::vector &exDummy, int n, int MethNo, Value *threshold); +void processGraph(Graph &g, Instruction *rInst, Value *countInst, std::vector &be, std::vector &stDummy, std::vector &exDummy, int n, int MethNo, Value *threshold); //print the graph (for debugging) void printGraph(Graph &g); @@ -432,7 +432,7 @@ //void printGraph(const Graph g); //insert a basic block with appropriate code //along a given edge -void insertBB(Edge ed, getEdgeCode *edgeCode, Instruction *rInst, Instruction *countInst, int n, int Methno, Value *threshold); +void insertBB(Edge ed, getEdgeCode *edgeCode, Instruction *rInst, Value *countInst, int n, int Methno, Value *threshold); //Insert the initialization code in the top BB //this includes initializing r, and count @@ -442,7 +442,7 @@ //number of that path //Count is an array, where Count[k] represents //the number of executions of path k -void insertInTopBB(BasicBlock *front, int k, Instruction *rVar, Instruction *countVar, Value *threshold); +void insertInTopBB(BasicBlock *front, int k, Instruction *rVar, Value *threshold); //Add dummy edges corresponding to the back edges //If a->b is a backedge From lattner at cs.uiuc.edu Sun Feb 9 17:05:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Feb 9 17:05:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/Local.cpp Message-ID: <200302092304.RAA31428@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: Local.cpp updated: 1.48 -> 1.49 --- Log message: Don't insert null entries into the scalar map for constexpr (cast null to Ty) --- Diffs of the changes: Index: llvm/lib/Analysis/DataStructure/Local.cpp diff -u llvm/lib/Analysis/DataStructure/Local.cpp:1.48 llvm/lib/Analysis/DataStructure/Local.cpp:1.49 --- llvm/lib/Analysis/DataStructure/Local.cpp:1.48 Sat Feb 8 14:18:39 2003 +++ llvm/lib/Analysis/DataStructure/Local.cpp Sun Feb 9 17:04:12 2003 @@ -174,16 +174,22 @@ return NH = getValueDest(*CPR->getValue()); } else if (ConstantExpr *CE = dyn_cast(C)) { if (CE->getOpcode() == Instruction::Cast) - return NH = getValueDest(*CE->getOperand(0)); - if (CE->getOpcode() == Instruction::GetElementPtr) { + NH = getValueDest(*CE->getOperand(0)); + else if (CE->getOpcode() == Instruction::GetElementPtr) { visitGetElementPtrInst(*CE); hash_map::iterator I = ScalarMap.find(CE); assert(I != ScalarMap.end() && "GEP didn't get processed right?"); - return NH = I->second; + NH = I->second; + } else { + // This returns a conservative unknown node for any unhandled ConstExpr + return NH = createNode(DSNode::UnknownNode); } + if (NH.getNode() == 0) { // (getelementptr null, X) returns null + ScalarMap.erase(V); + return 0; + } + return NH; - // This returns a conservative unknown node for any unhandled ConstExpr - return NH = createNode(DSNode::UnknownNode); } else if (ConstantIntegral *CI = dyn_cast(C)) { // Random constants are unknown mem return NH = createNode(DSNode::UnknownNode); From lattner at cs.uiuc.edu Sun Feb 9 18:16:01 2003 From: lattner at cs.uiuc.edu (Chris Lattner) Date: Sun Feb 9 18:16:01 2003 Subject: [llvm-commits] CVS: llvm/lib/Analysis/DataStructure/Steensgaard.cpp Message-ID: <200302100015.SAA05457@apoc.cs.uiuc.edu> Changes in directory llvm/lib/Analysis/DataStructure: Steensgaard.cpp updated: 1.23 -> 1.24 --- Log message: Make steensgaards performance not shameful --- Diffs of the changes: Index: llvm/lib/Analysis/DataStructure/Steensgaard.cpp diff -u llvm/lib/Analysis/DataStructure/Steensgaard.cpp:1.23 llvm/lib/Analysis/DataStructure/Steensgaard.cpp:1.24 --- llvm/lib/Analysis/DataStructure/Steensgaard.cpp:1.23 Sun Feb 9 13:26:47 2003 +++ llvm/lib/Analysis/DataStructure/Steensgaard.cpp Sun Feb 9 18:14:57 2003 @@ -121,6 +121,7 @@ // Loop over the rest of the module, merging graphs for non-external functions // into this graph. // + unsigned Count = 0; for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) if (!I->isExternal()) { hash_map ValMap; @@ -142,6 +143,9 @@ for (hash_map::iterator I = ValMap.begin(), E = ValMap.end(); I != E; ++I) GVM[I->first].mergeWith(I->second); + + if ((++Count & 1) == 0) // Prune nodes out every other time... + ResultGraph->removeTriviallyDeadNodes(); } // FIXME: Must recalculate and use the Incomplete markers!! @@ -174,15 +178,17 @@ ResolveFunctionCall(F, CurCall, RetValMap[F]); Eliminated = true; } - if (Eliminated) - CallTargets.erase(CallTargets.begin()+c); - else + if (Eliminated) { + CallTargets[c] = CallTargets.back(); + CallTargets.pop_back(); + } else ++c; // Cannot eliminate this call, skip over it... } - if (CallTargets.empty()) // Eliminated all calls? - Calls.erase(Calls.begin()+i); // Remove from call list... - else + if (CallTargets.empty()) { // Eliminated all calls? + CurCall = Calls.back(); // Remove entry + Calls.pop_back(); + } else ++i; // Skip this call site... }