[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