Add ReplaceAllUsesWith that can take a vector of replacement values.

Add some foldings to hopefully help the illegal setcc issue, and move some code around.

llvm-svn: 23025
This commit is contained in:
Chris Lattner 2005-08-24 22:44:39 +00:00
parent 9130192229
commit d7ee4d8671
1 changed files with 90 additions and 15 deletions

View File

@ -534,8 +534,7 @@ SDOperand SelectionDAG::SimplifySetCC(MVT::ValueType VT, SDOperand N1,
case ISD::SETGE: return getConstant((int64_t)C1 >= (int64_t)C2, VT);
}
} else {
// If the LHS is a ZERO_EXTEND and if this is an ==/!= comparison, perform
// the comparison on the input.
// If the LHS is a ZERO_EXTEND, perform the comparison on the input.
if (N1.getOpcode() == ISD::ZERO_EXTEND) {
unsigned InSize = MVT::getSizeInBits(N1.getOperand(0).getValueType());
@ -577,6 +576,25 @@ SDOperand SelectionDAG::SimplifySetCC(MVT::ValueType VT, SDOperand N1,
default:
break; // todo, be more careful with signed comparisons
}
} else if (N1.getOpcode() == ISD::SIGN_EXTEND_INREG &&
(Cond == ISD::SETEQ || Cond == ISD::SETNE)) {
MVT::ValueType ExtSrcTy = cast<VTSDNode>(N1.getOperand(1))->getVT();
unsigned ExtSrcTyBits = MVT::getSizeInBits(ExtSrcTy);
MVT::ValueType ExtDstTy = N1.getValueType();
unsigned ExtDstTyBits = MVT::getSizeInBits(ExtDstTy);
// If the extended part has any inconsistent bits, it cannot ever
// compare equal. In other words, they have to be all ones or all
// zeros.
uint64_t ExtBits =
(~0ULL >> 64-ExtSrcTyBits) & (~0ULL << (ExtDstTyBits-1));
if ((C2 & ExtBits) != 0 && (C2 & ExtBits) != ExtBits)
return getConstant(Cond == ISD::SETNE, VT);
// Otherwise, make this a use of a zext.
return getSetCC(VT, getZeroExtendInReg(N1.getOperand(0), ExtSrcTy),
getConstant(C2 & (~0ULL >> 64-ExtSrcTyBits), ExtDstTy),
Cond);
}
uint64_t MinVal, MaxVal;
@ -1689,18 +1707,6 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
SDOperand N1, SDOperand N2, SDOperand N3,
SDOperand N4, SDOperand N5) {
if (ISD::SELECT_CC == Opcode) {
assert(N1.getValueType() == N2.getValueType() &&
"LHS and RHS of condition must have same type!");
assert(N3.getValueType() == N4.getValueType() &&
"True and False arms of SelectCC must have same type!");
assert(N3.getValueType() == VT &&
"select_cc node must be of same type as true and false value!");
SDOperand Simp = SimplifySelectCC(N1, N2, N3, N4,
cast<CondCodeSDNode>(N5)->get());
if (Simp.Val) return Simp;
}
std::vector<SDOperand> Ops;
Ops.reserve(5);
Ops.push_back(N1);
@ -1768,6 +1774,40 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
"Can't do FP-INT conversion!");
break;
}
case ISD::SELECT_CC: {
assert(Ops.size() == 5 && "TRUNCSTORE takes 5 operands!");
assert(Ops[0].getValueType() == Ops[1].getValueType() &&
"LHS and RHS of condition must have same type!");
assert(Ops[2].getValueType() == Ops[3].getValueType() &&
"True and False arms of SelectCC must have same type!");
assert(Ops[2].getValueType() == VT &&
"select_cc node must be of same type as true and false value!");
SDOperand Simp = SimplifySelectCC(Ops[0], Ops[1], Ops[2], Ops[3],
cast<CondCodeSDNode>(Ops[4])->get());
if (Simp.Val) return Simp;
break;
}
case ISD::BR_CC: {
assert(Ops.size() == 5 && "TRUNCSTORE takes 5 operands!");
assert(Ops[2].getValueType() == Ops[3].getValueType() &&
"LHS/RHS of comparison should match types!");
// Use SimplifySetCC to simplify SETCC's.
SDOperand Simp = SimplifySetCC(MVT::i1, Ops[2], Ops[3],
cast<CondCodeSDNode>(Ops[1])->get());
if (Simp.Val) {
if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Simp)) {
if (C->getValue() & 1) // Unconditional branch
return getNode(ISD::BR, MVT::Other, Ops[0], Ops[4]);
else
return Ops[0]; // Unconditional Fall through
} else if (Simp.Val->getOpcode() == ISD::SETCC) {
Ops[2] = Simp.getOperand(0);
Ops[3] = Simp.getOperand(1);
Ops[1] = Simp.getOperand(2);
}
}
break;
}
}
// Memoize nodes.
@ -1915,7 +1955,7 @@ void SelectionDAG::ReplaceAllUsesWith(SDNode *From, SDNode *To) {
for (unsigned i = 0, e = U->getNumOperands(); i != e; ++i)
if (U->getOperand(i).Val == From) {
assert(From->getValueType(U->getOperand(i).ResNo) ==
assert(U->getOperand(i).getValueType() ==
To->getValueType(U->getOperand(i).ResNo));
From->removeUser(U);
U->Operands[i].Val = To;
@ -1930,6 +1970,41 @@ void SelectionDAG::ReplaceAllUsesWith(SDNode *From, SDNode *To) {
}
}
void SelectionDAG::ReplaceAllUsesWith(SDNode *From,
const std::vector<SDOperand> &To) {
assert(From->getNumValues() == To.size() &&
"Incorrect number of values to replace with!");
if (To.size() == 1 && To[0].ResNo == 0) {
// Degenerate case handled above.
ReplaceAllUsesWith(From, To[0].Val);
return;
}
while (!From->use_empty()) {
// Process users until they are all gone.
SDNode *U = *From->use_begin();
// This node is about to morph, remove its old self from the CSE maps.
RemoveNodeFromCSEMaps(U);
for (unsigned i = 0, e = U->getNumOperands(); i != e; ++i)
if (U->getOperand(i).Val == From) {
const SDOperand &ToOp = To[U->getOperand(i).ResNo];
assert(U->getOperand(i).getValueType() == ToOp.getValueType());
From->removeUser(U);
U->Operands[i] = ToOp;
ToOp.Val->addUser(U);
}
// Now that we have modified U, add it back to the CSE maps. If it already
// exists there, recursively merge the results together.
if (SDNode *Existing = AddNonLeafNodeToCSEMaps(U))
ReplaceAllUsesWith(U, Existing);
// U is now dead.
}
}
//===----------------------------------------------------------------------===//
// SDNode Class
//===----------------------------------------------------------------------===//