diff options
author | Michael Zolotukhin <mzolotukhin@apple.com> | 2014-05-07 14:30:18 +0000 |
---|---|---|
committer | Michael Zolotukhin <mzolotukhin@apple.com> | 2014-05-07 14:30:18 +0000 |
commit | 355e0a6460c1b76abe966480a6a7401444f48034 (patch) | |
tree | 498dcb881fa6d9176adb2e7e64defcffda4f2e85 /lib | |
parent | 0c78010b8888ab4ebb4f7d0a33fa8078111d1808 (diff) | |
download | llvm-355e0a6460c1b76abe966480a6a7401444f48034.tar.gz llvm-355e0a6460c1b76abe966480a6a7401444f48034.tar.bz2 llvm-355e0a6460c1b76abe966480a6a7401444f48034.tar.xz |
[InstCombine] Add optimization of redundant insertvalue instructions.
rdar://problem/11861387
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@208214 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Transforms/InstCombine/InstCombine.h | 1 | ||||
-rw-r--r-- | lib/Transforms/InstCombine/InstCombineVectorOps.cpp | 36 |
2 files changed, 37 insertions, 0 deletions
diff --git a/lib/Transforms/InstCombine/InstCombine.h b/lib/Transforms/InstCombine/InstCombine.h index 88351a09ce..8a082fea04 100644 --- a/lib/Transforms/InstCombine/InstCombine.h +++ b/lib/Transforms/InstCombine/InstCombine.h @@ -211,6 +211,7 @@ public: Instruction *visitStoreInst(StoreInst &SI); Instruction *visitBranchInst(BranchInst &BI); Instruction *visitSwitchInst(SwitchInst &SI); + Instruction *visitInsertValueInst(InsertValueInst &IV); Instruction *visitInsertElementInst(InsertElementInst &IE); Instruction *visitExtractElementInst(ExtractElementInst &EI); Instruction *visitShuffleVectorInst(ShuffleVectorInst &SVI); diff --git a/lib/Transforms/InstCombine/InstCombineVectorOps.cpp b/lib/Transforms/InstCombine/InstCombineVectorOps.cpp index aa81e8c972..80c20b7075 100644 --- a/lib/Transforms/InstCombine/InstCombineVectorOps.cpp +++ b/lib/Transforms/InstCombine/InstCombineVectorOps.cpp @@ -490,6 +490,42 @@ static ShuffleOps CollectShuffleElements(Value *V, return std::make_pair(V, nullptr); } +/// Try to find redundant insertvalue instructions, like the following ones: +/// %0 = insertvalue { i8, i32 } undef, i8 %x, 0 +/// %1 = insertvalue { i8, i32 } %0, i8 %y, 0 +/// Here the second instruction inserts values at the same indices, as the +/// first one, making the first one redundant. +/// It should be transformed to: +/// %0 = insertvalue { i8, i32 } undef, i8 %y, 0 +Instruction *InstCombiner::visitInsertValueInst(InsertValueInst &I) { + bool IsRedundant = false; + ArrayRef<unsigned int> FirstIndices = I.getIndices(); + + // If there is a chain of insertvalue instructions (each of them except the + // last one has only one use and it's another insertvalue insn from this + // chain), check if any of the 'children' uses the same indices as the first + // instruction. In this case, the first one is redundant. + Value *V = &I; + unsigned int Depth = 0; + while (V->hasOneUse() && Depth < 10) { + User *U = V->user_back(); + InsertValueInst *UserInsInst = dyn_cast<InsertValueInst>(U); + if (!UserInsInst || U->getType() != I.getType()) { + break; + } + if (UserInsInst->getIndices() == FirstIndices) { + IsRedundant = true; + break; + } + V = UserInsInst; + Depth++; + } + + if (IsRedundant) + return ReplaceInstUsesWith(I, I.getOperand(0)); + return nullptr; +} + Instruction *InstCombiner::visitInsertElementInst(InsertElementInst &IE) { Value *VecOp = IE.getOperand(0); Value *ScalarOp = IE.getOperand(1); |