forked from OSchip/llvm-project
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:
parent
61feeb90f9
commit
cd62f11227
|
@ -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))
|
||||||
|
|
Loading…
Reference in New Issue