Implement mod/ref analysis for a trivial case where locals don't escape.
authorChris Lattner <sabre@nondot.org>
Fri, 12 Mar 2004 22:39:00 +0000 (22:39 +0000)
committerChris Lattner <sabre@nondot.org>
Fri, 12 Mar 2004 22:39:00 +0000 (22:39 +0000)
This comes up when you have a local array on the stack and you never pass
the address of elements around.

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

lib/Analysis/BasicAliasAnalysis.cpp

index 16bb53f63b7c7004a6c3046c16ceadd658f2a70c..617ae55d1aeaf5a9dee92d386541d612ff1619ed 100644 (file)
@@ -47,6 +47,8 @@ namespace {
     AliasResult alias(const Value *V1, unsigned V1Size,
                       const Value *V2, unsigned V2Size);
 
+    ModRefResult getModRefInfo(CallSite CS, Value *P, unsigned Size);
+
     /// pointsToConstantMemory - Chase pointers until we find a (constant
     /// global) or not.
     bool pointsToConstantMemory(const Value *P);
@@ -139,6 +141,56 @@ bool BasicAliasAnalysis::pointsToConstantMemory(const Value *P) {
   return false;
 }
 
+static bool AddressMightEscape(const Value *V) {
+  for (Value::use_const_iterator UI = V->use_begin(), E = V->use_end();
+       UI != E; ++UI) {
+    const Instruction *I = cast<Instruction>(*UI);
+    switch (I->getOpcode()) {
+    case Instruction::Load: break;
+    case Instruction::Store:
+      if (I->getOperand(0) == V)
+        return true; // Escapes if the pointer is stored.
+      break;
+    case Instruction::GetElementPtr:
+      if (AddressMightEscape(I)) return true;
+      break;
+    case Instruction::Cast:
+      if (!isa<PointerType>(I->getType()))
+        return true;
+      if (AddressMightEscape(I)) return true;
+      break;
+    case Instruction::PHI:
+      if (AddressMightEscape(I)) return true;
+      break;
+    default:
+      return true;
+    }
+  }
+  return false;
+}
+
+// getModRefInfo - Check to see if the specified callsite can clobber the
+// specified memory object.  Since we only look at local properties of this
+// function, we really can't say much about this query.  We do, however, use
+// simple "address taken" analysis on local objects.
+//
+AliasAnalysis::ModRefResult
+BasicAliasAnalysis::getModRefInfo(CallSite CS, Value *P, unsigned Size) {
+  if (!isa<Constant>(P) && !isa<GlobalValue>(P))
+    if (const AllocationInst *AI =
+                  dyn_cast<AllocationInst>(getUnderlyingObject(P))) {
+      // Okay, the pointer is to a stack allocated object.  If we can prove that
+      // the pointer never "escapes", then we know the call cannot clobber it,
+      // because it simply can't get its address.
+      if (!AddressMightEscape(AI))
+        return NoModRef;
+    }
+
+  // If P points to a constant memory location, the call definitely could not
+  // modify the memory location.
+  return pointsToConstantMemory(P) ? Ref : ModRef;
+}
+
 // 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.  :)