From 780ae5e1793f1a6e626610b1d26a41ede53e2a1d Mon Sep 17 00:00:00 2001 From: Matthijs Kooijman Date: Wed, 16 Jul 2008 12:55:45 +0000 Subject: Redo InstCombiner::visitExtractValueInst. Instead of using the (complicate) FindInsertedValue, it now performs a number of simple transformations that should result in the same effect when applied iteratively. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@53673 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Scalar/InstructionCombining.cpp | 85 ++++++++++++++++++++++++-- 1 file changed, 80 insertions(+), 5 deletions(-) (limited to 'lib') diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index c35d92c28f..4a45e668cf 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -10649,12 +10649,87 @@ Instruction *InstCombiner::visitSwitchInst(SwitchInst &SI) { } Instruction *InstCombiner::visitExtractValueInst(ExtractValueInst &EV) { - // See if we are trying to extract a known value. If so, use that instead. - if (Value *Elt = FindInsertedValue(EV.getOperand(0), EV.idx_begin(), - EV.idx_end(), &EV)) - return ReplaceInstUsesWith(EV, Elt); + Value *Agg = EV.getAggregateOperand(); - // No changes + if (!EV.hasIndices()) + return ReplaceInstUsesWith(EV, Agg); + + if (Constant *C = dyn_cast(Agg)) { + if (isa(C)) + return ReplaceInstUsesWith(EV, UndefValue::get(EV.getType())); + + if (isa(C)) + return ReplaceInstUsesWith(EV, Constant::getNullValue(EV.getType())); + + if (isa(C) || isa(C)) { + // Extract the element indexed by the first index out of the constant + Value *V = C->getOperand(*EV.idx_begin()); + if (EV.getNumIndices() > 1) + // Extract the remaining indices out of the constant indexed by the + // first index + return ExtractValueInst::Create(V, EV.idx_begin() + 1, EV.idx_end()); + else + return ReplaceInstUsesWith(EV, V); + } + return 0; // Can't handle other constants + } + if (InsertValueInst *IV = dyn_cast(Agg)) { + // We're extracting from an insertvalue instruction, compare the indices + const unsigned *exti, *exte, *insi, *inse; + for (exti = EV.idx_begin(), insi = IV->idx_begin(), + exte = EV.idx_end(), inse = IV->idx_end(); + exti != exte && insi != inse; + ++exti, ++insi) { + if (*insi != *exti) + // The insert and extract both reference distinctly different elements. + // This means the extract is not influenced by the insert, and we can + // replace the aggregate operand of the extract with the aggregate + // operand of the insert. i.e., replace + // %I = insertvalue { i32, { i32 } } %A, { i32 } { i32 42 }, 1 + // %E = extractvalue { i32, { i32 } } %I, 0 + // with + // %E = extractvalue { i32, { i32 } } %A, 0 + return ExtractValueInst::Create(IV->getAggregateOperand(), + EV.idx_begin(), EV.idx_end()); + } + if (exti == exte && insi == inse) + // Both iterators are at the end: Index lists are identical. Replace + // %B = insertvalue { i32, { i32 } } %A, i32 42, 1, 0 + // %C = extractvalue { i32, { i32 } } %B, 1, 0 + // with "i32 42" + return ReplaceInstUsesWith(EV, IV->getInsertedValueOperand()); + if (exti == exte) { + // The extract list is a prefix of the insert list. i.e. replace + // %I = insertvalue { i32, { i32 } } %A, i32 42, 1, 0 + // %E = extractvalue { i32, { i32 } } %I, 1 + // with + // %X = extractvalue { i32, { i32 } } %A, 1 + // %E = insertvalue { i32 } %X, i32 42, 0 + // by switching the order of the insert and extract (though the + // insertvalue should be left in, since it may have other uses). + Value *NewEV = InsertNewInstBefore( + ExtractValueInst::Create(IV->getAggregateOperand(), + EV.idx_begin(), EV.idx_end()), + EV); + return InsertValueInst::Create(NewEV, IV->getInsertedValueOperand(), + insi, inse); + } + if (insi == inse) + // The insert list is a prefix of the extract list + // We can simply remove the common indices from the extract and make it + // operate on the inserted value instead of the insertvalue result. + // i.e., replace + // %I = insertvalue { i32, { i32 } } %A, { i32 } { i32 42 }, 1 + // %E = extractvalue { i32, { i32 } } %I, 1, 0 + // with + // %E extractvalue { i32 } { i32 42 }, 0 + return ExtractValueInst::Create(IV->getInsertedValueOperand(), + exti, exte); + } + // Can't simplify extracts from other values. Note that nested extracts are + // already simplified implicitely by the above (extract ( extract (insert) ) + // will be translated into extract ( insert ( extract ) ) first and then just + // the value inserted, if appropriate). return 0; } -- cgit v1.2.3