[llvm-commits] [PATCH] extend analysis passes to treat malloc calls the same as MallocInst (patch #2)

Eli Friedman eli.friedman at gmail.com
Tue Sep 15 20:02:54 PDT 2009


On Tue, Sep 15, 2009 at 1:44 PM, Victor Hernandez <vhernandez at apple.com> wrote:
> These are the changes to make all the analysis passes apply the same
> analysis to malloc calls as to MallocInst.

Index: lib/Analysis/AliasAnalysis.cpp
===================================================================
--- lib/Analysis/AliasAnalysis.cpp	(revision 81898)
+++ lib/Analysis/AliasAnalysis.cpp	(working copy)
@@ -31,6 +31,7 @@
 #include "llvm/IntrinsicInst.h"
 #include "llvm/Instructions.h"
 #include "llvm/Type.h"
+#include "llvm/Analysis/MallocHelper.h"
 #include "llvm/Target/TargetData.h"
 using namespace llvm;

@@ -239,7 +240,7 @@
 ///    NoAlias returns
 ///
 bool llvm::isIdentifiedObject(const Value *V) {
-  if (isa<AllocationInst>(V) || isNoAliasCall(V))
+  if (isa<AllocationInst>(V) || isMalloc(V) || isNoAliasCall(V))
     return true;
   if (isa<GlobalValue>(V) && !isa<GlobalAlias>(V))
     return true;

Unnecessary change, assuming malloc gets a noalias attribute;
isIdentifiedObject is only used on values with the bitcasts stripped
off.

Index: lib/Analysis/BasicAliasAnalysis.cpp
===================================================================
--- lib/Analysis/BasicAliasAnalysis.cpp	(revision 81898)
+++ lib/Analysis/BasicAliasAnalysis.cpp	(working copy)
@@ -15,6 +15,7 @@

 #include "llvm/Analysis/AliasAnalysis.h"
 #include "llvm/Analysis/CaptureTracking.h"
+#include "llvm/Analysis/MallocHelper.h"
 #include "llvm/Analysis/Passes.h"
 #include "llvm/Constants.h"
 #include "llvm/DerivedTypes.h"
@@ -82,7 +83,7 @@
 /// object that never escapes from the function.
 static bool isNonEscapingLocalObject(const Value *V) {
   // If this is a local allocation, check to see if it escapes.
-  if (isa<AllocationInst>(V) || isNoAliasCall(V))
+  if (isa<AllocationInst>(V) || isMalloc(V) || isNoAliasCall(V))
     return !PointerMayBeCaptured(V, false);

   // If this is an argument that corresponds to a byval or noalias argument,

Same as above.

@@ -111,6 +112,20 @@
       AccessTy = AI->getType()->getElementType();
     else
       return false;
+  } else if (const CallInst* CI = extractMallocCall(V)) {
+    if (isArrayMalloc(V))
+      return false;
+    if (const Type* PT = getMallocAllocatedType(CI))
+      AccessTy = PT;
+    else
+      return false;
+  } else if (const CallInst* CI = extractMallocCallFromBitCast(V)) {
+    if (isArrayMalloc(V))
+      return false;
+    if (const Type* PT = getMallocAllocatedType(CI))
+      AccessTy = PT;
+    else
+      return false;
   } else if (const Argument *A = dyn_cast<Argument>(V)) {
     if (A->hasByValAttr())
       AccessTy = cast<PointerType>(A->getType())->getElementType();

It would be much more straightforward to just use the size argument to
the malloc here; also, V is never a bitcast.

@@ -328,8 +343,8 @@
       return NoAlias;

     // Arguments can't alias with local allocations or noalias calls.
-    if ((isa<Argument>(O1) && (isa<AllocationInst>(O2) ||
isNoAliasCall(O2))) ||
-        (isa<Argument>(O2) && (isa<AllocationInst>(O1) || isNoAliasCall(O1))))
+    if ((isa<Argument>(O1) && (isa<AllocationInst>(O2) ||
isMalloc(O2) || isNoAliasCall(O2))) ||
+        (isa<Argument>(O2) && (isa<AllocationInst>(O1) ||
isMalloc(O1) || isNoAliasCall(O1))))
       return NoAlias;

     // Most objects can't alias null.

Unnecessary change, assuming malloc gets a noalias attribute.

Index: lib/Analysis/PointerTracking.cpp
===================================================================
--- lib/Analysis/PointerTracking.cpp	(revision 81898)
+++ lib/Analysis/PointerTracking.cpp	(working copy)
@@ -13,6 +13,7 @@
 #include "llvm/Analysis/ConstantFolding.h"
 #include "llvm/Analysis/Dominators.h"
 #include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/MallocHelper.h"
 #include "llvm/Analysis/PointerTracking.h"
 #include "llvm/Analysis/ScalarEvolution.h"
 #include "llvm/Analysis/ScalarEvolutionExpressions.h"
@@ -99,6 +100,22 @@
     return SE->getSCEV(arraySize);
   }

+  if (CallInst *CI = extractMallocCall(V)) {
+    Value *arraySize = getMallocArraySize(CI);
+    Ty = getMallocAllocatedType(CI);
+    if (!Ty || !arraySize) return SE->getCouldNotCompute();
+    // arraySize elements of type Ty.
+    return SE->getSCEV(arraySize);
+  }
+
+  if (CallInst *CI = extractMallocCallFromBitCast(V)) {
+    Value *arraySize = getMallocArraySize(CI);
+    Ty = getMallocAllocatedType(CI);
+    if (!Ty || !arraySize) return SE->getCouldNotCompute();
+    // arraySize elements of type Ty.
+    return SE->getSCEV(arraySize);
+  }
+
   if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) {
     if (GV->hasDefinitiveInitializer()) {
       Constant *C = GV->getInitializer();

Will this mess up with malloc used as a char array?

Index: lib/Analysis/ValueTracking.cpp
===================================================================
--- lib/Analysis/ValueTracking.cpp	(revision 81898)
+++ lib/Analysis/ValueTracking.cpp	(working copy)
@@ -20,6 +20,7 @@
 #include "llvm/IntrinsicInst.h"
 #include "llvm/LLVMContext.h"
 #include "llvm/Operator.h"
+#include "llvm/Analysis/MallocHelper.h"
 #include "llvm/Target/TargetData.h"
 #include "llvm/Support/GetElementPtrTypeIterator.h"
 #include "llvm/Support/MathExtras.h"
@@ -621,6 +622,24 @@
         break;
       }
       }
+    } else if (CallInst* CI = extractMallocCall(I)) {
+      unsigned Align = 0;
+      const Type* T = getMallocAllocatedType(CI);
+      if (TD && T) {
+        // Malloc returns maximally aligned memory.
+        Align = TD->getABITypeAlignment(T);
+        Align =
+          std::max(Align,
+                   (unsigned)TD->getABITypeAlignment(
+                     Type::getDoubleTy(V->getContext())));
+        Align =
+          std::max(Align,
+                   (unsigned)TD->getABITypeAlignment(
+                      Type::getInt64Ty(V->getContext())));
+      }
+      if (Align > 0)
+        KnownZero = Mask & APInt::getLowBitsSet(BitWidth,
+                                                CountTrailingZeros_32(Align));
     }
     break;
   }

This is simply wrong; we can't make that guarantee for malloc.
Consider, for example, a malloc used as an SSE vector on Windows.

More generally, getMallocAllocatedType seems a bit suspect in that an
i8 array will get messed up by the change to getMallocAllocatedType.

-Eli



More information about the llvm-commits mailing list