aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2002-11-04 16:18:53 +0000
committerChris Lattner <sabre@nondot.org>2002-11-04 16:18:53 +0000
commit0864acf07bbb115375db2ac4e0e61e5c6373f8c4 (patch)
treed8adcc1cd187a81be0968926bfd90a48ca4fe125
parent0eaaa56f1f5a87446c7c45b530f0ab0bbe365f59 (diff)
Add a transformation to turn:
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
-rw-r--r--lib/Transforms/Scalar/InstructionCombining.cpp36
1 files changed, 36 insertions, 0 deletions
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp
index be9f637523..df3a611ba2 100644
--- a/lib/Transforms/Scalar/InstructionCombining.cpp
+++ b/lib/Transforms/Scalar/InstructionCombining.cpp
@@ -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),