diff options
author | Victor Hernandez <vhernandez@apple.com> | 2009-11-06 01:33:24 +0000 |
---|---|---|
committer | Victor Hernandez <vhernandez@apple.com> | 2009-11-06 01:33:24 +0000 |
commit | df98761d08ae091420b7e9c1366de7684400fc36 (patch) | |
tree | 19dd0e96430169e3c197a4817e5e55f3d2ea277d /lib/Analysis/MemoryBuiltins.cpp | |
parent | 465c3bed165dc76452606ea10a34ae2ef6033e8a (diff) |
Revert r86077 because it caused crashes in 179.art and 175.vpr on ARM
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@86213 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/MemoryBuiltins.cpp')
-rw-r--r-- | lib/Analysis/MemoryBuiltins.cpp | 76 |
1 files changed, 35 insertions, 41 deletions
diff --git a/lib/Analysis/MemoryBuiltins.cpp b/lib/Analysis/MemoryBuiltins.cpp index f4eb793f7a..e710350fa0 100644 --- a/lib/Analysis/MemoryBuiltins.cpp +++ b/lib/Analysis/MemoryBuiltins.cpp @@ -17,7 +17,6 @@ #include "llvm/Instructions.h" #include "llvm/Module.h" #include "llvm/Analysis/ConstantFolding.h" -#include "llvm/Target/TargetData.h" using namespace llvm; //===----------------------------------------------------------------------===// @@ -97,47 +96,45 @@ static Value *isArrayMallocHelper(const CallInst *CI, LLVMContext &Context, if (!CI) return NULL; - // The size of the malloc's result type must be known to determine array size. + // Type must be known to determine array size. const Type *T = getMallocAllocatedType(CI); - if (!T || !T->isSized() || !TD) + if (!T) return NULL; Value *MallocArg = CI->getOperand(1); - const Type *ArgType = MallocArg->getType(); ConstantExpr *CO = dyn_cast<ConstantExpr>(MallocArg); BinaryOperator *BO = dyn_cast<BinaryOperator>(MallocArg); - unsigned ElementSizeInt = TD->getTypeAllocSize(T); - if (const StructType *ST = dyn_cast<StructType>(T)) - ElementSizeInt = TD->getStructLayout(ST)->getSizeInBytes(); - Constant *ElementSize = ConstantInt::get(ArgType, ElementSizeInt); + Constant *ElementSize = ConstantExpr::getSizeOf(T); + ElementSize = ConstantExpr::getTruncOrBitCast(ElementSize, + MallocArg->getType()); + Constant *FoldedElementSize = + ConstantFoldConstantExpression(cast<ConstantExpr>(ElementSize), Context, TD); // First, check if CI is a non-array malloc. - if (CO && CO == ElementSize) + if (CO && ((CO == ElementSize) || + (FoldedElementSize && (CO == FoldedElementSize)))) // Match CreateMalloc's use of constant 1 array-size for non-array mallocs. - return ConstantInt::get(ArgType, 1); + return ConstantInt::get(MallocArg->getType(), 1); // Second, check if CI is an array malloc whose array size can be determined. - if (isConstantOne(ElementSize)) + if (isConstantOne(ElementSize) || + (FoldedElementSize && isConstantOne(FoldedElementSize))) return MallocArg; - if (ConstantInt *CInt = dyn_cast<ConstantInt>(MallocArg)) - if (CInt->getZExtValue() % ElementSizeInt == 0) - return ConstantInt::get(ArgType, CInt->getZExtValue() / ElementSizeInt); - if (!CO && !BO) return NULL; Value *Op0 = NULL; Value *Op1 = NULL; unsigned Opcode = 0; - if (CO && ((CO->getOpcode() == Instruction::Mul) || + if (CO && ((CO->getOpcode() == Instruction::Mul) || (CO->getOpcode() == Instruction::Shl))) { Op0 = CO->getOperand(0); Op1 = CO->getOperand(1); Opcode = CO->getOpcode(); } - if (BO && ((BO->getOpcode() == Instruction::Mul) || + if (BO && ((BO->getOpcode() == Instruction::Mul) || (BO->getOpcode() == Instruction::Shl))) { Op0 = BO->getOperand(0); Op1 = BO->getOperand(1); @@ -147,10 +144,12 @@ static Value *isArrayMallocHelper(const CallInst *CI, LLVMContext &Context, // Determine array size if malloc's argument is the product of a mul or shl. if (Op0) { if (Opcode == Instruction::Mul) { - if (Op1 == ElementSize) + if ((Op1 == ElementSize) || + (FoldedElementSize && (Op1 == FoldedElementSize))) // ArraySize * ElementSize return Op0; - if (Op0 == ElementSize) + if ((Op0 == ElementSize) || + (FoldedElementSize && (Op0 == FoldedElementSize))) // ElementSize * ArraySize return Op1; } @@ -162,10 +161,11 @@ static Value *isArrayMallocHelper(const CallInst *CI, LLVMContext &Context, uint64_t BitToSet = Op1Int.getLimitedValue(Op1Int.getBitWidth() - 1); Value *Op1Pow = ConstantInt::get(Context, APInt(Op1Int.getBitWidth(), 0).set(BitToSet)); - if (Op0 == ElementSize) + if (Op0 == ElementSize || (FoldedElementSize && Op0 == FoldedElementSize)) // ArraySize << log2(ElementSize) return Op1Pow; - if (Op1Pow == ElementSize) + if (Op1Pow == ElementSize || + (FoldedElementSize && Op1Pow == FoldedElementSize)) // ElementSize << log2(ArraySize) return Op0; } @@ -205,41 +205,35 @@ const CallInst *llvm::isArrayMalloc(const Value *I, LLVMContext &Context, } /// getMallocType - Returns the PointerType resulting from the malloc call. -/// The PointerType depends on the number of bitcast uses of the malloc call: -/// 0: PointerType is the calls' return type. -/// 1: PointerType is the bitcast's result type. -/// >1: Unique PointerType cannot be determined, return NULL. +/// This PointerType is the result type of the call's only bitcast use. +/// If there is no unique bitcast use, then return NULL. const PointerType *llvm::getMallocType(const CallInst *CI) { assert(isMalloc(CI) && "GetMallocType and not malloc call"); - const PointerType *MallocType = NULL; - unsigned NumOfBitCastUses = 0; - + const BitCastInst *BCI = NULL; + // Determine if CallInst has a bitcast use. for (Value::use_const_iterator UI = CI->use_begin(), E = CI->use_end(); UI != E; ) - if (const BitCastInst *BCI = dyn_cast<BitCastInst>(*UI++)) { - MallocType = cast<PointerType>(BCI->getDestTy()); - NumOfBitCastUses++; - } + if ((BCI = dyn_cast<BitCastInst>(cast<Instruction>(*UI++)))) + break; - // Malloc call has 1 bitcast use, so type is the bitcast's destination type. - if (NumOfBitCastUses == 1) - return MallocType; + // Malloc call has 1 bitcast use and no other uses, so type is the bitcast's + // destination type. + if (BCI && CI->hasOneUse()) + return cast<PointerType>(BCI->getDestTy()); // Malloc call was not bitcast, so type is the malloc function's return type. - if (NumOfBitCastUses == 0) + if (!BCI) return cast<PointerType>(CI->getType()); // Type could not be determined. return NULL; } -/// getMallocAllocatedType - Returns the Type allocated by malloc call. -/// The Type depends on the number of bitcast uses of the malloc call: -/// 0: PointerType is the malloc calls' return type. -/// 1: PointerType is the bitcast's result type. -/// >1: Unique PointerType cannot be determined, return NULL. +/// getMallocAllocatedType - Returns the Type allocated by malloc call. This +/// Type is the result type of the call's only bitcast use. If there is no +/// unique bitcast use, then return NULL. const Type *llvm::getMallocAllocatedType(const CallInst *CI) { const PointerType *PT = getMallocType(CI); return PT ? PT->getElementType() : NULL; |