Make anders-aa much more precise by not being completely pessimistic about
authorChris Lattner <sabre@nondot.org>
Mon, 28 Mar 2005 04:03:52 +0000 (04:03 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 28 Mar 2005 04:03:52 +0000 (04:03 +0000)
external functions.  Teach it about a few important ones.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@20889 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/IPA/Andersens.cpp

index bbabb795b4cc869cae3dc971f528b52f693bd80b..f7989f64941ef070a53d89df2c906dfee2637418 100644 (file)
@@ -92,6 +92,7 @@ namespace {
       }
 
       /// getValue - Return the LLVM value corresponding to this node.
+      ///
       Value *getValue() const { return Val; }
 
       typedef std::vector<Node*>::const_iterator iterator;
@@ -302,7 +303,9 @@ namespace {
     Node *getNodeForConstantPointer(Constant *C);
     Node *getNodeForConstantPointerTarget(Constant *C);
     void AddGlobalInitializerConstraints(Node *N, Constant *C);
+
     void AddConstraintsForNonInternalLinkage(Function *F);
+    bool AddConstraintsForExternalFunction(Function *F);
     void AddConstraintsForCall(CallSite CS, Function *F);
 
 
@@ -354,6 +357,7 @@ AliasAnalysis::AliasResult Andersens::alias(const Value *V1, unsigned V1Size,
   return AliasAnalysis::alias(V1, V1Size, V2, V2Size);
 }
 
+
 /// getMustAlias - We can provide must alias information if we know that a
 /// pointer can only point to a specific function or the null pointer.
 /// Unfortunately we cannot determine must-alias information for global
@@ -551,6 +555,9 @@ void Andersens::AddGlobalInitializerConstraints(Node *N, Constant *C) {
   }
 }
 
+/// AddConstraintsForNonInternalLinkage - If this function does not have
+/// internal linkage, realize that we can't trust anything passed into or
+/// returned by this function.
 void Andersens::AddConstraintsForNonInternalLinkage(Function *F) {
   for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E; ++I)
     if (isa<PointerType>(I->getType()))
@@ -560,6 +567,35 @@ void Andersens::AddConstraintsForNonInternalLinkage(Function *F) {
                                        &GraphNodes[UniversalSet]));
 }
 
+/// AddConstraintsForExternalFunction - If this is a call to a "known" function,
+/// add the constraints an return false.  If this is a call to an unknown
+/// function, return true.
+bool Andersens::AddConstraintsForExternalFunction(Function *F) {
+  assert(F->isExternal() && "Not an external function!");
+
+  // These functions don't induce any points-to constraints.
+  if (F->getName() == "printf" || F->getName() == "fprintf" ||
+      F->getName() == "open" || F->getName() == "fopen" ||
+      F->getName() == "atoi" ||
+      F->getName() == "llvm.memset" || F->getName() == "memcmp" ||
+      F->getName() == "read" || F->getName() == "write")
+    return false;
+
+  // These functions do induce points-to edges.
+  if (F->getName() == "llvm.memcpy" || F->getName() == "llvm.memmove") {
+    Function::arg_iterator Dst = F->arg_begin(), Src = Dst;
+    // Note: this is a poor approximation, this says Dest = Src, instead of
+    // *Dest = *Src.
+    ++Src;
+    Constraints.push_back(Constraint(Constraint::Copy, getNode(Dst),
+                                     getNode(Src)));
+    return false;
+  }
+
+  return true;
+}
+
+
 
 /// CollectConstraints - This stage scans the program, adding a constraint to
 /// the Constraints list for each instruction in the program that induces a
@@ -615,7 +651,9 @@ void Andersens::CollectConstraints(Module &M) {
       // allocation in the body of the function and a node to represent all
       // pointer values defined by instructions and used as operands.
       visit(F);
-    } else {
+    } else if (AddConstraintsForExternalFunction(F)) {
+      // If we don't "know" about this function, assume the worst.
+
       // External functions that return pointers return the universal set.
       if (isa<PointerType>(F->getFunctionType()->getReturnType()))
         Constraints.push_back(Constraint(Constraint::Copy,