aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2006-03-05 00:22:33 +0000
committerChris Lattner <sabre@nondot.org>2006-03-05 00:22:33 +0000
commit220b0cf3e4ceb58d4f114f8cfc163e1f5836ab91 (patch)
tree55b9885f1aabd24500ffcd09c8a773bccf9fae6b
parent00195e1129ca54ab8241928cb11acb289d06fbb1 (diff)
downloadexternal_llvm-220b0cf3e4ceb58d4f114f8cfc163e1f5836ab91.zip
external_llvm-220b0cf3e4ceb58d4f114f8cfc163e1f5836ab91.tar.gz
external_llvm-220b0cf3e4ceb58d4f114f8cfc163e1f5836ab91.tar.bz2
Make vector narrowing more effective, implementing
Transforms/InstCombine/vec_narrow.ll. This add support for narrowing extract_element(insertelement) also. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@26538 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Transforms/Scalar/InstructionCombining.cpp84
1 files changed, 62 insertions, 22 deletions
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp
index c409e91..f12a9f9 100644
--- a/lib/Transforms/Scalar/InstructionCombining.cpp
+++ b/lib/Transforms/Scalar/InstructionCombining.cpp
@@ -6549,42 +6549,77 @@ Instruction *InstCombiner::visitSwitchInst(SwitchInst &SI) {
return 0;
}
+/// CheapToScalarize - Return true if the value is cheaper to scalarize than it
+/// is to leave as a vector operation.
+static bool CheapToScalarize(Value *V, bool isConstant) {
+ if (isa<ConstantAggregateZero>(V))
+ return true;
+ if (ConstantPacked *C = dyn_cast<ConstantPacked>(V)) {
+ if (isConstant) return true;
+ // If all elts are the same, we can extract.
+ Constant *Op0 = C->getOperand(0);
+ for (unsigned i = 1; i < C->getNumOperands(); ++i)
+ if (C->getOperand(i) != Op0)
+ return false;
+ return true;
+ }
+ Instruction *I = dyn_cast<Instruction>(V);
+ if (!I) return false;
+
+ // Insert element gets simplified to the inserted element or is deleted if
+ // this is constant idx extract element and its a constant idx insertelt.
+ if (I->getOpcode() == Instruction::InsertElement && isConstant &&
+ isa<ConstantInt>(I->getOperand(2)))
+ return true;
+ if (I->getOpcode() == Instruction::Load && I->hasOneUse())
+ return true;
+ if (BinaryOperator *BO = dyn_cast<BinaryOperator>(I))
+ if (BO->hasOneUse() &&
+ (CheapToScalarize(BO->getOperand(0), isConstant) ||
+ CheapToScalarize(BO->getOperand(1), isConstant)))
+ return true;
+
+ return false;
+}
+
Instruction *InstCombiner::visitExtractElementInst(ExtractElementInst &EI) {
if (ConstantAggregateZero *C =
dyn_cast<ConstantAggregateZero>(EI.getOperand(0))) {
// If packed val is constant 0, replace extract with scalar 0
const Type *Ty = cast<PackedType>(C->getType())->getElementType();
- EI.replaceAllUsesWith(Constant::getNullValue(Ty));
return ReplaceInstUsesWith(EI, Constant::getNullValue(Ty));
}
if (ConstantPacked *C = dyn_cast<ConstantPacked>(EI.getOperand(0))) {
// If packed val is constant with uniform operands, replace EI
// with that operand
- Constant *op0 = cast<Constant>(C->getOperand(0));
+ Constant *op0 = C->getOperand(0);
for (unsigned i = 1; i < C->getNumOperands(); ++i)
- if (C->getOperand(i) != op0) return 0;
- return ReplaceInstUsesWith(EI, op0);
+ if (C->getOperand(i) != op0) {
+ op0 = 0;
+ break;
+ }
+ if (op0)
+ return ReplaceInstUsesWith(EI, op0);
}
+
if (Instruction *I = dyn_cast<Instruction>(EI.getOperand(0)))
if (I->hasOneUse()) {
// Push extractelement into predecessor operation if legal and
// profitable to do so
if (BinaryOperator *BO = dyn_cast<BinaryOperator>(I)) {
- if (!isa<Constant>(BO->getOperand(0)) &&
- !isa<Constant>(BO->getOperand(1)))
- return 0;
- ExtractElementInst *newEI0 =
- new ExtractElementInst(BO->getOperand(0), EI.getOperand(1),
- EI.getName());
- ExtractElementInst *newEI1 =
- new ExtractElementInst(BO->getOperand(1), EI.getOperand(1),
- EI.getName());
- InsertNewInstBefore(newEI0, EI);
- InsertNewInstBefore(newEI1, EI);
- return BinaryOperator::create(BO->getOpcode(), newEI0, newEI1);
- }
- switch(I->getOpcode()) {
- case Instruction::Load: {
+ bool isConstantElt = isa<ConstantInt>(EI.getOperand(1));
+ if (CheapToScalarize(BO, isConstantElt)) {
+ ExtractElementInst *newEI0 =
+ new ExtractElementInst(BO->getOperand(0), EI.getOperand(1),
+ EI.getName()+".lhs");
+ ExtractElementInst *newEI1 =
+ new ExtractElementInst(BO->getOperand(1), EI.getOperand(1),
+ EI.getName()+".rhs");
+ InsertNewInstBefore(newEI0, EI);
+ InsertNewInstBefore(newEI1, EI);
+ return BinaryOperator::create(BO->getOpcode(), newEI0, newEI1);
+ }
+ } else if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
Value *Ptr = InsertCastBefore(I->getOperand(0),
PointerType::get(EI.getType()), EI);
GetElementPtrInst *GEP =
@@ -6592,9 +6627,14 @@ Instruction *InstCombiner::visitExtractElementInst(ExtractElementInst &EI) {
I->getName() + ".gep");
InsertNewInstBefore(GEP, EI);
return new LoadInst(GEP);
- }
- default:
- return 0;
+ } else if (InsertElementInst *IE = dyn_cast<InsertElementInst>(I)) {
+ // Extracting the inserted element?
+ if (IE->getOperand(2) == EI.getOperand(1))
+ return ReplaceInstUsesWith(EI, IE->getOperand(1));
+ // If the inserted and extracted elements are constants, they must not
+ // be the same value, replace with the pre-inserted value.
+ if (isa<Constant>(IE->getOperand(2)) && isa<Constant>(EI.getOperand(1)))
+ return ReplaceInstUsesWith(EI, IE->getOperand(0));
}
}
return 0;