- Use the "Fast" flag instead of "OptimizeForSize" to determine whether to emit
[oota-llvm.git] / lib / Analysis / IPA / Andersens.cpp
index ab80bab95c7064d8471cc7f57f012a386d8ec1c1..8584d06f7a7b093d98576a7b4c5c6a230f42bee4 100644 (file)
@@ -89,14 +89,14 @@ STATISTIC(NumNodes      , "Number of nodes");
 STATISTIC(NumUnified    , "Number of variables unified");
 STATISTIC(NumErased     , "Number of redundant constraints erased");
 
-namespace {
-  const unsigned SelfRep = (unsigned)-1;
-  const unsigned Unvisited = (unsigned)-1;
-  // Position of the function return node relative to the function node.
-  const unsigned CallReturnPos = 1;
-  // Position of the function call node relative to the function node.
-  const unsigned CallFirstArgPos = 2;
+static const unsigned SelfRep = (unsigned)-1;
+static const unsigned Unvisited = (unsigned)-1;
+// Position of the function return node relative to the function node.
+static const unsigned CallReturnPos = 1;
+// Position of the function call node relative to the function node.
+static const unsigned CallFirstArgPos = 2;
 
+namespace {
   struct BitmapKeyInfo {
     static inline SparseBitVector<> *getEmptyKey() {
       return reinterpret_cast<SparseBitVector<> *>(-1);
@@ -431,7 +431,7 @@ namespace {
 
   public:
     static char ID;
-    Andersens() : ModulePass((intptr_t)&ID) {}
+    Andersens() : ModulePass(&ID) {}
 
     bool runOnModule(Module &M) {
       InitializeAliasAnalysis(this);
@@ -608,16 +608,15 @@ namespace {
       PrintPointsToGraph();
     }
   };
+}
 
-  char Andersens::ID = 0;
-  RegisterPass<Andersens> X("anders-aa",
-                            "Andersen's Interprocedural Alias Analysis", false,
-                            true);
-  RegisterAnalysisGroup<AliasAnalysis> Y(X);
+char Andersens::ID = 0;
+static RegisterPass<Andersens>
+X("anders-aa", "Andersen's Interprocedural Alias Analysis", false, true);
+static RegisterAnalysisGroup<AliasAnalysis> Y(X);
 
-  // Initialize Timestamp Counter (static).
-  unsigned Andersens::Node::Counter = 0;
-}
+// Initialize Timestamp Counter (static).
+unsigned Andersens::Node::Counter = 0;
 
 ModulePass *llvm::createAndersensPass() { return new Andersens(); }
 
@@ -864,7 +863,7 @@ unsigned Andersens::getNodeForConstantPointerTarget(Constant *C) {
 /// object N, which contains values indicated by C.
 void Andersens::AddGlobalInitializerConstraints(unsigned NodeIndex,
                                                 Constant *C) {
-  if (C->getType()->isFirstClassType()) {
+  if (C->getType()->isSingleValueType()) {
     if (isa<PointerType>(C->getType()))
       Constraints.push_back(Constraint(Constraint::Copy, NodeIndex,
                                        getNodeForConstantPointer(C)));
@@ -904,8 +903,7 @@ bool Andersens::AddConstraintsForExternalCall(CallSite CS, Function *F) {
       F->getName() == "atol" || F->getName() == "atoll" ||
       F->getName() == "remove" || F->getName() == "unlink" ||
       F->getName() == "rename" || F->getName() == "memcmp" ||
-      F->getName() == "llvm.memset.i32" ||
-      F->getName() == "llvm.memset.i64" ||
+      F->getName() == "llvm.memset" ||
       F->getName() == "strcmp" || F->getName() == "strncmp" ||
       F->getName() == "execl" || F->getName() == "execlp" ||
       F->getName() == "execle" || F->getName() == "execv" ||
@@ -943,34 +941,44 @@ bool Andersens::AddConstraintsForExternalCall(CallSite CS, Function *F) {
 
 
   // These functions do induce points-to edges.
-  if (F->getName() == "llvm.memcpy.i32" || F->getName() == "llvm.memcpy.i64" ||
-      F->getName() == "llvm.memmove.i32" ||F->getName() == "llvm.memmove.i64" ||
+  if (F->getName() == "llvm.memcpy" ||
+      F->getName() == "llvm.memmove" ||
       F->getName() == "memmove") {
 
-    // *Dest = *Src, which requires an artificial graph node to represent the
-    // constraint.  It is broken up into *Dest = temp, temp = *Src
-    unsigned FirstArg = getNode(CS.getArgument(0));
-    unsigned SecondArg = getNode(CS.getArgument(1));
-    unsigned TempArg = GraphNodes.size();
-    GraphNodes.push_back(Node());
-    Constraints.push_back(Constraint(Constraint::Store,
-                                     FirstArg, TempArg));
-    Constraints.push_back(Constraint(Constraint::Load,
-                                     TempArg, SecondArg));
-    // In addition, Dest = Src
-    Constraints.push_back(Constraint(Constraint::Copy,
-                                     FirstArg, SecondArg));
-    return true;
+    const FunctionType *FTy = F->getFunctionType();
+    if (FTy->getNumParams() > 1 && 
+        isa<PointerType>(FTy->getParamType(0)) &&
+        isa<PointerType>(FTy->getParamType(1))) {
+
+      // *Dest = *Src, which requires an artificial graph node to represent the
+      // constraint.  It is broken up into *Dest = temp, temp = *Src
+      unsigned FirstArg = getNode(CS.getArgument(0));
+      unsigned SecondArg = getNode(CS.getArgument(1));
+      unsigned TempArg = GraphNodes.size();
+      GraphNodes.push_back(Node());
+      Constraints.push_back(Constraint(Constraint::Store,
+                                       FirstArg, TempArg));
+      Constraints.push_back(Constraint(Constraint::Load,
+                                       TempArg, SecondArg));
+      // In addition, Dest = Src
+      Constraints.push_back(Constraint(Constraint::Copy,
+                                       FirstArg, SecondArg));
+      return true;
+    }
   }
 
   // Result = Arg0
   if (F->getName() == "realloc" || F->getName() == "strchr" ||
       F->getName() == "strrchr" || F->getName() == "strstr" ||
       F->getName() == "strtok") {
-    Constraints.push_back(Constraint(Constraint::Copy,
-                                     getNode(CS.getInstruction()),
-                                     getNode(CS.getArgument(0))));
-    return true;
+    const FunctionType *FTy = F->getFunctionType();
+    if (FTy->getNumParams() > 0 && 
+        isa<PointerType>(FTy->getParamType(0))) {
+      Constraints.push_back(Constraint(Constraint::Copy,
+                                       getNode(CS.getInstruction()),
+                                       getNode(CS.getArgument(0))));
+      return true;
+    }
   }
 
   return false;
@@ -1076,7 +1084,7 @@ void Andersens::CollectConstraints(Module &M) {
     // At some point we should just add constraints for the escaping functions
     // at solve time, but this slows down solving. For now, we simply mark
     // address taken functions as escaping and treat them as external.
-    if (!F->hasInternalLinkage() || AnalyzeUsesOfFunction(F))
+    if (!F->hasLocalLinkage() || AnalyzeUsesOfFunction(F))
       AddConstraintsForNonInternalLinkage(F);
 
     if (!F->isDeclaration()) {
@@ -2725,13 +2733,14 @@ unsigned Andersens::UniteNodes(unsigned First, unsigned Second,
   DOUT << "\n";
 
   if (SDTActive)
-    if (SDT[Second] >= 0)
+    if (SDT[Second] >= 0) {
       if (SDT[First] < 0)
         SDT[First] = SDT[Second];
       else {
         UniteNodes( FindNode(SDT[First]), FindNode(SDT[Second]) );
         First = FindNode(First);
       }
+    }
 
   return First;
 }