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 | 7d6293a0d3144ca6ee1bb84f9fba987d1600b272 (patch) | |
tree | 972a84ffca274101dfba70a0255ec1859e2200cf /llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp | |
parent | 5b864d0cbb3a3e3029782df8d000464e6f4d4b2d (diff) | |
download | bcm5719-llvm-7d6293a0d3144ca6ee1bb84f9fba987d1600b272.tar.gz bcm5719-llvm-7d6293a0d3144ca6ee1bb84f9fba987d1600b272.zip |
[InstCombine] Add optimization of redundant insertvalue instructions.
rdar://problem/11861387
llvm-svn: 208214
Diffstat (limited to 'llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp')
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp index aa81e8c9724..80c20b70758 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp +++ b/llvm/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); |