make this code more efficient by not creating a phi node we are just going to

delete in the first place.  This also makes it simpler.

llvm-svn: 31562
This commit is contained in:
Chris Lattner 2006-11-08 19:29:23 +00:00
parent 61feeb90f9
commit cd62f11227
1 changed files with 33 additions and 36 deletions

View File

@ -6766,8 +6766,11 @@ Instruction *InstCombiner::FoldPHIArgBinOpIntoPHI(PHINode &PN) {
assert(isa<BinaryOperator>(FirstInst) || isa<ShiftInst>(FirstInst) || assert(isa<BinaryOperator>(FirstInst) || isa<ShiftInst>(FirstInst) ||
isa<GetElementPtrInst>(FirstInst)); isa<GetElementPtrInst>(FirstInst));
unsigned Opc = FirstInst->getOpcode(); unsigned Opc = FirstInst->getOpcode();
const Type *LHSType = FirstInst->getOperand(0)->getType(); Value *LHSVal = FirstInst->getOperand(0);
const Type *RHSType = FirstInst->getOperand(1)->getType(); Value *RHSVal = FirstInst->getOperand(1);
const Type *LHSType = LHSVal->getType();
const Type *RHSType = RHSVal->getType();
// Scan to see if all operands are the same opcode, all have one use, and all // 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). // kill their operands (i.e. the operands have one use).
@ -6779,52 +6782,46 @@ Instruction *InstCombiner::FoldPHIArgBinOpIntoPHI(PHINode &PN) {
I->getOperand(0)->getType() != LHSType || I->getOperand(0)->getType() != LHSType ||
I->getOperand(1)->getType() != RHSType) I->getOperand(1)->getType() != RHSType)
return 0; return 0;
// Keep track of which operand needs a phi node.
if (I->getOperand(0) != LHSVal) LHSVal = 0;
if (I->getOperand(1) != RHSVal) RHSVal = 0;
} }
// Otherwise, this is safe and profitable to transform. Create two phi nodes. // Otherwise, this is safe and profitable to transform. Create up to two phi
PHINode *NewLHS = new PHINode(FirstInst->getOperand(0)->getType(), // nodes.
FirstInst->getOperand(0)->getName()+".pn"); PHINode *NewLHS = 0, *NewRHS = 0;
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); Value *InLHS = FirstInst->getOperand(0);
NewLHS->addIncoming(InLHS, PN.getIncomingBlock(0));
Value *InRHS = FirstInst->getOperand(1); Value *InRHS = FirstInst->getOperand(1);
NewRHS->addIncoming(InRHS, PN.getIncomingBlock(0));
// Add all operands to the new PHsI. if (LHSVal == 0) {
for (unsigned i = 1, e = PN.getNumIncomingValues(); i != e; ++i) { NewLHS = new PHINode(LHSType, FirstInst->getOperand(0)->getName()+".pn");
Value *NewInLHS = cast<Instruction>(PN.getIncomingValue(i))->getOperand(0); NewLHS->reserveOperandSpace(PN.getNumOperands()/2);
Value *NewInRHS = cast<Instruction>(PN.getIncomingValue(i))->getOperand(1); NewLHS->addIncoming(InLHS, PN.getIncomingBlock(0));
if (NewInLHS != InLHS) InLHS = 0;
if (NewInRHS != InRHS) InRHS = 0;
NewLHS->addIncoming(NewInLHS, PN.getIncomingBlock(i));
NewRHS->addIncoming(NewInRHS, PN.getIncomingBlock(i));
}
Value *LHSVal;
if (InLHS) {
// The new PHI unions all of the same values together. This is really
// common, so we handle it intelligently here for compile-time speed.
LHSVal = InLHS;
delete NewLHS;
} else {
InsertNewInstBefore(NewLHS, PN); InsertNewInstBefore(NewLHS, PN);
LHSVal = NewLHS; LHSVal = NewLHS;
} }
Value *RHSVal;
if (InRHS) { if (RHSVal == 0) {
// The new PHI unions all of the same values together. This is really NewRHS = new PHINode(RHSType, FirstInst->getOperand(1)->getName()+".pn");
// common, so we handle it intelligently here for compile-time speed. NewRHS->reserveOperandSpace(PN.getNumOperands()/2);
RHSVal = InRHS; NewRHS->addIncoming(InRHS, PN.getIncomingBlock(0));
delete NewRHS;
} else {
InsertNewInstBefore(NewRHS, PN); InsertNewInstBefore(NewRHS, PN);
RHSVal = NewRHS; RHSVal = NewRHS;
} }
// Add all operands to the new PHIs.
for (unsigned i = 1, e = PN.getNumIncomingValues(); i != e; ++i) {
if (NewLHS) {
Value *NewInLHS =cast<Instruction>(PN.getIncomingValue(i))->getOperand(0);
NewLHS->addIncoming(NewInLHS, PN.getIncomingBlock(i));
}
if (NewRHS) {
Value *NewInRHS =cast<Instruction>(PN.getIncomingValue(i))->getOperand(1);
NewRHS->addIncoming(NewInRHS, PN.getIncomingBlock(i));
}
}
if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(FirstInst)) if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(FirstInst))
return BinaryOperator::create(BinOp->getOpcode(), LHSVal, RHSVal); return BinaryOperator::create(BinOp->getOpcode(), LHSVal, RHSVal);
else if (ShiftInst *SI = dyn_cast<ShiftInst>(FirstInst)) else if (ShiftInst *SI = dyn_cast<ShiftInst>(FirstInst))