summaryrefslogtreecommitdiffstats
path: root/lib/Analysis
diff options
context:
space:
mode:
authorrdivacky <rdivacky@FreeBSD.org>2009-11-05 17:17:44 +0000
committerrdivacky <rdivacky@FreeBSD.org>2009-11-05 17:17:44 +0000
commitded64d5d348ce8d8c5aa42cf63f6de9dd84b7e89 (patch)
treeadc0bc5dc9cb37579ee90d3c0f08c98c0711bebe /lib/Analysis
parentee2025263d979561bba11dc526f01d690a2565e7 (diff)
downloadFreeBSD-src-ded64d5d348ce8d8c5aa42cf63f6de9dd84b7e89.zip
FreeBSD-src-ded64d5d348ce8d8c5aa42cf63f6de9dd84b7e89.tar.gz
Update LLVM to r86140.
Diffstat (limited to 'lib/Analysis')
-rw-r--r--lib/Analysis/DebugInfo.cpp18
-rw-r--r--lib/Analysis/MemoryBuiltins.cpp76
2 files changed, 53 insertions, 41 deletions
diff --git a/lib/Analysis/DebugInfo.cpp b/lib/Analysis/DebugInfo.cpp
index 7bff11e..b64dbf4 100644
--- a/lib/Analysis/DebugInfo.cpp
+++ b/lib/Analysis/DebugInfo.cpp
@@ -401,12 +401,18 @@ bool DIVariable::Verify() const {
/// getOriginalTypeSize - If this type is derived from a base type then
/// return base type size.
uint64_t DIDerivedType::getOriginalTypeSize() const {
- DIType BT = getTypeDerivedFrom();
- if (!BT.isNull() && BT.isDerivedType())
- return DIDerivedType(BT.getNode()).getOriginalTypeSize();
- if (BT.isNull())
- return getSizeInBits();
- return BT.getSizeInBits();
+ unsigned Tag = getTag();
+ if (Tag == dwarf::DW_TAG_member || Tag == dwarf::DW_TAG_typedef ||
+ Tag == dwarf::DW_TAG_const_type || Tag == dwarf::DW_TAG_volatile_type ||
+ Tag == dwarf::DW_TAG_restrict_type) {
+ DIType BaseType = getTypeDerivedFrom();
+ if (BaseType.isDerivedType())
+ return DIDerivedType(BaseType.getNode()).getOriginalTypeSize();
+ else
+ return BaseType.getSizeInBits();
+ }
+
+ return getSizeInBits();
}
/// describes - Return true if this subprogram provides debugging
diff --git a/lib/Analysis/MemoryBuiltins.cpp b/lib/Analysis/MemoryBuiltins.cpp
index e710350..f4eb793 100644
--- a/lib/Analysis/MemoryBuiltins.cpp
+++ b/lib/Analysis/MemoryBuiltins.cpp
@@ -17,6 +17,7 @@
#include "llvm/Instructions.h"
#include "llvm/Module.h"
#include "llvm/Analysis/ConstantFolding.h"
+#include "llvm/Target/TargetData.h"
using namespace llvm;
//===----------------------------------------------------------------------===//
@@ -96,45 +97,47 @@ static Value *isArrayMallocHelper(const CallInst *CI, LLVMContext &Context,
if (!CI)
return NULL;
- // Type must be known to determine array size.
+ // The size of the malloc's result type must be known to determine array size.
const Type *T = getMallocAllocatedType(CI);
- if (!T)
+ if (!T || !T->isSized() || !TD)
return NULL;
Value *MallocArg = CI->getOperand(1);
+ const Type *ArgType = MallocArg->getType();
ConstantExpr *CO = dyn_cast<ConstantExpr>(MallocArg);
BinaryOperator *BO = dyn_cast<BinaryOperator>(MallocArg);
- Constant *ElementSize = ConstantExpr::getSizeOf(T);
- ElementSize = ConstantExpr::getTruncOrBitCast(ElementSize,
- MallocArg->getType());
- Constant *FoldedElementSize =
- ConstantFoldConstantExpression(cast<ConstantExpr>(ElementSize), Context, TD);
+ unsigned ElementSizeInt = TD->getTypeAllocSize(T);
+ if (const StructType *ST = dyn_cast<StructType>(T))
+ ElementSizeInt = TD->getStructLayout(ST)->getSizeInBytes();
+ Constant *ElementSize = ConstantInt::get(ArgType, ElementSizeInt);
// First, check if CI is a non-array malloc.
- if (CO && ((CO == ElementSize) ||
- (FoldedElementSize && (CO == FoldedElementSize))))
+ if (CO && CO == ElementSize)
// Match CreateMalloc's use of constant 1 array-size for non-array mallocs.
- return ConstantInt::get(MallocArg->getType(), 1);
+ return ConstantInt::get(ArgType, 1);
// Second, check if CI is an array malloc whose array size can be determined.
- if (isConstantOne(ElementSize) ||
- (FoldedElementSize && isConstantOne(FoldedElementSize)))
+ if (isConstantOne(ElementSize))
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);
@@ -144,12 +147,10 @@ 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) ||
- (FoldedElementSize && (Op1 == FoldedElementSize)))
+ if (Op1 == ElementSize)
// ArraySize * ElementSize
return Op0;
- if ((Op0 == ElementSize) ||
- (FoldedElementSize && (Op0 == FoldedElementSize)))
+ if (Op0 == ElementSize)
// ElementSize * ArraySize
return Op1;
}
@@ -161,11 +162,10 @@ 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 || (FoldedElementSize && Op0 == FoldedElementSize))
+ if (Op0 == ElementSize)
// ArraySize << log2(ElementSize)
return Op1Pow;
- if (Op1Pow == ElementSize ||
- (FoldedElementSize && Op1Pow == FoldedElementSize))
+ if (Op1Pow == ElementSize)
// ElementSize << log2(ArraySize)
return Op0;
}
@@ -205,35 +205,41 @@ const CallInst *llvm::isArrayMalloc(const Value *I, LLVMContext &Context,
}
/// getMallocType - Returns the PointerType resulting from the malloc call.
-/// This PointerType is the result type of the call's only bitcast use.
-/// If there is no unique bitcast use, then return NULL.
+/// 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.
const PointerType *llvm::getMallocType(const CallInst *CI) {
assert(isMalloc(CI) && "GetMallocType and not malloc call");
- const BitCastInst *BCI = NULL;
-
+ const PointerType *MallocType = NULL;
+ unsigned NumOfBitCastUses = 0;
+
// Determine if CallInst has a bitcast use.
for (Value::use_const_iterator UI = CI->use_begin(), E = CI->use_end();
UI != E; )
- if ((BCI = dyn_cast<BitCastInst>(cast<Instruction>(*UI++))))
- break;
+ if (const BitCastInst *BCI = dyn_cast<BitCastInst>(*UI++)) {
+ MallocType = cast<PointerType>(BCI->getDestTy());
+ NumOfBitCastUses++;
+ }
- // 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 has 1 bitcast use, so type is the bitcast's destination type.
+ if (NumOfBitCastUses == 1)
+ return MallocType;
// Malloc call was not bitcast, so type is the malloc function's return type.
- if (!BCI)
+ if (NumOfBitCastUses == 0)
return cast<PointerType>(CI->getType());
// Type could not 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.
+/// 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.
const Type *llvm::getMallocAllocatedType(const CallInst *CI) {
const PointerType *PT = getMallocType(CI);
return PT ? PT->getElementType() : NULL;
OpenPOWER on IntegriCloud