All DSGraphs keep a reference to the targetdata they are created with.  This is
used to eliminate the hard coded, hacked in, sparc specific, global TargetData.
Changing the TargetData used to actually match the code fixes problems, and
eliminates a crash.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@9659 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/llvm/Analysis/DSGraph.h b/include/llvm/Analysis/DSGraph.h
index fae11f4..4226cf1 100644
--- a/include/llvm/Analysis/DSGraph.h
+++ b/include/llvm/Analysis/DSGraph.h
@@ -62,12 +62,19 @@
   // 
   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 @@
   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 0bbc0f7..ba5328b 100644
--- a/include/llvm/Analysis/DSNode.h
+++ b/include/llvm/Analysis/DSNode.h
@@ -18,6 +18,7 @@
 
 template<typename BaseType>
 class DSNodeIterator;          // Data structure graph traversal iterator
+class TargetData;
 
 //===----------------------------------------------------------------------===//
 /// DSNode - Data structure node class
@@ -134,6 +135,11 @@
   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 3ebe15d..e5662ff 100644
--- a/include/llvm/Analysis/DSSupport.h
+++ b/include/llvm/Analysis/DSSupport.h
@@ -28,7 +28,7 @@
 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 f32d41f..afea126 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 @@
   // getAnalysisUsage - This obviously provides a data structure graph.
   virtual void getAnalysisUsage(AnalysisUsage &AU) const {
     AU.setPreservesAll();
+    AU.addRequired<TargetData>();
   }
 };
 
diff --git a/include/llvm/Analysis/DataStructure/DSGraph.h b/include/llvm/Analysis/DataStructure/DSGraph.h
index fae11f4..4226cf1 100644
--- a/include/llvm/Analysis/DataStructure/DSGraph.h
+++ b/include/llvm/Analysis/DataStructure/DSGraph.h
@@ -62,12 +62,19 @@
   // 
   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 @@
   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 0bbc0f7..ba5328b 100644
--- a/include/llvm/Analysis/DataStructure/DSNode.h
+++ b/include/llvm/Analysis/DataStructure/DSNode.h
@@ -18,6 +18,7 @@
 
 template<typename BaseType>
 class DSNodeIterator;          // Data structure graph traversal iterator
+class TargetData;
 
 //===----------------------------------------------------------------------===//
 /// DSNode - Data structure node class
@@ -134,6 +135,11 @@
   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 3ebe15d..e5662ff 100644
--- a/include/llvm/Analysis/DataStructure/DSSupport.h
+++ b/include/llvm/Analysis/DataStructure/DSSupport.h
@@ -28,7 +28,7 @@
 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 f32d41f..afea126 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 @@
   // getAnalysisUsage - This obviously provides a data structure graph.
   virtual void getAnalysisUsage(AnalysisUsage &AU) const {
     AU.setPreservesAll();
+    AU.addRequired<TargetData>();
   }
 };
 
diff --git a/lib/Analysis/DataStructure/DataStructure.cpp b/lib/Analysis/DataStructure/DataStructure.cpp
index efcae98..c20299e 100644
--- a/lib/Analysis/DataStructure/DataStructure.cpp
+++ b/lib/Analysis/DataStructure/DataStructure.cpp
@@ -28,9 +28,6 @@
   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 @@
   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 @@
     };
 
     std::vector<StackState> 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 @@
 /// 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 @@
 ///
 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 @@
   // 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 @@
 }
 
 
-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, 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 fcaadf3..689373e 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 @@
 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<PointerType>(Ty))
@@ -152,7 +147,8 @@
 //===----------------------------------------------------------------------===//
 // 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 @@
     return;
   }
 
+  const TargetData &TD = Value.getNode()->getTargetData();
+
 #if 0
   // Handle the pointer index specially...
   if (GEP.getNumOperands() > 1 &&
@@ -531,7 +529,9 @@
       NH.addEdgeTo(getValueDest(*C));
     return;
   }
-  
+
+  const TargetData &TD = NH.getNode()->getTargetData();
+
   if (ConstantArray *CA = dyn_cast<ConstantArray>(C)) {
     for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i)
       // We don't currently do any indexing for arrays...
@@ -556,12 +556,14 @@
 
 
 bool LocalDataStructures::run(Module &M) {
-  GlobalsGraph = new DSGraph();
+  GlobalsGraph = new DSGraph(getAnalysis<TargetData>());
+
+  const TargetData &TD = getAnalysis<TargetData>();
 
   // 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 29bbf3a..8bf917f 100644
--- a/lib/Analysis/DataStructure/Steensgaard.cpp
+++ b/lib/Analysis/DataStructure/Steensgaard.cpp
@@ -110,8 +110,8 @@
   LocalDataStructures &LDS = getAnalysis<LocalDataStructures>();
 
   // Create a new, empty, graph...
-  ResultGraph = new DSGraph();
-  GlobalsGraph = new DSGraph();
+  ResultGraph = new DSGraph(getTargetData());
+  GlobalsGraph = new DSGraph(getTargetData());
   ResultGraph->setGlobalsGraph(GlobalsGraph);
   ResultGraph->setPrintAuxCalls();