Instruction *InsertBefore);
// SimplifyCommutative - This performs a few simplifications for commutative
- // operators...
+ // operators.
bool SimplifyCommutative(BinaryOperator &I);
+
+ // FoldOpIntoPhi - Given a binary operator or cast instruction which has a
+ // PHI node as operand #0, see if we can fold the instruction into the PHI
+ // (which is only possible if all operands to the PHI are constants).
+ Instruction *FoldOpIntoPhi(Instruction &I);
+
Instruction *OptAndOp(Instruction *Op, ConstantIntegral *OpRHS,
ConstantIntegral *AndRHS, BinaryOperator &TheAnd);
};
return IC->InsertNewInstBefore(New, BI);
}
+
+/// FoldOpIntoPhi - Given a binary operator or cast instruction which has a PHI
+/// node as operand #0, see if we can fold the instruction into the PHI (which
+/// is only possible if all operands to the PHI are constants).
+Instruction *InstCombiner::FoldOpIntoPhi(Instruction &I) {
+ PHINode *PN = cast<PHINode>(I.getOperand(0));
+ if (!PN->hasOneUse()) return 0;
+
+ // Check to see if all of the operands of the PHI are constants. If not, we
+ // cannot do the transformation.
+ for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
+ if (!isa<Constant>(PN->getIncomingValue(i)))
+ return 0;
+
+ // Okay, we can do the transformation: create the new PHI node.
+ PHINode *NewPN = new PHINode(I.getType(), I.getName());
+ I.setName("");
+ NewPN->op_reserve(PN->getNumOperands());
+ InsertNewInstBefore(NewPN, *PN);
+
+ // Next, add all of the operands to the PHI.
+ if (I.getNumOperands() == 2) {
+ Constant *C = cast<Constant>(I.getOperand(1));
+ for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
+ Constant *InV = cast<Constant>(PN->getIncomingValue(i));
+ NewPN->addIncoming(ConstantExpr::get(I.getOpcode(), InV, C),
+ PN->getIncomingBlock(i));
+ }
+ } else {
+ assert(isa<CastInst>(I) && "Unary op should be a cast!");
+ const Type *RetTy = I.getType();
+ for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
+ Constant *InV = cast<Constant>(PN->getIncomingValue(i));
+ NewPN->addIncoming(ConstantExpr::getCast(InV, RetTy),
+ PN->getIncomingBlock(i));
+ }
+ }
+ return ReplaceInstUsesWith(I, NewPN);
+}
+
// FoldBinOpIntoSelect - Given an instruction with a select as one operand and a
// constant as the other operand, try to fold the binary operator into the
// select arguments.
if (Val == (1ULL << NumBits-1))
return BinaryOperator::createXor(LHS, RHS);
}
+
+ if (isa<PHINode>(LHS))
+ if (Instruction *NV = FoldOpIntoPhi(I))
+ return NV;
}
// X + X --> X << 1
if (SelectInst *SI = dyn_cast<SelectInst>(Op1))
if (Instruction *R = FoldBinOpIntoSelect(I, SI, this))
return R;
+
+ if (isa<PHINode>(Op0))
+ if (Instruction *NV = FoldOpIntoPhi(I))
+ return NV;
}
if (BinaryOperator *Op1I = dyn_cast<BinaryOperator>(Op1))
if (SelectInst *SI = dyn_cast<SelectInst>(Op0))
if (Instruction *R = FoldBinOpIntoSelect(I, SI, this))
return R;
+
+ if (isa<PHINode>(Op0))
+ if (Instruction *NV = FoldOpIntoPhi(I))
+ return NV;
}
if (Value *Op0v = dyn_castNegVal(Op0)) // -X * -Y = X*Y
if (uint64_t C = Log2(Val))
return new ShiftInst(Instruction::Shr, I.getOperand(0),
ConstantUInt::get(Type::UByteTy, C));
+
+ if (isa<PHINode>(I.getOperand(0)) && !RHS->isNullValue())
+ if (Instruction *NV = FoldOpIntoPhi(I))
+ return NV;
}
// 0 / X == 0, we don't need to preserve faults!
if (!(Val & (Val-1))) // Power of 2
return BinaryOperator::createAnd(I.getOperand(0),
ConstantUInt::get(I.getType(), Val-1));
+ if (isa<PHINode>(I.getOperand(0)) && !RHS->isNullValue())
+ if (Instruction *NV = FoldOpIntoPhi(I))
+ return NV;
}
// 0 % X == 0, we don't need to preserve faults!
if (SelectInst *SI = dyn_cast<SelectInst>(Op0))
if (Instruction *R = FoldBinOpIntoSelect(I, SI, this))
return R;
+ if (isa<PHINode>(Op0))
+ if (Instruction *NV = FoldOpIntoPhi(I))
+ return NV;
}
Value *Op0NotVal = dyn_castNotVal(Op0);
if (SelectInst *SI = dyn_cast<SelectInst>(Op0))
if (Instruction *R = FoldBinOpIntoSelect(I, SI, this))
return R;
+ if (isa<PHINode>(Op0))
+ if (Instruction *NV = FoldOpIntoPhi(I))
+ return NV;
}
// (A & C1)|(A & C2) == A & (C1|C2)
if (SelectInst *SI = dyn_cast<SelectInst>(Op0))
if (Instruction *R = FoldBinOpIntoSelect(I, SI, this))
return R;
+ if (isa<PHINode>(Op0))
+ if (Instruction *NV = FoldOpIntoPhi(I))
+ return NV;
}
if (Value *X = dyn_castNotVal(Op0)) // ~A ^ A == -1
if (ConstantInt *CI = dyn_cast<ConstantInt>(Op1)) {
if (Instruction *LHSI = dyn_cast<Instruction>(Op0))
switch (LHSI->getOpcode()) {
+ case Instruction::PHI:
+ if (Instruction *NV = FoldOpIntoPhi(I))
+ return NV;
+ break;
case Instruction::And:
if (LHSI->hasOneUse() && isa<ConstantInt>(LHSI->getOperand(1)) &&
LHSI->getOperand(0)->hasOneUse()) {
if (SelectInst *SI = dyn_cast<SelectInst>(Op0))
if (Instruction *R = FoldBinOpIntoSelect(I, SI, this))
return R;
+ if (isa<PHINode>(Op0))
+ if (Instruction *NV = FoldOpIntoPhi(I))
+ return NV;
// If the operand is an bitwise operator with a constant RHS, and the
// shift is the only use, we can pull it out of the shift.
}
}
+ if (isa<PHINode>(Src))
+ if (Instruction *NV = FoldOpIntoPhi(CI))
+ return NV;
+
// If the source value is an instruction with only this use, we can attempt to
// propagate the cast into the instruction. Also, only handle integral types
// for now.