[llvm-branch-commits] [llvm-branch] r86704 - in /llvm/branches/Apple/Leela: examples/BrainF/ include/llvm/ include/llvm/Analysis/ lib/Analysis/ lib/AsmParser/ lib/Bitcode/Reader/ lib/Transforms/IPO/ lib/VMCore/ test/Analysis/PointerTracking/ test/Transforms/GlobalOpt/
Victor Hernandez
vhernandez at apple.com
Tue Nov 10 11:33:10 PST 2009
Author: hernande
Date: Tue Nov 10 13:33:09 2009
New Revision: 86704
URL: http://llvm.org/viewvc/llvm-project?rev=86704&view=rev
Log:
$ svn merge -c 86077 https://llvm.org/svn/llvm-project/llvm/trunk
--- Merging r86077 into '.':
U test/Analysis/PointerTracking/sizes.ll
U test/Transforms/GlobalOpt/heap-sra-phi.ll
U test/Transforms/GlobalOpt/malloc-promote-1.ll
U test/Transforms/GlobalOpt/malloc-promote-3.ll
U test/Transforms/GlobalOpt/heap-sra-2.ll
U test/Transforms/GlobalOpt/heap-sra-4.ll
U test/Transforms/GlobalOpt/malloc-promote-2.ll
U test/Transforms/GlobalOpt/heap-sra-1.ll
U test/Transforms/GlobalOpt/heap-sra-3.ll
U test/Transforms/GlobalOpt/2009-06-01-RecursivePHI.ll
U include/llvm/Analysis/MemoryBuiltins.h
U include/llvm/Instructions.h
U lib/Analysis/MemoryBuiltins.cpp
U lib/Bitcode/Reader/BitcodeReader.cpp
U lib/VMCore/Instructions.cpp
U lib/VMCore/Core.cpp
U lib/AsmParser/LLParser.cpp
U lib/Transforms/IPO/GlobalOpt.cpp
U examples/BrainF/BrainF.cpp
$ svn merge -c 86213 https://llvm.org/svn/llvm-project/llvm/trunk
--- Merging r86213 into '.':
G test/Analysis/PointerTracking/sizes.ll
G test/Transforms/GlobalOpt/heap-sra-phi.ll
G test/Transforms/GlobalOpt/malloc-promote-1.ll
G test/Transforms/GlobalOpt/malloc-promote-3.ll
G test/Transforms/GlobalOpt/heap-sra-2.ll
G test/Transforms/GlobalOpt/heap-sra-4.ll
G test/Transforms/GlobalOpt/malloc-promote-2.ll
G test/Transforms/GlobalOpt/heap-sra-1.ll
G test/Transforms/GlobalOpt/heap-sra-3.ll
G test/Transforms/GlobalOpt/2009-06-01-RecursivePHI.ll
G include/llvm/Analysis/MemoryBuiltins.h
G include/llvm/Instructions.h
G lib/Analysis/MemoryBuiltins.cpp
G lib/Bitcode/Reader/BitcodeReader.cpp
G lib/VMCore/Instructions.cpp
G lib/VMCore/Core.cpp
G lib/AsmParser/LLParser.cpp
G lib/Transforms/IPO/GlobalOpt.cpp
G examples/BrainF/BrainF.cpp
$ svn merge -c 86290 https://llvm.org/svn/llvm-project/llvm/trunk
--- Merging r86290 into '.':
U lib/VMCore/Instructions.cpp
$ svn merge -c 86311 https://llvm.org/svn/llvm-project/llvm/trunk
--- Merging r86311 into '.':
U test/Analysis/PointerTracking/sizes.ll
U test/Transforms/GlobalOpt/heap-sra-phi.ll
U test/Transforms/GlobalOpt/malloc-promote-1.ll
U test/Transforms/GlobalOpt/malloc-promote-3.ll
U test/Transforms/GlobalOpt/heap-sra-2.ll
U test/Transforms/GlobalOpt/heap-sra-4.ll
U test/Transforms/GlobalOpt/malloc-promote-2.ll
U test/Transforms/GlobalOpt/heap-sra-1.ll
U test/Transforms/GlobalOpt/heap-sra-3.ll
U test/Transforms/GlobalOpt/2009-06-01-RecursivePHI.ll
C include/llvm/Analysis/MemoryBuiltins.h
U include/llvm/Instructions.h
C lib/Analysis/MemoryBuiltins.cpp
U lib/Bitcode/Reader/BitcodeReader.cpp
G lib/VMCore/Instructions.cpp
U lib/VMCore/Core.cpp
U lib/AsmParser/LLParser.cpp
C lib/Transforms/IPO/GlobalOpt.cpp
U examples/BrainF/BrainF.cpp
$ svn merge -c 86316 https://llvm.org/svn/llvm-project/llvm/trunk
--- Merging r86316 into '.':
G lib/VMCore/Instructions.cpp
$ svn merge -c 86317 https://llvm.org/svn/llvm-project/llvm/trunk
--- Merging r86317 into '.':
C lib/Transforms/IPO/GlobalOpt.cpp
$ svn merge -c 86365 https://llvm.org/svn/llvm-project/llvm/trunk
--- Merging r86365 into '.':
G lib/VMCore/Instructions.cpp
$ svn merge -c 86525 https://llvm.org/svn/llvm-project/llvm/trunk
--- Merging r86525 into '.':
G lib/VMCore/Instructions.cpp
$ svn merge -c 86675 https://llvm.org/svn/llvm-project/llvm/trunk
--- Merging r86675 into '.':
U include/llvm/Analysis/ValueTracking.h
U lib/Analysis/ValueTracking.cpp
$ svn merge -c 86676 https://llvm.org/svn/llvm-project/llvm/trunk
--- Merging r86676 into '.':
G test/Analysis/PointerTracking/sizes.ll
C include/llvm/Analysis/MemoryBuiltins.h
C lib/Analysis/MemoryBuiltins.cpp
C lib/Transforms/IPO/GlobalOpt.cpp
svn merge -r 86230:86231 lib/Transforms/IPO/GlobalOpt.cpp
Modified:
llvm/branches/Apple/Leela/examples/BrainF/BrainF.cpp
llvm/branches/Apple/Leela/include/llvm/Analysis/MemoryBuiltins.h
llvm/branches/Apple/Leela/include/llvm/Analysis/ValueTracking.h
llvm/branches/Apple/Leela/include/llvm/Instructions.h
llvm/branches/Apple/Leela/lib/Analysis/BasicAliasAnalysis.cpp
llvm/branches/Apple/Leela/lib/Analysis/MemoryBuiltins.cpp
llvm/branches/Apple/Leela/lib/Analysis/PointerTracking.cpp
llvm/branches/Apple/Leela/lib/Analysis/ValueTracking.cpp
llvm/branches/Apple/Leela/lib/AsmParser/LLParser.cpp
llvm/branches/Apple/Leela/lib/Bitcode/Reader/BitcodeReader.cpp
llvm/branches/Apple/Leela/lib/Transforms/IPO/GlobalOpt.cpp
llvm/branches/Apple/Leela/lib/VMCore/Core.cpp
llvm/branches/Apple/Leela/lib/VMCore/Instructions.cpp
llvm/branches/Apple/Leela/test/Analysis/PointerTracking/sizes.ll
llvm/branches/Apple/Leela/test/Transforms/GlobalOpt/2009-06-01-RecursivePHI.ll
llvm/branches/Apple/Leela/test/Transforms/GlobalOpt/heap-sra-1.ll
llvm/branches/Apple/Leela/test/Transforms/GlobalOpt/heap-sra-2.ll
llvm/branches/Apple/Leela/test/Transforms/GlobalOpt/heap-sra-3.ll
llvm/branches/Apple/Leela/test/Transforms/GlobalOpt/heap-sra-4.ll
llvm/branches/Apple/Leela/test/Transforms/GlobalOpt/heap-sra-phi.ll
llvm/branches/Apple/Leela/test/Transforms/GlobalOpt/malloc-promote-1.ll
llvm/branches/Apple/Leela/test/Transforms/GlobalOpt/malloc-promote-2.ll
llvm/branches/Apple/Leela/test/Transforms/GlobalOpt/malloc-promote-3.ll
Modified: llvm/branches/Apple/Leela/examples/BrainF/BrainF.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Leela/examples/BrainF/BrainF.cpp?rev=86704&r1=86703&r2=86704&view=diff
==============================================================================
--- llvm/branches/Apple/Leela/examples/BrainF/BrainF.cpp (original)
+++ llvm/branches/Apple/Leela/examples/BrainF/BrainF.cpp Tue Nov 10 13:33:09 2009
@@ -81,8 +81,11 @@
ConstantInt *val_mem = ConstantInt::get(C, APInt(32, memtotal));
BasicBlock* BB = builder->GetInsertBlock();
const Type* IntPtrTy = IntegerType::getInt32Ty(C);
- ptr_arr = CallInst::CreateMalloc(BB, IntPtrTy, IntegerType::getInt8Ty(C),
- val_mem, NULL, "arr");
+ const Type* Int8Ty = IntegerType::getInt8Ty(C);
+ Constant* allocsize = ConstantExpr::getSizeOf(Int8Ty);
+ allocsize = ConstantExpr::getTruncOrBitCast(allocsize, IntPtrTy);
+ ptr_arr = CallInst::CreateMalloc(BB, IntPtrTy, Int8Ty, allocsize, val_mem,
+ NULL, "arr");
BB->getInstList().push_back(cast<Instruction>(ptr_arr));
//call void @llvm.memset.i32(i8 *%arr, i8 0, i32 %d, i32 1)
Modified: llvm/branches/Apple/Leela/include/llvm/Analysis/MemoryBuiltins.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Leela/include/llvm/Analysis/MemoryBuiltins.h?rev=86704&r1=86703&r2=86704&view=diff
==============================================================================
--- llvm/branches/Apple/Leela/include/llvm/Analysis/MemoryBuiltins.h (original)
+++ llvm/branches/Apple/Leela/include/llvm/Analysis/MemoryBuiltins.h Tue Nov 10 13:33:09 2009
@@ -17,7 +17,6 @@
namespace llvm {
class CallInst;
-class LLVMContext;
class PointerType;
class TargetData;
class Type;
@@ -29,50 +28,52 @@
/// isMalloc - Returns true if the value is either a malloc call or a bitcast of
/// the result of a malloc call
-bool isMalloc(const Value* I);
+bool isMalloc(const Value *I);
/// extractMallocCall - Returns the corresponding CallInst if the instruction
/// is a malloc call. Since CallInst::CreateMalloc() only creates calls, we
/// ignore InvokeInst here.
-const CallInst* extractMallocCall(const Value* I);
-CallInst* extractMallocCall(Value* I);
+const CallInst *extractMallocCall(const Value *I);
+CallInst *extractMallocCall(Value *I);
/// extractMallocCallFromBitCast - Returns the corresponding CallInst if the
/// instruction is a bitcast of the result of a malloc call.
-const CallInst* extractMallocCallFromBitCast(const Value* I);
-CallInst* extractMallocCallFromBitCast(Value* I);
+const CallInst *extractMallocCallFromBitCast(const Value *I);
+CallInst *extractMallocCallFromBitCast(Value *I);
/// isArrayMalloc - Returns the corresponding CallInst if the instruction
/// is a call to malloc whose array size can be determined and the array size
/// is not constant 1. Otherwise, return NULL.
-CallInst* isArrayMalloc(Value* I, LLVMContext &Context, const TargetData* TD);
-const CallInst* isArrayMalloc(const Value* I, LLVMContext &Context,
- const TargetData* TD);
+const CallInst *isArrayMalloc(const Value *I, const TargetData *TD);
/// 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.
-const PointerType* getMallocType(const CallInst* CI);
-
-/// 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* getMallocAllocatedType(const CallInst* CI);
+/// The PointerType 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 PointerType *getMallocType(const CallInst *CI);
+
+/// 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 *getMallocAllocatedType(const CallInst *CI);
/// getMallocArraySize - Returns the array size of a malloc call. If the
/// argument passed to malloc is a multiple of the size of the malloced type,
/// then return that multiple. For non-array mallocs, the multiple is
/// constant 1. Otherwise, return NULL for mallocs whose array size cannot be
/// determined.
-Value* getMallocArraySize(CallInst* CI, LLVMContext &Context,
- const TargetData* TD);
+Value *getMallocArraySize(CallInst *CI, const TargetData *TD,
+ bool LookThroughSExt = false);
//===----------------------------------------------------------------------===//
// free Call Utility Functions.
//
/// isFreeCall - Returns true if the the value is a call to the builtin free()
-bool isFreeCall(const Value* I);
+bool isFreeCall(const Value *I);
} // End llvm namespace
Modified: llvm/branches/Apple/Leela/include/llvm/Analysis/ValueTracking.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Leela/include/llvm/Analysis/ValueTracking.h?rev=86704&r1=86703&r2=86704&view=diff
==============================================================================
--- llvm/branches/Apple/Leela/include/llvm/Analysis/ValueTracking.h (original)
+++ llvm/branches/Apple/Leela/include/llvm/Analysis/ValueTracking.h Tue Nov 10 13:33:09 2009
@@ -63,6 +63,15 @@
unsigned ComputeNumSignBits(Value *Op, const TargetData *TD = 0,
unsigned Depth = 0);
+ /// ComputeMultiple - This function computes the integer multiple of Base that
+ /// equals V. If successful, it returns true and returns the multiple in
+ /// Multiple. If unsuccessful, it returns false. Also, if V can be
+ /// simplified to an integer, then the simplified V is returned in Val. Look
+ /// through sext only if LookThroughSExt=true.
+ bool ComputeMultiple(Value *V, unsigned Base, Value *&Multiple, APInt &Val,
+ bool LookThroughSExt = false, const TargetData *TD = 0,
+ unsigned Depth = 0);
+
/// CannotBeNegativeZero - Return true if we can prove that the specified FP
/// value is never equal to -0.0.
///
Modified: llvm/branches/Apple/Leela/include/llvm/Instructions.h
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Leela/include/llvm/Instructions.h?rev=86704&r1=86703&r2=86704&view=diff
==============================================================================
--- llvm/branches/Apple/Leela/include/llvm/Instructions.h (original)
+++ llvm/branches/Apple/Leela/include/llvm/Instructions.h Tue Nov 10 13:33:09 2009
@@ -899,11 +899,12 @@
/// 3. Bitcast the result of the malloc call to the specified type.
static Instruction *CreateMalloc(Instruction *InsertBefore,
const Type *IntPtrTy, const Type *AllocTy,
- Value *ArraySize = 0,
+ Value *AllocSize, Value *ArraySize = 0,
const Twine &Name = "");
static Instruction *CreateMalloc(BasicBlock *InsertAtEnd,
const Type *IntPtrTy, const Type *AllocTy,
- Value *ArraySize = 0, Function* MallocF = 0,
+ Value *AllocSize, Value *ArraySize = 0,
+ Function* MallocF = 0,
const Twine &Name = "");
/// CreateFree - Generate the IR for a call to the builtin free function.
static void CreateFree(Value* Source, Instruction *InsertBefore);
Modified: llvm/branches/Apple/Leela/lib/Analysis/BasicAliasAnalysis.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Leela/lib/Analysis/BasicAliasAnalysis.cpp?rev=86704&r1=86703&r2=86704&view=diff
==============================================================================
--- llvm/branches/Apple/Leela/lib/Analysis/BasicAliasAnalysis.cpp (original)
+++ llvm/branches/Apple/Leela/lib/Analysis/BasicAliasAnalysis.cpp Tue Nov 10 13:33:09 2009
@@ -109,7 +109,7 @@
else
return false;
} else if (const CallInst* CI = extractMallocCall(V)) {
- if (!isArrayMalloc(V, Context, &TD))
+ if (!isArrayMalloc(V, &TD))
// The size is the argument to the malloc call.
if (const ConstantInt* C = dyn_cast<ConstantInt>(CI->getOperand(1)))
return (C->getZExtValue() < Size);
Modified: llvm/branches/Apple/Leela/lib/Analysis/MemoryBuiltins.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Leela/lib/Analysis/MemoryBuiltins.cpp?rev=86704&r1=86703&r2=86704&view=diff
==============================================================================
--- llvm/branches/Apple/Leela/lib/Analysis/MemoryBuiltins.cpp (original)
+++ llvm/branches/Apple/Leela/lib/Analysis/MemoryBuiltins.cpp Tue Nov 10 13:33:09 2009
@@ -16,7 +16,8 @@
#include "llvm/Constants.h"
#include "llvm/Instructions.h"
#include "llvm/Module.h"
-#include "llvm/Analysis/ConstantFolding.h"
+#include "llvm/Analysis/ValueTracking.h"
+#include "llvm/Target/TargetData.h"
using namespace llvm;
//===----------------------------------------------------------------------===//
@@ -86,115 +87,38 @@
: NULL;
}
-/// isConstantOne - Return true only if val is constant int 1.
-static bool isConstantOne(Value *val) {
- return isa<ConstantInt>(val) && cast<ConstantInt>(val)->isOne();
-}
-
-static Value *isArrayMallocHelper(const CallInst *CI, LLVMContext &Context,
- const TargetData *TD) {
+static Value *computeArraySize(const CallInst *CI, const TargetData *TD,
+ bool LookThroughSExt = false) {
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);
- 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);
-
- // First, check if CI is a non-array malloc.
- if (CO && ((CO == ElementSize) ||
- (FoldedElementSize && (CO == FoldedElementSize))))
- // Match CreateMalloc's use of constant 1 array-size for non-array mallocs.
- return ConstantInt::get(MallocArg->getType(), 1);
-
- // Second, check if CI is an array malloc whose array size can be determined.
- if (isConstantOne(ElementSize) ||
- (FoldedElementSize && isConstantOne(FoldedElementSize)))
- return MallocArg;
+ unsigned ElementSize = TD->getTypeAllocSize(T);
+ if (const StructType *ST = dyn_cast<StructType>(T))
+ ElementSize = TD->getStructLayout(ST)->getSizeInBytes();
- if (!CO && !BO)
- return NULL;
-
- Value *Op0 = NULL;
- Value *Op1 = NULL;
- unsigned Opcode = 0;
- 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) ||
- (BO->getOpcode() == Instruction::Shl))) {
- Op0 = BO->getOperand(0);
- Op1 = BO->getOperand(1);
- Opcode = BO->getOpcode();
- }
-
- // 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)))
- // ArraySize * ElementSize
- return Op0;
- if ((Op0 == ElementSize) ||
- (FoldedElementSize && (Op0 == FoldedElementSize)))
- // ElementSize * ArraySize
- return Op1;
- }
- if (Opcode == Instruction::Shl) {
- ConstantInt *Op1CI = dyn_cast<ConstantInt>(Op1);
- if (!Op1CI) return NULL;
-
- APInt Op1Int = Op1CI->getValue();
- 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))
- // ArraySize << log2(ElementSize)
- return Op1Pow;
- if (Op1Pow == ElementSize ||
- (FoldedElementSize && Op1Pow == FoldedElementSize))
- // ElementSize << log2(ArraySize)
- return Op0;
- }
- }
+ // If malloc calls' arg can be determined to be a multiple of ElementSize,
+ // return the multiple. Otherwise, return NULL.
+ Value *MallocArg = CI->getOperand(1);
+ Value *Multiple = NULL;
+ APInt Val(TD->getTypeSizeInBits(MallocArg->getType()->getScalarType()), 0);
+ if (ComputeMultiple(MallocArg, ElementSize, Multiple,
+ Val, LookThroughSExt, TD))
+ return Multiple;
- // We could not determine the malloc array size from MallocArg.
return NULL;
}
/// isArrayMalloc - Returns the corresponding CallInst if the instruction
/// is a call to malloc whose array size can be determined and the array size
/// is not constant 1. Otherwise, return NULL.
-CallInst *llvm::isArrayMalloc(Value *I, LLVMContext &Context,
- const TargetData *TD) {
- CallInst *CI = extractMallocCall(I);
- Value *ArraySize = isArrayMallocHelper(CI, Context, TD);
-
- if (ArraySize &&
- ArraySize != ConstantInt::get(CI->getOperand(1)->getType(), 1))
- return CI;
-
- // CI is a non-array malloc or we can't figure out that it is an array malloc.
- return NULL;
-}
-
-const CallInst *llvm::isArrayMalloc(const Value *I, LLVMContext &Context,
- const TargetData *TD) {
+const CallInst *llvm::isArrayMalloc(const Value *I, const TargetData *TD) {
const CallInst *CI = extractMallocCall(I);
- Value *ArraySize = isArrayMallocHelper(CI, Context, TD);
+ Value *ArraySize = computeArraySize(CI, TD);
if (ArraySize &&
ArraySize != ConstantInt::get(CI->getOperand(1)->getType(), 1))
@@ -205,35 +129,41 @@
}
/// 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;
+ assert(isMalloc(CI) && "getMallocType and not malloc call");
+ 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;
@@ -244,9 +174,10 @@
/// then return that multiple. For non-array mallocs, the multiple is
/// constant 1. Otherwise, return NULL for mallocs whose array size cannot be
/// determined.
-Value *llvm::getMallocArraySize(CallInst *CI, LLVMContext &Context,
- const TargetData *TD) {
- return isArrayMallocHelper(CI, Context, TD);
+Value *llvm::getMallocArraySize(CallInst *CI, const TargetData *TD,
+ bool LookThroughSExt) {
+ assert(isMalloc(CI) && "getMallocArraySize and not malloc call");
+ return computeArraySize(CI, TD, LookThroughSExt);
}
//===----------------------------------------------------------------------===//
Modified: llvm/branches/Apple/Leela/lib/Analysis/PointerTracking.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Leela/lib/Analysis/PointerTracking.cpp?rev=86704&r1=86703&r2=86704&view=diff
==============================================================================
--- llvm/branches/Apple/Leela/lib/Analysis/PointerTracking.cpp (original)
+++ llvm/branches/Apple/Leela/lib/Analysis/PointerTracking.cpp Tue Nov 10 13:33:09 2009
@@ -101,7 +101,7 @@
}
if (CallInst *CI = extractMallocCall(V)) {
- Value *arraySize = getMallocArraySize(CI, P->getContext(), TD);
+ Value *arraySize = getMallocArraySize(CI, TD);
const Type* AllocTy = getMallocAllocatedType(CI);
if (!AllocTy || !arraySize) return SE->getCouldNotCompute();
Ty = AllocTy;
Modified: llvm/branches/Apple/Leela/lib/Analysis/ValueTracking.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Leela/lib/Analysis/ValueTracking.cpp?rev=86704&r1=86703&r2=86704&view=diff
==============================================================================
--- llvm/branches/Apple/Leela/lib/Analysis/ValueTracking.cpp (original)
+++ llvm/branches/Apple/Leela/lib/Analysis/ValueTracking.cpp Tue Nov 10 13:33:09 2009
@@ -789,6 +789,131 @@
return std::max(FirstAnswer, std::min(TyBits, Mask.countLeadingZeros()));
}
+/// ComputeMultiple - This function computes the integer multiple of Base that
+/// equals V. If successful, it returns true and returns the multiple in
+/// Multiple. If unsuccessful, it returns false. Also, if V can be
+/// simplified to an integer, then the simplified V is returned in Val. It looks
+/// through SExt instructions only if LookThroughSExt is true.
+bool llvm::ComputeMultiple(Value *V, unsigned Base, Value *&Multiple,
+ APInt &Val, bool LookThroughSExt,
+ const TargetData *TD, unsigned Depth) {
+ const unsigned MaxDepth = 6;
+
+ assert(TD && V && "No Value?");
+ assert(Depth <= MaxDepth && "Limit Search Depth");
+ assert(V->getType()->isInteger() && "Not integer or pointer type!");
+
+ const Type *T = V->getType();
+ unsigned TSize = TD->getTypeSizeInBits(T->getScalarType());
+
+ ConstantInt *CI = NULL;
+ if ((CI = dyn_cast<ConstantInt>(V)))
+ Val = CI->getValue();
+
+ if (Base == 0)
+ return false;
+
+ if (Base == 1) {
+ Multiple = V;
+ return true;
+ }
+
+ ConstantExpr *CO = dyn_cast<ConstantExpr>(V);
+ Constant *BaseVal = ConstantInt::get(T, Base);
+ if (CO && CO == BaseVal) {
+ // Multiple is 1.
+ Multiple = ConstantInt::get(T, 1);
+ return true;
+ }
+
+ if (CI && CI->getZExtValue() % Base == 0) {
+ Multiple = ConstantInt::get(T, CI->getZExtValue() / Base);
+ return true;
+ }
+
+ if (Depth == MaxDepth) return false; // Limit search depth.
+
+ Operator *I = dyn_cast<Operator>(V);
+ if (!I) return false;
+
+ switch (I->getOpcode()) {
+ default: break;
+ case Instruction::SExt: {
+ if (!LookThroughSExt) return false;
+ // otherwise fall through to ZExt
+ }
+ case Instruction::ZExt: {
+ return ComputeMultiple(I->getOperand(0), Base, Multiple, Val,
+ LookThroughSExt, TD, Depth+1);
+ }
+ case Instruction::Shl:
+ case Instruction::Mul: {
+ Value *Op0 = I->getOperand(0);
+ Value *Op1 = I->getOperand(1);
+
+ if (I->getOpcode() == Instruction::Shl) {
+ ConstantInt *Op1CI = dyn_cast<ConstantInt>(Op1);
+ if (!Op1CI) return false;
+ // Turn Op0 << Op1 into Op0 * 2^Op1
+ APInt Op1Int = Op1CI->getValue();
+ uint64_t BitToSet = Op1Int.getLimitedValue(Op1Int.getBitWidth() - 1);
+ Op1 = ConstantInt::get(V->getContext(),
+ APInt(Op1Int.getBitWidth(), 0).set(BitToSet));
+ }
+
+ Value *Mul0 = NULL;
+ Value *Mul1 = NULL;
+ APInt Val0(TSize, 0), Val1(TSize, 0);
+ bool M0 = ComputeMultiple(Op0, Base, Mul0, Val0,
+ LookThroughSExt, TD, Depth+1);
+ bool M1 = ComputeMultiple(Op1, Base, Mul1, Val1,
+ LookThroughSExt, TD, Depth+1);
+
+ if (M0) {
+ if (isa<Constant>(Op1) && isa<Constant>(Mul0)) {
+ // V == Base * (Mul0 * Op1), so return (Mul0 * Op1)
+ Multiple = ConstantExpr::getMul(cast<Constant>(Mul0),
+ Val1.getBoolValue() ? ConstantInt::get(V->getContext(), Val1):
+ cast<Constant>(Op1));
+ return true;
+ }
+
+ if (ConstantInt *Mul0CI = dyn_cast<ConstantInt>(Mul0))
+ if (Mul0CI->getValue() == 1) {
+ // V == Base * Op1, so return Op1
+ Multiple = Op1;
+ return true;
+ }
+ }
+
+ if (M1) {
+ if (isa<Constant>(Op0) && isa<Constant>(Mul1)) {
+ // V == Base * (Mul1 * Op0), so return (Mul1 * Op0)
+ Multiple = ConstantExpr::getMul(cast<Constant>(Mul1),
+ Val0.getBoolValue() ? ConstantInt::get(V->getContext(), Val0):
+ cast<Constant>(Op0));
+ return true;
+ }
+
+ if (ConstantInt *Mul1CI = dyn_cast<ConstantInt>(Mul1))
+ if (Mul1CI->getValue() == 1) {
+ // V == Base * Op0, so return Op0
+ Multiple = Op0;
+ return true;
+ }
+ }
+
+ if (Val0.getBoolValue() && Val1.getBoolValue())
+ // Op1*Op2 was simplified, try computing multiple again.
+ return ComputeMultiple(ConstantInt::get(V->getContext(), Val0 * Val1),
+ Base, Multiple, Val, LookThroughSExt, TD, Depth+1);
+ }
+ }
+
+ // We could not determine if V is a multiple of Base.
+ return false;
+}
+
/// CannotBeNegativeZero - Return true if we can prove that the specified FP
/// value is never equal to -0.0.
///
Modified: llvm/branches/Apple/Leela/lib/AsmParser/LLParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Leela/lib/AsmParser/LLParser.cpp?rev=86704&r1=86703&r2=86704&view=diff
==============================================================================
--- llvm/branches/Apple/Leela/lib/AsmParser/LLParser.cpp (original)
+++ llvm/branches/Apple/Leela/lib/AsmParser/LLParser.cpp Tue Nov 10 13:33:09 2009
@@ -3619,12 +3619,14 @@
// Autoupgrade old malloc instruction to malloc call.
// FIXME: Remove in LLVM 3.0.
const Type *IntPtrTy = Type::getInt32Ty(Context);
+ Constant *AllocSize = ConstantExpr::getSizeOf(Ty);
+ AllocSize = ConstantExpr::getTruncOrBitCast(AllocSize, IntPtrTy);
if (!MallocF)
// Prototype malloc as "void *(int32)".
// This function is renamed as "malloc" in ValidateEndOfModule().
MallocF = cast<Function>(
M->getOrInsertFunction("", Type::getInt8PtrTy(Context), IntPtrTy, NULL));
- Inst = CallInst::CreateMalloc(BB, IntPtrTy, Ty, Size, MallocF);
+ Inst = CallInst::CreateMalloc(BB, IntPtrTy, Ty, AllocSize, Size, MallocF);
return false;
}
Modified: llvm/branches/Apple/Leela/lib/Bitcode/Reader/BitcodeReader.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Leela/lib/Bitcode/Reader/BitcodeReader.cpp?rev=86704&r1=86703&r2=86704&view=diff
==============================================================================
--- llvm/branches/Apple/Leela/lib/Bitcode/Reader/BitcodeReader.cpp (original)
+++ llvm/branches/Apple/Leela/lib/Bitcode/Reader/BitcodeReader.cpp Tue Nov 10 13:33:09 2009
@@ -2101,8 +2101,10 @@
if (!Ty || !Size) return Error("Invalid MALLOC record");
if (!CurBB) return Error("Invalid malloc instruction with no BB");
const Type *Int32Ty = IntegerType::getInt32Ty(CurBB->getContext());
+ Constant *AllocSize = ConstantExpr::getSizeOf(Ty->getElementType());
+ AllocSize = ConstantExpr::getTruncOrBitCast(AllocSize, Int32Ty);
I = CallInst::CreateMalloc(CurBB, Int32Ty, Ty->getElementType(),
- Size, NULL);
+ AllocSize, Size, NULL);
InstructionList.push_back(I);
break;
}
Modified: llvm/branches/Apple/Leela/lib/Transforms/IPO/GlobalOpt.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Leela/lib/Transforms/IPO/GlobalOpt.cpp?rev=86704&r1=86703&r2=86704&view=diff
==============================================================================
--- llvm/branches/Apple/Leela/lib/Transforms/IPO/GlobalOpt.cpp (original)
+++ llvm/branches/Apple/Leela/lib/Transforms/IPO/GlobalOpt.cpp Tue Nov 10 13:33:09 2009
@@ -801,10 +801,10 @@
/// ConstantPropUsersOf - Walk the use list of V, constant folding all of the
/// instructions that are foldable.
-static void ConstantPropUsersOf(Value *V, LLVMContext &Context) {
+static void ConstantPropUsersOf(Value *V) {
for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI != E; )
if (Instruction *I = dyn_cast<Instruction>(*UI++))
- if (Constant *NewC = ConstantFoldInstruction(I, Context)) {
+ if (Constant *NewC = ConstantFoldInstruction(I, V->getContext())) {
I->replaceAllUsesWith(NewC);
// Advance UI to the next non-I use to avoid invalidating it!
@@ -822,32 +822,41 @@
/// malloc into a global, and any loads of GV as uses of the new global.
static GlobalVariable *OptimizeGlobalAddressOfMalloc(GlobalVariable *GV,
CallInst *CI,
- BitCastInst *BCI,
+ const Type *AllocTy,
Value* NElems,
- LLVMContext &Context,
TargetData* TD) {
- DEBUG(errs() << "PROMOTING MALLOC GLOBAL: " << *GV
- << " CALL = " << *CI << " BCI = " << *BCI << '\n');
+ DEBUG(errs() << "PROMOTING GLOBAL: " << *GV << " CALL = " << *CI << '\n');
- const Type *IntPtrTy = TD->getIntPtrType(Context);
+ const Type *IntPtrTy = TD->getIntPtrType(GV->getContext());
+ // CI has either 0 or 1 bitcast uses (getMallocType() would otherwise have
+ // returned NULL and we would not be here).
+ BitCastInst *BCI = NULL;
+ for (Value::use_iterator UI = CI->use_begin(), E = CI->use_end(); UI != E; )
+ if ((BCI = dyn_cast<BitCastInst>(cast<Instruction>(*UI++))))
+ break;
+
ConstantInt *NElements = cast<ConstantInt>(NElems);
if (NElements->getZExtValue() != 1) {
// If we have an array allocation, transform it to a single element
// allocation to make the code below simpler.
- Type *NewTy = ArrayType::get(getMallocAllocatedType(CI),
- NElements->getZExtValue());
- Value* NewM = CallInst::CreateMalloc(CI, IntPtrTy, NewTy);
- Instruction* NewMI = cast<Instruction>(NewM);
+ Type *NewTy = ArrayType::get(AllocTy, NElements->getZExtValue());
+ unsigned TypeSize = TD->getTypeAllocSize(NewTy);
+ if (const StructType *ST = dyn_cast<StructType>(NewTy))
+ TypeSize = TD->getStructLayout(ST)->getSizeInBytes();
+ Instruction *NewCI = CallInst::CreateMalloc(CI, IntPtrTy, NewTy,
+ ConstantInt::get(IntPtrTy, TypeSize));
Value* Indices[2];
Indices[0] = Indices[1] = Constant::getNullValue(IntPtrTy);
- Value *NewGEP = GetElementPtrInst::Create(NewMI, Indices, Indices + 2,
- NewMI->getName()+".el0", CI);
- BCI->replaceAllUsesWith(NewGEP);
- BCI->eraseFromParent();
+ Value *NewGEP = GetElementPtrInst::Create(NewCI, Indices, Indices + 2,
+ NewCI->getName()+".el0", CI);
+ Value *Cast = new BitCastInst(NewGEP, CI->getType(), "el0", CI);
+ if (BCI) BCI->replaceAllUsesWith(NewGEP);
+ CI->replaceAllUsesWith(Cast);
+ if (BCI) BCI->eraseFromParent();
CI->eraseFromParent();
- BCI = cast<BitCastInst>(NewMI);
- CI = extractMallocCallFromBitCast(NewMI);
+ BCI = dyn_cast<BitCastInst>(NewCI);
+ CI = BCI ? extractMallocCallFromBitCast(BCI) : cast<CallInst>(NewCI);
}
// Create the new global variable. The contents of the malloc'd memory is
@@ -861,8 +870,9 @@
GV,
GV->isThreadLocal());
- // Anything that used the malloc now uses the global directly.
- BCI->replaceAllUsesWith(NewGV);
+ // Anything that used the malloc or its bitcast now uses the global directly.
+ if (BCI) BCI->replaceAllUsesWith(NewGV);
+ CI->replaceAllUsesWith(new BitCastInst(NewGV, CI->getType(), "newgv", CI));
Constant *RepValue = NewGV;
if (NewGV->getType() != GV->getType()->getElementType())
@@ -872,10 +882,10 @@
// If there is a comparison against null, we will insert a global bool to
// keep track of whether the global was initialized yet or not.
GlobalVariable *InitBool =
- new GlobalVariable(Context, Type::getInt1Ty(Context), false,
- GlobalValue::InternalLinkage,
- ConstantInt::getFalse(Context), GV->getName()+".init",
- GV->isThreadLocal());
+ new GlobalVariable(GV->getContext(), Type::getInt1Ty(GV->getContext()),
+ false, GlobalValue::InternalLinkage,
+ ConstantInt::getFalse(GV->getContext()),
+ GV->getName()+".init", GV->isThreadLocal());
bool InitBoolUsed = false;
// Loop over all uses of GV, processing them in turn.
@@ -894,8 +904,8 @@
switch (ICI->getPredicate()) {
default: llvm_unreachable("Unknown ICmp Predicate!");
case ICmpInst::ICMP_ULT:
- case ICmpInst::ICMP_SLT:
- LV = ConstantInt::getFalse(Context); // X < null -> always false
+ case ICmpInst::ICMP_SLT: // X < null -> always false
+ LV = ConstantInt::getFalse(GV->getContext());
break;
case ICmpInst::ICMP_ULE:
case ICmpInst::ICMP_SLE:
@@ -917,7 +927,7 @@
} else {
StoreInst *SI = cast<StoreInst>(GV->use_back());
// The global is initialized when the store to it occurs.
- new StoreInst(ConstantInt::getTrue(Context), InitBool, SI);
+ new StoreInst(ConstantInt::getTrue(GV->getContext()), InitBool, SI);
SI->eraseFromParent();
}
@@ -930,17 +940,17 @@
GV->getParent()->getGlobalList().insert(GV, InitBool);
- // Now the GV is dead, nuke it and the malloc.
+ // Now the GV is dead, nuke it and the malloc (both CI and BCI).
GV->eraseFromParent();
- BCI->eraseFromParent();
+ if (BCI) BCI->eraseFromParent();
CI->eraseFromParent();
// To further other optimizations, loop over all users of NewGV and try to
// constant prop them. This will promote GEP instructions with constant
// indices into GEP constant-exprs, which will allow global-opt to hack on it.
- ConstantPropUsersOf(NewGV, Context);
+ ConstantPropUsersOf(NewGV);
if (RepValue != NewGV)
- ConstantPropUsersOf(RepValue, Context);
+ ConstantPropUsersOf(RepValue);
return NewGV;
}
@@ -1142,8 +1152,7 @@
static Value *GetHeapSROAValue(Value *V, unsigned FieldNo,
DenseMap<Value*, std::vector<Value*> > &InsertedScalarizedValues,
- std::vector<std::pair<PHINode*, unsigned> > &PHIsToRewrite,
- LLVMContext &Context) {
+ std::vector<std::pair<PHINode*, unsigned> > &PHIsToRewrite) {
std::vector<Value*> &FieldVals = InsertedScalarizedValues[V];
if (FieldNo >= FieldVals.size())
@@ -1161,7 +1170,7 @@
// a new Load of the scalarized global.
Result = new LoadInst(GetHeapSROAValue(LI->getOperand(0), FieldNo,
InsertedScalarizedValues,
- PHIsToRewrite, Context),
+ PHIsToRewrite),
LI->getName()+".f"+Twine(FieldNo), LI);
} else if (PHINode *PN = dyn_cast<PHINode>(V)) {
// PN's type is pointer to struct. Make a new PHI of pointer to struct
@@ -1185,16 +1194,14 @@
/// the load, rewrite the derived value to use the HeapSRoA'd load.
static void RewriteHeapSROALoadUser(Instruction *LoadUser,
DenseMap<Value*, std::vector<Value*> > &InsertedScalarizedValues,
- std::vector<std::pair<PHINode*, unsigned> > &PHIsToRewrite,
- LLVMContext &Context) {
+ std::vector<std::pair<PHINode*, unsigned> > &PHIsToRewrite) {
// If this is a comparison against null, handle it.
if (ICmpInst *SCI = dyn_cast<ICmpInst>(LoadUser)) {
assert(isa<ConstantPointerNull>(SCI->getOperand(1)));
// If we have a setcc of the loaded pointer, we can use a setcc of any
// field.
Value *NPtr = GetHeapSROAValue(SCI->getOperand(0), 0,
- InsertedScalarizedValues, PHIsToRewrite,
- Context);
+ InsertedScalarizedValues, PHIsToRewrite);
Value *New = new ICmpInst(SCI, SCI->getPredicate(), NPtr,
Constant::getNullValue(NPtr->getType()),
@@ -1212,8 +1219,7 @@
// Load the pointer for this field.
unsigned FieldNo = cast<ConstantInt>(GEPI->getOperand(2))->getZExtValue();
Value *NewPtr = GetHeapSROAValue(GEPI->getOperand(0), FieldNo,
- InsertedScalarizedValues, PHIsToRewrite,
- Context);
+ InsertedScalarizedValues, PHIsToRewrite);
// Create the new GEP idx vector.
SmallVector<Value*, 8> GEPIdx;
@@ -1245,8 +1251,7 @@
// users.
for (Value::use_iterator UI = PN->use_begin(), E = PN->use_end(); UI != E; ) {
Instruction *User = cast<Instruction>(*UI++);
- RewriteHeapSROALoadUser(User, InsertedScalarizedValues, PHIsToRewrite,
- Context);
+ RewriteHeapSROALoadUser(User, InsertedScalarizedValues, PHIsToRewrite);
}
}
@@ -1256,13 +1261,11 @@
/// AllGlobalLoadUsesSimpleEnoughForHeapSRA.
static void RewriteUsesOfLoadForHeapSRoA(LoadInst *Load,
DenseMap<Value*, std::vector<Value*> > &InsertedScalarizedValues,
- std::vector<std::pair<PHINode*, unsigned> > &PHIsToRewrite,
- LLVMContext &Context) {
+ std::vector<std::pair<PHINode*, unsigned> > &PHIsToRewrite) {
for (Value::use_iterator UI = Load->use_begin(), E = Load->use_end();
UI != E; ) {
Instruction *User = cast<Instruction>(*UI++);
- RewriteHeapSROALoadUser(User, InsertedScalarizedValues, PHIsToRewrite,
- Context);
+ RewriteHeapSROALoadUser(User, InsertedScalarizedValues, PHIsToRewrite);
}
if (Load->use_empty()) {
@@ -1273,13 +1276,9 @@
/// PerformHeapAllocSRoA - CI is an allocation of an array of structures. Break
/// it up into multiple allocations of arrays of the fields.
-static GlobalVariable *PerformHeapAllocSRoA(GlobalVariable *GV,
- CallInst *CI, BitCastInst* BCI,
- Value* NElems,
- LLVMContext &Context,
- TargetData *TD) {
- DEBUG(errs() << "SROA HEAP ALLOC: " << *GV << " MALLOC CALL = " << *CI
- << " BITCAST = " << *BCI << '\n');
+static GlobalVariable *PerformHeapAllocSRoA(GlobalVariable *GV, CallInst *CI,
+ Value* NElems, TargetData *TD) {
+ DEBUG(errs() << "SROA HEAP ALLOC: " << *GV << " MALLOC = " << *CI << '\n');
const Type* MAT = getMallocAllocatedType(CI);
const StructType *STy = cast<StructType>(MAT);
@@ -1287,8 +1286,8 @@
// it into GV). If there are other uses, change them to be uses of
// the global to simplify later code. This also deletes the store
// into GV.
- ReplaceUsesOfMallocWithGlobal(BCI, GV);
-
+ ReplaceUsesOfMallocWithGlobal(CI, GV);
+
// Okay, at this point, there are no users of the malloc. Insert N
// new mallocs at the same place as CI, and N globals.
std::vector<Value*> FieldGlobals;
@@ -1306,11 +1305,18 @@
GV->isThreadLocal());
FieldGlobals.push_back(NGV);
- Value *NMI = CallInst::CreateMalloc(CI, TD->getIntPtrType(Context),
- FieldTy, NElems,
- BCI->getName() + ".f" + Twine(FieldNo));
- FieldMallocs.push_back(NMI);
- new StoreInst(NMI, NGV, BCI);
+ unsigned TypeSize = TD->getTypeAllocSize(FieldTy);
+ if (const StructType *ST = dyn_cast<StructType>(FieldTy))
+ TypeSize = TD->getStructLayout(ST)->getSizeInBytes();
+ const Type *IntPtrTy = TD->getIntPtrType(CI->getContext());
+ Value *NMI = CallInst::CreateMalloc(CI, IntPtrTy, FieldTy,
+ ConstantInt::get(IntPtrTy, TypeSize),
+ NElems,
+ CI->getName() + ".f" + Twine(FieldNo));
+ CallInst *NCI = dyn_cast<BitCastInst>(NMI) ?
+ extractMallocCallFromBitCast(NMI) : cast<CallInst>(NMI);
+ FieldMallocs.push_back(NCI);
+ new StoreInst(NMI, NGV, CI);
}
// The tricky aspect of this transformation is handling the case when malloc
@@ -1325,24 +1331,25 @@
// if (F1) { free(F1); F1 = 0; }
// if (F2) { free(F2); F2 = 0; }
// }
- Value *RunningOr = 0;
+ // The malloc can also fail if its argument is too large.
+ Constant *ConstantZero = ConstantInt::get(CI->getOperand(1)->getType(), 0);
+ Value *RunningOr = new ICmpInst(CI, ICmpInst::ICMP_SLT, CI->getOperand(1),
+ ConstantZero, "isneg");
for (unsigned i = 0, e = FieldMallocs.size(); i != e; ++i) {
- Value *Cond = new ICmpInst(BCI, ICmpInst::ICMP_EQ, FieldMallocs[i],
- Constant::getNullValue(FieldMallocs[i]->getType()),
- "isnull");
- if (!RunningOr)
- RunningOr = Cond; // First seteq
- else
- RunningOr = BinaryOperator::CreateOr(RunningOr, Cond, "tmp", BCI);
+ Value *Cond = new ICmpInst(CI, ICmpInst::ICMP_EQ, FieldMallocs[i],
+ Constant::getNullValue(FieldMallocs[i]->getType()),
+ "isnull");
+ RunningOr = BinaryOperator::CreateOr(RunningOr, Cond, "tmp", CI);
}
// Split the basic block at the old malloc.
- BasicBlock *OrigBB = BCI->getParent();
- BasicBlock *ContBB = OrigBB->splitBasicBlock(BCI, "malloc_cont");
+ BasicBlock *OrigBB = CI->getParent();
+ BasicBlock *ContBB = OrigBB->splitBasicBlock(CI, "malloc_cont");
// Create the block to check the first condition. Put all these blocks at the
// end of the function as they are unlikely to be executed.
- BasicBlock *NullPtrBlock = BasicBlock::Create(Context, "malloc_ret_null",
+ BasicBlock *NullPtrBlock = BasicBlock::Create(OrigBB->getContext(),
+ "malloc_ret_null",
OrigBB->getParent());
// Remove the uncond branch from OrigBB to ContBB, turning it into a cond
@@ -1357,9 +1364,9 @@
Value *Cmp = new ICmpInst(*NullPtrBlock, ICmpInst::ICMP_NE, GVVal,
Constant::getNullValue(GVVal->getType()),
"tmp");
- BasicBlock *FreeBlock = BasicBlock::Create(Context, "free_it",
+ BasicBlock *FreeBlock = BasicBlock::Create(Cmp->getContext(), "free_it",
OrigBB->getParent());
- BasicBlock *NextBlock = BasicBlock::Create(Context, "next",
+ BasicBlock *NextBlock = BasicBlock::Create(Cmp->getContext(), "next",
OrigBB->getParent());
Instruction *BI = BranchInst::Create(FreeBlock, NextBlock,
Cmp, NullPtrBlock);
@@ -1374,9 +1381,8 @@
}
BranchInst::Create(ContBB, NullPtrBlock);
-
- // CI and BCI are no longer needed, remove them.
- BCI->eraseFromParent();
+
+ // CI is no longer needed, remove it.
CI->eraseFromParent();
/// InsertedScalarizedLoads - As we process loads, if we can't immediately
@@ -1394,8 +1400,7 @@
Instruction *User = cast<Instruction>(*UI++);
if (LoadInst *LI = dyn_cast<LoadInst>(User)) {
- RewriteUsesOfLoadForHeapSRoA(LI, InsertedScalarizedValues, PHIsToRewrite,
- Context);
+ RewriteUsesOfLoadForHeapSRoA(LI, InsertedScalarizedValues, PHIsToRewrite);
continue;
}
@@ -1426,7 +1431,7 @@
for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
Value *InVal = PN->getIncomingValue(i);
InVal = GetHeapSROAValue(InVal, FieldNo, InsertedScalarizedValues,
- PHIsToRewrite, Context);
+ PHIsToRewrite);
FieldPN->addIncoming(InVal, PN->getIncomingBlock(i));
}
}
@@ -1463,14 +1468,9 @@
/// cast of malloc.
static bool TryToOptimizeStoreOfMallocToGlobal(GlobalVariable *GV,
CallInst *CI,
- BitCastInst *BCI,
+ const Type *AllocTy,
Module::global_iterator &GVI,
- TargetData *TD,
- LLVMContext &Context) {
- // If we can't figure out the type being malloced, then we can't optimize.
- const Type *AllocTy = getMallocAllocatedType(CI);
- assert(AllocTy);
-
+ TargetData *TD) {
// If this is a malloc of an abstract type, don't touch it.
if (!AllocTy->isSized())
return false;
@@ -1491,7 +1491,7 @@
// for.
{
SmallPtrSet<PHINode*, 8> PHIs;
- if (!ValueIsOnlyUsedLocallyOrStoredToOneGlobal(BCI, GV, PHIs))
+ if (!ValueIsOnlyUsedLocallyOrStoredToOneGlobal(CI, GV, PHIs))
return false;
}
@@ -1499,16 +1499,15 @@
// transform the program to use global memory instead of malloc'd memory.
// This eliminates dynamic allocation, avoids an indirection accessing the
// data, and exposes the resultant global to further GlobalOpt.
- Value *NElems = getMallocArraySize(CI, Context, TD);
// We cannot optimize the malloc if we cannot determine malloc array size.
- if (NElems) {
+ if (Value *NElems = getMallocArraySize(CI, TD, true)) {
if (ConstantInt *NElements = dyn_cast<ConstantInt>(NElems))
// Restrict this transformation to only working on small allocations
// (2048 bytes currently), as we don't want to introduce a 16M global or
// something.
if (TD &&
NElements->getZExtValue() * TD->getTypeAllocSize(AllocTy) < 2048) {
- GVI = OptimizeGlobalAddressOfMalloc(GV, CI, BCI, NElems, Context, TD);
+ GVI = OptimizeGlobalAddressOfMalloc(GV, CI, AllocTy, NElems, TD);
return true;
}
@@ -1526,26 +1525,27 @@
// This the structure has an unreasonable number of fields, leave it
// alone.
if (AllocSTy->getNumElements() <= 16 && AllocSTy->getNumElements() != 0 &&
- AllGlobalLoadUsesSimpleEnoughForHeapSRA(GV, BCI)) {
+ AllGlobalLoadUsesSimpleEnoughForHeapSRA(GV, CI)) {
// If this is a fixed size array, transform the Malloc to be an alloc of
// structs. malloc [100 x struct],1 -> malloc struct, 100
if (const ArrayType *AT =
dyn_cast<ArrayType>(getMallocAllocatedType(CI))) {
- Value* NumElements = ConstantInt::get(Type::getInt32Ty(Context),
- AT->getNumElements());
- Value* NewMI = CallInst::CreateMalloc(CI, TD->getIntPtrType(Context),
- AllocSTy, NumElements,
- BCI->getName());
- Value *Cast = new BitCastInst(NewMI, getMallocType(CI), "tmp", CI);
- BCI->replaceAllUsesWith(Cast);
- BCI->eraseFromParent();
+ const Type *IntPtrTy = TD->getIntPtrType(CI->getContext());
+ unsigned TypeSize = TD->getStructLayout(AllocSTy)->getSizeInBytes();
+ Value *AllocSize = ConstantInt::get(IntPtrTy, TypeSize);
+ Value *NumElements = ConstantInt::get(IntPtrTy, AT->getNumElements());
+ Instruction *Malloc = CallInst::CreateMalloc(CI, IntPtrTy, AllocSTy,
+ AllocSize, NumElements,
+ CI->getName());
+ Instruction *Cast = new BitCastInst(Malloc, CI->getType(), "tmp", CI);
+ CI->replaceAllUsesWith(Cast);
CI->eraseFromParent();
- BCI = cast<BitCastInst>(NewMI);
- CI = extractMallocCallFromBitCast(NewMI);
+ CI = dyn_cast<BitCastInst>(Malloc) ?
+ extractMallocCallFromBitCast(Malloc) : cast<CallInst>(Malloc);
}
- GVI = PerformHeapAllocSRoA(GV, CI, BCI, NElems, Context, TD);
+ GVI = PerformHeapAllocSRoA(GV, CI, getMallocArraySize(CI, TD, true),TD);
return true;
}
}
@@ -1577,15 +1577,10 @@
if (OptimizeAwayTrappingUsesOfLoads(GV, SOVC, Context))
return true;
} else if (CallInst *CI = extractMallocCall(StoredOnceVal)) {
- if (getMallocAllocatedType(CI)) {
- BitCastInst* BCI = NULL;
- for (Value::use_iterator UI = CI->use_begin(), E = CI->use_end();
- UI != E; )
- BCI = dyn_cast<BitCastInst>(cast<Instruction>(*UI++));
- if (BCI &&
- TryToOptimizeStoreOfMallocToGlobal(GV, CI, BCI, GVI, TD, Context))
- return true;
- }
+ const Type* MallocType = getMallocAllocatedType(CI);
+ if (MallocType && TryToOptimizeStoreOfMallocToGlobal(GV, CI, MallocType,
+ GVI, TD))
+ return true;
}
}
@@ -1702,24 +1697,26 @@
if (!AnalyzeGlobal(GV, GS, PHIUsers)) {
#if 0
- cerr << "Global: " << *GV;
- cerr << " isLoaded = " << GS.isLoaded << "\n";
- cerr << " StoredType = ";
+ DEBUG(errs() << "Global: " << *GV);
+ DEBUG(errs() << " isLoaded = " << GS.isLoaded << "\n");
+ DEBUG(errs() << " StoredType = ");
switch (GS.StoredType) {
- case GlobalStatus::NotStored: cerr << "NEVER STORED\n"; break;
- case GlobalStatus::isInitializerStored: cerr << "INIT STORED\n"; break;
- case GlobalStatus::isStoredOnce: cerr << "STORED ONCE\n"; break;
- case GlobalStatus::isStored: cerr << "stored\n"; break;
+ case GlobalStatus::NotStored: DEBUG(errs() << "NEVER STORED\n"); break;
+ case GlobalStatus::isInitializerStored: DEBUG(errs() << "INIT STORED\n");
+ break;
+ case GlobalStatus::isStoredOnce: DEBUG(errs() << "STORED ONCE\n"); break;
+ case GlobalStatus::isStored: DEBUG(errs() << "stored\n"); break;
}
if (GS.StoredType == GlobalStatus::isStoredOnce && GS.StoredOnceValue)
- cerr << " StoredOnceValue = " << *GS.StoredOnceValue << "\n";
+ DEBUG(errs() << " StoredOnceValue = " << *GS.StoredOnceValue << "\n");
if (GS.AccessingFunction && !GS.HasMultipleAccessingFunctions)
- cerr << " AccessingFunction = " << GS.AccessingFunction->getName()
- << "\n";
- cerr << " HasMultipleAccessingFunctions = "
- << GS.HasMultipleAccessingFunctions << "\n";
- cerr << " HasNonInstructionUser = " << GS.HasNonInstructionUser<<"\n";
- cerr << "\n";
+ DEBUG(errs() << " AccessingFunction = " << GS.AccessingFunction->getName()
+ << "\n");
+ DEBUG(errs() << " HasMultipleAccessingFunctions = "
+ << GS.HasMultipleAccessingFunctions << "\n");
+ DEBUG(errs() << " HasNonInstructionUser = "
+ << GS.HasNonInstructionUser<<"\n");
+ DEBUG(errs() << "\n");
#endif
// If this is a first class global and has only one accessing function
Modified: llvm/branches/Apple/Leela/lib/VMCore/Core.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Leela/lib/VMCore/Core.cpp?rev=86704&r1=86703&r2=86704&view=diff
==============================================================================
--- llvm/branches/Apple/Leela/lib/VMCore/Core.cpp (original)
+++ llvm/branches/Apple/Leela/lib/VMCore/Core.cpp Tue Nov 10 13:33:09 2009
@@ -1699,18 +1699,24 @@
LLVMValueRef LLVMBuildMalloc(LLVMBuilderRef B, LLVMTypeRef Ty,
const char *Name) {
- const Type* IntPtrT = Type::getInt32Ty(unwrap(B)->GetInsertBlock()->getContext());
- return wrap(unwrap(B)->Insert(CallInst::CreateMalloc(
- unwrap(B)->GetInsertBlock(), IntPtrT, unwrap(Ty), 0, 0, ""),
- Twine(Name)));
+ const Type* ITy = Type::getInt32Ty(unwrap(B)->GetInsertBlock()->getContext());
+ Constant* AllocSize = ConstantExpr::getSizeOf(unwrap(Ty));
+ AllocSize = ConstantExpr::getTruncOrBitCast(AllocSize, ITy);
+ Instruction* Malloc = CallInst::CreateMalloc(unwrap(B)->GetInsertBlock(),
+ ITy, unwrap(Ty), AllocSize,
+ 0, 0, "");
+ return wrap(unwrap(B)->Insert(Malloc, Twine(Name)));
}
LLVMValueRef LLVMBuildArrayMalloc(LLVMBuilderRef B, LLVMTypeRef Ty,
LLVMValueRef Val, const char *Name) {
- const Type* IntPtrT = Type::getInt32Ty(unwrap(B)->GetInsertBlock()->getContext());
- return wrap(unwrap(B)->Insert(CallInst::CreateMalloc(
- unwrap(B)->GetInsertBlock(), IntPtrT, unwrap(Ty), unwrap(Val), 0, ""),
- Twine(Name)));
+ const Type* ITy = Type::getInt32Ty(unwrap(B)->GetInsertBlock()->getContext());
+ Constant* AllocSize = ConstantExpr::getSizeOf(unwrap(Ty));
+ AllocSize = ConstantExpr::getTruncOrBitCast(AllocSize, ITy);
+ Instruction* Malloc = CallInst::CreateMalloc(unwrap(B)->GetInsertBlock(),
+ ITy, unwrap(Ty), AllocSize,
+ unwrap(Val), 0, "");
+ return wrap(unwrap(B)->Insert(Malloc, Twine(Name)));
}
LLVMValueRef LLVMBuildAlloca(LLVMBuilderRef B, LLVMTypeRef Ty,
Modified: llvm/branches/Apple/Leela/lib/VMCore/Instructions.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Leela/lib/VMCore/Instructions.cpp?rev=86704&r1=86703&r2=86704&view=diff
==============================================================================
--- llvm/branches/Apple/Leela/lib/VMCore/Instructions.cpp (original)
+++ llvm/branches/Apple/Leela/lib/VMCore/Instructions.cpp Tue Nov 10 13:33:09 2009
@@ -448,22 +448,11 @@
return isa<ConstantInt>(val) && cast<ConstantInt>(val)->isOne();
}
-static Value *checkArraySize(Value *Amt, const Type *IntPtrTy) {
- if (!Amt)
- Amt = ConstantInt::get(IntPtrTy, 1);
- else {
- assert(!isa<BasicBlock>(Amt) &&
- "Passed basic block into malloc size parameter! Use other ctor");
- assert(Amt->getType() == IntPtrTy &&
- "Malloc array size is not an intptr!");
- }
- return Amt;
-}
-
static Instruction *createMalloc(Instruction *InsertBefore,
BasicBlock *InsertAtEnd, const Type *IntPtrTy,
- const Type *AllocTy, Value *ArraySize,
- Function *MallocF, const Twine &NameStr) {
+ const Type *AllocTy, Value *AllocSize,
+ Value *ArraySize, Function *MallocF,
+ const Twine &Name) {
assert(((!InsertBefore && InsertAtEnd) || (InsertBefore && !InsertAtEnd)) &&
"createMalloc needs either InsertBefore or InsertAtEnd");
@@ -471,10 +460,16 @@
// bitcast (i8* malloc(typeSize)) to type*
// malloc(type, arraySize) becomes:
// bitcast (i8 *malloc(typeSize*arraySize)) to type*
- Value *AllocSize = ConstantExpr::getSizeOf(AllocTy);
- AllocSize = ConstantExpr::getTruncOrBitCast(cast<Constant>(AllocSize),
- IntPtrTy);
- ArraySize = checkArraySize(ArraySize, IntPtrTy);
+ if (!ArraySize)
+ ArraySize = ConstantInt::get(IntPtrTy, 1);
+ else if (ArraySize->getType() != IntPtrTy) {
+ if (InsertBefore)
+ ArraySize = CastInst::CreateIntegerCast(ArraySize, IntPtrTy, false,
+ "", InsertBefore);
+ else
+ ArraySize = CastInst::CreateIntegerCast(ArraySize, IntPtrTy, false,
+ "", InsertAtEnd);
+ }
if (!IsConstantOne(ArraySize)) {
if (IsConstantOne(AllocSize)) {
@@ -513,17 +508,18 @@
Result = MCall;
if (Result->getType() != AllocPtrType)
// Create a cast instruction to convert to the right type...
- Result = new BitCastInst(MCall, AllocPtrType, NameStr, InsertBefore);
+ Result = new BitCastInst(MCall, AllocPtrType, Name, InsertBefore);
} else {
MCall = CallInst::Create(MallocF, AllocSize, "malloccall");
Result = MCall;
if (Result->getType() != AllocPtrType) {
InsertAtEnd->getInstList().push_back(MCall);
// Create a cast instruction to convert to the right type...
- Result = new BitCastInst(MCall, AllocPtrType, NameStr);
+ Result = new BitCastInst(MCall, AllocPtrType, Name);
}
}
MCall->setTailCall();
+ MCall->setCallingConv(MallocF->getCallingConv());
assert(MCall->getType() != Type::getVoidTy(BB->getContext()) &&
"Malloc has void return type");
@@ -538,8 +534,9 @@
/// 3. Bitcast the result of the malloc call to the specified type.
Instruction *CallInst::CreateMalloc(Instruction *InsertBefore,
const Type *IntPtrTy, const Type *AllocTy,
- Value *ArraySize, const Twine &Name) {
- return createMalloc(InsertBefore, NULL, IntPtrTy, AllocTy,
+ Value *AllocSize, Value *ArraySize,
+ const Twine &Name) {
+ return createMalloc(InsertBefore, NULL, IntPtrTy, AllocTy, AllocSize,
ArraySize, NULL, Name);
}
@@ -553,9 +550,9 @@
/// responsibility of the caller.
Instruction *CallInst::CreateMalloc(BasicBlock *InsertAtEnd,
const Type *IntPtrTy, const Type *AllocTy,
- Value *ArraySize, Function* MallocF,
- const Twine &Name) {
- return createMalloc(NULL, InsertAtEnd, IntPtrTy, AllocTy,
+ Value *AllocSize, Value *ArraySize,
+ Function *MallocF, const Twine &Name) {
+ return createMalloc(NULL, InsertAtEnd, IntPtrTy, AllocTy, AllocSize,
ArraySize, MallocF, Name);
}
@@ -572,8 +569,7 @@
const Type *VoidTy = Type::getVoidTy(M->getContext());
const Type *IntPtrTy = Type::getInt8PtrTy(M->getContext());
// prototype free as "void free(void*)"
- Constant *FreeFunc = M->getOrInsertFunction("free", VoidTy, IntPtrTy, NULL);
-
+ Value *FreeFunc = M->getOrInsertFunction("free", VoidTy, IntPtrTy, NULL);
CallInst* Result = NULL;
Value *PtrCast = Source;
if (InsertBefore) {
@@ -586,6 +582,8 @@
Result = CallInst::Create(FreeFunc, PtrCast, "");
}
Result->setTailCall();
+ if (Function *F = dyn_cast<Function>(FreeFunc))
+ Result->setCallingConv(F->getCallingConv());
return Result;
}
Modified: llvm/branches/Apple/Leela/test/Analysis/PointerTracking/sizes.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Leela/test/Analysis/PointerTracking/sizes.ll?rev=86704&r1=86703&r2=86704&view=diff
==============================================================================
--- llvm/branches/Apple/Leela/test/Analysis/PointerTracking/sizes.ll (original)
+++ llvm/branches/Apple/Leela/test/Analysis/PointerTracking/sizes.ll Tue Nov 10 13:33:09 2009
@@ -60,9 +60,9 @@
ret i32 %add16
}
-define i32 @foo2(i32 %n) nounwind {
+define i32 @foo2(i64 %n) nounwind {
entry:
- %call = malloc i8, i32 %n ; <i8*> [#uses=1]
+ %call = tail call i8* @malloc(i64 %n) ; <i8*> [#uses=1]
; CHECK: %call =
; CHECK: ==> %n elements, %n bytes allocated
%call2 = tail call i8* @calloc(i64 2, i64 4) nounwind ; <i8*> [#uses=1]
@@ -79,6 +79,8 @@
ret i32 %add11
}
+declare noalias i8* @malloc(i64) nounwind
+
declare noalias i8* @calloc(i64, i64) nounwind
declare noalias i8* @realloc(i8* nocapture, i64) nounwind
Modified: llvm/branches/Apple/Leela/test/Transforms/GlobalOpt/2009-06-01-RecursivePHI.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Leela/test/Transforms/GlobalOpt/2009-06-01-RecursivePHI.ll?rev=86704&r1=86703&r2=86704&view=diff
==============================================================================
--- llvm/branches/Apple/Leela/test/Transforms/GlobalOpt/2009-06-01-RecursivePHI.ll (original)
+++ llvm/branches/Apple/Leela/test/Transforms/GlobalOpt/2009-06-01-RecursivePHI.ll Tue Nov 10 13:33:09 2009
@@ -1,4 +1,5 @@
; RUN: opt < %s -globalopt
+target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
%struct.s_annealing_sched = type { i32, float, float, float, float }
%struct.s_bb = type { i32, i32, i32, i32 }
@@ -96,7 +97,9 @@
unreachable
bb1.i38: ; preds = %bb
- %0 = malloc %struct.s_net, i32 undef ; <%struct.s_net*> [#uses=1]
+ %mallocsize = mul i64 28, undef ; <i64> [#uses=1]
+ %malloccall = tail call i8* @malloc(i64 %mallocsize) ; <i8*> [#uses=1]
+ %0 = bitcast i8* %malloccall to %struct.s_net* ; <%struct.s_net*> [#uses=1]
br i1 undef, label %bb.i1.i39, label %my_malloc.exit2.i
bb.i1.i39: ; preds = %bb1.i38
@@ -115,3 +118,5 @@
bb7: ; preds = %bb6.preheader
unreachable
}
+
+declare noalias i8* @malloc(i64)
Modified: llvm/branches/Apple/Leela/test/Transforms/GlobalOpt/heap-sra-1.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Leela/test/Transforms/GlobalOpt/heap-sra-1.ll?rev=86704&r1=86703&r2=86704&view=diff
==============================================================================
--- llvm/branches/Apple/Leela/test/Transforms/GlobalOpt/heap-sra-1.ll (original)
+++ llvm/branches/Apple/Leela/test/Transforms/GlobalOpt/heap-sra-1.ll Tue Nov 10 13:33:09 2009
@@ -1,18 +1,22 @@
-; RUN: opt < %s -globalopt -S | grep {@X.f0}
-; RUN: opt < %s -globalopt -S | grep {@X.f1}
-target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
-target triple = "i386-apple-darwin7"
+; RUN: opt < %s -globalopt -S | FileCheck %s
+target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
%struct.foo = type { i32, i32 }
@X = internal global %struct.foo* null
+; CHECK: @X.f0
+; CHECK: @X.f1
-define void @bar(i32 %Size) nounwind noinline {
+define void @bar(i64 %Size) nounwind noinline {
entry:
- %.sub = malloc %struct.foo, i32 %Size
+ %mallocsize = mul i64 %Size, 8 ; <i64> [#uses=1]
+ %malloccall = tail call i8* @malloc(i64 %mallocsize) ; <i8*> [#uses=1]
+ %.sub = bitcast i8* %malloccall to %struct.foo* ; <%struct.foo*> [#uses=1]
store %struct.foo* %.sub, %struct.foo** @X, align 4
ret void
}
+declare noalias i8* @malloc(i64)
+
define i32 @baz() nounwind readonly noinline {
bb1.thread:
%0 = load %struct.foo** @X, align 4
Modified: llvm/branches/Apple/Leela/test/Transforms/GlobalOpt/heap-sra-2.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Leela/test/Transforms/GlobalOpt/heap-sra-2.ll?rev=86704&r1=86703&r2=86704&view=diff
==============================================================================
--- llvm/branches/Apple/Leela/test/Transforms/GlobalOpt/heap-sra-2.ll (original)
+++ llvm/branches/Apple/Leela/test/Transforms/GlobalOpt/heap-sra-2.ll Tue Nov 10 13:33:09 2009
@@ -1,20 +1,22 @@
-; RUN: opt < %s -globalopt -S | grep {@X.f0}
-; RUN: opt < %s -globalopt -S | grep {@X.f1}
+; RUN: opt < %s -globalopt -S | FileCheck %s
+target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
-target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
-target triple = "i386-apple-darwin7"
%struct.foo = type { i32, i32 }
@X = internal global %struct.foo* null ; <%struct.foo**> [#uses=2]
+; CHECK: @X.f0
+; CHECK: @X.f1
define void @bar(i32 %Size) nounwind noinline {
entry:
- %0 = malloc [1000000 x %struct.foo]
- ;%.sub = bitcast [1000000 x %struct.foo]* %0 to %struct.foo*
+ %malloccall = tail call i8* @malloc(i64 8000000) ; <i8*> [#uses=1]
+ %0 = bitcast i8* %malloccall to [1000000 x %struct.foo]* ; <[1000000 x %struct.foo]*> [#uses=1]
%.sub = getelementptr [1000000 x %struct.foo]* %0, i32 0, i32 0 ; <%struct.foo*> [#uses=1]
store %struct.foo* %.sub, %struct.foo** @X, align 4
ret void
}
+declare noalias i8* @malloc(i64)
+
define i32 @baz() nounwind readonly noinline {
bb1.thread:
%0 = load %struct.foo** @X, align 4 ; <%struct.foo*> [#uses=1]
Modified: llvm/branches/Apple/Leela/test/Transforms/GlobalOpt/heap-sra-3.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Leela/test/Transforms/GlobalOpt/heap-sra-3.ll?rev=86704&r1=86703&r2=86704&view=diff
==============================================================================
--- llvm/branches/Apple/Leela/test/Transforms/GlobalOpt/heap-sra-3.ll (original)
+++ llvm/branches/Apple/Leela/test/Transforms/GlobalOpt/heap-sra-3.ll Tue Nov 10 13:33:09 2009
@@ -1,24 +1,22 @@
; RUN: opt < %s -globalopt -S | FileCheck %s
-
-target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
-target triple = "i386-apple-darwin10"
+target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
%struct.foo = type { i32, i32 }
@X = internal global %struct.foo* null
; CHECK: @X.f0
; CHECK: @X.f1
-define void @bar(i32 %Size) nounwind noinline {
+define void @bar(i64 %Size) nounwind noinline {
entry:
- %mallocsize = mul i32 ptrtoint (%struct.foo* getelementptr (%struct.foo* null, i32 1) to i32), %Size, ; <i32> [#uses=1]
-; CHECK: mul i32 %Size
- %malloccall = tail call i8* @malloc(i32 %mallocsize) ; <i8*> [#uses=1]
+ %mallocsize = mul i64 8, %Size, ; <i64> [#uses=1]
+; CHECK: mul i64 %Size, 4
+ %malloccall = tail call i8* @malloc(i64 %mallocsize) ; <i8*> [#uses=1]
%.sub = bitcast i8* %malloccall to %struct.foo* ; <%struct.foo*> [#uses=1]
store %struct.foo* %.sub, %struct.foo** @X, align 4
ret void
}
-declare noalias i8* @malloc(i32)
+declare noalias i8* @malloc(i64)
define i32 @baz() nounwind readonly noinline {
bb1.thread:
Modified: llvm/branches/Apple/Leela/test/Transforms/GlobalOpt/heap-sra-4.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Leela/test/Transforms/GlobalOpt/heap-sra-4.ll?rev=86704&r1=86703&r2=86704&view=diff
==============================================================================
--- llvm/branches/Apple/Leela/test/Transforms/GlobalOpt/heap-sra-4.ll (original)
+++ llvm/branches/Apple/Leela/test/Transforms/GlobalOpt/heap-sra-4.ll Tue Nov 10 13:33:09 2009
@@ -1,24 +1,22 @@
; RUN: opt < %s -globalopt -S | FileCheck %s
-
-target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
-target triple = "i386-apple-darwin7"
+target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
%struct.foo = type { i32, i32 }
@X = internal global %struct.foo* null
; CHECK: @X.f0
; CHECK: @X.f1
-define void @bar(i32 %Size) nounwind noinline {
+define void @bar(i64 %Size) nounwind noinline {
entry:
- %mallocsize = shl i32 ptrtoint (%struct.foo* getelementptr (%struct.foo* null, i32 1) to i32), 9, ; <i32> [#uses=1]
- %malloccall = tail call i8* @malloc(i32 %mallocsize) ; <i8*> [#uses=1]
-; CHECK: @malloc(i32 mul (i32 512
+ %mallocsize = shl i64 %Size, 3 ; <i64> [#uses=1]
+ %malloccall = tail call i8* @malloc(i64 %mallocsize) ; <i8*> [#uses=1]
+; CHECK: mul i64 %Size, 4
%.sub = bitcast i8* %malloccall to %struct.foo* ; <%struct.foo*> [#uses=1]
store %struct.foo* %.sub, %struct.foo** @X, align 4
ret void
}
-declare noalias i8* @malloc(i32)
+declare noalias i8* @malloc(i64)
define i32 @baz() nounwind readonly noinline {
bb1.thread:
Modified: llvm/branches/Apple/Leela/test/Transforms/GlobalOpt/heap-sra-phi.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Leela/test/Transforms/GlobalOpt/heap-sra-phi.ll?rev=86704&r1=86703&r2=86704&view=diff
==============================================================================
--- llvm/branches/Apple/Leela/test/Transforms/GlobalOpt/heap-sra-phi.ll (original)
+++ llvm/branches/Apple/Leela/test/Transforms/GlobalOpt/heap-sra-phi.ll Tue Nov 10 13:33:09 2009
@@ -1,19 +1,21 @@
; RUN: opt < %s -globalopt -S | grep {tmp.f1 = phi i32. }
; RUN: opt < %s -globalopt -S | grep {tmp.f0 = phi i32. }
+target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
-target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
-target triple = "i386-apple-darwin7"
%struct.foo = type { i32, i32 }
@X = internal global %struct.foo* null ; <%struct.foo**> [#uses=2]
define void @bar(i32 %Size) nounwind noinline {
entry:
- %tmp = malloc [1000000 x %struct.foo] ; <[1000000 x %struct.foo]*> [#uses=1]
+ %malloccall = tail call i8* @malloc(i64 8000000) ; <i8*> [#uses=1]
+ %tmp = bitcast i8* %malloccall to [1000000 x %struct.foo]* ; <[1000000 x %struct.foo]*> [#uses=1]
%.sub = getelementptr [1000000 x %struct.foo]* %tmp, i32 0, i32 0 ; <%struct.foo*> [#uses=1]
store %struct.foo* %.sub, %struct.foo** @X, align 4
ret void
}
+declare noalias i8* @malloc(i64)
+
define i32 @baz() nounwind readonly noinline {
bb1.thread:
%tmpLD1 = load %struct.foo** @X, align 4 ; <%struct.foo*> [#uses=1]
Modified: llvm/branches/Apple/Leela/test/Transforms/GlobalOpt/malloc-promote-1.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Leela/test/Transforms/GlobalOpt/malloc-promote-1.ll?rev=86704&r1=86703&r2=86704&view=diff
==============================================================================
--- llvm/branches/Apple/Leela/test/Transforms/GlobalOpt/malloc-promote-1.ll (original)
+++ llvm/branches/Apple/Leela/test/Transforms/GlobalOpt/malloc-promote-1.ll Tue Nov 10 13:33:09 2009
@@ -1,18 +1,23 @@
-; RUN: opt < %s -globalopt -S | not grep global
+; RUN: opt < %s -globalopt -S | FileCheck %s
@G = internal global i32* null ; <i32**> [#uses=3]
+; CHECK-NOT: global
define void @init() {
- %P = malloc i32 ; <i32*> [#uses=1]
+ %malloccall = tail call i8* @malloc(i64 4) ; <i8*> [#uses=1]
+ %P = bitcast i8* %malloccall to i32* ; <i32*> [#uses=1]
store i32* %P, i32** @G
%GV = load i32** @G ; <i32*> [#uses=1]
store i32 0, i32* %GV
ret void
}
+declare noalias i8* @malloc(i64)
+
define i32 @get() {
%GV = load i32** @G ; <i32*> [#uses=1]
%V = load i32* %GV ; <i32> [#uses=1]
ret i32 %V
+; CHECK: ret i32 0
}
Modified: llvm/branches/Apple/Leela/test/Transforms/GlobalOpt/malloc-promote-2.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Leela/test/Transforms/GlobalOpt/malloc-promote-2.ll?rev=86704&r1=86703&r2=86704&view=diff
==============================================================================
--- llvm/branches/Apple/Leela/test/Transforms/GlobalOpt/malloc-promote-2.ll (original)
+++ llvm/branches/Apple/Leela/test/Transforms/GlobalOpt/malloc-promote-2.ll Tue Nov 10 13:33:09 2009
@@ -1,11 +1,11 @@
; RUN: opt < %s -globalopt -globaldce -S | not grep malloc
-target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
-target triple = "i686-apple-darwin8"
+target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
@G = internal global i32* null ; <i32**> [#uses=3]
define void @init() {
- %P = malloc i32, i32 100 ; <i32*> [#uses=1]
+ %malloccall = tail call i8* @malloc(i64 mul (i64 100, i64 4)) ; <i8*> [#uses=1]
+ %P = bitcast i8* %malloccall to i32* ; <i32*> [#uses=1]
store i32* %P, i32** @G
%GV = load i32** @G ; <i32*> [#uses=1]
%GVe = getelementptr i32* %GV, i32 40 ; <i32*> [#uses=1]
@@ -13,6 +13,8 @@
ret void
}
+declare noalias i8* @malloc(i64)
+
define i32 @get() {
%GV = load i32** @G ; <i32*> [#uses=1]
%GVe = getelementptr i32* %GV, i32 40 ; <i32*> [#uses=1]
Modified: llvm/branches/Apple/Leela/test/Transforms/GlobalOpt/malloc-promote-3.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/branches/Apple/Leela/test/Transforms/GlobalOpt/malloc-promote-3.ll?rev=86704&r1=86703&r2=86704&view=diff
==============================================================================
--- llvm/branches/Apple/Leela/test/Transforms/GlobalOpt/malloc-promote-3.ll (original)
+++ llvm/branches/Apple/Leela/test/Transforms/GlobalOpt/malloc-promote-3.ll Tue Nov 10 13:33:09 2009
@@ -1,11 +1,11 @@
; RUN: opt < %s -globalopt -globaldce -S | not grep malloc
-target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
-target triple = "i686-apple-darwin8"
+target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
@G = internal global i32* null ; <i32**> [#uses=4]
define void @init() {
- %P = malloc i32, i32 100 ; <i32*> [#uses=1]
+ %malloccall = tail call i8* @malloc(i64 mul (i64 100, i64 4)) ; <i8*> [#uses=1]
+ %P = bitcast i8* %malloccall to i32* ; <i32*> [#uses=1]
store i32* %P, i32** @G
%GV = load i32** @G ; <i32*> [#uses=1]
%GVe = getelementptr i32* %GV, i32 40 ; <i32*> [#uses=1]
@@ -13,6 +13,8 @@
ret void
}
+declare noalias i8* @malloc(i64)
+
define i32 @get() {
%GV = load i32** @G ; <i32*> [#uses=1]
%GVe = getelementptr i32* %GV, i32 40 ; <i32*> [#uses=1]
More information about the llvm-branch-commits
mailing list