[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