forked from OSchip/llvm-project
Add new node, SELECT_CC. This node is for targets that don't natively
implement SELECT. llvm-svn: 22755
This commit is contained in:
parent
3428b95634
commit
e5b86d7442
|
@ -183,6 +183,19 @@ public:
|
||||||
ISD::CondCode Cond) {
|
ISD::CondCode Cond) {
|
||||||
return getNode(ISD::SETCC, VT, LHS, RHS, getCondCode(Cond));
|
return getNode(ISD::SETCC, VT, LHS, RHS, getCondCode(Cond));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// getSelectCC - Helper function to make it easier to build SelectCC's if you
|
||||||
|
/// just have an ISD::CondCode instead of an SDOperand.
|
||||||
|
///
|
||||||
|
SDOperand getSelectCC(SDOperand LHS, SDOperand RHS,
|
||||||
|
SDOperand True, SDOperand False, ISD::CondCode Cond) {
|
||||||
|
MVT::ValueType VT = True.getValueType();
|
||||||
|
assert(LHS.getValueType() == RHS.getValueType() &&
|
||||||
|
"LHS and RHS of condition must have same type!");
|
||||||
|
assert(True.getValueType() == False.getValueType() &&
|
||||||
|
"True and False arms of SelectCC must have same type!");
|
||||||
|
return getNode(ISD::SELECT_CC, VT, LHS, RHS, True, False,getCondCode(Cond));
|
||||||
|
}
|
||||||
|
|
||||||
/// getLoad - Loads are not normal binary operators: their result type is not
|
/// getLoad - Loads are not normal binary operators: their result type is not
|
||||||
/// determined by their operands, and they produce a value AND a token chain.
|
/// determined by their operands, and they produce a value AND a token chain.
|
||||||
|
|
|
@ -103,8 +103,14 @@ namespace ISD {
|
||||||
// Counting operators
|
// Counting operators
|
||||||
CTTZ, CTLZ, CTPOP,
|
CTTZ, CTLZ, CTPOP,
|
||||||
|
|
||||||
// Select operator.
|
// Select
|
||||||
SELECT,
|
SELECT,
|
||||||
|
|
||||||
|
// Select with condition operator - This selects between a true value and
|
||||||
|
// a false value (ops #2 and #3) based on the boolean result of comparing
|
||||||
|
// the lhs and rhs (ops #0 and #1) of a conditional expression with the
|
||||||
|
// condition code in op #4, a CondCodeSDNode.
|
||||||
|
SELECT_CC,
|
||||||
|
|
||||||
// SetCC operator - This evaluates to a boolean (i1) true value if the
|
// SetCC operator - This evaluates to a boolean (i1) true value if the
|
||||||
// condition is true. The operands to this are the left and right operands
|
// condition is true. The operands to this are the left and right operands
|
||||||
|
|
|
@ -362,7 +362,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
|
||||||
std::map<SDOperand, SDOperand>::iterator I = LegalizedNodes.find(Op);
|
std::map<SDOperand, SDOperand>::iterator I = LegalizedNodes.find(Op);
|
||||||
if (I != LegalizedNodes.end()) return I->second;
|
if (I != LegalizedNodes.end()) return I->second;
|
||||||
|
|
||||||
SDOperand Tmp1, Tmp2, Tmp3;
|
SDOperand Tmp1, Tmp2, Tmp3, Tmp4;
|
||||||
|
|
||||||
SDOperand Result = Op;
|
SDOperand Result = Op;
|
||||||
|
|
||||||
|
@ -911,6 +911,17 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
|
||||||
|
|
||||||
switch (TLI.getOperationAction(Node->getOpcode(), Tmp2.getValueType())) {
|
switch (TLI.getOperationAction(Node->getOpcode(), Tmp2.getValueType())) {
|
||||||
default: assert(0 && "This action is not supported yet!");
|
default: assert(0 && "This action is not supported yet!");
|
||||||
|
case TargetLowering::Expand:
|
||||||
|
if (Tmp1.getOpcode() == ISD::SETCC) {
|
||||||
|
Result = DAG.getSelectCC(Tmp1.getOperand(0), Tmp1.getOperand(1),
|
||||||
|
Tmp2, Tmp3,
|
||||||
|
cast<CondCodeSDNode>(Tmp1.getOperand(2))->get());
|
||||||
|
} else {
|
||||||
|
Result = DAG.getSelectCC(Tmp1,
|
||||||
|
DAG.getConstant(0, Tmp1.getValueType()),
|
||||||
|
Tmp2, Tmp3, ISD::SETNE);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case TargetLowering::Legal:
|
case TargetLowering::Legal:
|
||||||
if (Tmp1 != Node->getOperand(0) || Tmp2 != Node->getOperand(1) ||
|
if (Tmp1 != Node->getOperand(0) || Tmp2 != Node->getOperand(1) ||
|
||||||
Tmp3 != Node->getOperand(2))
|
Tmp3 != Node->getOperand(2))
|
||||||
|
@ -938,6 +949,29 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case ISD::SELECT_CC:
|
||||||
|
Tmp3 = LegalizeOp(Node->getOperand(2)); // True
|
||||||
|
Tmp4 = LegalizeOp(Node->getOperand(3)); // False
|
||||||
|
|
||||||
|
if (getTypeAction(Node->getOperand(0).getValueType()) == Legal) {
|
||||||
|
Tmp1 = LegalizeOp(Node->getOperand(0)); // LHS
|
||||||
|
Tmp2 = LegalizeOp(Node->getOperand(1)); // RHS
|
||||||
|
if (Tmp1 != Node->getOperand(0) || Tmp2 != Node->getOperand(1) ||
|
||||||
|
Tmp3 != Node->getOperand(2) || Tmp4 != Node->getOperand(3)) {
|
||||||
|
Result = DAG.getNode(ISD::SELECT_CC, Node->getValueType(0), Tmp1, Tmp2,
|
||||||
|
Tmp3, Tmp4, Node->getOperand(4));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
Tmp1 = LegalizeOp(DAG.getNode(ISD::SETCC, TLI.getSetCCResultTy(),
|
||||||
|
Node->getOperand(0), // LHS
|
||||||
|
Node->getOperand(1), // RHS
|
||||||
|
Node->getOperand(4)));
|
||||||
|
Result = DAG.getSelectCC(Tmp1,
|
||||||
|
DAG.getConstant(0, Tmp1.getValueType()),
|
||||||
|
Tmp3, Tmp4, ISD::SETNE);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case ISD::SETCC:
|
case ISD::SETCC:
|
||||||
switch (getTypeAction(Node->getOperand(0).getValueType())) {
|
switch (getTypeAction(Node->getOperand(0).getValueType())) {
|
||||||
case Legal:
|
case Legal:
|
||||||
|
@ -1999,6 +2033,13 @@ SDOperand SelectionDAGLegalize::PromoteOp(SDOperand Op) {
|
||||||
Tmp3 = PromoteOp(Node->getOperand(2)); // Legalize the op1
|
Tmp3 = PromoteOp(Node->getOperand(2)); // Legalize the op1
|
||||||
Result = DAG.getNode(ISD::SELECT, NVT, Tmp1, Tmp2, Tmp3);
|
Result = DAG.getNode(ISD::SELECT, NVT, Tmp1, Tmp2, Tmp3);
|
||||||
break;
|
break;
|
||||||
|
case ISD::SELECT_CC:
|
||||||
|
Tmp2 = PromoteOp(Node->getOperand(2)); // True
|
||||||
|
Tmp3 = PromoteOp(Node->getOperand(3)); // False
|
||||||
|
Result = DAG.getNode(ISD::SELECT_CC, NVT, Node->getOperand(0),
|
||||||
|
Node->getOperand(1), Tmp2, Tmp3,
|
||||||
|
Node->getOperand(4));
|
||||||
|
break;
|
||||||
case ISD::TAILCALL:
|
case ISD::TAILCALL:
|
||||||
case ISD::CALL: {
|
case ISD::CALL: {
|
||||||
Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain.
|
Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain.
|
||||||
|
@ -2733,6 +2774,16 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){
|
||||||
Hi = DAG.getNode(ISD::SELECT, NVT, C, LH, RH);
|
Hi = DAG.getNode(ISD::SELECT, NVT, C, LH, RH);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case ISD::SELECT_CC: {
|
||||||
|
SDOperand TL, TH, FL, FH;
|
||||||
|
ExpandOp(Node->getOperand(2), TL, TH);
|
||||||
|
ExpandOp(Node->getOperand(3), FL, FH);
|
||||||
|
Lo = DAG.getNode(ISD::SELECT_CC, NVT, Node->getOperand(0),
|
||||||
|
Node->getOperand(1), TL, FL, Node->getOperand(4));
|
||||||
|
Hi = DAG.getNode(ISD::SELECT_CC, NVT, Node->getOperand(0),
|
||||||
|
Node->getOperand(1), TH, FH, Node->getOperand(4));
|
||||||
|
break;
|
||||||
|
}
|
||||||
case ISD::SIGN_EXTEND: {
|
case ISD::SIGN_EXTEND: {
|
||||||
SDOperand In;
|
SDOperand In;
|
||||||
switch (getTypeAction(Node->getOperand(0).getValueType())) {
|
switch (getTypeAction(Node->getOperand(0).getValueType())) {
|
||||||
|
|
|
@ -686,8 +686,6 @@ SDOperand SelectionDAG::SimplifySetCC(MVT::ValueType VT, SDOperand N1,
|
||||||
return SDOperand();
|
return SDOperand();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// getNode - Gets or creates the specified node.
|
/// getNode - Gets or creates the specified node.
|
||||||
///
|
///
|
||||||
SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT) {
|
SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT) {
|
||||||
|
@ -1702,6 +1700,7 @@ const char *SDNode::getOperationName() const {
|
||||||
|
|
||||||
case ISD::SETCC: return "setcc";
|
case ISD::SETCC: return "setcc";
|
||||||
case ISD::SELECT: return "select";
|
case ISD::SELECT: return "select";
|
||||||
|
case ISD::SELECT_CC: return "select_cc";
|
||||||
case ISD::ADD_PARTS: return "add_parts";
|
case ISD::ADD_PARTS: return "add_parts";
|
||||||
case ISD::SUB_PARTS: return "sub_parts";
|
case ISD::SUB_PARTS: return "sub_parts";
|
||||||
case ISD::SHL_PARTS: return "shl_parts";
|
case ISD::SHL_PARTS: return "shl_parts";
|
||||||
|
|
Loading…
Reference in New Issue