CSE simple binary expressions when they are inserted. This makes LSR produce

less huge code that needs to be cleaned up by sdisel.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@35959 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2007-04-13 05:04:18 +00:00
parent 849c9a28e1
commit 7fec90ebf4
2 changed files with 32 additions and 9 deletions

View File

@ -89,7 +89,10 @@ namespace llvm {
/// we can to share the casts.
static Value *InsertCastOfTo(Instruction::CastOps opcode, Value *V,
const Type *Ty);
/// InsertBinop - Insert the specified binary operator, doing a small amount
/// of work to avoid inserting an obviously redundant operation.
static Value *InsertBinop(Instruction::BinaryOps Opcode, Value *LHS,
Value *RHS, Instruction *InsertPt);
protected:
Value *expand(SCEV *S) {
// Check to see if we already expanded this.
@ -141,8 +144,8 @@ namespace llvm {
// Emit a bunch of add instructions
for (int i = S->getNumOperands()-2; i >= 0; --i)
V = BinaryOperator::createAdd(V, expandInTy(S->getOperand(i), Ty),
"tmp.", InsertPt);
V = InsertBinop(Instruction::Add, V, expandInTy(S->getOperand(i), Ty),
InsertPt);
return V;
}
@ -152,7 +155,7 @@ namespace llvm {
const Type *Ty = S->getType();
Value *LHS = expandInTy(S->getLHS(), Ty);
Value *RHS = expandInTy(S->getRHS(), Ty);
return BinaryOperator::createSDiv(LHS, RHS, "tmp.", InsertPt);
return InsertBinop(Instruction::SDiv, LHS, RHS, InsertPt);
}
Value *visitAddRecExpr(SCEVAddRecExpr *S);

View File

@ -68,6 +68,25 @@ Value *SCEVExpander::InsertCastOfTo(Instruction::CastOps opcode, Value *V,
return CastInst::create(opcode, V, Ty, V->getName(), IP);
}
/// InsertBinop - Insert the specified binary operator, doing a small amount
/// of work to avoid inserting an obviously redundant operation.
Value *SCEVExpander::InsertBinop(Instruction::BinaryOps Opcode, Value *LHS,
Value *RHS, Instruction *InsertPt) {
// Do a quick scan to see if we have this binop nearby. If so, reuse it.
unsigned ScanLimit = 6;
for (BasicBlock::iterator IP = InsertPt, E = InsertPt->getParent()->begin();
ScanLimit; --IP, --ScanLimit) {
if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(IP))
if (BinOp->getOpcode() == Opcode && BinOp->getOperand(0) == LHS &&
BinOp->getOperand(1) == RHS)
return BinOp;
if (IP == E) break;
}
// If we don't have
return BinaryOperator::create(Opcode, LHS, RHS, "tmp.", InsertPt);
}
Value *SCEVExpander::visitMulExpr(SCEVMulExpr *S) {
const Type *Ty = S->getType();
int FirstOp = 0; // Set if we should emit a subtract.
@ -80,11 +99,12 @@ Value *SCEVExpander::visitMulExpr(SCEVMulExpr *S) {
// Emit a bunch of multiply instructions
for (; i >= FirstOp; --i)
V = BinaryOperator::createMul(V, expandInTy(S->getOperand(i), Ty),
"tmp.", InsertPt);
V = InsertBinop(Instruction::Mul, V, expandInTy(S->getOperand(i), Ty),
InsertPt);
// -1 * ... ---> 0 - ...
if (FirstOp == 1)
V = BinaryOperator::createNeg(V, "tmp.", InsertPt);
V = InsertBinop(Instruction::Sub, Constant::getNullValue(V->getType()), V,
InsertPt);
return V;
}
@ -103,7 +123,7 @@ Value *SCEVExpander::visitAddRecExpr(SCEVAddRecExpr *S) {
Value *Rest = expandInTy(SCEVAddRecExpr::get(NewOps, L), Ty);
// FIXME: look for an existing add to use.
return BinaryOperator::createAdd(Rest, Start, "tmp.", InsertPt);
return InsertBinop(Instruction::Add, Rest, Start, InsertPt);
}
// {0,+,1} --> Insert a canonical induction variable into the loop!
@ -164,7 +184,7 @@ Value *SCEVExpander::visitAddRecExpr(SCEVAddRecExpr *S) {
}
}
return BinaryOperator::createMul(I, F, "tmp.", MulInsertPt);
return InsertBinop(Instruction::Mul, I, F, MulInsertPt);
}
// If this is a chain of recurrences, turn it into a closed form, using the