diff --git a/include/llvm/Analysis/DSGraph.h b/include/llvm/Analysis/DSGraph.h index fae11f4abe2..4226cf1e460 100644 --- a/include/llvm/Analysis/DSGraph.h +++ b/include/llvm/Analysis/DSGraph.h @@ -62,12 +62,19 @@ private: // GlobalSetTy InlinedGlobals; + /// TD - This is the target data object for the machine this graph is + /// constructed for. + const TargetData &TD; + void operator=(const DSGraph &); // DO NOT IMPLEMENT public: // Create a new, empty, DSGraph. - DSGraph() : GlobalsGraph(0), PrintAuxCalls(false) {} - DSGraph(Function &F, DSGraph *GlobalsGraph); // Compute the local DSGraph + DSGraph(const TargetData &td) + : GlobalsGraph(0), PrintAuxCalls(false), TD(td) {} + + // Compute the local DSGraph + DSGraph(const TargetData &td, Function &F, DSGraph *GlobalsGraph); // Copy ctor - If you want to capture the node mapping between the source and // destination graph, you may optionally do this by specifying a map to record @@ -84,9 +91,13 @@ public: DSGraph *getGlobalsGraph() const { return GlobalsGraph; } void setGlobalsGraph(DSGraph *G) { GlobalsGraph = G; } - // setPrintAuxCalls - If you call this method, the auxillary call vector will - // be printed instead of the standard call vector to the dot file. - // + /// getTargetData - Return the TargetData object for the current target. + /// + const TargetData &getTargetData() const { return TD; } + + /// setPrintAuxCalls - If you call this method, the auxillary call vector will + /// be printed instead of the standard call vector to the dot file. + /// void setPrintAuxCalls() { PrintAuxCalls = true; } bool shouldPrintAuxCalls() const { return PrintAuxCalls; } diff --git a/include/llvm/Analysis/DSNode.h b/include/llvm/Analysis/DSNode.h index 0bbc0f7198a..ba5328b2b8f 100644 --- a/include/llvm/Analysis/DSNode.h +++ b/include/llvm/Analysis/DSNode.h @@ -18,6 +18,7 @@ template class DSNodeIterator; // Data structure graph traversal iterator +class TargetData; //===----------------------------------------------------------------------===// /// DSNode - Data structure node class @@ -134,6 +135,11 @@ public: DSGraph *getParentGraph() const { return ParentGraph; } void setParentGraph(DSGraph *G) { ParentGraph = G; } + + /// getTargetData - Get the target data object used to construct this node. + /// + const TargetData &getTargetData() const; + /// getForwardNode - This method returns the node that this node is forwarded /// to, if any. DSNode *getForwardNode() const { return ForwardNH.getNode(); } diff --git a/include/llvm/Analysis/DSSupport.h b/include/llvm/Analysis/DSSupport.h index 3ebe15dbfe9..e5662ff0a4c 100644 --- a/include/llvm/Analysis/DSSupport.h +++ b/include/llvm/Analysis/DSSupport.h @@ -28,7 +28,7 @@ class DSNode; // Each node in the graph class DSGraph; // A graph for a function namespace DS { // FIXME: After the paper, this should get cleaned up - enum { PointerShift = 3, // 64bit ptrs = 3, 32 bit ptrs = 2 + enum { PointerShift = 2, // 64bit ptrs = 3, 32 bit ptrs = 2 PointerSize = 1 << PointerShift }; diff --git a/include/llvm/Analysis/DataStructure.h b/include/llvm/Analysis/DataStructure.h index f32d41f26e0..afea126c074 100644 --- a/include/llvm/Analysis/DataStructure.h +++ b/include/llvm/Analysis/DataStructure.h @@ -15,6 +15,7 @@ #define LLVM_ANALYSIS_DATA_STRUCTURE_H #include "llvm/Pass.h" +#include "llvm/Target/TargetData.h" #include "Support/hash_set" class Type; @@ -69,6 +70,7 @@ public: // getAnalysisUsage - This obviously provides a data structure graph. virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); + AU.addRequired(); } }; diff --git a/include/llvm/Analysis/DataStructure/DSGraph.h b/include/llvm/Analysis/DataStructure/DSGraph.h index fae11f4abe2..4226cf1e460 100644 --- a/include/llvm/Analysis/DataStructure/DSGraph.h +++ b/include/llvm/Analysis/DataStructure/DSGraph.h @@ -62,12 +62,19 @@ private: // GlobalSetTy InlinedGlobals; + /// TD - This is the target data object for the machine this graph is + /// constructed for. + const TargetData &TD; + void operator=(const DSGraph &); // DO NOT IMPLEMENT public: // Create a new, empty, DSGraph. - DSGraph() : GlobalsGraph(0), PrintAuxCalls(false) {} - DSGraph(Function &F, DSGraph *GlobalsGraph); // Compute the local DSGraph + DSGraph(const TargetData &td) + : GlobalsGraph(0), PrintAuxCalls(false), TD(td) {} + + // Compute the local DSGraph + DSGraph(const TargetData &td, Function &F, DSGraph *GlobalsGraph); // Copy ctor - If you want to capture the node mapping between the source and // destination graph, you may optionally do this by specifying a map to record @@ -84,9 +91,13 @@ public: DSGraph *getGlobalsGraph() const { return GlobalsGraph; } void setGlobalsGraph(DSGraph *G) { GlobalsGraph = G; } - // setPrintAuxCalls - If you call this method, the auxillary call vector will - // be printed instead of the standard call vector to the dot file. - // + /// getTargetData - Return the TargetData object for the current target. + /// + const TargetData &getTargetData() const { return TD; } + + /// setPrintAuxCalls - If you call this method, the auxillary call vector will + /// be printed instead of the standard call vector to the dot file. + /// void setPrintAuxCalls() { PrintAuxCalls = true; } bool shouldPrintAuxCalls() const { return PrintAuxCalls; } diff --git a/include/llvm/Analysis/DataStructure/DSNode.h b/include/llvm/Analysis/DataStructure/DSNode.h index 0bbc0f7198a..ba5328b2b8f 100644 --- a/include/llvm/Analysis/DataStructure/DSNode.h +++ b/include/llvm/Analysis/DataStructure/DSNode.h @@ -18,6 +18,7 @@ template class DSNodeIterator; // Data structure graph traversal iterator +class TargetData; //===----------------------------------------------------------------------===// /// DSNode - Data structure node class @@ -134,6 +135,11 @@ public: DSGraph *getParentGraph() const { return ParentGraph; } void setParentGraph(DSGraph *G) { ParentGraph = G; } + + /// getTargetData - Get the target data object used to construct this node. + /// + const TargetData &getTargetData() const; + /// getForwardNode - This method returns the node that this node is forwarded /// to, if any. DSNode *getForwardNode() const { return ForwardNH.getNode(); } diff --git a/include/llvm/Analysis/DataStructure/DSSupport.h b/include/llvm/Analysis/DataStructure/DSSupport.h index 3ebe15dbfe9..e5662ff0a4c 100644 --- a/include/llvm/Analysis/DataStructure/DSSupport.h +++ b/include/llvm/Analysis/DataStructure/DSSupport.h @@ -28,7 +28,7 @@ class DSNode; // Each node in the graph class DSGraph; // A graph for a function namespace DS { // FIXME: After the paper, this should get cleaned up - enum { PointerShift = 3, // 64bit ptrs = 3, 32 bit ptrs = 2 + enum { PointerShift = 2, // 64bit ptrs = 3, 32 bit ptrs = 2 PointerSize = 1 << PointerShift }; diff --git a/include/llvm/Analysis/DataStructure/DataStructure.h b/include/llvm/Analysis/DataStructure/DataStructure.h index f32d41f26e0..afea126c074 100644 --- a/include/llvm/Analysis/DataStructure/DataStructure.h +++ b/include/llvm/Analysis/DataStructure/DataStructure.h @@ -15,6 +15,7 @@ #define LLVM_ANALYSIS_DATA_STRUCTURE_H #include "llvm/Pass.h" +#include "llvm/Target/TargetData.h" #include "Support/hash_set" class Type; @@ -69,6 +70,7 @@ public: // getAnalysisUsage - This obviously provides a data structure graph. virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); + AU.addRequired(); } }; diff --git a/lib/Analysis/DataStructure/DataStructure.cpp b/lib/Analysis/DataStructure/DataStructure.cpp index efcae9826ef..c20299e0bb2 100644 --- a/lib/Analysis/DataStructure/DataStructure.cpp +++ b/lib/Analysis/DataStructure/DataStructure.cpp @@ -28,9 +28,6 @@ namespace { Statistic<> NumCallNodesMerged("dsnode", "Number of call nodes merged"); }; -namespace DS { // TODO: FIXME - extern TargetData TD; -} using namespace DS; DSNode *DSNodeHandle::HandleForwarding() const { @@ -72,6 +69,12 @@ DSNode::DSNode(const DSNode &N, DSGraph *G) G->getNodes().push_back(this); } +/// getTargetData - Get the target data object used to construct this node. +/// +const TargetData &DSNode::getTargetData() const { + return ParentGraph->getTargetData(); +} + void DSNode::assertOK() const { assert((Ty != Type::VoidTy || Ty == Type::VoidTy && (Size == 0 || @@ -172,8 +175,9 @@ namespace { }; std::vector Stack; + const TargetData &TD; public: - TypeElementWalker(const Type *T) { + TypeElementWalker(const Type *T, const TargetData &td) : TD(td) { Stack.push_back(T); StepToLeaf(); } @@ -256,8 +260,8 @@ namespace { /// is true, then we also allow a larger T1. /// static bool ElementTypesAreCompatible(const Type *T1, const Type *T2, - bool AllowLargerT1) { - TypeElementWalker T1W(T1), T2W(T2); + bool AllowLargerT1, const TargetData &TD){ + TypeElementWalker T1W(T1, TD), T2W(T2, TD); while (!T1W.isDone() && !T2W.isDone()) { if (T1W.getCurrentOffset() != T2W.getCurrentOffset()) @@ -286,6 +290,7 @@ static bool ElementTypesAreCompatible(const Type *T1, const Type *T2, /// bool DSNode::mergeTypeInfo(const Type *NewTy, unsigned Offset, bool FoldIfIncompatible) { + const TargetData &TD = getTargetData(); // Check to make sure the Size member is up-to-date. Size can be one of the // following: // Size = 0, Ty = Void: Nothing is known about this node. @@ -426,7 +431,7 @@ bool DSNode::mergeTypeInfo(const Type *NewTy, unsigned Offset, // just require each element in the node to be compatible. if (NewTySize <= SubTypeSize && NewTySize && NewTySize < 256 && SubTypeSize && SubTypeSize < 256 && - ElementTypesAreCompatible(NewTy, SubType, !isArray())) + ElementTypesAreCompatible(NewTy, SubType, !isArray(), TD)) return false; // Okay, so we found the leader type at the offset requested. Search the list @@ -743,7 +748,7 @@ std::string DSGraph::getFunctionNames() const { } -DSGraph::DSGraph(const DSGraph &G) : GlobalsGraph(0) { +DSGraph::DSGraph(const DSGraph &G) : GlobalsGraph(0), TD(G.TD) { PrintAuxCalls = false; NodeMapTy NodeMap; cloneInto(G, ScalarMap, ReturnNodes, NodeMap); @@ -751,7 +756,7 @@ DSGraph::DSGraph(const DSGraph &G) : GlobalsGraph(0) { } DSGraph::DSGraph(const DSGraph &G, NodeMapTy &NodeMap) - : GlobalsGraph(0) { + : GlobalsGraph(0), TD(G.TD) { PrintAuxCalls = false; cloneInto(G, ScalarMap, ReturnNodes, NodeMap); InlinedGlobals.clear(); // clear set of "up-to-date" globals diff --git a/lib/Analysis/DataStructure/Local.cpp b/lib/Analysis/DataStructure/Local.cpp index fcaadf3755f..689373ee7d2 100644 --- a/lib/Analysis/DataStructure/Local.cpp +++ b/lib/Analysis/DataStructure/Local.cpp @@ -16,8 +16,6 @@ #include "llvm/Analysis/DSGraph.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" -#include "llvm/Function.h" -#include "llvm/GlobalVariable.h" #include "llvm/Instructions.h" #include "llvm/Support/InstVisitor.h" #include "llvm/Target/TargetData.h" @@ -34,9 +32,6 @@ static RegisterAnalysis X("datastructure", "Local Data Structure Analysis"); namespace DS { - // FIXME: Do something smarter with target data! - TargetData TD("temp-td"); - // isPointerType - Return true if this type is big enough to hold a pointer. bool isPointerType(const Type *Ty) { if (isa(Ty)) @@ -152,7 +147,8 @@ namespace { //===----------------------------------------------------------------------===// // DSGraph constructor - Simply use the GraphBuilder to construct the local // graph. -DSGraph::DSGraph(Function &F, DSGraph *GG) : GlobalsGraph(GG) { +DSGraph::DSGraph(const TargetData &td, Function &F, DSGraph *GG) + : GlobalsGraph(GG), TD(td) { PrintAuxCalls = false; DEBUG(std::cerr << " [Loc] Calculating graph for: " << F.getName() << "\n"); @@ -311,6 +307,8 @@ void GraphBuilder::visitGetElementPtrInst(User &GEP) { return; } + const TargetData &TD = Value.getNode()->getTargetData(); + #if 0 // Handle the pointer index specially... if (GEP.getNumOperands() > 1 && @@ -531,7 +529,9 @@ void GraphBuilder::MergeConstantInitIntoNode(DSNodeHandle &NH, Constant *C) { NH.addEdgeTo(getValueDest(*C)); return; } - + + const TargetData &TD = NH.getNode()->getTargetData(); + if (ConstantArray *CA = dyn_cast(C)) { for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i) // We don't currently do any indexing for arrays... @@ -556,12 +556,14 @@ void GraphBuilder::mergeInGlobalInitializer(GlobalVariable *GV) { bool LocalDataStructures::run(Module &M) { - GlobalsGraph = new DSGraph(); + GlobalsGraph = new DSGraph(getAnalysis()); + + const TargetData &TD = getAnalysis(); // Calculate all of the graphs... for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) if (!I->isExternal()) - DSInfo.insert(std::make_pair(I, new DSGraph(*I, GlobalsGraph))); + DSInfo.insert(std::make_pair(I, new DSGraph(TD, *I, GlobalsGraph))); GraphBuilder GGB(*GlobalsGraph); diff --git a/lib/Analysis/DataStructure/Steensgaard.cpp b/lib/Analysis/DataStructure/Steensgaard.cpp index 29bbf3a3fb1..8bf917f0483 100644 --- a/lib/Analysis/DataStructure/Steensgaard.cpp +++ b/lib/Analysis/DataStructure/Steensgaard.cpp @@ -110,8 +110,8 @@ bool Steens::run(Module &M) { LocalDataStructures &LDS = getAnalysis(); // Create a new, empty, graph... - ResultGraph = new DSGraph(); - GlobalsGraph = new DSGraph(); + ResultGraph = new DSGraph(getTargetData()); + GlobalsGraph = new DSGraph(getTargetData()); ResultGraph->setGlobalsGraph(GlobalsGraph); ResultGraph->setPrintAuxCalls();