[llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
Chris Lattner
lattner at cs.uiuc.edu
Mon Mar 10 15:44:01 PST 2003
Changes in directory llvm/lib/Transforms/Scalar:
InstructionCombining.cpp updated: 1.73 -> 1.74
---
Log message:
Generalize (A+c1)+c2 optimization to work with all associative operators
---
Diffs of the changes:
Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.73 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.74
--- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.73 Mon Mar 10 13:20:30 2003
+++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Mon Mar 10 15:43:22 2003
@@ -109,14 +109,49 @@
RegisterOpt<InstCombiner> X("instcombine", "Combine redundant instructions");
}
+// getComplexity: Assign a complexity or rank value to LLVM Values...
+// 0 -> Constant, 1 -> Other, 2 -> Argument, 2 -> Unary, 3 -> OtherInst
+static unsigned getComplexity(Value *V) {
+ if (isa<Instruction>(V)) {
+ if (BinaryOperator::isNeg(V) || BinaryOperator::isNot(V))
+ return 2;
+ return 3;
+ }
+ if (isa<Argument>(V)) return 2;
+ return isa<Constant>(V) ? 0 : 1;
+}
-// Make sure that this instruction has a constant on the right hand side if it
-// has any constant arguments. If not, fix it an return true.
+// SimplifyCommutative - This performs a few simplifications for commutative
+// operators:
+//
+// 1. Order operands such that they are listed from right (least complex) to
+// left (most complex). This puts constants before unary operators before
+// binary operators.
//
-static bool SimplifyBinOp(BinaryOperator &I) {
- if (isa<Constant>(I.getOperand(0)) && !isa<Constant>(I.getOperand(1)))
- return !I.swapOperands();
- return false;
+// 2. Handle the case of (op (op V, C1), C2), changing it to:
+// (op V, (op C1, C2))
+//
+static bool SimplifyCommutative(BinaryOperator &I) {
+ bool Changed = false;
+ if (getComplexity(I.getOperand(0)) < getComplexity(I.getOperand(1)))
+ Changed = !I.swapOperands();
+
+ if (!I.isAssociative()) return Changed;
+ Instruction::BinaryOps Opcode = I.getOpcode();
+ if (BinaryOperator *Op = dyn_cast<BinaryOperator>(I.getOperand(0))) {
+ if (Op->getOpcode() == Opcode && isa<Constant>(I.getOperand(1)) &&
+ isa<Constant>(Op->getOperand(1))) {
+ Instruction *New = BinaryOperator::create(I.getOpcode(), I.getOperand(1),
+ Op->getOperand(1));
+ Constant *Folded = ConstantFoldInstruction(New);
+ delete New;
+ assert(Folded && "Couldn't constant fold commutative operand?");
+ I.setOperand(0, Op->getOperand(0));
+ I.setOperand(1, Folded);
+ return true;
+ }
+ }
+ return Changed;
}
// dyn_castNegInst - Given a 'sub' instruction, return the RHS of the
@@ -157,7 +192,7 @@
Instruction *InstCombiner::visitAdd(BinaryOperator &I) {
- bool Changed = SimplifyBinOp(I);
+ bool Changed = SimplifyCommutative(I);
Value *LHS = I.getOperand(0), *RHS = I.getOperand(1);
// Eliminate 'add int %X, 0'
@@ -172,26 +207,6 @@
if (Value *V = dyn_castNegInst(RHS))
return BinaryOperator::create(Instruction::Sub, LHS, V);
- // Simplify add instructions with a constant RHS...
- if (Constant *Op2 = dyn_cast<Constant>(RHS)) {
- if (BinaryOperator *ILHS = dyn_cast<BinaryOperator>(LHS)) {
- if (ILHS->getOpcode() == Instruction::Add &&
- isa<Constant>(ILHS->getOperand(1))) {
- // Fold:
- // %Y = add int %X, 1
- // %Z = add int %Y, 1
- // into:
- // %Z = add int %X, 2
- //
- if (Constant *Val = *Op2 + *cast<Constant>(ILHS->getOperand(1))) {
- I.setOperand(0, ILHS->getOperand(0));
- I.setOperand(1, Val);
- return &I;
- }
- }
- }
- }
-
// X*C + X --> X * (C+1)
if (dyn_castFoldableMul(LHS) == RHS) {
Constant *CP1 = *cast<Constant>(cast<Instruction>(LHS)->getOperand(1)) +
@@ -279,7 +294,7 @@
}
Instruction *InstCombiner::visitMul(BinaryOperator &I) {
- bool Changed = SimplifyBinOp(I);
+ bool Changed = SimplifyCommutative(I);
Value *Op0 = I.getOperand(0);
// Simplify mul instructions with a constant RHS...
@@ -397,7 +412,7 @@
Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
- bool Changed = SimplifyBinOp(I);
+ bool Changed = SimplifyCommutative(I);
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
// and X, X = X and X, 0 == 0
@@ -429,7 +444,7 @@
Instruction *InstCombiner::visitOr(BinaryOperator &I) {
- bool Changed = SimplifyBinOp(I);
+ bool Changed = SimplifyCommutative(I);
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
// or X, X = X or X, 0 == X
@@ -457,7 +472,7 @@
Instruction *InstCombiner::visitXor(BinaryOperator &I) {
- bool Changed = SimplifyBinOp(I);
+ bool Changed = SimplifyCommutative(I);
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
// xor X, X = 0
@@ -510,11 +525,11 @@
if (Op0I->getOpcode() == Instruction::Or && Op0I->use_size() == 1) {
if (Op0I->getOperand(0) == Op1) // (B|A)^B == (A|B)^B
cast<BinaryOperator>(Op0I)->swapOperands();
- if (Op0I->getOperand(1) == Op1) { // (A|B)^B == ~B & A
+ if (Op0I->getOperand(1) == Op1) { // (A|B)^B == A & ~B
Value *NotB = BinaryOperator::createNot(Op1, Op1->getName()+".not", &I);
WorkList.push_back(cast<Instruction>(NotB));
- return BinaryOperator::create(Instruction::And, NotB,
- Op0I->getOperand(0));
+ return BinaryOperator::create(Instruction::And, Op0I->getOperand(0),
+ NotB);
}
}
@@ -543,7 +558,7 @@
}
Instruction *InstCombiner::visitSetCondInst(BinaryOperator &I) {
- bool Changed = SimplifyBinOp(I);
+ bool Changed = SimplifyCommutative(I);
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
const Type *Ty = Op0->getType();
More information about the llvm-commits
mailing list