Add a transformation to turn:
authorChris Lattner <sabre@nondot.org>
Mon, 4 Nov 2002 16:18:53 +0000 (16:18 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 4 Nov 2002 16:18:53 +0000 (16:18 +0000)
  malloc Ty, C
int
  malloc [C x Ty], 1

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@4534 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Scalar/InstructionCombining.cpp

index be9f63752314d0f0d3c0b8e098ab0f0c462279e0..df3a611ba27c0a9f3f828fca89c04d950ee9696a 100644 (file)
@@ -23,6 +23,7 @@
 #include "llvm/iPHINode.h"
 #include "llvm/iOperators.h"
 #include "llvm/Pass.h"
+#include "llvm/DerivedTypes.h"
 #include "llvm/Support/InstIterator.h"
 #include "llvm/Support/InstVisitor.h"
 #include "Support/Statistic.h"
@@ -76,6 +77,7 @@ namespace {
     Instruction *visitCastInst(CastInst &CI);
     Instruction *visitPHINode(PHINode &PN);
     Instruction *visitGetElementPtrInst(GetElementPtrInst &GEP);
+    Instruction *visitAllocationInst(AllocationInst &AI);
 
     // visitInstruction - Specify what to return for unhandled instructions...
     Instruction *visitInstruction(Instruction &I) { return 0; }
@@ -711,6 +713,40 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
   return 0;
 }
 
+Instruction *InstCombiner::visitAllocationInst(AllocationInst &AI) {
+  // Convert: malloc Ty, C - where C is a constant != 1 into: malloc [C x Ty], 1
+  if (AI.isArrayAllocation())    // Check C != 1
+    if (const ConstantUInt *C = dyn_cast<ConstantUInt>(AI.getArraySize())) {
+      const Type *NewTy = ArrayType::get(AI.getAllocatedType(), C->getValue());
+      AllocationInst *New;
+
+      // Create and insert the replacement instruction...
+      if (isa<MallocInst>(AI))
+        New = new MallocInst(NewTy, 0, AI.getName(), &AI);
+      else if (isa<AllocaInst>(AI))
+        New = new AllocaInst(NewTy, 0, AI.getName(), &AI);
+      
+      // Scan to the end of the allocation instructions, to skip over a block of
+      // allocas if possible...
+      //
+      BasicBlock::iterator It = New;
+      while (isa<AllocationInst>(*It)) ++It;
+
+      // Now that I is pointing to the first non-allocation-inst in the block,
+      // insert our getelementptr instruction...
+      //
+      std::vector<Value*> Idx(2, Constant::getNullValue(Type::LongTy));
+      Value *V = new GetElementPtrInst(New, Idx, New->getName()+".sub", It);
+
+      // Now make everything use the getelementptr instead of the original
+      // allocation.
+      ReplaceInstUsesWith(AI, V);
+      return &AI;
+    }
+  return 0;
+}
+
+
 
 void InstCombiner::removeFromWorkList(Instruction *I) {
   WorkList.erase(std::remove(WorkList.begin(), WorkList.end(), I),