[llvm-commits] CVS: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
Chris Lattner
sabre at nondot.org
Tue Oct 31 20:51:32 PST 2006
Changes in directory llvm/lib/Transforms/Scalar:
InstructionCombining.cpp updated: 1.529 -> 1.530
---
Log message:
Fold things like "phi [add (a,b), add(c,d)]" into two phi's and one add.
This triggers thousands of times on multisource.
---
Diffs of the changes: (+57 -3)
InstructionCombining.cpp | 60 ++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 57 insertions(+), 3 deletions(-)
Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp
diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.529 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.530
--- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.529 Thu Oct 26 14:19:06 2006
+++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Tue Oct 31 22:51:18 2006
@@ -276,7 +276,9 @@
// operator and they all are only used by the PHI, PHI together their
// inputs, and do the operation once, to the result of the PHI.
Instruction *FoldPHIArgOpIntoPHI(PHINode &PN);
-
+ Instruction *FoldPHIArgBinOpIntoPHI(PHINode &PN);
+
+
Instruction *OptAndOp(Instruction *Op, ConstantIntegral *OpRHS,
ConstantIntegral *AndRHS, BinaryOperator &TheAnd);
@@ -6778,6 +6780,56 @@
return true;
}
+/// FoldPHIArgBinOpIntoPHI - If we have something like phi [add (a,b), add(c,d)]
+/// and if a/b/c/d and the add's all have a single use, turn this into two phi's
+/// and a single binop.
+Instruction *InstCombiner::FoldPHIArgBinOpIntoPHI(PHINode &PN) {
+ Instruction *FirstInst = cast<Instruction>(PN.getIncomingValue(0));
+ assert(isa<BinaryOperator>(FirstInst) || isa<ShiftInst>(FirstInst));
+ unsigned Opc = FirstInst->getOpcode();
+
+ // Scan to see if all operands are the same opcode, all have one use, and all
+ // kill their operands (i.e. the operands have one use).
+ unsigned NumValues = PN.getNumIncomingValues();
+ for (unsigned i = 0; i != NumValues; ++i) {
+ Instruction *I = dyn_cast<Instruction>(PN.getIncomingValue(i));
+ if (!I || I->getOpcode() != Opc || !I->hasOneUse())
+ return 0;
+ }
+
+ // Otherwise, this is safe and profitable to transform. Create two phi nodes.
+ PHINode *NewLHS = new PHINode(FirstInst->getOperand(0)->getType(),
+ FirstInst->getOperand(0)->getName()+".pn");
+ NewLHS->reserveOperandSpace(PN.getNumOperands()/2);
+ PHINode *NewRHS = new PHINode(FirstInst->getOperand(1)->getType(),
+ FirstInst->getOperand(1)->getName()+".pn");
+ NewRHS->reserveOperandSpace(PN.getNumOperands()/2);
+
+ Value *InLHS = FirstInst->getOperand(0);
+ NewLHS->addIncoming(InLHS, PN.getIncomingBlock(0));
+ Value *InRHS = FirstInst->getOperand(1);
+ NewRHS->addIncoming(InRHS, PN.getIncomingBlock(0));
+
+ // Add all operands to the new PHsI.
+ for (unsigned i = 1, e = PN.getNumIncomingValues(); i != e; ++i) {
+ Value *NewInLHS = cast<Instruction>(PN.getIncomingValue(i))->getOperand(0);
+ Value *NewInRHS = cast<Instruction>(PN.getIncomingValue(i))->getOperand(1);
+ if (NewInLHS != InLHS) InLHS = 0;
+ if (NewInRHS != InRHS) InRHS = 0;
+ NewLHS->addIncoming(NewInLHS, PN.getIncomingBlock(i));
+ NewRHS->addIncoming(NewInRHS, PN.getIncomingBlock(i));
+ }
+
+ InsertNewInstBefore(NewLHS, PN);
+ InsertNewInstBefore(NewRHS, PN);
+
+ if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(FirstInst))
+ return BinaryOperator::create(BinOp->getOpcode(), NewLHS, NewRHS);
+ else
+ return new ShiftInst(cast<ShiftInst>(FirstInst)->getOpcode(),
+ NewLHS, NewRHS);
+}
+
// FoldPHIArgOpIntoPHI - If all operands to a PHI node are the same "unary"
// operator and they all are only used by the PHI, PHI together their
@@ -6794,9 +6846,11 @@
if (isa<CastInst>(FirstInst)) {
CastSrcTy = FirstInst->getOperand(0)->getType();
} else if (isa<BinaryOperator>(FirstInst) || isa<ShiftInst>(FirstInst)) {
- // Can fold binop or shift if the RHS is a constant.
+ // Can fold binop or shift here if the RHS is a constant, otherwise call
+ // FoldPHIArgBinOpIntoPHI.
ConstantOp = dyn_cast<Constant>(FirstInst->getOperand(1));
- if (ConstantOp == 0) return 0;
+ if (ConstantOp == 0)
+ return FoldPHIArgBinOpIntoPHI(PN);
} else {
return 0; // Cannot fold this operation.
}
More information about the llvm-commits
mailing list